DC motors (Part 2)

Part 1, 2, 3

Time for code ! Let’s write a few lines of trivial code in order to drive our controller (Check previous post). You probably heard about the analogWrite() function which is very convenient for generating PWM. Well, we will not use it ! Is it because it is too easy ? It is because there is a limited number of pins capable of generating a PWM signal ? Or is it because of the limited choice of base frequency ? All these arguments must be taken into account. However on top of that, the reason why we will use bit bang code relates to the need for having full and easy access to all timed events from each cycle. Although this choice may not look obvious to you now, it will in the next posts.

So here is the basic code that we will use as a staring point:

/* set pwm pin */
const uint8_t _outputPinMask = (1 << PINB5);
volatile uint8_t *_outputPort = &PORTB;
/* set timing variables */
const uint16_t _cycleTime = 10000; /* in micro seconds */
uint16_t _onTime = 0; /* in micro seconds */
uint32_t _lastCycleTime; /* in micro seconds */
uint32_t _lastOnTime; /* in micro seconds */
/* User defined pwm ratio */
uint8_t _pwmRatio = 50; /* from 0 to 100 */

void setup(void)
{
	/* Init pwm pin */
	*(_outputPort - 1) |= _outputPinMask; 
	/* Constrain pwm ratio */
	if (_pwmRatio < 0) {
		_pwmRatio = 0;
	} else if (_pwmRatio > 100) {
		_pwmRatio = 100;
	}	
	/* Compute on-time */
	_onTime = (((uint32_t)_cycleTime * _pwmRatio) / 100);
	/* Init cycle time */
	_lastCycleTime = (micros() - _cycleTime);
}


void loop(void)
{
	uint32_t now = micros();
	if (((now - _lastCycleTime) >= _cycleTime)) {
		/* cycle-time has elapsed */
		/* Reset timing variables */
		_lastCycleTime = now;
		_lastOnTime = now;
		/* turn motor ON (MOFET gate high) */
		*(_outputPort) |= _outputPinMask; 
	} else if (((now - _lastOnTime) >= _onTime)) {
		/* on-time has elapsed */
		/* turn motor OFF (MOFET gate low) */
		*(_outputPort) &= ~_outputPinMask; 
	}
}

If you are unsure about your electronic skills, do not connect anything thing to your Arduino board and just observe the built in LED. Using various PWM ratio will dim the LED accordingly. Once you are ready, it might be a good idea to see what’s going on using an oscilloscope. Connect the probe A to TP1 (as per the schematic below) and probe B to TP2. The clean signal from channel A (yellow trace) will be used for synchronization, while we will pay attention to the signal on channel B (blue trace).

pwm_driver

Set a PWM ratio of 50 (50% on 50% off), upload your code and will get these kind of plots on your screen. This is the plot of the signal at TP2 when the motor in not loaded:

pwm_signal_1

Under a moderate load, this what you’ll get

pwm_signal_2

Ultimately, this is the resulting plot when the rotor is blocked

pwm_signal_3

Let’s discuss these plots starting from the ON state (5 V applied to the gate of the MOSFET as per channel A): there’s nothing much we can say about it. The MOSFET does the job perfectly and switches one of the motor ends to the ground or almost to the ground. The OFF state shows a more confusing signal. The pattern of the signal looks the same under various load conditions: a strong spike which exceed the supply voltage followed by a plateau which is equal or lower than the supply voltage. On the other hand, we observe that the higher the load, the more intense is the signal.

The spike is no big surprise as you may already know that opening a circuit loaded with an inductance will generate an intense reverse voltage. This is the principle of boost voltage converters or spark plug ignition coils. As this pulse may severely impact other components, we will get rid of it using a clamp diode in parallel with the motor which will absorb the reverse voltage. Once again, we will use a slightly different option by using an other MOSFET which features a built in protective diode… See why in the next pictures, starting with a zoom in the spike area

Protective diode (1N4007), blocked motor shaft

NewFile0

Protective MOSFET, blocked motor shaft

NewFile1

Are you convinced by my choice? Note that a Schottky diode would do the job as well. However, if you have one MOSFET, it is very likely that you also have its little brother !

Next post on same subject

Leave a Reply

You must be logged in to post a comment.