0

I tried to make a car that moves using a 4x4 keypad. Pressing "12" unlocks the car and sets the motors to move forward. After that, if I press 4, the speed of the left motor is reduced to half allowing the motor to turn left, and vice versa for right wheel when key 6 is pressed.

Here is the code:

#include <Key.h>
#include <Keypad.h>

char* startCar = "12";
int position = 0, state = 0;

/*
 * state 0: off
 * state 1: forward
 * state 2: backward
 * 
 */

const byte rows = 3; 
const byte cols = 3; 
char keys[rows][cols] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'}
};

byte rowPins[rows] = {2,3,4}; 
byte colPins[cols] = {PD7, PD6, PD5}; 
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);

int a=12,b=11,c=10,d=9;
void setup()                    
{
  pinMode(a,OUTPUT);
  pinMode(b,OUTPUT);
  pinMode(c,OUTPUT);
  pinMode(d,OUTPUT);
  Serial.begin(9600);
  setLocked(true);
}

void loop()                    
{
  char key = keypad.getKey();
  Serial.print(key);
  if (key == '9')
  {
    position = 0;
    setLocked(true);
  }
  if (key == startCar[position])
  {
    position ++;
  }
  if (position == 2)
  {
    setLocked(false);
  }
  if(state)
  {
    if(key=='2')
     {
      //Move forward
        state = 1;
        runmotors(255,0,0,255);
     }
     if(key=='8')
     {
      //Move backward
        state = 2;
        runmotors(0,255,255,0);
     }
    if(key == '4')
    {
      if(state == 1)
      {
        runmotors(127.5,0,0,255);
      }
        
      else if(state==2)
        runmotors(0,127.5,255,0);
    }
    if(key == '6')
    {
      if(state == 1)
        runmotors(255,0,0,127.5);
      else if(state==2)
        runmotors(0,255,127.5,0);
      
    }
  }
  delay(100);
}

void setLocked(int locked)
{
  if (locked)
  {
    state = 0;
    runmotors(0,0,0,0);
  }
  else
  {
    state = 1; // Moves forward 
    runmotors(127.5,0,0,255);  
  }
}
void runmotors(int s1,int s2,int s3,int s4)
{
  analogWrite(a,s1);
  analogWrite(b,s2);
  analogWrite(c,s3);
  analogWrite(d,s4);
}

Everything works perfectly, except for the fact that when the state is 1, i.e. car is running forward, and I press 4 the left motor completely stops instead of reduced speed. The LED on the motor driver shield which shows whether a motor is running or not also goes off. It is not a fault of the motor shield or the arduino as it worked when I test it individually with the motors (i.e. without the keypad etc).

Here is a photo of the shield: Arduino motor driver shield

Although my problem is not quite visible in this, but here is a video of the car: https://www.youtube.com/watch?v=bq19gNOL8Pg

  • If you pick the car up off the ground do the motors turn? In my experience you can't control speed on DC motors all the way to 0. At some point you hit a point where you're giving the motor power but just not enough to turn. On my tank robot a PWM of 127 usually just gets me a hum and no movement. Sometimes if I pick it up so that there is less rolling resistance the motor will turn a little. Try using like 200 or so instead and see if it works like that. That will at least tell you that the code is working. – Delta_G Jun 26 at 13:43
  • Also note that analogWrite only takes integer values. Sending 127.5 is the same as 127 in that case. – Delta_G Jun 26 at 13:43
  • @Delta_G, The LED on the motor shield shows whether a motor is getting power or not. That LED itself goes off. I think the particular pin (pin 12) of L293D is defective and is only supplying digital power, either full or 0. – Raghav Arora Jun 26 at 14:28
  • What board? On an UNO pin 12 is not a PWM pin. It will give full power for anything above 127 and nothing for 127 and below. It is truly a digital pin. – Delta_G Jun 26 at 18:24
  • Yes an Arduino Uno board using the L293D motor driver shield. robomart.com/…. According to the documentation, the pins for connecting the robots are 9,10,11,12. All other pins are working perfectly except pin 12. – Raghav Arora Jun 27 at 6:32
0

On an UNO only certain pins are capable of PWM. Pin 12 is not one of them. When you try to call analogWrite with pin 12 it will recognize this and will simply call digitalRead for you with HIGH or LOW depending on whether your input is greater than 127.

With most motor controllers you can use one pin as a direction pin and the other as a PWM pin. So to go one direction you set pin 12 HIGH and do inverted PWM on 11 (if those indeed go to the same motor I didn't look at your shield). To go the other direction you write LOW on 12 and PWM on 11.

The motor turns when one pin is HIGH and the other is LOW. When you set pin 12 high then PWM pin 11, whenever 11 is LOW in the PWM cycle it is turning the motor on and when it is HIGH it is turning it off. So to make it run you might have to PWM 0 for go and 255 for stop. Sometimes your PWM is on the enable line and then you still use 255 for go and 0 for stop. It just depends on how things are wired.

When pin 12 is set to LOW then the motor is on when 11 is at the high part of the PWM cycle and off when it's low so you use 255 for go and 0 for stop. But the whole time pin 12 doesn't have to change.

Now I am not 100% sure that this is the case with your particular motor controller, I'm more of a coder than a hardware guy. But I've written enough code for motor controllers to know that you usually either need two direction lines and one PWM line or one direction and one PWM. If that's not the case here then we can let someone else work on why.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.