Arduino bot has a mind of it own???

Hello,
My bot seems to have a mind of its own. code seems to be working but at times it react to an object thats not there??? its set to find a better path after coming 30 cm within an object but sometimes theres nothing there and it looks for a better path? can this be from the ping returning false values, or i think it might be from the 9v battery draining quickly. Any ideas?? Thanks
Video here: http://www.youtube.com/watch?v=SiXvlV6-0S8

Heres the code:

  #define servoPin     12         // Servomotor on pin D12.
  #define pingpin      13         // Ping ultrasonic sensor on pin D13.
  #define redled        9         // 2 drive motors, motor driver SN754410NE
  #define whiteled      8
  
  #define leftSpeedPin   10       // Left motor speed control
  #define leftmotorpin1  5        // Left motor direction 1
  #define leftmotorpin2  6        // Left motor direction 2
 
  #define rightmotorpin1 3        // Right motor direction 1
  #define rightmotorpin2 4        // Right motor direction 2
  #define rightSpeedPin  11       // Right motor speed control

  #define SERVOCENTER   1500     // Tweak so sensor looks straight ahead.
  #define SERVORIGHT    550      // Servo position when looking right.
  #define SERVOLEFT     2500     // Servo position when looking left.
  int numPulses;                 // Number of pulses to servomotor.
  
void setup() {
  
  pinMode(leftmotorpin1, OUTPUT);        // Set motor pins as outputs.
  pinMode(leftmotorpin2, OUTPUT);
  pinMode(leftSpeedPin, OUTPUT);  
  pinMode(rightmotorpin1, OUTPUT);      
  pinMode(rightmotorpin2, OUTPUT); 
  pinMode(rightSpeedPin, OUTPUT);
  pinMode(servoPin, OUTPUT);             // Servomotor as output.
  pinMode(redled, OUTPUT);               // leds as outputs
  pinMode(whiteled, OUTPUT);
  
  centerServo();                         // Centers Servo
  delay(2000);                           // Wait 2 seconds
  
  Serial.begin(115200);
}

void loop() {
  
  int leftDistance, rightDistance, currDist;                   // Distance readings from Ping sensor.
  int dangerlevel = 30;                                        // How far away should things be, before we react?
                                                               // int numPulses;
  
  currDist = readDistance();
  if(currDist > dangerlevel) {
    nodanger();                         // If no danger, drive ahead
  }
  else {
    whichway();                         // If obstacle ahead then decide which way is better
  }
}

  
void nodanger() {                       // Drive forward
  digitalWrite(whiteled, HIGH);
  digitalWrite(redled, LOW);
  analogWrite(leftSpeedPin, 100);       //PWM Speed Control 0 - 255
  analogWrite(rightSpeedPin, 100);
  digitalWrite(leftmotorpin1, HIGH);
  digitalWrite(leftmotorpin2, LOW);
  digitalWrite(rightmotorpin1, HIGH);
  digitalWrite(rightmotorpin2, LOW);
  return;
}  

void whichway() {
  digitalWrite(whiteled, LOW);
  digitalWrite(redled, HIGH);
  totalhalt();                                        // First stop before looking left and right

int leftDistance, rightDistance, currDist;

for (numPulses = 0; numPulses < 20; numPulses++)      // Turn servo left (look left)        
  {
    pulseOut(servoPin, SERVOLEFT);               
    delay(40);
  } 
  leftDistance = readDistance();                      // Check distance
  totalhalt();                                        // totalhalt also centers the servo

   for (numPulses = 0; numPulses < 20; numPulses++)   // Turn servo right (look right)
  {
    pulseOut(servoPin, SERVORIGHT);
    delay(40);
  }

  rightDistance = readDistance();                     // Check distance
  totalhalt();                                        // totalhalt also centers the servo

  if(leftDistance > rightDistance) {                  // Choose better direction. Greater space
    body_leftturn();
  }
    else {
    body_rightturn();
  }
  return;
}  

void totalhalt() {
  digitalWrite(whiteled, LOW);
  digitalWrite(redled, HIGH);
  digitalWrite(leftmotorpin1, LOW);
  digitalWrite(leftmotorpin2, LOW);
  digitalWrite(rightmotorpin1, LOW);
  digitalWrite(rightmotorpin2, LOW);
  digitalWrite(leftSpeedPin, LOW);
  digitalWrite(rightSpeedPin, LOW);
  centerServo();
  delay(500);
}  

 

void body_leftturn() {
  digitalWrite(whiteled, LOW);
  digitalWrite(redled, HIGH);
  digitalWrite(leftmotorpin1, LOW);
  digitalWrite(leftmotorpin2, HIGH);
  digitalWrite(rightmotorpin1, HIGH);
  digitalWrite(rightmotorpin2, LOW);
  digitalWrite(leftSpeedPin, HIGH);
  digitalWrite(rightSpeedPin, HIGH);
  delay(200);
  totalhalt();
}  

