Author Topic: Help integrating a Parallax Ping sensor into an arduino wall avoiding robot  (Read 2519 times)

0 Members and 1 Guest are viewing this topic.

Offline jlowe64Topic starter

  • Jr. Member
  • **
  • Posts: 7
  • Helpful? 0
I am so close to getting this I can taste it (kinda). I've been trying to integrate a Ping sensor into a wall avoiding robot. I think I have almost everything, but it's still not behaving the way I'd like. It tends to go full speed forward, but doesn't seem to be getting a signal from the Ping sensor to tell it to stop and turn around.

Right now it goes forward.. but doesn't detect anything from the ping sensor. The ping sensor is sending out echoes, though, which is more than it was doing before.

Here's what I have (arduino code):
Code: [Select]
#define Motor1A 10 // H-Bridge input 1
#define Motor1B 11 // H-Bridge input 2              
#define enable 3     // H-Bridge motor 1 enable
#define Motor2A 9  // H-Bridge input 3            
#define Motor2B 8  // H-Bridge input 4              
#define enable2 5     // H-Bridge motor 2 enable
#define ledPin 13    // sets the indicator led to pin 13
#define pingPin 12


void straight() // go straight function
{
    digitalWrite(enable, HIGH);
    digitalWrite(Motor1A, HIGH);
    digitalWrite(Motor1B, LOW);
    digitalWrite(enable2, HIGH);
    digitalWrite(Motor2A, HIGH);
    digitalWrite(Motor2B,LOW);
}

void turnRight() // turn right function          
{
    digitalWrite(enable, HIGH);
    digitalWrite(Motor1A, LOW);
    digitalWrite(Motor1B, HIGH);
    digitalWrite(enable2, HIGH);
    digitalWrite(Motor2A, HIGH);
    digitalWrite(Motor2B,LOW);
}

long duration;
  long ping(int numIter = 3) {
  duration = 0; // reset duration value
  for (int i = 0; i < numIter; i++) {
    pinMode(pingPin, OUTPUT);

    digitalWrite(pingPin, LOW);
    delayMicroseconds(2);

    digitalWrite(pingPin, HIGH);
    delayMicroseconds(5);

    digitalWrite(pingPin, LOW);

    pinMode(pingPin, INPUT);
    duration += pulseIn(pingPin, HIGH); // add the current reading to the total
  }
    return duration / 74 / 2 / numIter; // return averaged value in inches
}
  

void avoideWalls()
{  
    if(duration < 10)                            // if the distance is less than 10 inches
  {
    digitalWrite(ledPin, HIGH);             // turn on the LED
    turnRight();                            // turns Walbot right using turnRight function
    delay(100);
  }
   else                                      // otherwise
  {
    digitalWrite(ledPin, LOW);              // turn off the LED
    straight();                            // go straight using the straight function
  }
}

  
void setup()
{
  pinMode(Motor1A, OUTPUT);      // sets motor pin 1A as output  
  pinMode(Motor1B, OUTPUT);      // sets motor pin 1B as output
  pinMode(Motor2A, OUTPUT);      // sets motor pin 2A as output
  pinMode(Motor2B, OUTPUT);      // sets motor pin 2B as output
  pinMode(enable, OUTPUT);       // sets enable2 as output
  pinMode(enable2, OUTPUT);      // sets enable as output
  pinMode(pingPin, OUTPUT);      // sets pingPin as output
  pinMode(pingPin, INPUT);      // sets pingPin as output
  pinMode(ledPin, OUTPUT);       // sets ledPin as output
  
  straight(); // initializes Walbot to go straight
}

void loop() {
  digitalWrite(pingPin, HIGH);           // turns on sonar
  ping();
  avoideWalls();                             // tells Walbot not to run into inanimate objects by calling avoideWalls function
  delay(20);                                 // delay for 20 milliseconds
}

I added a number here to average:

Code: [Select]
long ping(int numIter = 3)
Was trying different numbers but it doesn't seem to make a difference. When I didn't have any number at all there, the robot was in a permanent right turn motion. Very odd.

