2WD robot code

I am EXTREMELY NEW to Arduino and writing code. I've built a 2WD chassis connected an Arduino board w/ motor shield. Uploaded a test code I found on the Internet and the robot works fine. I've been unsuccessful in trying to write/find basic code for the robot to move forward (both wheels), stop, and move backwards (both wheels). I guess I don't get how the code controls the motors. Can anyone help an absolute newb at this?

You need to tell us more about the mechanics and the geometry.

What are you using to send the commands to the robot, the serial monitor?

If so try this, look at the example that controls an LED on or off.
Now your motors can be controlled either fully on/off OR with pulse width modulation. 0-255.

Try this.(psudocode)

If data from serial monitor is 'W' both motors are set HIgh.
Else if data == 'S', both motors reverse
...'A', rotate left
...'D', rotate right.

Motor1F = digitalWrite(LFmotorPin, HIGH);Motor2F = digitalWrite(RFmotorPin, HIGH);
Motor1R = digitalWrite(LRmotorPin, LOW);Motor2R = digitalWrite(RRmotorPin, LOW);

This will drive forward.

Uploaded a test code I found on the Internet and the robot works fine.

Perhaps you should post this working code as a place to start, then work from there.

I'm not home right now, but I will give you my old code that does exactly as my psudocode, if you want it.

Thanks, My inexperience is showing.

I bought the 2WD chassis. Built it and mounted a arduino uno with their motorshield on top. I connected the two motors (that came with the chassis) to the motorshield and the battery back to the power. Eventually we want to hook up a ultrasonic sensor to judge distance to the walls, but I need to walk first and get my head around the code.

I'm trying to figure out how to engage both motors equally, stop, and reverse. If someone could explain how that code would work it would be great as I have to explain it to my students who want this robot to build more on to it.
thanks

HazardsMind:
I'm not home right now, but I will give you my old code that does exactly as my psudocode, if you want it.

Thanks would be great. I'm trying to wrap my head on exactly HOW the code controls the motors.

zoomkat:

Uploaded a test code I found on the Internet and the robot works fine.

Perhaps you should post this working code as a place to start, then work from there.

Here is the test code I used to see if it worked OK..It basically made the bot do a figure 8

/*************************************************************
Motor Shield 2-Channel DC Motor Demo
by Randy Sarafan

For more information see:
http://www.instructables.com/id/Arduino-Motor-Shield-Tutorial/

*************************************************************/

void setup() {
  
  //Setup Channel A
  pinMode(12, OUTPUT); //Initiates Motor Channel A pin
  pinMode(9, OUTPUT); //Initiates Brake Channel A pin

  //Setup Channel B
  pinMode(13, OUTPUT); //Initiates Motor Channel A pin
  pinMode(8, OUTPUT);  //Initiates Brake Channel A pin
  
}

void loop(){

  
  //Motor A forward @ full speed
  digitalWrite(12, HIGH); //Establishes forward direction of Channel A
  digitalWrite(9, LOW);   //Disengage the Brake for Channel A
  analogWrite(3, 255);   //Spins the motor on Channel A at full speed

  //Motor B backward @ half speed
  digitalWrite(13, LOW);  //Establishes backward direction of Channel B
  digitalWrite(8, LOW);   //Disengage the Brake for Channel B
  analogWrite(11, 123);    //Spins the motor on Channel B at half speed

  
  delay(3000);

  
  digitalWrite(9, HIGH);  //Engage the Brake for Channel A
  digitalWrite(9, HIGH);  //Engage the Brake for Channel B


  delay(1000);
  
  
  //Motor A forward @ full speed
  digitalWrite(12, LOW);  //Establishes backward direction of Channel A
  digitalWrite(9, LOW);   //Disengage the Brake for Channel A
  analogWrite(3, 123);    //Spins the motor on Channel A at half speed
  
  //Motor B forward @ full speed
  digitalWrite(13, HIGH); //Establishes forward direction of Channel B
  digitalWrite(8, LOW);   //Disengage the Brake for Channel B
  analogWrite(11, 255);   //Spins the motor on Channel B at full speed
  
  
  delay(3000);
  
  
  digitalWrite(9, HIGH);  //Engage the Brake for Channel A
  digitalWrite(9, HIGH);  //Engage the Brake for Channel B
  
  
  delay(1000);
  
}

Moderator edit. Code tags.

Motor1F = digitalWrite(LFmotorPin, HIGH);

digitalWrite doesn't return anything, so this code is problematical.