void body_rightturn() {
  digitalWrite(whiteled, LOW);
  digitalWrite(redled, HIGH);
  digitalWrite(leftmotorpin1, HIGH);
  digitalWrite(leftmotorpin2, LOW);
  digitalWrite(rightmotorpin1, LOW);
  digitalWrite(rightmotorpin2, HIGH);
  digitalWrite(leftSpeedPin, HIGH);
  digitalWrite(rightSpeedPin, HIGH);
  delay(200);
  totalhalt();
}

void pulseOut(byte pinNumber, int duration)
{
  digitalWrite(servoPin, HIGH);
  delayMicroseconds(duration);
  digitalWrite(servoPin, LOW);
}

void centerServo()
{
  byte index;
  
  for (index = 0; index < 20; index++)
  {
    pulseOut(servoPin, SERVOCENTER);
    delay(20);
  }}
  
long readDistance() {

  long duration, inches, cm;

  // The Ping is triggered by a HIGH pulse of 2 or more microseconds.
  // We give a short LOW pulse beforehand to ensure a clean HIGH pulse.
  pinMode(pingpin, OUTPUT);
  digitalWrite(pingpin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingpin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingpin, LOW);

  // The same pin is used to read the signal from the Ping: a HIGH
  // pulse whose duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  pinMode(pingpin, INPUT);
  duration = pulseIn(pingpin, HIGH);

  // Convert the time into a distance.
  cm = microsecondsToCentimeters(duration);
  return(cm);
}

long microsecondsToCentimeters(long microseconds)
{
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the
  // object we take half of the distance traveled.
  return microseconds / 29 / 2;}

Have you got something against using the servo libary? It would get rid of dead time spent in "delay".

I'm not too familiar with the servo library yet which is why ide rather not use it, i dont think that would be the problem though. thanks

Maybe a slightly longer pause after stopping the motors or servo before operating the Ping? Some of your servo frame delays are 40ms, some 20ms - any reason?

Looking at your video though it doesn't seem like the bot is behaving well at all. Maybe this is a fluke that you just happened to catch on video but if not, there's some basic problem with the algorithm.

ahh, maybe I see something simple. If you ping a distance of >30 cm you will run nodanger but then you'll ping again almost immediately. You need to give the ping sensor a break between readings so that the echos die away - i believe the parallax sensor wants 50 ms. You can either check how long it's been since you pinged last or put a 50ms delay in nodanger.

my experience is with the seeed sensor rather than the parallax one but I definitely ran into stability problems when the battery got low. I always had the odd flakey reading but the way my code was written it didn't affect the bot's behaviour too much.

I'd encourage you to use the servo library to simplify your code and make the behaviour of the bot less dramatic - avoid long pauses so that the odd flakey reading won't show up so much.

There’s a robot called “makey” with similar sensors and motors to yours - you can probably run its software changing only a couple of pin definitions. There are several examples of object avoidance and following. It will maybe give you some ideas.

I built a carbot, again similar sensors and motors to yours. It’s glorious capability is wall racing (tearing ariound a closed track as fast as possible staying close to the walls) but i trained it with makey. I can show you the code and behaviour if you’re interested - maybe a race?

Here’s a link to makey. don’t be put off by the cutesy appearance. http://makeprojects.com/Project/My-Robot-Makey/51/1

ahh, here’s carbot http://arduino.cc/forum/index.php/topic,8756.0.html a much tougher customer.

@awol i dont know lol im still new to the arduino language, pretty much wrote this code on trial and error.

@Bill2009 yea i saw the makey page, i used its code as a basis for mine but just did a mkaeover. Makey's code is made for it to follow things, while i want mind to avoid things. The avoidance code posted on that page does not allow for the servo to move. I would definately race you, pretty sure i would win lol. I have to pwm my bot to 1/3 its speed so it can work properly otherwise it takes off like a bullet. Car bot looks NICE! im confused though my arduino only goes up to pin 13.

check it out: http://letsmakerobots.com/node/26101

confused though my arduino only goes up to pin 13.

Plus the six analogue input pins, 14 through 19.

@awol thanks

@bill2009 how would i add this delay, maybe adding delay(50) right after nodanger() in the beginning of the loop?

@bill2009 how would i add this delay, maybe adding delay(50) right after nodanger() in the beginning of the loop?

that would be fine. You can think of it as giving the bot a little time to move forward before you check again.

There are a few sketches posted for makey. the one i copied was an object avoider.

Thanks everybody, i added "delay(10)" after "readDistance()" in the beginning of the loop and it worked perfect!

Elijah912: My bot seems to have a mind of its own.

This reminds me of a quote:

"My software doesn't have bugs... it has random features."

Great, glad it works. Now, let's see a good picture and a new video.

Hi Elijah, Can you please post the final sketch for this project. I tried modifying the code as mentioned by you. When I power on, bot moves ahead, servo panning happens & obstacle sensing is also happenning. But when a obstacle found, the motor reverse action is not happenning. So wanted to take help from you to resolve the problem. ALso wanted to confirm regarding motors, I am using one servo motor for panning of Ping sensor & 2 DC motors driven by L293D chip. Am I supposed to use the same components or do I need to use all 3 servo motors. Please help. Thanks in advance,

Sudhakar