code suggestions

I’ve been working on a wall sensing robot that will turn when it comes close to a wall and I’m on a newer version of my code. It’s buggy and I can’t figure out the issue. When I turn the robot on, it goes for a second or two, turns, goes a bit more, turns again…this just keeps repeating. In don’t know if it is actually picking up the sensor readings or not.

Here is a you tube video of what it is currently doing

// names the LED and pin number
int led = 10;
int led2 = 6;


// this constant won't change.  It's the pin number for the sensor
// of the sensor's output:
const int pingPin = 7;

//sets the interger for the pulse sensor
long distance;
unsigned long pulseDuration=0;

void setup() {

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

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

  //SETUP LED HEADLIGHTS
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode (led2, OUTPUT);

  // initialize serial communication: SENSOR
  Serial.begin(9600);
}

void loop (){
  distance = pingsensor();
  //for debugging
  Serial.println(distance);
  if (distance < 5){
    turnAround();
  } 
  else {
    goForward();    
  }
}


long pingsensor(){
  // establish variables for duration of the ping,
  // and the distance result in inches and centimeters:
  long duration, inches, cm;

  // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  // 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
  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);

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

  return inches;
  //delay(100);
}

long microsecondsToInches(long microseconds)
{
  // According to Parallax's datasheet for the PING))), there are
  // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
  // second).  This gives the distance travelled by the ping, outbound
  // and return, so we divide by 2 to get the distance of the obstacle.
  return microseconds / 74 / 2;
}

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 travelled.
  return microseconds / 29 / 2;
}

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

  //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, 150);  //Spins the motor on Channel B
}

void turnAround(){
  //engages the brake for left motor
  digitalWrite(9, HIGH);  

  //DELAY FOR LONG ENOUGH TO TURN, CHANGE AS NEEDED
  delay(2000);

}

Is your ping sensor bouncing? That will surely cause bad readings. Another would be your ping wire, does that have a solid connection. My money is on the sensor bouncing.

Actually no. Because I didn't want to solder the sensor I'm using jumper wires to connect the sensor to a breadboard. Would that really make the difference?

Yes, I've had similar problems in the past. Even if it is on a bread board, it must not be able to bounce, otherwise your readings will be off.

Actually, where and how is it attached to your robot? I noticed in your code that your accepting reading from 0 to 4 inches. If your ping sensor is too close to the surface of the chassis, then it may be returning values like 1 inch, 2 inches, just from being too close to the surface of the chassis. Set a limit. If distance is greater than 1 and less than 5, turn left.

The ping sensor is securely mounted however all the wiring is done with jumper wires. Could that still be the issue?

It is a possibility. Try to tape them down if you can.

Hot melt glue works great, too. and is easily removed.

What do your serial.prints tell you? How does it behave if you set it up on blocks and bring obstacles towards the ping sensor?

Now that you mention it, the serial prints are a bit erratic. Sometimes they drop to zero randomly, but I just assumed the ping sensor was resetting. I am currently using female jumper wire to run from the sensor to a standard jumper wire to go into the board. Should I try to simplify?
Thanks

My advice is to run it on blocks until you get consistent performance - then let it go roaming around.

I had made a distance sensor using the PING and was having the same issues, random erratic returns from the PING How I fixed it was by using the library you can download called NewPing. There are options in that library to take many readings per second from the PING and average them. It stabilized the data I got from the PING sensor and stopped the erratic readings completely.

There are good examples for the library to write the code from, and if it would help, I can post the code I wrote as an example also :)

Thanks for the info...yes, could you please post the code.

gizahuna:
Thanks for the info…yes, could you please post the code.

I post this with the caveat that I am very new, and this is litterally the first project I made that wasn’t in a book or tutorial. It also happens to be the last project I did before yesterday :stuck_out_tongue:
I am not positive that this is the best way to do this, but it does work, and should show the use of the “NewPing” library well enough to give you some idea how to use it…
when you download the library from this link

http://playground.arduino.cc/Code/NewPing

there are some great examples that were a great help to me in writing this code…

