Previous Tutorial | Tutorial 16 | Next Tutorial | |||||
DC Motor Speed Control With PIC And L293D IC | PWM | |||||||
Introductory Level★☆☆☆☆ |
In this tutorial, we’ll be doing DC motor speed control with PIC microcontrollers using PWM and L293D motor driver H-bridge IC. You’ll learn how DC motors work, How to control both the speed & direction of a DC motor. You’ll also get familiar with the required hardware driving circuitry. We’ll develop the required firmware code in order to control a DC motor as a practical Lab at the end of this tutorial. We’ll finally draw in some concluding remarks. So let’s get started!
[toc]
Required Components
Qty. | Component Name | Buy On Amazon.com |
1 | PIC16F877A | Add |
1 | BreadBoard | Add |
1 | DC Motor 12v 1000RPM | Add |
5 | Push Buttons | Add |
1 | Resistors Kit | Add Add |
1 | Capacitors Kit | Add Add |
1 | Jumper Wires Pack | Add Add |
1 | L293D DC Motor Driver | Add Add |
1 | LM7805 Voltage Regulator (5v) | Add |
1 | Crystal Oscillator | Add |
1 | PICkit2 or 3 Programmer | Add |
2 | 9v Battery or DC Power Supply | Add Add Add |
The Prototyping Board Setup
How A DC Motor Works?
DC Motors are very simple rotary actuators that transform electrical energy into a mechanical rotation at a specific torque. A typical DC motor will have the following features:
- Torque (in kg.cm)
- Rated Rotation Speed (RPM)
- Rated Full-Load current (e.x. 2A)
- Rated No-Load current (e.x. 0.2A)
- Rated voltage for operation (e.x. 12v)
image source (Renesas Electronics) @ renesas.com |
Electrical current is passing through coils that are arranged within a fixed magnetic field (Stator). The current generates magnetic fields in the coils. Which in turns causes the coil assembly (Rotor) to rotate, as each coil is pushed away from the like-pole and attracted to the unlike-pole of the stator.
Reversing the direction of current flow in the coil translates to an inversion in the direction of the rotor’s magnetic field. Which in turns applies an inversed torque of each side of the coil resulting in a reverse direction in the rotation.
This is simply how a DC motor is actually working. Now, it’s our mission to control the behavior of such a device as we’ll discuss in the section right below.
How To Control DC Motors?
Controlling a DC motor involves two different processes. The 1st one is controlling the direction of the motor’s rotation CW & CCW (Clock-Wise & Counter-Clock-Wise). The 2nd one is controlling the speed of rotation. Hereafter, we’ll discuss each of these processes in more detail.
Direction Control
To control the direction of a DC motor, you need to reverse the polarity of the input power source. In fact, polarity-reversal circuitry has many implications and it can go really complex and tricky. This sort of driver circuitry is called to be H-Bridge. it’s an H-shaped circuitry in which the DC motor is hooked through Switches/Transistors between the power rails ( VM & Ground ). Altering the activated switches reverses the polarity of the voltage (VM) applied to the DC Motor. Hence, the rotation direction is reversed.
Actually, a real-world H-bridge will not have ON/OFF switches. Instead, there will be 4-Transistors which are basically electronic switches doing the job of reversing the polarity of the motor supply voltage. Designing and building a fully-functioning H-Bridge circuit is beyond the intent of this tutorial. However, we’ll discuss a couple of ways to get polarity-reversal H-Bridge solutions on the cheap and so easily with the least overhead.
I- L293D Motor Driver IC
This integrated circuit (IC) is a 2-channel full H-Bridge motor driver. That is capable of driving two distinct DC motors. It’s the easiest way to go around building a whole H-Bridge driver from scratch. It comes in a DIP package which fits nicely on a typical breadboard. The L293D provides an easy wire-up interface with some decent features as follows:
- Motor Channels: 2
- Output Current Per Channel: 0.6A
- Output Peak Current (Non-Continuous): 1.2A
- Supply Voltage: up to 36v
- Switching Frequency: up to 5kHz
- Thermal Shutdown (Overheat Protection)
Here is the pinout diagram for an L293D motor driver ic
This is actually the driver circuitry we’ll be using in the following practical lab hereafter in this tutorial. However, I’ll also show you another simple way of driving DC motors in case you’re interested or don’t have an available L293D chip.
II- 2-Channel Relay Module
The rated values of voltage, current for each relay is printed/labeled on the electronic device package itself. Which you should be choosing carefully. Especially when driving large DC motors, but for now a small DC motor will cause no problem to any given relay. A couple of relays are basically capable of driving a single DC motor as shown in the diagram right below.
image sourcehttp://healthygets.info |
Activating (energizing) the coil of each relay will connect the COM pin to the NO pin. Hence the DC motor pins are connected to (the VM+ or to the V-). Which in turns makes the DC motor rotate clockwise (control signal 1,0), counter-clockwise (control signal 0,1) or stop! (when signal is 1,1 or 0,0).
Speed Control
Controlling the speed of a DC motor’s rotation (Permanent Magnet Motors) is basically achieved by a couple of ways as shown below:
- Variable Supply Voltage
- Using PWM-Controlled Gate
I- Variable Supply Voltage: can be achieved using voltage regulation circuitries. However. there are too many limitations and drawbacks to such a method. But theoretically, it just works and does the job! Varying the supply voltage will definitely control the motor’s speed accordingly.
II- Using PWM-Controlled Gate: is the most common technique for digitally-controlled systems. It’s basically done be isolating one of the power source rails from the H-Bridge circuitry using a transistor. Hence, creating an open circuit with the (Ground or VM+). In this way, activating the Control Gate (the transistor) will cause the H-Bridge to be powered-up then the motor will start rotating. Regardless of the direction of rotations, activating the control gate with a PWM signal will somehow control the average voltage being delivered from the supply to the motor through the control transistor. A simplified diagram is shown right below
The gate transistor in this setting is controlling whether the negative power rail is connected to the H-bridge circuit or not. By turning this transistor ON/OFF using a PWM signal, we’ll be seemingly controlling the average voltage being delivered to the DC Motor.
DC Motor Speed Control – LAB
Lab Name | DC Motor Speed Control (PWM) |
Lab Number | 14 |
Lab Level | Beginner |
Lab Objectives | Learn how to use PWM signal to control the speed of a DC Motor. Also, you should be using an L293D Motor Driver IC in order to control the direction of motor’s rotation. Push buttons should be used to specify the speed 0%, 50%, 75%, 100% and an extra button for reversing the direction of rotation. |
1. Coding
Open the MPLAB IDE and create a new project name it “DC_Motor_PWM”. If you have some issues doing so, you can always refer to the previous tutorial using the link below.
Set the configuration bits to match the generic setting which we’ve stated earlier. And if you also find troubles creating this file, you can always refer to the previous tutorial using the link below.
Now, open the main.c file and let’s start developing the firmware for our project.
Our first task is to define the IO pins used for controlling (choosing) the desired speed levels and direction reversal. Configuring these input pins can be done as shown below
1 2 3 4 5 6 7 | #define Rev RB0 // Reverse Direction Button #define LV0 RB1 // 0% Speed Button #define LV1 RB2 // 50% Speed Button #define LV2 RB3 // 75% Speed Button #define LV3 RB4 // 100% Speed Button TRISB = 0x1F; // Low 5-pins are input pins |
There should also be a couple of output pins in order to send the direction control logic signal to the motor driver. Let’s use a couple of PORTD pins for this function.
1 2 3 4 5 6 7 | // Set The Direction To Be Output Pins TRISD0 = 0; TRISD1 = 0; // Initially (0, 1) Say it's ClockWise rotation! // For Reversing The Direction Write (1, 0) RD0 = 0; RD1 = 1; |
Then we should configure the CCP module to operate in PWM mode. And to output a PWM signal with a 2kHz signal (any frequency is acceptable as long as it’s inside the 5kHz window). For this, we’ll be using the same lines of code in the previous lab
1 2 3 4 5 6 7 8 9 10 11 | //--[ Configure The CCP Module For PWM Mode ]-- CCP1M3 = 1; CCP1M2 = 1; TRISC2 = 0; // The CCP1 Output Pin (PWM) // Set The PWM Frequency (2kHz) PR2 = 124; // Set The PS For Timer2 (1:4 Ratio) T2CKPS0 = 1; T2CKPS1 = 0; // Start CCP1 PWM ! TMR2ON = 1; |
Now, it’s time to write the main loop (routine) of the system. Which is basically polling the Buttons and apply the respective action of varying the DC (duty cycle) or reversing the direction of rotation. Let’s first calculate the DC values to be written in each case for (0%, 50%, 75%, 100%) speed levels.
Using the exact resolution equation. And by substituting for Fosc, FPWM, and TMR2Presclaerin the following equation, we get the exact resolution for our PWM output
Resolution = 8.96578 bits
Hence, the maximum duty cycle 100% is given by writing 2Resolution = 28.96578= 500
Now, if 100% DC (duty cycle) is produced by writing 500 to the 10-Bit DC buffer register
Then, 50% DC is given by writing 250
And, 75% DC is given by writing 375
And of course, 0% DC is obtained by moving a 0 to the DC buffer register.
Obviously, we’re now done with writing the firmware. However, here is the full code listing for this LAB for you to use as a fully-functioning starting point for your projects. Which you can play around and make some changes to meet your application’s needs
The Full Code Listing
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | /* * LAB Number: 14 * LAB Name: PWM - DC Motor Speed Control * Author: Khaled Magdy * For More Information Visit My Website @ DeepBlueMbedded.com * */ #include <xc.h> #include <stdint.h> #include "config.h" #define _XTAL_FREQ 4000000 //--[ Pin Definitions ]-- #define Rev RB0 // Reverse Direction Button #define LV0 RB1 // 0% Speed Button #define LV1 RB2 // 50% Speed Button #define LV2 RB3 // 75% Speed Button #define LV3 RB4 // 100% Speed Button //================================ //--[ Function Declarations ]-- void PWM1_Set_Duty(uint16_t); void main(void) { //--[ Configuration For IO Pins ]-- TRISB = 0x1F; // Low 5-pins are input pins // Set The Direction To Be Output Pins TRISD0 = 0; TRISD1 = 0; // Initially (0, 1) Say it's ClockWise rotation! // For Reversing The Direction Write (1, 0) RD0 = 0; RD1 = 1; //--[ Configure The CCP Module For PWM Mode ]-- CCP1M3 = 1; CCP1M2 = 1; TRISC2 = 0; // The CCP1 Output Pin (PWM) // Set The PWM Frequency (2kHz) PR2 = 124; // Set The PS For Timer2 (1:4 Ratio) T2CKPS0 = 1; T2CKPS1 = 0; // Start CCP1 PWM ! TMR2ON = 1; // The Main Loop (Routine) while(1) { if(Rev) // Reverse The Direction { RD0 = ~RD0; RD1 = ~RD1; __delay_ms(500); // Wait For The Button To Be Released } if(LV0) // 0% DC { PWM1_Set_Duty(0); __delay_ms(100); // Wait For The Button To Be Released } if(LV1) // 50% DC { PWM1_Set_Duty(250); __delay_ms(100); // Wait For The Button To Be Released } if(LV2) // 75% DC { PWM1_Set_Duty(375); __delay_ms(100); // Wait For The Button To Be Released } if (LV3) // 100% DC { PWM1_Set_Duty(500); __delay_ms(100); // Wait For The Button To Be Released } __delay_ms(10);// Wait To Reduce The Simulation Overloading } return; } // Definition For PWM1_Set_Duty Function void PWM1_Set_Duty(uint16_t DC) { // Check The DC Value To Make Sure it's Within 10-Bit Range if(DC<1024) { CCP1Y = DC & 1; CCP1X = DC & 2; CCPR1L = DC >> 2; } } |
2. Simulation
To simulate the project, just hook an 5 Pull-Down Push Buttons to the pins RB0-RB4. Connect the L293D IC referring to the following connection diagram
Add the hex file and run the simulator. Here is the schematic for the full circuit diagram.
Note | |||
please, be advised that there are some inconsistencies in pinouts of the L293D simulation packages. So you should always refer to the datasheet to make sure you’re getting everything correctly. Or you can just follow the hand-drawn diagrams shown earlier. |
It’s highly recommended to hook an oscilloscope to the PWM output line in order to have a clear vision of what is exactly going on. Due to many factors, the motor speed of rotation may not be running in real-time on simulators. And here is the typical simulation results!
3. Prototyping
Prototyping this project involves connecting a relativelylarger power supply (12v). You should be careful about the motor driver connections. Just follow the schematic diagrams carefully and run your project! And here is the final running project in case you’re curious.
Pro Tips + Concluding Remarks
1
Shoot-Through Current
Let’s consider the following H-Bridge motor driver circuitry.
Controlling the direction of rotation is done via A, B control lines. If writing (1, 0) gives a clockwise rotation, then (0, 1) results in a counter-clockwise rotation. However, you should not reverse the direction at very high duty cycle as it’ll result in what we call Shoot-Through Current which is a guaranteed short-circuit between your power supply rails. Let’s dig deeper into this problem to see when it happens exactly.
At the moment pointed in the figure above. You’ll be switching from clockwise rotation to the counter-clockwise direction. At this moment both Line A and Line B are active (High) instantaneously before Line Drops down to 0. This means that both Q1 and Q2 are activated creating a guaranteed short-circuit between the power line and the ground and passing avery high amount of current through The couple of transistors. Which will damage both of them in the long run.
The bottom line. You shouldn’t hold both of line A & Line B High at any instance at any const for whatever reason! The other tip is to avoid switching the direction at a very high duty cycle. Just to reduce the effective (average) voltage pushing the Shoot-Through current in order to reduce the damage as much as possible.
2
Practical Limitations & PWM Frequency Effect
I- Duty Cycle Limitations
Common sense suggests that giving a DC motor 25% DC will result in a 25% speed of rotation and 50% DC will yield a 50% RPM of the motor’s rated speed. But neither will ever happen!
For each motor to start rotation it needs to gain the same rotational inertia in comparison to the static resistance of the grease, gearing, and gaps between commutators. Which essentially means that each DC motor starts rotating at a different value of duty cycle. Some motors start at 20% DC, maybe 25% or even 35% But the matter of fact is that no DC motor starts rotating at 1% DC. Instead, it should be producing a silenced whining kind of sound.
II- PWM Frequency Effect
Increasing the frequency above 20 kHz may silence the motor whining. But, many motors, transistors, or motor driver chips are unable to switch ON and OFF that quickly! You’ll need to experiment to select the suitable frequency for your particular motor and driver circuitry. I’ve selected 2kHz because it is likely to work for most generic DC motors and it’s also below the 5kHz cap for the L293D driver chip.
3
Soft-start .. Soft-end
If you’re involved in any kind of robotics or automation project, you should be aware of the following matter of fact. Inertia causes very strong vibrational motion to the DC motor and its mounting system at the beginning of the rotation. it gets more problematic when trying to accelerate from 0%DC to 100%DC instantly! or conversely, decelerates from 100% DC to 0%DC instantly (Brake). Then your robot will unintentionally drift a little bit or the overall system will be oscillatory.
The common practice to overcome such a problem is via implementing a soft-start soft-end routine in your code. This should be as easy as creating a loop that gradually increases the DutyCycle from 0% to the desired level during a specific time period. And also another loop for decelerating from the current DC level to 0% instead of the sudden breaking method. Here is a very simple example for implementing such a thing.
1 2 3 4 5 6 7 8 9 10 | // Accelerate From 0% To 100% in 1 Second // Duty Cycle Range (0-To-500) uint16_t DC=0; for(uint8_t i=0; i<10; i++) { Set_Duty(DC); DC += 50; __delay_ms(100); } |
Now, we’re done with PWM. Of course, there are many applications and interfacings that we can possibly do in the meantime. However, this series of tutorials is geared toward giving you all the fundamental concepts in the shortest possible time frame. Then, we’ll be interfacing all sensors, modules, and actuators that we’ve intentionally left over. So let’s move to the next module in our microcontroller!
Previous Tutorial | Tutorial 16 | Next Tutorial |