Professional Documents
Culture Documents
Introduction
Everywhere, where wheels are turning the interfacing of one or mostly more dc motors are necessary. For autonomous robots, wheel or crawler driven vehicles, for RC cars and boats for example, you need to control the motion of these crafts in a very precise manner from very slow to very fast. Breaking the motor is sometimes a design constrain, too. How to do this and how easy it is to implement the stuff with the .NET Micro Framework, this article is about. At first I dont want to explain the whole stuff in deep, because there are better sources where you can read something about PWM and H-Bridges in detail listed at the summarized links at the end of this article. But a short introduction should be useful for the understanding of the motor driver and .NET Micro Framework code explained here.
NON TFT Embedded Master Figure 1: GHI Embedded Boards and modules
PWM
Pulse width modulation (PWM) is a very simple and powerful technique to control an analog signal with a digital device, like a microcontroller. The simplicity is in the control electronics of a microcontroller that switches an analog signal on or off. When a digital pin port is switched from off to on and then back to off, a pulse is generated. When the port pin signal is switched on and off repeatedly, a pulse train is generated. By controlling the period of time from the start of one pulse to the start of the next pulse in a pulse train, the modulation can be established and controlled. By controlling the period of time that each pulse of a pulse train is on and the period (P) of time that each pulse of a pulse train is off the duty cycle (D) can be established and controlled. Pulse width modulation is the creation and control of a pulse trains frequency and duty cycle. Pulse width modulation can be used to control power and current of a device or to transmit information.
Figure 2: Pulse Width Modulation with Time-Varying Duty (D) Cycles in a pulse train
This very efficient technique employs pulses which are width modulated to generate the current through the coil of a motor. A 50% D (duty cycle) results in a perfect square wave (see below - Figure 3).
()
0
If the duty cycle is 25% the power reaching the driven device is nearly as high, too. If you drive a 12 Volt DC motor it is the same as if you drive 3 Volts (at 25% duty cycle). At 50% its like 6 V effective, at 75% its 9 V effective and at 100% are (nearly) the full 12 Volts present. PWM Effective Voltage
Figure 4: Relationship between duty cycles and effective voltage reaching of the driven device. Motor speed response to this signal shall be a continuous and monotonic function of the duty cycle of the signal, from 100% to the minimum RPM. The motor RPM (as a percentage of maximum RPM) should match the PWM duty cycle within 5%. The undetermined zone where a PWM signal is present while the motor isnt turning has to be found through experiments. It depends on the implemented motor or motor type, if it is gearless or not and on the retention force working against the power produced through the cyclic PWM signal. Speed versus PWM duty cycles
H-Bridge theory
H-Bridge The H-Bridge is a very simple device. As you can see in the schematic all you need to build one, are four switches. This is possible with relays, too but the current that can flow in such a relay application is not so high. A typical relay can drive approximately about 1-5 Amps depending on the type and is pretty voluminous. Power MOSFETs like the once used in the H-Bridge design shown later, are much better for high current applications and also smaller. Currents above 5 Amps are possible and we can drive pretty nice and powerful motors with or without gears, too. These motors can be built in robots for motion control or into crawler vehicles. If the H-Bridge is designed with SMDs (Surface Mounted Devices) the whole bridge will be very small and can be build in devices with few space left.
Figure 6: H-Bridge Function System An illegal state in a full quadrant H-bridge is one that turns on the upper source and lower sink on the same side (see Figure 7). This combination causes a direct short circuit to be created between the battery terminals or power source and usually causes one or both of the transistors that are on to go up in smoke. The current has only to flow through the motor (see Figure 8). The H-Bridge design (with friendly permission of Mr. Chuck McManis) shown and used in this article is avoiding this situation and the software cant produce such an illegal state. Turning the motor motion from clockwise to counter-clockwise or vice versa can lead to this not recommended state, too but only for the very short time the transistor is switching.
So please be aware of this, if you are changing the H-Bridge design to use other Transistors or POWER MOSFETs. First take a look into the design specifications of your Transistor or FET of choice underneath the switching behavior chapter for the falling and rising edges. The .NET Micro Framework is not very fast in execution of the code for the moment so problems are not expected here for now. But if the hardware gets more performant the code execution time and the transistor switching time will go down. Then maybe the source code has to be changed and some short wait states are necessary. So be aware of that, if you are using this code on faster hardware or if you are writing an own PWM driver. Illegal state left Illegal state right
Figure 7: Not recommended shorting the power source - producing a very high current
In Figure 8 you can see, how the rotation can be changed from clockwise to counterclockwise or vice versa. All we need now for controlling the motion and speed of the motor is the PWM signal switching on and off. Rotation clockwise Rotation counter-clockwise
Figure 9 shows how the whole stuff is working together: The .NET Micro Framework system, the H-Bridge and the motor - wired up like shown below. Arrange all together
Figure 9: Block schematic of the whole system What kind of signals do we need to control the motor in speed and motion? Forward (FWD) and Reverse (REV) are necessary for rotation control. Sending a high signal to FWD and a low signal to REV the motor isnt rotating. Even when the PWM signal is sent out to ENA the motor is going to rotate clockwise. The duty cycle of the pulse is equivalent to the motor speed.
Figure 10: Clockwise motion A low signal at FWD and a high signal at REV in conjunction with a PWM signal at ENA will force the motor to spin counter-clockwise.
Figure 11: Counter-clockwise motion With the PWM signal (ENA*) the speed of rotation (RPM: Rotations per Minute) can be controlled. The pulse width duty cycles are equivalent to the percentage of the voltage reaching the DC motor like explained before.
Figure 12: H-Bridge schematic (with friendly permission of Mr. Chuck McManis) The fast recovery diodes (shown in light blue) are optional when you are using the TIP102/107 as those transistors have a diode assembled. However you can include them for greater protection at higher currents. If size is an issue, you'll rather go with surface mounted devices than this type of circuits. Qty 2 2 4 4 4 4 4 Description TIP107, PNP Power Darlington Transistor (TO-220AB) TIP102, NPN Power Darlington Transistor (TO-220AB) 10K Ohm, Resistors 470 Ohm, Resistors 1K Ohm, Resistors Opto-coupler CNY17 III 1N4936, 1A Fast Recovery Rectifier (Optional if included in the transistor or FET)
Table 1) Parts List for the Simple H-Bridge You can notice that the opto-isolator LEDs are connected to the three previous described wires labeled "FWD" (forward), "REV" (reverse), and "ENA* (enable all)." These wires deserve a little bit more detailed explanation and notice.
Description Turn on upper left source and lower right sink. (go forward) Disable lower right sink. When fed a PWM signal the bridge modulates the "forward" current through the motor. Turn on both lower left sink and lower right sink, shorting the motor. This causes a rotating motor to stop rotating so this mode is called "Braking." Disable both lower sinks. When fed a PWM signal the bridge modulates the "braking" of the motor. Turn on the upper right source and lower left sink. (go backward) Disable lower left sink. When fed a PWM signal the bridge modulates the "reverse" current through the motor. Turn off all sources and sinks. "Coast" motor is not engaged at all.
1 0 0 0
1 1 1 0
1 0 1 0
0 0 1 Turn off all sources and sinks in a different way, same effect though. Table 2) Interfacing the H-Bridge (with friendly permission of Mr. Chuck McManis) This works because the processor pins become a connection to ground when they are outputting logic 0. When FWD is 1 and ENA is 0, the lower right sink is getting current from FWD which it is returning through the pin connected to ENA. At any given time the pin must be able to supply enough current to turn on two LEDs and when set to zero sink the current of two LEDs. With the 470 ohm resistors and a 3.3V processor like the GHI Embedded Master offers this is not a problem. From the data sheet on the opto-isolator, each LED has a forward voltage drop of 1.2V, so (3.3 - 1.2) / 330 is 6.4mA per LED or 12.8mA of load total. The selected GHI pin is specified to be able to drive 20mA. You can further replace the 330 ohm resistors with 470 ohm resistors to reduce the current through the LEDs. However the LED voltage drop can be as high as 1.4V and the GHI controller operating voltage can be as low as 3.0V, in that condition with 470 ohm resistors you would only put 3.4mA into each LED which is below the 5mA specified in the datasheet. The 470 ohm resistor is the better choice as it maintains a sufficient broad margin. The interface as designed gives you access to all of the interesting combinations of sinks and sources enable, while not allowed for any "illegal" state (see Figure 7 above). The human ear can hear frequencies up to roughly 20 kHz. When using PWM at frequencies below this, the device being driven can often be heard as a buzz. Higher frequencies avoid this but your cat or dog will probably leave the room, even if you cannot hear the frequency.
Table 3) GHI Embedded Master PWM pins (white: Non TFT, all pins on TFT module) The user would first initialize the needed PWM channel and then set the desired frequency and duty cycle which can be set to different values at anytime later. The Duty Cycle value is a percentage of the total period. Valid values are 0% to 100%, inclusive. Frequency can be set to 0 to disable the PWM module. Other values less or equal to PWM.MAX_FREQUENCY are also valid. Currently, the maximum value for the GHI Embedded Master is set to 10MHZ.
Example
// Initialize PWM 1 channel (PWM1.1 pin 17 see table 3 above) PWM pwmChannel1 = new PWM(PWM.PWMChannel.Channel_1);
PWM/MISC Header
PWM/MISC Header
PWM and other miscellaneous pins are available on this header (Figure 14). An LED is connected to PWM0 for a quick test of the PWM functionality, too. Its changing the intensity if the motor speed is going higher or lower. Header Pin # Function Pin Connected to H-Bridge 1 E13/P3.16/PWM0 (PWM Timer 0) ENA* 2 E14/P3.24/PWM1 (PWM Timer 1) 3 E16/P1.19/USB_PWR_EN FWD 4 E19/P1.27/USB_OC# REV 5 GND Table 4) the pins used for the interface are rendered in red
Figure 15: Wiring up the H-Bridge <Picture of the whole stuff> Figure 16: Board + H-Bridge
Percent_65 = 35, Percent_60 = 40, Percent_55 = 45, Half = 50, Percent_50 = 50, Percent_45 = 55, Percent_40 = 60, Percent_35 = 65, Percent_30 = 70, Percent_25 = 75, Percent_20 = 80, Percent_15 = 85, Percent_10 = 90, Percent_5 = 95, Stopped = 100, None = 100 } #endregion #region motor direction and PWM frequency enums public enum Direction : int { None, Left, Right, Break}; public enum Frequency : int { None = 0, kHz_20 = 20000, kHz_25 = 25000, kHz_30 = 30000, kHz_50 = 50000 }; #endregion #region initialization // moving states private Direction direction = Direction.None; // motor PWM parameter private int duty = (int)Speed.None; private PWM pwm = null; private Frequency fequency = Frequency.kHz_50; private PWM.PWMChannel pwmChannel = PWM.PWMChannel.Channel_0; //stearing ports for motor movement into //clockwise or counter-clockwise spin direction private OutputPort moveLeft; private OutputPort moveRight; #endregion #region constructors for motor PWM /// <summary> /// Initialization of the PWM stuff to stear a DC motor /// </summary> /// <param name="PWMPort">PWM Port Channel</param> public Motor(PWM.PWMChannel PWMPort) { // channel used this.pwmChannel = PWMPort; // preset port pins - change this if another hardware is used // false means: pin is not high! this.moveLeft = new OutputPort(EmbeddedMaster.Pins.E16, false); // false means: pin is not high! this.moveRight = new OutputPort(EmbeddedMaster.Pins.E19x, false); // the motor is current less this.duty = (int)Speed.None; // set PWM freq. to 50 kHz this.fequency = Frequency.kHz_50; StartMotorPWM(); System.Threading.Timer timer = new System.Threading.Timer(new TimerCallback(OnTimer), null, 0, 200); } /// <summary> /// Initialization of the PWM stuff to stear a DC motor.
/// Use this ctr if other pins for stearing the moting are wished /// </summary> /// <param name="PWMPort">PWM port channel</param> /// <param name="RightPin">Port pin for clokwise motion</param> /// <param name="LeftPin">Port pin for anti-clockwise motion</param> public Motor(PWM.PWMChannel PWMPort, Cpu.Pin RightPin, Cpu.Pin LeftPin) : this(PWMPort) { // false means: pin is not high! No signal to the pin no movement this.moveLeft = new OutputPort(LeftPin, false); // false means: pin is not high! No signal to the pin no movement this.moveRight = new OutputPort(RightPin, false); } /// <summary> /// Initialization of the PWM stuff to stear a DC motor. /// Use this ctr if all possibilities have to be set for /// stearing a motor and it's behaviour /// </summary> /// <param name="PWMPort">PWM port channel</param> /// <param name="RightPin">Port pin for clokwise motion</param> /// <param name="LeftPin">Port pin for anti-clokwise motion</param> /// <param name="Frequency">PWM frequency - use something above 20 kHz</param> /// <param name="dutyState">PWM duty cycle</param> public Motor(PWM.PWMChannel PWMPort, Cpu.Pin RightPin, Cpu.Pin LeftPin, Motor.Frequency Frequency, int dutyState) : this(PWMPort, RightPin, LeftPin) { this.duty = dutyState; this.fequency = Frequency; } #endregion #region private methods private void StartMotorPWM() { SystemManager.Start(null); this.pwm = this.pwm ?? new PWM(pwmChannel); this.pwm.Set((int)this.fequency, this.duty); } private void StopMotorPWM() { this.Dispose(); SystemManager.Shutdown(); } /// <summary> /// direction of motor movement /// </summary> /// <param name="direction">direction of movement</param> private int Velocity(int Speed) { if ((Speed >= 0) && (Speed <= 100)) { this.duty = (int)Speed; } return this.duty; } private void OnTimer(object state) { this.pwm.Set((int)this.fequency, this.duty); switch (this.direction) { case Direction.Right: this.moveRight.Write(true); this.moveLeft.Write(false); break;
case Direction.Left: this.moveLeft.Write(true); this.moveRight.Write(false); break; case Direction.Break: this.moveRight.Write(true); this.moveLeft.Write(true); break; case Direction.None: this.moveLeft.Write(false); this.moveRight.Write(false); break; default: this.moveLeft.Write(false); this.moveRight.Write(false); break; } } #endregion #region motor properties /// <summary> /// get/set the direction of motor movement /// </summary> /// <param name="direction">clockwise or anti-clockwise</param> public Direction Move { get { return this.direction; } set { this.direction = value; } } /// <summary> /// set/get the motor motion speed /// </summary> /// <param name="duty">the duty cycle is equivalent to the motor speed</param> public int MovingSpeed { get { return this.duty; } set { Velocity(value); } } #endregion #region IDisposable Members public void Dispose() { // Dispose PWM StopMotorPWM(); } #endregion } }
// Connect the button handler to all of the buttons. mainWindow.AddHandler(Buttons.ButtonDownEvent, new ButtonEventHandler(this.OnButtonDown), false);
// start the PWM test this.StartMotor(); return mainWindow; } private void StartMotor() {
this.motor = new Motor(PWM.PWMChannel.Channel_0); this.motor.MovingSpeed = (int)Motor.Speed.None; } private void OnExit() { // do shut down here... this.motor.Dispose(); } private void OnButtonDown(object sender, ButtonEventArgs e) { // Print the button code to the Visual Studio output window. Debug.Print(e.Button.ToString()); switch (e.Button) { case Button.VK_UP: if (this.motor.MovingSpeed > (int)Motor.Speed.Maximum) this.motor.MovingSpeed -= 5; else this.motor.MovingSpeed = (int)Motor.Speed.Maximum; break; case Button.VK_DOWN: if (this.motor.MovingSpeed < (int)Motor.Speed.Stopped) this.motor.MovingSpeed += 5; else this.motor.MovingSpeed = (int)Motor.Speed.Stopped; break; case Button.VK_LEFT: this.motor.Move = Motor.Direction.Left; break; case Button.VK_RIGHT: this.motor.Move = Motor.Direction.Right; break; case Button.VK_MENU: this.motor.Move = Motor.Direction.Break; break; case Button.VK_BACK: this.motor.Move = Motor.Direction.Break; break; case Button.VK_SELECT: this.motor.Move = Motor.Direction.None; break; default: this.motor.Move = Motor.Direction.None; break; } }
Whats next?
Motor driver designed with the integrated circuit LM298. A Power Supply steering the output voltage over PWM. A poor mans DAC with PWM.
Revision History
Revision 0.5 0.8 0.9 1.0 Description Initial Release - Internally Internal Release After Revision Initial Public Release Date 2009.23.April 2009.24.April 2009.04.Mai 2009.10.Mai
Sources:
(1) (2) (3) (4) (5) A Basic Step by Step Guide for .NET Micro Framework Application Development on the iPac 9302 (By Sean Liming & John R. Malin - SJJ Embedded Micro Solutions, LLC) Embedded Master User Manual; Rev. 2.03 Date: March 23, 2009 Embedded Master User Manual; Rev. 2.04 Date: April 29, 2009 Device solutions.net (http://devicesolutions.net/default.aspx?id=116) Expert .NET Micro Framework book by Apress written by Jens Khner (ISBN-13: 978-1-59059-973-0)
The really great home page of Mr. McManis (http://www.mcmanis.com/chuck/robotics/tutorial/h-bridge/index.html) Wikipedia, the free encyclopedia (http://en.wikipedia.org/wiki/H-bridge) http://www.discovercircuits.com/H/hbridge.htm http://electronicdesign.com/Articles/Index.cfm?AD=1&ArticleID=6199 http://www.4qdtec.com/bridge.html http://bansky.net/blog/2008/07/dc-motor-driver-and-power-supply-board/