Do yourself a big favour and start giving pins sensible names related to their function.

Arduino board w/ motor shield.

Do you have a link to this motor shield?

zoomkat:

Arduino board w/ motor shield.

Do you have a link to this motor shield?

This is the code that I've been playing with to have the robot go in a straight line

void setup() {

//Setup Channel A
pinMode(12, OUTPUT); //Initiates Motor Channel A pin
pinMode(9, OUTPUT); //Initiates Brake Channel A pin

//Setup Channel B
pinMode(13, OUTPUT); //Initiates Motor Channel A pin
pinMode(8, OUTPUT); //Initiates Brake Channel A pin

}

void loop(){

//Motor A forward @ full speed (left motor)
digitalWrite(12, LOW); //Establishes forward direction of Channel A left motor
digitalWrite(9, LOW); //Disengage the Brake for Channel A
analogWrite(3, 255); //Spins the motor on Channel A full speed

//motor B forward @ full speed (right motor)
digitalWrite (13, HIGH); //Establishes forward motion of Channel B right motor
digitalWrite (8, LOW); //Disengages the brake for Channel B
analogWrite (11, 255); //Spins the motor on Channel B full speed

}

issues???

This is the code that I've been playing with to have the robot go in a straight line

The robot will only go in a straight line if the motors are identical, the wheel are exactly the same size, and traction is perfect.

Since three of those things are unlikely to be true, your assumption that the robot will go in a straight line is also unlikely to be true.

Start by looking at the motor shield doc's.

You have 2 pins which control each motor. One for the direction (forward/backward) and one for the speed of the motor.

So both motors set to forward at the same speed will give you something like a straight line forward, both to backward at the same speed it goes backward.

Now play with other comboes and see what happens.

Mark

PS take a go long look at blink without delay, as you can'tuse code with delay()'s in it and a sensor.

M

issues?

You tell us - you're the one with the eyeballs on the project.

digitalWrite (13, HIGH); //Establishes forward motion of Channel B right motor

A simple sensible pin name would have been shorter and more descriptive than the comment.

I should have mentioned before, my code works with a basic H-Bridge driver that I built myself, it use 2 pins to control a single motor. I label my pins as
left(L) forward(F) motor1, for the left motor drive forward .
........reverse(R) motor1 , for left motor drive reverse.

Likewise for the right motor.

Now which ever pin is high, tells which direction the motor is going, forward or reverse.

@AWOL
It does not need to return anything, it just has to go forward or backward based on which pin is HIGH.
My code can also use PWM, just change it to analogWrite( pin, 0-255), and the other to LOW or 0.

This can work with his motor shield, he just to change up the pins a little.

Here, this is my old testing code, you might be able to learn something from it and apply it to your project.
It is very primitive, and improper, but it does work. As and added bonus, this code also uses a Parallax ultrasonic ping sensor. (the 4 pin sensor)

/*
simple keyboard control test
 */
long duration, inches, cm;
const int ping = 7;//Sensor (trigger)
const int echo = 8;//Sensor (echo)
int distance;

char val;         // variable to receive data from the serial port
byte M1L = 3;// PWM
byte M1R = 5;// PWM
byte M2L = 9;// PWM
byte M2R = 6;// PWM

void setup()
{
  pinMode(M1L, OUTPUT);                                
  pinMode(M1R, OUTPUT);
  pinMode(M2L, OUTPUT);                                
  pinMode(M2R, OUTPUT);
  Serial.begin(9600);       // start serial communication at 9600bps

}

void loop() {
  if( Serial.available() )       // if data is available to read
  { 
    val = Serial.read();
    
    if( val == 'W' || val == 'w' )//forwards               
    {
      //Serial.println("Moving Forwards");  
      digitalWrite(M1L, HIGH); digitalWrite(M2L, HIGH);
      digitalWrite(M1R, LOW); digitalWrite(M2R, LOW);                 
    }
    else if( val == 'S' || val == 's' )//backwards              
    {
      //Serial.println("Moving Backwards");
      digitalWrite(M1L, LOW);  digitalWrite(M2L, LOW); 
      digitalWrite(M1R, HIGH); digitalWrite(M2R, HIGH);                   
    }
    else if( val == 'A' || val == 'a' )//Left         
    {
      //Serial.println("LEFT");
      digitalWrite(M1L, LOW);  digitalWrite(M2L, HIGH);    
      digitalWrite(M1R, HIGH); digitalWrite(M2R, LOW);              
    }
   else if( val == 'D' || val == 'd' )              
    {
      //Serial.println("RIGHT");
      digitalWrite(M1L, HIGH); digitalWrite(M2L, LOW);
      digitalWrite(M1R, LOW);  digitalWrite(M2R, HIGH);                 
    }    
    else { //full stop
      digitalWrite(M1L, LOW); digitalWrite(M2L, LOW);
      digitalWrite(M1R, LOW); digitalWrite(M2R, LOW);  
    } 
   if( val == 'R' || val == 'r' ){ //search mode
      getping();}  
  }
}

