As promised, here are some more details on how I implemented back-emf to control the wheel’s rotational speed.
First, what is back-emf exactly?
When you apply voltage to a DC motor, it turns. But also when the DC motor is turning, voltage appears on its pins, like a dynamo. This voltage is the back-emf I’m using here.
The back-emf voltage is proportional to the speed at which the motor turns, so it can be used to measure the motor speed. But this can only be measured when the pins are not already supplied with voltage from the h-bridge. So we need to “cut power” for short time intervals to do the measurement. For more details you can visit this site.
Here is a schematic of the circuit I used:
You’ll notice the h-bridge has one enable pin (E1/E2) for each input pin (I1/I2). I need separate enable pins when I measure the back-emf, because one output has to be set to ground, while the other is on hi-Z.
On most h-bridges I1 and I2 share the same enable pin. So to get around this limitation, I only use of the h-bridge. Then combine two halves to make a full h-bridge with separate E1/E2 pins. Luckily the L298 has 2 full h-bridges on the same chip. So I one L298, with its two h-bridges, controls a single DC motor.
Both motor wires are connected to analog input 0 through identical resistors. But since one of those 2 wires will always be set to the ground (exactly which one depends on motor direction), the other wire will receive the back-emf voltage from the motor. So effectively the three resistors are a voltage divider by 3. Since the theoretical maximum back-emf voltage is 12V, the analog would see a maximum of 4V, which is fine for its 5V range.
When the motor is running, the arduino will run the motor for 100ms, by setting one output to the ground and the other to a PWM signal.
When the 100ms are up, the PWM output will switch to hi-Z for 4ms: first 2ms to allow transient currents to flow out, then another 2ms to measure. The average voltage taken during those last 2ms is then compared to our target voltage. Then PWM signal driving the motor speed is increased or decreased depending on the difference between that average and the target voltage.
Arduino code I used for this project is available at http://code.google.com/p/robidouille/
There is room for improvement in the algorithm.
- the 2ms wait for transient voltage to dissipate is a maximum value. If we autodetected the end of the transient spike, we could start sampling the input voltage sooner
- the 2ms measuring and averaging voltages could also be shortened
- shortening the 4ms during which the motor is not driven, but back-emf voltage is instead measured would allow us to measure more frequently, and react more quickly to changing conditions.
While these 3 points are valid, I’ll wait for the motors to be mounted on an actual platform to make tweaks that are really necessary.
Here is the video showing back-emf in action.
Visit the Robidouille website for the latest updates to this project