# understanding how a motor is controlled with an L293D and raspberry pi

See update, picture of robot below.

So today I hooked up a motor and made it spin with my raspberry pi and an L293D by reading this tutorial.

This is what the circuit looks like (larger pictures):

It work's and I'm pretty happy. My end goal is to understand this and build something that can control two motors and I'm set to build a small bot :)

My issues:

If I'm not mistaken in this circuit, the enable pin on the L293D is getting a PWM signal for the speed of the motor it drives.

1. From the software page I can follow what the python is doing but I don't see where it says that pin 18 on the raspberry GPIO should be enabled as PWM? The docs say that Pin 12 supports PWM ? How does this work?

2. What if I didn't care about speed? Can I just use an regular GPIO pin for output a high on the enable of the L293D? With the Pi I'm assume that would out a 3.3v? And if I'm looking at the datasheet correct the enable pin can take upto 7v as a high? (What speed would it run on?)

3. Also again, if I didn't care about speed control, I could hook another GPIO to the second enable and control another motor also right. And I can then control each of they're directions?

Update:

Thanks @Passerby and @JImDearden I got it to work. No PWM, but just two motors. Like @Passerby says, I need three GPIO's for each motor. One for enable/disable and two for direction.

Here is what I made :) And it's wifi network controlled (with a wifi dongle attached) The cable is just a USB power cable :)

• You can control this motor controller with static DC voltages just as well as PWM voltages - it will mean the motor runs at full speed of course. – Andy aka Jun 24 '13 at 21:36

From the software page I can follow what the python is doing but I don't see where it says that pin 18 on the raspberry GPIO should be enabled as PWM? The docs say that Pin 12 supports PWM ? How does this work?

Not knowing the specifics of the RPI GPIO Library that Adafruit uses, but looking at the page you link to, it enables it with set("mode", "pwm"). As it says, The Python program first sets-up the two GPIO pins to be outputs. It then defines the same convenience function (“set”) that we used in Lesson 8, to write to the PWM Kernel Module. This is then used to set the parameters for PWM. The RPI hardware PWM is enabled through that library.

What if I didn't care about speed? Can I just use an regular GPIO pin for output a high on the enable of the L293D? With the Pi I'm assume that would out a 3.3v? And if I'm looking at the datasheet correct the enable pin can take upto 7v as a high? (What speed would it run on?)

Yes, you can do that. It would run at 100%, because you simply toggled the pin on. The voltage at the pin is not what sets the speed, but simply how fast you turn the pin off or on in a given time period that does. Like flipping a light switch on and off fast enough that it seems like the lights are only half on.

Also again, if I didn't care about speed control, I could hook another GPIO to the second enable and control another motor also right. And I can then control each of they directions?

Yes, but you would actual need three gpio to control both directions of one motor. 1 for the motor enable (on/off), and 2 for the motor 2 direction. Exactly as it is now, except without pwm.

• Thanks a bunch for your answer. For (1) I know I'm setting PWM mode, but how does it choose pin 18. Why not pin 17 or 15? For the last part, I'm going to try two motors. I'm (As usual) scared of burning my Pi, so if there anything plain wrong mistake I can make as a newbie here? – gideon Jun 25 '13 at 8:17
• @gideon it uses /sys/class/rpi-pwm/pwm0/ PWM0, which is active on gpio18. There is a second one, PWM1, but that's tied to the audio hardware, and is not normally accessible. As far as actual mistakes, well, if you wire it wrong, you might fry something. Like if you tie the gpio pins to your 6v battery somehow (for example, connecting it to the motor out pins instead of motor enable pins). Just you know, make sure you plug them in right. – Passerby Jun 25 '13 at 8:30
• I got it working with one motor and a regular GPIO. Just to confirm, the L293D is already connect to logic power from the Pi. Now all I need is two GPIO's from the Pi for direction and one GPIO to the enable2 pin right? – gideon Jun 25 '13 at 9:43
• @gideon yes. Notice that l293D's pin 1 is connected to the RPI PWM, that is the enable pin. Pin 2 and pin 7 are the two control/direction pins. For the other half, pin 9 is the enable pin, while pin 10 and 15 are the control/direction pins. – Passerby Jun 25 '13 at 9:54
• hey thanks @Passerby it works. I updated my question with a proof :) – gideon Jun 25 '13 at 11:39
1. Any general purpose I/O pin can be made to output a PWM signal, It is simply a matter of turning it ON for a given time and then OFF for the remainder of the period.