void getping()
{
  Serial.print("R is not pressed ");
  while(val == 'r')
  {
    Serial.print("R is pressed ");
    pinMode(ping, OUTPUT);
    digitalWrite(ping, LOW);
    delayMicroseconds(2);
    digitalWrite(ping, HIGH);
    delayMicroseconds(5);
    digitalWrite(ping, LOW);

    pinMode(echo, INPUT);
    duration = pulseIn(echo, HIGH);

    // convert the time into a distance
    inches = microsecondsToInches(duration);
    cm = microsecondsToCentimeters(duration);

    Serial.print(inches);
    Serial.print("in, ");
    Serial.print(cm);
    Serial.print("cm ");
    Serial.println();

    delay(100);


    //------Search for object with in range------

    if(inches > 12)
    { 
      Serial.println("Searching for object");
      analogWrite(M1R, 100);
      digitalWrite(M1L, LOW);
      analogWrite(M2L, 100);
      digitalWrite(M2R, LOW);
    }
    else if(inches >= 4 && inches <= 12)
    { 
      analogWrite(M1R, 90);
      digitalWrite(M1L, LOW);
      analogWrite(M2L, 90);
      digitalWrite(M2R, LOW);
      
      Serial.println("Object Found!!!");//Move forward to object
      if(inches <= 6){ distance = 450;}
      else distance = 300;
      
      delay(distance);
      Serial.println("Going to object"); //is within 5 inches
      while(inches != 3) //go to up object and stop when object 
      { 
        Serial.println(inches);
        pinMode(ping, OUTPUT);
        digitalWrite(ping, LOW);
        delayMicroseconds(2);
        digitalWrite(ping, HIGH);
        delayMicroseconds(5);
        digitalWrite(ping, LOW);
        pinMode(echo, INPUT);
        duration = pulseIn(echo, HIGH);
        inches = microsecondsToInches(duration);

        analogWrite(M1L, 100);
        digitalWrite(M1R, LOW);
        analogWrite(M2L, 100);
        digitalWrite(M2R, LOW);
      }
      digitalWrite(M1L, LOW); //all motors stop
      digitalWrite(M1R, LOW);
      digitalWrite(M2L, LOW);
      digitalWrite(M2R, LOW);

      delay(500);
      return;
    }
    
    if(val=='x')
    {
      Serial.print("Returning to prog ");
      return;
    } 
    else
    {
      Serial.print("X not pressed,");
    } 
  }
}


long microsecondsToInches(long microseconds)
{
  return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds)
{
  return microseconds / 29 / 2;
}

The magic in this code occurs in the analogWrite lines. There are small inconsistencies in all electric motors. Even if they are "IDENTICAL". but the faster motor will need a slightyly smaller value than 255 "the max". so take a few tries and slow the faster motor by 5 or so each time until you get them running as close to the same as possible. Let us say for example that motor a is the sluggish one and the robot wanders in a circle to the a motor side when going forward. Also when we give motor b an analog write command of only 200 the robot goes very nearly straight. Then we know that motor b must be skewed by 55 at full throttle forward. This can be easily done with the map function described in the docs. map motor a 0 to 255 forward and motor b 0 to 200 and it works relatively well. However not perfect. Now the flip side is that it is likely that in reverse the faster motor may be the other one or not. To make a robot go straight really you will need an input device of some sort that monitors actual position and changes the values to correct on the fly. There is a lipoly bord available at cute digi wit a gps chip that can tell a robot where it is with in 15 feet or so this robot would need a large out door playing field but they are a hoot to watch run around finding there targets.

Check this post i have it working with a ping sensor for object avoidance, a piezo for sounds, a robot has to make sounds :D, and 2 motors. i use a uno r3 and a
motorsheild r3 same as yours. just trying to get a led to light when the piezo beeps. robot has to have blinky lights also. :smiley: http://arduino.cc/forum/index.php/topic,115743.0.html