A simple DC motor switch... that doesnt work! Why?

Hi!

Im kind of new with the Arduino...

I have run into some problems with my little code.. I trying to get a DC motor run back and forward with 2 buttons.

Im using a H-bridge L293NE.

I have wired it like this http://itp.nyu.edu/physcomp/images/labs/hbridge_labpinout.jpg

Motor Logic Pin 1 to pin 2 on the Arduino Motor Logic Pin 2 to pin 3 on the Arduino

And here is my code

int backPin = 2;      // back input
int forwardPin = 3;   // forward input
int motor1Pin = 4;    // H-bridge leg 1 (pin 2, 1A)
int motor2Pin = 5;    // H-bridge leg 2 (pin 7, 2A)
int enablePin = 9;    // H-bridge enable pin

void setup() {
  // set the back/forward pins as an input:
  pinMode(backPin, INPUT); 
  pinMode(forwardPin, INPUT);

  // set all the other pins you're using as outputs:
  pinMode(motor1Pin, OUTPUT); 
  pinMode(motor2Pin, OUTPUT); 
  pinMode(enablePin, OUTPUT);
  pinMode(ledPin, OUTPUT);

  // set enablePin high so that motor can turn on:
  digitalWrite(enablePin, HIGH); 

}

void loop() {

  if (digitalRead(backPin) == HIGH) {
    digitalWrite(motor1Pin, LOW);   // set leg 1 of the H-bridge low
    digitalWrite(motor2Pin, HIGH);  // set leg 2 of the H-bridge high
  }
  
 if (digitalRead(forwardPin) == HIGH) {
    digitalWrite(motor1Pin, HIGH);   // set leg 1 of the H-bridge high
    digitalWrite(motor2Pin, LOW);  // set leg 2 of the H-bridge low
  }
  else {
    digitalWrite(motor1Pin, LOW);  // set leg 1 of the H-bridge low
    digitalWrite(motor2Pin, LOW);   // set leg 2 of the H-bridge low
}

}

But my problem is that when i meassure between the two motor terminals, i get 5V in one direction, but only 2.5V in the other direction!

The 5V is correct, but why is it only pushing out 2.5 the other way?

The error lies in your if statement. The else if isn't logically correct.

void loop() {

  if (digitalRead(backPin) == HIGH) {
      //GO BACK
  }
  
 if (digitalRead(forwardPin) == HIGH) {
      //GO FWD
  }
  else {
      //STOP
  }

}

So you say that you get 5v in one direction but only 2.5 in the other. This makes sense looking at your code.

When you set the forwardPin = HIGH, all is well and you get 5v. The issue arises when backPin = HIGH.

Lets step through the code now.

  if (digitalRead(backPin) == HIGH) {
      //GO BACK
  }

This condition is TRUE, therefore the lines of code within the braces will be executed. In this case the motor will begin spinning backwards.

 if (digitalRead(forwardPin) == HIGH) {
      //GO FWD
  }

This condition is false so lets move on.

  else {
      //STOP
  }

execute the lines of code within these braces because we failed the previous if condition and this is an else. So now we stop the motor.

So you first started the motor. The motor runs for a bit, until we reach the if statement and then it stops. This cycle repeats. Your voltmeter displays average voltage sampled across a period of time, therefore it just so happens that within the sampling period, the output is high for half the duty cycle.

The error simply lies in the illogical placement of the else.

I have revised your code. Try this.

void loop() {

  //The if statement below doesn't handle the  (digitalRead(backPin) == HIGH && digitalRead(forwardPin) == HIGH) case
  if(digitalRead(backPin) == LOW && digitalRead(forwardPin) == LOW)
  {
    digitalWrite(motor1Pin, LOW);  // set leg 1 of the H-bridge low
    digitalWrite(motor2Pin, LOW);   // set leg 2 of the H-bridge low
  }
  else if(digitalRead(backPin) == HIGH && digitalRead(forwardPin) == LOW)
  {
    digitalWrite(motor1Pin, LOW);   // set leg 1 of the H-bridge low
    digitalWrite(motor2Pin, HIGH);  // set leg 2 of the H-bridge high
  }
  else if(digitalRead(backPin) == LOW && digitalRead(forwardPin) == HIGH)
  {
    digitalWrite(motor1Pin, HIGH);   // set leg 1 of the H-bridge high
    digitalWrite(motor2Pin, LOW);  // set leg 2 of the H-bridge low
  }
}

Notice how I am explicitly checking both the back and forward pins. I suggest you do this, it improves code readability and adds error handling with minuscule overhead

Not that my method is better, but just another route:

void loop()
{ 
    digitalWrite(motor1Pin, digitalRead(forwardPin));   
    digitalWrite(motor2Pin, digitalRead(backPin)); 
}

A side note: Don't bother with the enablePin on the H bridge. Why not just directly connect the enable pin to +5. If you ever want to stop the motor, just set both the motor logic pins to low, which is what your code currently does anyway.

THANKS MAN!! :D

Great explanation! I have a look at it when i get home!

Thanks again!

Works perfectly!

Thanks you man!!