I added Ping(); here. I don't know if that is right (I'm a total noob with arduino code). I figured I needed to pull a number in the loop from the distance. I dunno if this is right, though.
Code: [Select]
void loop() {
  digitalWrite(pingPin, HIGH);           // turns on sonar
  ping();
  avoideWalls();                             // tells Walbot not to run into inanimate objects by calling avoideWalls function
  delay(20);                                 // delay for 20 milliseconds
}

Thanks in advance for all your help!

Jerrett

Offline rbtying

  • Supreme Robot
  • *****
  • Posts: 452
  • Helpful? 31
Hey,
    In your code, try to output your data to your computer.

For example:

Code: [Select]
void loop() {
   Serial.print("ping))):\t");
   Serial.println(ping());
}

What's it say?

Offline jlowe64Topic starter

  • Jr. Member
  • **
  • Posts: 7
  • Helpful? 0
Did what you said.

When the motors aren't plugged in the ping sensor acts normally, sending out distance values slowly when nothing is in front of it and faster when there is something near. Numbers remain consistent.

When the motors are getting power and going in the "straight" motion, the ping sensor acts up. It returns false distance values and it's returning the values faster than they should even when nothing is in front of it. The motors are also going way faster than I thought they should, or imagined that they should, but I've never built a robot like this. 

I think the motors may be giving off EM noise and causing the ping sensor to get false data. I know that I could wire some capacitors to the motors to save on this. I'm not really sure, though, if this is the problem. Even when the ping sensor is going crazy.. it still knows something is in front of it and the motors don't go through with the stop, reverse right, and going forward.

Thanks for the help!


Offline waltr

  • Supreme Robot
  • *****
  • Posts: 1,943
  • Helpful? 98
Adding caps on the motors is always a good idea and trying to troubleshoot noise issues is always difficult even with lots of good test equipment. So you'll just need to try different things until the problem goes away.

Offline Metal Slug 2

  • Supreme Robot
  • *****
  • Posts: 333
  • Helpful? 11
Code: [Select]
void loop() {
  digitalWrite(pingPin, HIGH);           // turns on sonar
  ping();
  avoideWalls();                             // tells Walbot not to run into inanimate objects by calling avoideWalls function
  delay(20);                                 // delay for 20 milliseconds
}

Remove the line: "digitalWrite(pingPin, HIGH);"

In your "ping();" function, you already have all the code you need to run the Ping sensor perfectly.  Your ping() function however leaves the pin your ping sensor is attached to in INPUT mode, and when your main loop loops, you set the pin to HIGH.

When you set a pin that is set for Input to HIGH, this actually enables an internal 20k pull-up resistor on that pin: http://arduino.cc/en/Tutorial/DigitalPins


Offline jlowe64Topic starter

  • Jr. Member
  • **
  • Posts: 7
  • Helpful? 0
Code: [Select]
void loop() {
  digitalWrite(pingPin, HIGH);           // turns on sonar
  ping();
  avoideWalls();                             // tells Walbot not to run into inanimate objects by calling avoideWalls function
  delay(20);                                 // delay for 20 milliseconds
}

Remove the line: "digitalWrite(pingPin, HIGH);"

In your "ping();" function, you already have all the code you need to run the Ping sensor perfectly.  Your ping() function however leaves the pin your ping sensor is attached to in INPUT mode, and when your main loop loops, you set the pin to HIGH.

When you set a pin that is set for Input to HIGH, this actually enables an internal 20k pull-up resistor on that pin: http://arduino.cc/en/Tutorial/DigitalPins


I did your suggestion, thank you so much. The ping sensor acts much better. There is still an issue with the programming, though. When it's just sending the Ping data to the USB, then it's sending correct data, but when the motors are hooked up, even though the ping data is much cleaner, it still doesn't react in the way I want it to. I feel like I'm missing something crucial.

Thanks for everyone's help!

Currently I'm about to add capacitors to the motors. :)

Jerrett

 


Get Your Ad Here

data_list