Let's Make Robots!

L293D Motor Driver

Hey, can anyone tell me if the L293D motor driver chip can take an analog value to its input pins?

Or does it have to be a logical 1 or 0?

Just wondering if I can drive my motor at variable speeds with it, or if I only get one speed or no speed.

Here is a diagram of the chip:

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Calculon tried using his chip using PWM, by putting one input LOW, the other PWM (per motor). This didn't work. However, if he puts one input HIGH, the other PWM, it had the desired effect.

When doing it this way, you're actually "sinking" with the PWM, not "sourcing". So higher PWM actually goes slower than lower PWM value.

Thing is, putting one LOW and the other PWM works for one side. But that is an interesting idea, I might try it for the other side.

Ah, ok, that makes sense. Thanks, I get it now.

You aren't writing an analog value to the pins on the l293d. Analog write on the arduino is creating a pwm signal. The l293d only understands logic high and low. But if you change between the 2 quickly and with varying duty cycle(off time to on time) you get your motor speed control. All you have to worry about on the arduino is setting the speed via a number from 1 to 255.

If you were to use hardware based pwm it is much more involved setting up the registers for pulse width and duty cycle and clock.

I have tried using analogWrrite() on one of the PWM pins on the Arduino to the L293D, but the motor connected to that won't run. It doesn't matter what value I try, the motor doesn't want tio run on PWM. Can you think of a reason or solution to this?

Show me your code and I'll see if that's it. As you've had the ds kit running already I'll assume you have the circuit correct.

Oddbot: I have got it all connected up right, or so I assume, as both motors runs fine with a norma;l digital output. It is simply PWM that, on that one side f the L293D, won't function.

 

merser: Here's the drive code:

void driveForwards()
{
  digitalWrite(motor_left[0], HIGH);
  digitalWrite(motor_left[1], LOW);
  analogWrite(motor_right[0], 200);
  digitalWrite(motor_right[1], LOW);
}

 

if that is a digitalWrite(motor_right[0], HIGH);   it works fine.

But then the fault may be somewhere else. Why have you got what looks like an array subscript next to the motor name? Is there more than one left and right motor? It really helps if you are not stingy with your code. How much harder is it to post the whole sketch?

Sorry about that. No, there is only one for each, but the parts of the array are the pins:

motor_left[0] = pin 5, and [1] = pin 6.

Uh, the whole sketch is fairly large all up, but separated into three files, one with the drive functuions (forwards, back, left, right), the main one, and one with other stuff.

Pins 5 and 6 are both PWM pins tied to Timer0. You need to connect one of them to motor_left and the other to motor_right. Then the second pin of the motors can be a regular digital pin (for example 4 and 7). Lets group the pins like this:

#define motor_left_0    4 // direction pin, set it LOW for forward, HIGH for reverse
#define motor_left_1    5 // PWM pin, 0-255 values

#define motor_right_1  6 // PWM pin
#define motor_right_0  7 // direction pin, set it LOW for forward, HIGH for reverse

The enable pins have to be connected to Vcc (5V).

When driving forward, you set the direction pin LOW. A PWM value of 0 will have the motor stopped, then higher values make the motor spin faster and faster, 255 being the max speed.

When driving in reverse, you set the direction pin HIGH. A PWM value of 255 will have the motor stopped and lower vales will make the motor spin faster and faster, 0 being the max speed. To make this easy to use, just subtract the desired PWM value from 255 to get the inverted one, like this:

byte setPWM = 200;

//forward
digitalWrite(motor_right_0, LOW);
analogWrite(motor_right_1, setPWM);

//reverse
digitalWrite(motor_right_0, HIGH);
analogWrite(motor_right_1, 255-setPWM);

 

Does this look clear enough?