problems with robot using ultrasonic sensor to avoid obstacles [solved]

Hi!
This is my first Arduino project and I'm having problems. I want to make a robot use an ultrasonic sensor to tell it to back away when it gets within 10 centimeters of something. I'm using an Arduino Uno R3, a Makeblock Me ultrasonic sensor, an OSEPP MTD-01 motor driver, and 2 DC motors. My code is a combination of the ultrasonic sensor example in the IDE and a code for what I want to do from a book. I modified it for the motor driver but I think I'm trying to use the motor driver wrong, since I couldn't find any instructions online. The robot runs fine until right after the LED is on for 5 seconds, then I start having problems. First, both motors are running backwards though they were fine during setup. Then, if I put my hand in front of the sensor, the left motor starts going forwards while the right one just stops. When I move my hand both motors start going backwards again. Here's my code:

const int pwm1 = 11;//left motor  
const int in1 = 10;//left backward
const int in2 = 9;//left forward
const int pwm2 = 6;//right motor 
const int in3 = 5;// right backward
const int in4 = 4;// right forward
const int led = 13;
const int pingPin = 7;

 
void setup() {
  pinMode (pwm1, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(pwm2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  pinMode(led, OUTPUT);
  
  digitalWrite(in2, HIGH);
  digitalWrite(pwm1, 100);
  digitalWrite(in4, HIGH);
  digitalWrite(pwm2, 100);
  delay(1000);
  digitalWrite(in2, LOW);
  digitalWrite(pwm1, LOW);
  digitalWrite(in4, LOW);
  digitalWrite(pwm2, LOW);
  delay(1000);
  digitalWrite(in1, HIGH);
  digitalWrite(pwm1, 100);
  digitalWrite(in3, HIGH);
  digitalWrite(pwm2, 100);
  delay(1000);
  digitalWrite(in1, LOW);
  digitalWrite(pwm1, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(pwm2, LOW);
  
  digitalWrite(led, HIGH);//LED on for 5 seconds
  delay(5000);
  digitalWrite(led, LOW);
  Serial.begin(9600);// stops doing what i want it to do here
}
void loop(){
  digitalWrite(in2, HIGH);
  digitalWrite(pwm1, 100);
  digitalWrite(in4, HIGH);
  digitalWrite(pwm2, 100);
  uint8_t i;

  long duration, inches, cm;
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin,HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
  
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);
  cm = microsecondsToCentimeters(duration);
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  if (cm >10){
    digitalWrite(in2, LOW);//left motor, backwards
    digitalWrite(pwm1, LOW);
    digitalWrite(in1, HIGH);
    digitalWrite(pwm1, 100);

  //for (i=0; i<255; i++){
 // delay(10);}
  
  digitalWrite(in4, LOW);// right motor, backwards
  digitalWrite(pwm2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(pwm2, 100);
  for (i=0; i<255; i++){
  delay(10);}
  
digitalWrite(in3, LOW);//start both motors forward again
digitalWrite(in4, HIGH);
digitalWrite(in2, LOW);
digitalWrite(in1, HIGH);
delay(30);
  }
  else{
    digitalWrite(in2, HIGH);
    digitalWrite(pwm1, 100);
    digitalWrite(in4, HIGH);
    digitalWrite(pwm2, 100);
  }
  }
  long microsecondsToCentimeters(long microseconds)
  {
  
    return microseconds / 29/ 2;}

And here's the one I modified it from:

#include <AFMotor.h>
AF_DCMotor motorleft(1);
AF.DCMotor motorright(4);
const int pingPin = 7;
void setup() {
  Serial.begin(9600);
  motorleft.setSpeed(50);
  motorright.setSpeed(50);

}

void loop() {
 uint8_t i;
 long duration, inches, cm;
 pinMode(pingPin, OUTPUT);
 digitalWrite(pingPin, LOW);
 delayMicroseconds(2);
 digitalWrite(pingPin, HIGH);
 delayMicroseconds(5);
 digitalWrite(pingPin,LOW);
 pinMode(pingPin, INPUT);
 duration = pulseIn(pingPin, HIGH);
 cm = microsecondsToCentimeters(duration);
 Serial.print(cm);
 Serial.print("cm");
 Serial.println();
 if (cm>10){
  motorleft.run(BACKWARD);
  for (i=0; i<255; i++){
    motorleft.setSpeed(i);
    delay(10);}
    motorright.run(BACKWARD);
    for (i=0, i<255; i++){
      motorright.setSpeed(i);
      delay(10);
    }
    motorleft.run(RELEASE);
    motorright.run(RELEASE);
    delay(30);
 }
}
long microsecondsToCentimeters(long microseconds)
{
  return microseconds / 29 / 2;
}

I have checked my wiring. Since I'm a noob and don't really know what every single part of the code is doing, I'm probably using it wrong and making some noob mistake, though I have no idea what. Thanks in advance for any help!
-p.

So why did you decide to use the Make Me sensor like that instead of using the library and instructions from the website at http://learn.makeblock.com/en/me-ultrasonic-sensor/ ? I would have thought that would be easier. But since you have those serial writes in there, is it actually getting the distances correct?

And then there is the question of why you're running the motors and switching LED on and off in setup() which only runs once when the Arduino is powered on. That routine is usually used just to set up (as the name suggests) some default conditions and do one-off things like enabling Serial, the drivers etc. But since you have all that code in there what EXACTLY do the motors do at that point?

Can you please post a diagram showing exactly how you have the motor driver and sensors wired to the Arduino, including power and ground connections. I'm sure you have checked that it is wired as you intended but unfortunately that may not be how it actually needs to be wired.

Steve

Thanks for the reply! I just got the sensor on Amazon and didn't realize it had a library. It looks like it is getting the distances right.
That whole weird setup thing was just so I could see exactly how far my sketch got before it started not working like I wanted. The motors run forward for a second, stop for a second, then run backward for a second. That part seems to be working fine.
Here's how it's all wired:
Sorry for the rough diagram! Hope it's not too hard to read.
-p.

Diagram 2.pdf (643 KB)

Hi,
What is your battery pack?

Thanks.. Tom... :slight_smile:

The diagram is a little confusing because the motors are not shown where the code says they should be.

But I'm guessing that the main problems with your code in loop() are :

  1. You're normally only setting half the motor control pins e.g. you set in2 and in4 HIGH but ignore in1 and in3 so leaving their values at whatever they were last set at. The motor driver will throw up its hands in disgust if you set both Go Back and Go Forward to HIGH for a single motor. Basically to use that motor driver safely you have to set both motor pins for each motor every time. You're getting away with it once in setup() but not when it's looping round. You may have spotted this more easily if you'd used more meaningful variable names like leftReverse, rightForward instead of in1, 2, 3 etc.

  2. The other thing is that to control motor speed with PWM you use analogWrite() to the PWM pins not digitalWrite(). The 2nd parameter to digitalWrite() is HIGH or LOW so setting it to 100 doesn't make much sense.

Steve

Thanks for replying! My battery pack is just a 6 AA pack with a switch, and six 1.5 volt batteries.

Should I just use HIGH for PWM or should I replace digitalWrite() with analogWrite()?

So I need to make sure that I'm not telling my motor driver to go forwards and backwards at the same time? I thought I had checked for that and used digitalWrite(whatever it was, LOW) before turning the opposite pin HIGH. Is there some sort of problem because of the fact that it's looping and I need to digitalWrite everything LOW before starting the loop again? Or are the values only set LOW in a certain function and go back to HIGH when it's over?

Thanks so much for helping!
-p.

padawan:
Thanks for replying! My battery pack is just a 6 AA pack with a switch, and six 1.5 volt batteries.

Should I just use HIGH for PWM or should I replace digitalWrite() with analogWrite()?

So I need to make sure that I'm not telling my motor driver to go forwards and backwards at the same time? I thought I had checked for that and used digitalWrite(whatever it was, LOW) before turning the opposite pin HIGH. Is there some sort of problem because of the fact that it's looping and I need to digitalWrite everything LOW before starting the loop again? Or are the values only set LOW in a certain function and go back to HIGH when it's over?

If the batteries are alkaline you should be o.k. Carbon-zinc could be a problem delivering enough current.

If you don't use analogWrite() you don't get any PWM so no control over the speed. Just OFF or ON at full speed. If that's what you want then you should be o.k.

As for the rest I simply can't follow what it's trying to do so you may be right that you have it covered. To me it looks as if you go forward then check the sensor and if there's nothing within 10cm you reverse a bit and then go straight forward again. Should that test perhaps have been if (cm < 10)? I also can't see why the last thing in the loop sets it drive forward and then at the start of the loop before any checking you set the same conditions again...but perhaps there is some reason for it that I just haven't noticed.

Steve

Hi,
How are you using your ultrasonic device, you need 4 wires, two for supply and one for "ping" and the other for "echo".

~~http://howtomechatronics.com/tutorials/arduino/ultrasonic-sensor-hc-sr04/~~

Edit. Sorry you are using the Make Sonic unit.

How are you powering your UNO, you only show the battery powering the driver?

Tom... :slight_smile:

Hi,
If you look at the schematic of the driver,you will see your 6V battery pack is going to L298 to power the motors as well as a 7805 , 5V, regulator.
However the regulator can only output 5V, if the input volts is about 7.5V or higher, your 6V will not be enough and the L298 IC will not be getting 5V to perform properly.


Tom... :slight_smile:

Hi,
I have put your circuit into a CAD.
Your diag is good, lots of labels which makes it easy to follow, just needs some layout logic, you will find this with practice in your diagram.

Tom... :slight_smile:

Thanks for all the help, Steve and Tom! I didn't write all of the code so I don't know why it sets conditions at the end of the loop and again at the start without checking. Maybe I should just go back and write the code more or less from scratch.

I have a nine volt battery attached to the Uno by a battery clip, which is how the original project did it.

I don't have much practice reading schematics! So do I need to add more voltage and bring it up to 7.5 volts? If so please advise how. Sorry I'm such a noob!
-p.

TomGeorge:
Hi,
If you look at the schematic of the driver,you will see your 6V battery pack is going to L298 to power the motors as well as a 7805 , 5V, regulator.
However the regulator can only output 5V, if the input volts is about 7.5V or higher, your 6V will not be enough and the L298 IC will not be getting 5V to perform properly.


Tom... :slight_smile:

Hi
My battery pack has 6 1.5v alkaline batteries, which should mean it's outputting 9v, right? So shouldn't that be enough, since it's above 7.5v? I'm probably missing something obvious, but I have no idea what.

I added more comments to my code and changed the digitalWrite(pwm?, 100); to digitalWrite(pwm?, HIGH);. My robot's still doing the exact same thing as before. Here's the new code:

[code]
const int in1 = 10;//left backward
const int in2 = 9;//left forward
const int pwm2 = 6;//right motor 
const int in3 = 5;// right backward
const int in4 = 4;// right forward
const int led = 13;
const int pingPin = 7;

 
void setup() {
  pinMode (pwm1, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(pwm2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  pinMode(led, OUTPUT);
  
  digitalWrite(in2, HIGH);//left motor forward
  digitalWrite(pwm1, HIGH);
  digitalWrite(in4, HIGH);//right motor forward
  digitalWrite(pwm2, HIGH);
  delay(1000);
  digitalWrite(in2, LOW);
  digitalWrite(pwm1, LOW);
  digitalWrite(in4, LOW);
  digitalWrite(pwm2, LOW);
  delay(1000);
  digitalWrite(in1, HIGH);// left motor backwards
  digitalWrite(pwm1, HIGH);
  digitalWrite(in3, HIGH);//right motor backwards
  digitalWrite(pwm2, HIGH);
  delay(1000);
  digitalWrite(in1, LOW);
  digitalWrite(pwm1, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(pwm2, LOW);
  
  digitalWrite(led, HIGH);//led on for five seconds
  delay(5000);
  digitalWrite(led, LOW);// led off
  Serial.begin(9600);// stops doing what i want it to do here
}
void loop(){
  digitalWrite(in2, HIGH);//left motor forwards
  digitalWrite(pwm1, HIGH);
  digitalWrite(in4, HIGH);//left motor forwards
  digitalWrite(pwm2, HIGH);
  uint8_t i;

  long duration, inches, cm;
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin,HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
  
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);
  cm = microsecondsToCentimeters(duration);
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  if (cm >10){
    digitalWrite(in2, LOW);//left motor, backwards
    digitalWrite(pwm1, LOW);
    digitalWrite(in1, HIGH);
    digitalWrite(pwm1, HIGH);

  //for (i=0; i<255; i++){
 // delay(10);}
  
  digitalWrite(in4, LOW);// right motor, backwards
  digitalWrite(pwm2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(pwm2, HIGH);
  for (i=0; i<255; i++){
  delay(10);}
  
digitalWrite(in3, LOW);//start both motors forward again
digitalWrite(in4, HIGH);
digitalWrite(in2, LOW);
digitalWrite(in1, HIGH);
delay(30);
  }
  else{
    digitalWrite(in2, HIGH);//keep going straight
    digitalWrite(pwm1, HIGH);
    digitalWrite(in4, HIGH);
    digitalWrite(pwm2, HIGH);
  }
  }
  long microsecondsToCentimeters(long microseconds)
  {
  
    return microseconds / 29/ 2;}

[/code]
Should I just go back and write the code from scratch? It might be easier.
-p.

A rewrite may not be necessary, but I'd suggest you write a series of much simpler sketches to assure yourself that the hardware's ok. Just run the motors forward for five seconds and then back for example.

It may just be me but I would be expecting you always to set BOTH input pins for the motor driver whenever you want a motor to do something. They should be either HIGH-LOW for one direction or LOW-HIGH for the other. And then you set the PWM pin HIGH for full speed. And when you want the motor to stop you set the PWM pin to LOW. There are too many places where you're just relying on pins staying set to sensible values.

There are also places where you set one input pin for a motor then set the PWM pin to LOW then set the other input pin then set PWM to HIGH. I don't understand what that is supposed to do.

And then there are those places where you set the input pins but don't send any PWM command.

Perhaps it is just me being simpleminded but I like 3 digitalWrites (in1, in2 & pwm1 or in3, in4 and pwm2) each time a motor is supposed to run. You may well be able to follow what state everything is in but I'm afraid I get completely confused about what is supposed to be happening.

Late edit: the other thing I've only just spotted is that you are changing direction without stopping the motors whereas in the setup() code that seems to work the motors are stopped and then reversed. I don't know how well that motor driver copes with trying to to change direction while the motors are still going at full speed but that may be another thing worth looking at.

BTW your 6AA batteries should be fine.

Steve

I'm so sorry I didn't have time to reply sooner.

@wildbill it's late here so I won't run any tests right now but thanks for the idea and I'll do it. If I find any hardware issues I'll post them.

@slipstick So you mean like at the start of void loop() where I only set in2 and in4 I should also set in1 and in3 again even though I already used digitalWrite() in setup? Does it only work within that function and the fact that I didn't reset makes my motor driver "throw up its hands in disgust" and mess up the rest of the code? I went through my code to check for those errors and added comments where I added a line. But since it's really too late to be writing in code or normal English for that matter I probably missed some. I can't test to see if my robot works now because it's kind of loud and everyone else is being smart and sleeping. Sorry if my post is incoherent. I can't even tell because I'm not sure how awake I am. Here's the revised code:

const int pwm1 = 11;//left motor  
const int in1 = 10;//left backward
const int in2 = 9;//left forward
const int pwm2 = 6;//right motor 
const int in3 = 5;// right backward
const int in4 = 4;// right forward
const int led = 13;
const int pingPin = 7;

 
void setup() {
  pinMode (pwm1, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(pwm2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  pinMode(led, OUTPUT);
  
  digitalWrite(in2, HIGH);//left motor forward
  digitalWrite(pwm1, HIGH);
  digitalWrite(in4, HIGH);//right motor forward
  digitalWrite(pwm2, HIGH);
  delay(1000);
  digitalWrite(in2, LOW);
  digitalWrite(pwm1, LOW);
  digitalWrite(in4, LOW);
  digitalWrite(pwm2, LOW);
  delay(1000);
  digitalWrite(in1, HIGH);// left motor backwards
  digitalWrite(pwm1, HIGH);
  digitalWrite(in3, HIGH);//right motor backwards
  digitalWrite(pwm2, HIGH);
  delay(1000);
  digitalWrite(in1, LOW);
  digitalWrite(pwm1, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(pwm2, LOW);
  
  digitalWrite(led, HIGH);//led on for five seconds
  delay(5000);
  digitalWrite(led, LOW);// led off
  Serial.begin(9600);// stops doing what i want it to do here
}
void loop(){
  digitalWrite(in1, LOW);//added
  digitalWrite(pwm1, LOW);//added
  digitalWrite(in3, LOW);//added
  digitalWrite(pwm2, LOW);//added
  digitalWrite(in2, HIGH);//left motor forwards
  digitalWrite(pwm1, HIGH);
  digitalWrite(in4, HIGH);//left edit that should be right motor forwards
  digitalWrite(pwm2, HIGH);
  uint8_t i;

  long duration, inches, cm;
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin,HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
  
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);
  cm = microsecondsToCentimeters(duration);
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  if (cm >10){
    digitalWrite(in1,LOW);//added
    digitalWrite(in2, LOW);//left motor, backwards
    digitalWrite(pwm1, LOW);
    digitalWrite(in1, HIGH);
    digitalWrite(pwm1, HIGH);

  //for (i=0; i<255; i++){ i can't even remember why i commented this out. any ideas?
 // delay(10);}
  digitalWrite(in3,LOW);//added
  digitalWrite(in4, LOW);// right motor, backwards
  digitalWrite(pwm2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(pwm2, HIGH);
  for (i=0; i<255; i++){
  delay(10);}
  
digitalWrite(in3, LOW);//start both motors forward again
digitalWrite(pwm2,LOW);// added is this one of the parts you were talking about?
digitalWrite(in4, HIGH);
digitalWrite(pwm2, HIGH);//added
digitalWrite(in2, LOW);
digitalWrite(pwm1,LOW);//added
digitalWrite(in1, HIGH);
digitalWrite(pwm1, HIGH);//added
delay(30);
  }
  else{
    digitalWrite(in1, LOW);//added
    digitalWrite(pwm1, LOW);//added
    digitalWrite(in2, HIGH);//keep going straight
    digitalWrite(pwm1, HIGH);
    digitalWrite(in3, LOW);//added
    digitalWrite(pwm2, LOW);//added
    digitalWrite(in4, HIGH);
    digitalWrite(pwm2, HIGH);
  }
  }
  long microsecondsToCentimeters(long microseconds)
  {
  
    return microseconds / 29/ 2;}

I'll test my robot tomorrow or actually today and post the results.
-p.

Hi

I think it would more simple if you create functions to move forward, backwads, turn left/right

At a moment i'm build a robot exactly like yours, here the code i'm using maybe it can helps

#include <Servo.h>          //Servo motor library. This is standard library
#include <NewPing.h>        //Ultrasonic sensor function library. You must install this library

//our L298N control pins
const int LeftMotorForward = 3;
const int LeftMotorBackward = 5;
const int RightMotorForward = 6;
const int RightMotorBackward = 11;

//sensor pins
#define trig_pin A0 //analog input 1
#define echo_pin A1 //analog input 2

#define maximum_distance 200
boolean goesForward = false;
int distance = 100;

NewPing sonar(trig_pin, echo_pin, maximum_distance); //sensor function
Servo servo_motor; //our servo name


void setup(){

  pinMode(RightMotorForward, OUTPUT);
  pinMode(LeftMotorForward, OUTPUT);
  pinMode(LeftMotorBackward, OUTPUT);
  pinMode(RightMotorBackward, OUTPUT);
  
  servo_motor.attach(10); //our servo pin

  servo_motor.write(115);
  delay(2000);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
}

void loop(){

  int distanceRight = 0;
  int distanceLeft = 0;
  delay(50);

  if (distance <= 20){
    moveStop();
    delay(300);
    moveBackward();
    delay(400);
    moveStop();
    delay(300);
    distanceRight = lookRight();
    delay(300);
    distanceLeft = lookLeft();
    delay(300);

    if (distance >= distanceLeft){
      turnRight();
      moveStop();
    }
    else{
      turnLeft();
      moveStop();
    }
  }
  else{
    moveForward(); 
  }
    distance = readPing();
}

int lookRight(){  
  servo_motor.write(50);
  delay(500);
  int distance = readPing();
  delay(100);
  servo_motor.write(115);
  return distance;
}

int lookLeft(){
  servo_motor.write(170);
  delay(500);
  int distance = readPing();
  delay(100);
  servo_motor.write(115);
  return distance;
  delay(100);
}

int readPing(){
  delay(70);
  int cm = sonar.ping_cm();
  if (cm==0){
    cm=250;
  }
  return cm;
}

void moveStop(){
  
  digitalWrite(RightMotorForward, LOW);
  digitalWrite(LeftMotorForward, LOW);
  digitalWrite(RightMotorBackward, LOW);
  digitalWrite(LeftMotorBackward, LOW);
}

void moveForward(){

  if(!goesForward){

    goesForward=true;
    
    analogWrite(LeftMotorForward, 90);
    analogWrite(RightMotorForward, 95);
  
    analogWrite(LeftMotorBackward, 0);
    analogWrite(RightMotorBackward, 0); 
  }
}

void moveBackward(){

  goesForward=false;

  analogWrite(LeftMotorBackward, 90);
  analogWrite(RightMotorBackward, 95);
  
  analogWrite(LeftMotorForward, 0);
  analogWrite(RightMotorForward, 0);
  
}

void turnRight(){

  analogWrite(LeftMotorForward, 90);
  analogWrite(RightMotorBackward, 95);
  
  analogWrite(LeftMotorBackward, 0);
  analogWrite(RightMotorForward, 0);
  
  delay(450);
  
  analogWrite(LeftMotorForward, 90);
  analogWrite(RightMotorForward, 95);
  
  analogWrite(LeftMotorBackward, 0);
  analogWrite(RightMotorBackward, 0);
 
  
  
}

void turnLeft(){

  analogWrite(LeftMotorBackward, 90);
  analogWrite(RightMotorForward, 95);
  
  analogWrite(LeftMotorForward, 0);
  analogWrite(RightMotorBackward, 0);

  delay(450);
  
  digitalWrite(LeftMotorForward, 90);
  digitalWrite(RightMotorForward, 95);
  
  digitalWrite(LeftMotorBackward, 0);
  digitalWrite(RightMotorBackward, 0);
}

Hi

@jorpec thanks for the advice but I think I might finally have figured this out! ...mostly at least... I plan on making this little guy do more fun stuff later so I might use your suggestion. I saw you were making an R2D2 robot. I hope it works because that would just be so cute, and besides...it's Star Wars!

Ok so I tested the robot again and with the new code everything was still running backwards, but then both wheels started forwards when something got within 10 cm of the sensor. I think I just made a stupid stupid stupid mistake. I probably just mixed up which is left and which is right motor on the motor driver, because I switched the motors and now everything runs right. Thanks everyone for all the help especially to make both the motors react to the sensor. Does that seem like a plausible solution to you all?

But then my weird setup thing started running backwards so I added a few digitalWrite()'s (is that how you make that plural?) to the setup. Those have an "added2" comment. It kept doing the exact same thing so I added more digitalWrite()'s with an "added3" comment, but that didn't change anything. My "motor switching" solution doesn't explain this! Any ideas? I'm probably missing something obvious, again! Here's the revised code:

[code]
const int pwm1 = 11;//left motor  
const int in1 = 10;//left backward
const int in2 = 9;//left forward
const int pwm2 = 6;//right motor 
const int in3 = 5;// right backward
const int in4 = 4;// right forward
const int led = 13;
const int pingPin = 7;

 
void setup() {
  pinMode (pwm1, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(pwm2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  pinMode(led, OUTPUT);
  
  digitalWrite(in1, LOW);//added2
  digitalWrite(pwm1, LOW);//added3, is this necessary?
  digitalWrite(in2, HIGH);//left motor forward
  digitalWrite(pwm1, HIGH);
  digitalWrite(in3, LOW);//added2
  digitalWrite(pwm2, LOW);//added3, is this necessary?
  digitalWrite(in4, HIGH);//right motor forward
  digitalWrite(pwm2, HIGH);
  delay(1000);
  digitalWrite(in2, LOW);
  digitalWrite(pwm1, LOW);
  digitalWrite(in4, LOW);
  digitalWrite(pwm2, LOW);
  delay(1000);
  digitalWrite(in1, HIGH);// left motor backwards
  digitalWrite(pwm1, HIGH);
  digitalWrite(in3, HIGH);//right motor backwards
  digitalWrite(pwm2, HIGH);
  delay(1000);
  digitalWrite(in1, LOW);
  digitalWrite(pwm1, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(pwm2, LOW);
  
  digitalWrite(led, HIGH);//led on for five seconds
  delay(5000);
  digitalWrite(led, LOW);// led off
  Serial.begin(9600);// stops doing what i want it to do here
}
void loop(){
  digitalWrite(in1, LOW);//added
  digitalWrite(pwm1, LOW);//added
  digitalWrite(in3, LOW);//added
  digitalWrite(pwm2, LOW);//added
  digitalWrite(in2, HIGH);//left motor forwards
  digitalWrite(pwm1, HIGH);
  digitalWrite(in4, HIGH);//right motor forwards
  digitalWrite(pwm2, HIGH);
  uint8_t i;

  long duration, inches, cm;
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin,HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
  
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);
  cm = microsecondsToCentimeters(duration);
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  if (cm >10){
    digitalWrite(in1,LOW);//added
    digitalWrite(in2, LOW);//left motor, backwards
    digitalWrite(pwm1, LOW);
    digitalWrite(in1, HIGH);
    digitalWrite(pwm1, HIGH);

  //for (i=0; i<255; i++){ i can't even remember why i commented this out. any ideas?
 // delay(10);}
  digitalWrite(in3,LOW);//added
  digitalWrite(in4, LOW);// right motor, backwards
  digitalWrite(pwm2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(pwm2, HIGH);
  for (i=0; i<255; i++){
  delay(10);}
  
digitalWrite(in3, LOW);//start both motors forward again
digitalWrite(pwm2,LOW);// added is this one of the parts you were talking about?
digitalWrite(in4, HIGH);
digitalWrite(pwm2, HIGH);//added
digitalWrite(in2, LOW);
digitalWrite(pwm1,LOW);//added
digitalWrite(in1, HIGH);
digitalWrite(pwm1, HIGH);//added
delay(30);
  }
  else{
    digitalWrite(in1, LOW);//added
    digitalWrite(pwm1, LOW);//added
    digitalWrite(in2, HIGH);//keep going straight
    digitalWrite(pwm1, HIGH);
    digitalWrite(in3, LOW);//added
    digitalWrite(pwm2, LOW);//added
    digitalWrite(in4, HIGH);
    digitalWrite(pwm2, HIGH);
  }
  }
  long microsecondsToCentimeters(long microseconds)
  {
  
    return microseconds / 29/ 2;}

[/code]
Thanks again.
-p.

I see you are using the same motor driver as i, and I had the same motor problems as you, the motors move backwards on the first run but i realize the wires on the motors was in reverse, then another user of this forum suggested that i keep the pwm1 and pwn2 jumper on the motor driver and just deal only with the in1, in2 ... to make the motor move

I used this code to test the motors to see if the my problem was on the motors wiring or code, maybe you can check with this very simple code where is the problem (just need to change the pins number)

// connect motor controller pins to Arduino digital pins
// motor one
int enA = 10;
int in1 = 9;
int in2 = 8;
// motor two
int enB = 5;
int in3 = 7;
int in4 = 6;
void setup()
{
  // set all the motor control pins to outputs
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
}
void demoOne()
{
  // this function will run the motors in both directions at a fixed speed
  // turn on motor A
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  // set speed to 200 out of possible range 0~255
  analogWrite(enA, 200);
  // turn on motor B
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  // set speed to 200 out of possible range 0~255
  analogWrite(enB, 200);
  delay(2000);
  // now change motor directions
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);  
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH); 
  delay(2000);
  // now turn off motors
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);  
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
}
void demoTwo()
{
  // this function will run the motors across the range of possible speeds
  // note that maximum speed is determined by the motor itself and the operating voltage
  // the PWM values sent by analogWrite() are fractions of the maximum speed possible 
  // by your hardware
  // turn on motors
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);  
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH); 
  // accelerate from zero to maximum speed
  for (int i = 0; i < 256; i++)
  {
    analogWrite(enA, i);
    analogWrite(enB, i);
    delay(20);
  } 
  // decelerate from maximum speed to zero
  for (int i = 255; i >= 0; --i)
  {
    analogWrite(enA, i);
    analogWrite(enB, i);
    delay(20);
  } 
  // now turn off motors
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);  
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);  
}
void loop()
{
  demoOne();
  delay(1000);
  demoTwo();
  delay(1000);
}

Hi
@jorpec thanks for the advice. I ran that test and the first demo ran fine but the second one ran backwards, with the left motor starting half a second or so before the right. I changed the 9v battery powering the Uno to see if that would change anything but it didn't. So I tried changing my 6 AA batteries as well as the 9v, no change. I'm wondering if there might be something wrong with one of the motors, or maybe the motor driver. I don't think there could be a problem with the Uno, but it's still possible so I'll troubleshoot and post the results.

I also saw that my robot was running too fast to react to the sensor in time so I changed the digitalWrite(pwm?, HIGH or LOW); to analogWrite(pwm?, 100 or 0); and that solved the speed problem, though my robot still hits walls before it backs away from them. But my left motor is also for whatever reason running better than the right one, making the robot turn to the right slightly when it should be going straight. Is there anything in the code that could be making it do that? Or do I need to add more batteries, or is my right motor faulty? Any ideas?

I also decided to change the distance the robot would back off at to 20 cm instead of 10 because I'm running it in a kitchen where the sensor sometimes doesn't "see" the ledge where the lower cupboards jut out over the floor and it works a bit better this way I think. It still hits stuff before backing off though. Any ideas? Thanks in advance! New code:

const int pwm1 = 11;//left motor  
const int in1 = 10;//left backward
const int in2 = 9;//left forward
const int pwm2 = 6;//right motor 
const int in3 = 5;// right backward
const int in4 = 4;// right forward
const int led = 13;
const int pingPin = 7;

 
void setup() {
  pinMode (pwm1, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(pwm2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  pinMode(led, OUTPUT);
  
  digitalWrite(in1, LOW);//added2
  analogWrite(pwm1, 0);//added3, is this necessary? speed control
  digitalWrite(in2, HIGH);//left motor forward
  analogWrite(pwm1, 100);//speed control
  digitalWrite(in3, LOW);//added2
  analogWrite(pwm2, 0);//added3, is this necessary? speed control
  digitalWrite(in4, HIGH);//right motor forward
  analogWrite(pwm2, 100);//speed control
  delay(1000);
  digitalWrite(in2, LOW);
  analogWrite(pwm1, 0);//speed control
  digitalWrite(in4, LOW);
  analogWrite(pwm2, 0);//speed control
  delay(1000);
  digitalWrite(in1, HIGH);// left motor backwards
  analogWrite(pwm1, 100);//speed control
  digitalWrite(in3, HIGH);//right motor backwards
  analogWrite(pwm2, 100);//speed control
  delay(1000);
  digitalWrite(in1, LOW);
  analogWrite(pwm1, 0);//speed control
  digitalWrite(in3, LOW);
  analogWrite(pwm2, 0);//speed control
  
  digitalWrite(led, HIGH);//led on for five seconds
  delay(5000);
  digitalWrite(led, LOW);// led off
  Serial.begin(9600);// stops doing what i want it to do here
}
void loop(){
  digitalWrite(in1, LOW);//added
  analogWrite(pwm1, 0);//added, speed control
  digitalWrite(in3, LOW);//added
  analogWrite(pwm2, 0);//added, speed control
  digitalWrite(in2, HIGH);//left motor forwards
  analogWrite(pwm1, 100);//speed control
  digitalWrite(in4, HIGH);//right motor forwards
  analogWrite(pwm2, 100);//speed control
  uint8_t i;

  long duration, inches, cm;
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin,HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
  
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);
  cm = microsecondsToCentimeters(duration);
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  if (cm >20){
    digitalWrite(in1,LOW);//added
    digitalWrite(in2, LOW);//left motor, backwards
    analogWrite(pwm1, 0);//speed control
    digitalWrite(in1, HIGH);
    analogWrite(pwm1, 100);//speed control

  //for (i=0; i<255; i++){ i can't even remember why i commented this out. any ideas?
 // delay(10);}
  digitalWrite(in3,LOW);//added
  digitalWrite(in4, LOW);// right motor, backwards
  analogWrite(pwm2, 0);//speed control
  digitalWrite(in3, HIGH);
  analogWrite(pwm2, 100);//speed control
  for (i=0; i<255; i++){
  delay(10);}
  
digitalWrite(in3, LOW);//start both motors forward again
analogWrite(pwm2, 0);// added, is this one of the parts you were talking about? speed control
digitalWrite(in4, HIGH);
analogWrite(pwm2, 100);//added, speed control
digitalWrite(in2, LOW);
analogWrite(pwm1,0);//added, speed control
digitalWrite(in1, HIGH);
analogWrite(pwm1, 100);//added, speed control
delay(30);
  }
  else{
    digitalWrite(in1, LOW);//added
    analogWrite(pwm1, 0);//added, speed control
    digitalWrite(in2, HIGH);//keep going straight
    analogWrite(pwm1, 100);//speed control
    digitalWrite(in3, LOW);//added
    analogWrite(pwm2, 0);//added, speed control
    digitalWrite(in4, HIGH);
    analogWrite(pwm2, 100);//speed control
  }
  }
  long microsecondsToCentimeters(long microseconds)
  {
  
    return microseconds / 29/ 2;}

-p.

About the "left motor starting half a second or so before the right" the same happens to me, i guess the motors are not exactly the same, i solved by on analogWrite on the weak motor put an higher value, about the speed try to lower the pwm value ( in my case to the robot goes straight forward i need to put 95 in the left motor and 75 on the right motor)

Also check the arduino pins that cant handle the analogWrite, i made that mistake (in my case the analogWrite only works on pins nº 3, 5, 6, 11)

About "It still hits stuff before backing off though. Any ideas?" again the same happens to me so i'm thinking to change the ultrasonic sensors by InfraRed Leds