2. A continuous HIGH is just like a PWM with no OFF period so yes, the motor will run at full speed. The speed of the motor is a function of SUPPLY VOLTAGE and not the size of the enable signal. The motor supply is taken from the battery pack (6V)

3. With the right software (see answer 1) you could operate a second motor and control both speed and direction

• In this case, the RPI has hardware PWM, enabled through the python script. – Passerby Jun 25 '13 at 8:12
• Thanks for your answer yea I've been yea I've been looking into using software solutions to make any GPIO pin a PWM pin. I just want to get to control two motors first before burning anything. – gideon Jun 25 '13 at 8:13
• @gideon Your welcome - Always best to be cautious – JIm Dearden Jun 25 '13 at 11:02
• @Passerby a good point that ties up the documentation reference in the question. – JIm Dearden Jun 25 '13 at 11:08
• @JImDearden hey thanks. It works :) I updated my question. – gideon Jun 25 '13 at 11:39

While you can produce a PWM signal from any of the GPIO pins, the fact that the Raspberry Pi is not running a real time operating system means that using anything other than the hardware PWM outputs will be low performance and/or unpredictable, and the higher performance you try for the more unpredictable it will be. For stable robotic control you want it to be as predictable as is possible.

The WiringPi library appears to support both hardware PWM output on one GPIO pin and software PWM on any of the other GPIO pins. Which of these is suitable for your applications depends on how many PWM outputs you need and what performance you want out of those outputs.

If you application is tolerant of low timing resolution and high jitter then you could use a software timing loop. If you want higher precision / lower jitter PWM then you will need hardware assistance.

### When might Software PWM be suitable?

If you want to flash a bunch of LEDs with different human visible cadences (10's of hertz) with soft real-time response requirements then the software loop could handle as many PWM's as you have GPIO pins (more with multiplexes).

### When might Hardware PWM be suitable?

If you want to control a servo motor with hard real-time response requirements then you will need to use the Hardware PWM. Even then you may have problems ensuring a real-time response for the servo loop which ties encoder input to PWM output.

A stable servo loop needs to read encoders at a regular rate (low jitter), write out revised PWM output values at a regular rate and the latency between these should be fixed (low jitter overall) or you will have to under tune your motor to prevent it becoming unstable under load. This is hard to do with a multi-tasking operating system without low level support.

### What if I need multiple hardware PWM outputs?

If you need to run multiple servo loops, then you are probably going to need to offload them to another device to ensure hard real-time performance, relegating your Raspberry Pi to being a soft real-time supervisor.

One option, would be something like the Adafruit 16-Channel 12-bit PWM/Servo Driver - I2C interface - PCA9685 which would allow you to control 16 pwm outputs with just a few pins of GPIO for the I2C bus. For an example of it's use, check out the I2C 16 Channel PWM/Servo Breakout - Working post on the Raspberry Pi forums.

Based on my answer over on Raspberry Pi with thanks to Alex Chamberlain for his answer

• Hey thanks for your answer. I found the Adafruit servo driver but on the first page there was this line that got me confused : Note this cannot be used for driving anything other than analog (1-2 millisecond pulse drive) servos. DC motors, AC motors and digital servos are not going to work. I'm assuming they're saying you can't run the motors straight out of this controller, but you can just control them? Also in the tutorial the driver runs on a 5V/2A supply? Why is this? – gideon Jun 26 '13 at 8:17