//This sketch uses a PING))) ultrasonic sensor to sense distance in cm
//and use that data to activate a 6 LED bar graph, with a piezzo buzzer
//to sound out warnings at close intervals.

#include <NewPing.h>  //includes the NewPing library
#define TRIGGER_PIN 8  //defines the trigger pin as 8
#define ECHO_PIN 8     //also defines the echo pin as 8
#define MAX_DISTANCE 400  //sets the maximum distance the sketch will use
#define ITERATIONS 10   //defines how many times you want the sonar to ping

//defines for the library that "sonar" uses the trigger pin, echo pin and
//and max distance as definitions
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); 

int BUZZ = 10; //sets the buzzer to pin 10

const int minDist = 0;    //defines constant minDist as 0cm
const int maxDist = 161;  //defines constant maxDist as 161cm
int BUZZstate = LOW;  //defines variable BUZZstate as LOW
long prevBUZZ = 0;  //defines long "prevBUZZ" and stores it
long interval = 500;  //defines long "interval" and sets it to 500

const int ledCount = 6;  //defines constant "ledCount" and sets it to 6

int ledPins[] =  //defines the variable ledPins as an array ranging from 2-7
{
  2, 3, 4, 5, 6, 7
};

void setup()
{
  pinMode(BUZZ, OUTPUT);  //sets the BUZZ pin (10) as an output
  
  //for loop to increment thisLED up by one and to ser thisLED to the array
  //ledPins and set those pins as OUTPUT
  for (int thisLED = 0; thisLED < ledCount; thisLED++)
  {
    pinMode(ledPins[thisLED], OUTPUT);
  }
  Serial.begin(115200);  //begin Serial communication at 115,200 baud
}

void loop()
{
  delay(30);  //wait 30mS
  //defines "uS" as an unsigned integer sets it to "sonar" then take 10 ITERATIONS
  //and find the median of them.
  unsigned int uS = sonar.ping_median(ITERATIONS); 
  //uses Serial data to print the result in cm (Ping: XXcm) to the monitor
  Serial.print("Ping: ");
  Serial.print(uS / US_ROUNDTRIP_CM);
  Serial.print("cm");
  Serial.println();
  
  //defines the variable "ledLevel" and maps it to (distance in cm) from zero
  //up to 161cm, and sets the ledCount down to 0 to that map, to turn on more LEDs
  //the closer you get and to turn them off further away
  int ledLevel = map(uS / US_ROUNDTRIP_CM, 0, 161, ledCount, 0); 
  //for loop to incement "thisLED" up by one and turn them on or off by the ledCOUNT
  for (int thisLED = 0; thisLED < ledCount; thisLED++)
  {
    //if statement for turning the LEDs on or off in the for loop
    if (thisLED < ledLevel)
    {
      digitalWrite(ledPins[thisLED], HIGH);  //turns LED on
    } else {
      digitalWrite(ledPins[thisLED], LOW);  //turns LED off
    }
    {
      //uses a switch case to control when the peizzo buzzes based on the ledCount
      switch(ledCount)
      {
        case 1:  //LED 1, no sound
        digitalWrite(BUZZ, LOW);
        break;
        case 2:  //LED 2 no sound
        digitalWrite(BUZZ, LOW);
        break;
        case 3:  //LED 3 no sound
        digitalWrite(BUZZ, LOW);
        break;
        case 4:  //LED 4 no sound
        digitalWrite(BUZZ, LOW);
        break;
        case 5:  //LED 5 will cause the piezzo to signal a series of regular short beeps
        {
          unsigned long BUZZmillis = millis();
          if(BUZZmillis - prevBUZZ > interval)
          {
            prevBUZZ = BUZZmillis;
            if (BUZZstate == LOW)
            BUZZstate = HIGH;
            else
            BUZZstate = LOW;
            digitalWrite(BUZZ, BUZZstate);
          }
        }
        break;
        case 6:  //LED 6 will cause the piezzo to make a continuous tone when the distance is shortest
        digitalWrite(BUZZ, HIGH);
        break;
      }
    }
  }
}

Hope that helps, building a robot is one of the next things I want to tackle.
Good Luck!