Go Down

Topic: Using Multiple PING))) Ultrasonic sensors (Read 6179 times) previous topic - next topic

mjmcondor

Sorry if this topic is on the forum elsewhere but I couldn't find it if it is.

I am trying to use multiple PING))) ultrasonic sensors (4 to be exact) for navigation on an autonomus vehicle I'm creating. The code I've been working with is from "arduino.cc/playground/Main/UltrasonicSensor" (can't post actual links yet). Currently I have all four sensors outputting values in the Serial Monitor, but I think all 4 PING))) sensors are firing at once, and I believe that this is causing trouble with my controller code. Can someone tell me if I'm doing this right?

Code: [Select]

unsigned long echoFL = 0;
unsigned long echoF = 0;
unsigned long echoFR = 0;
unsigned long echoR = 0;
int ultraSoundSignalFL = 8; // Front Left Ultrasound signal pin
int ultraSoundSignalF = 7; // Front Ultrasound signal pin
int ultraSoundSignalFR = 6; // Front Right Ultrasound signal pin
int ultraSoundSignalR = 9; // Rear Ultrasound signal pin
unsigned long ultrasoundValueFL = 0;
unsigned long ultrasoundValueF = 0;
unsigned long ultrasoundValueFR = 0;
unsigned long ultrasoundValueR = 0;

void setup()
{
Serial.begin(9600);
pinMode(ultraSoundSignalF,OUTPUT);
pinMode(ultraSoundSignalFL,OUTPUT);
pinMode(ultraSoundSignalFR,OUTPUT);
pinMode(ultraSoundSignalR,OUTPUT);
}

//Front ultrasonic
unsigned long pingF(){
pinMode(ultraSoundSignalF, OUTPUT); // Switch signalpin to output
digitalWrite(ultraSoundSignalF, LOW); // Send low pulse
delayMicroseconds(2); // Wait for 2 microseconds
digitalWrite(ultraSoundSignalF, HIGH); // Send high pulse
delayMicroseconds(5); // Wait for 5 microseconds
digitalWrite(ultraSoundSignalF, LOW); // Holdoff
pinMode(ultraSoundSignalF, INPUT); // Switch signalpin to input
digitalWrite(ultraSoundSignalF, HIGH); // Turn on pullup resistor
 echoF = pulseIn(ultraSoundSignalF, HIGH); //Listen for echo
 ultrasoundValueF = (echoF / 58.138) * .39; //convert to CM then to inches
return ultrasoundValueF;
}

//Front Left ultrasonic
unsigned long pingFL(){
pinMode(ultraSoundSignalFL, OUTPUT); // Switch signalpin to output
digitalWrite(ultraSoundSignalFL, LOW); // Send low pulse
delayMicroseconds(2); // Wait for 2 microseconds
digitalWrite(ultraSoundSignalFL, HIGH); // Send high pulse
delayMicroseconds(5); // Wait for 5 microseconds
digitalWrite(ultraSoundSignalFL, LOW); // Holdoff
pinMode(ultraSoundSignalFL, INPUT); // Switch signalpin to input
digitalWrite(ultraSoundSignalFL, HIGH); // Turn on pullup resistor
 echoFL = pulseIn(ultraSoundSignalFL, HIGH); //Listen for echo
 ultrasoundValueFL = (echoFL / 58.138) * .39; //convert to CM then to inches
return ultrasoundValueFL;
}

//Front Right ultrasonic
unsigned long pingFR(){
pinMode(ultraSoundSignalFR, OUTPUT); // Switch signalpin to output
digitalWrite(ultraSoundSignalFR, LOW); // Send low pulse
delayMicroseconds(2); // Wait for 2 microseconds
digitalWrite(ultraSoundSignalFR, HIGH); // Send high pulse
delayMicroseconds(5); // Wait for 5 microseconds
digitalWrite(ultraSoundSignalFR, LOW); // Holdoff
pinMode(ultraSoundSignalFR, INPUT); // Switch signalpin to input
digitalWrite(ultraSoundSignalFR, HIGH); // Turn on pullup resistor
 echoFR = pulseIn(ultraSoundSignalFR, HIGH); //Listen for echo
 ultrasoundValueFR = (echoFR / 58.138) * .39; //convert to CM then to inches
return ultrasoundValueFR;
}

//Rear ultrasonic
unsigned long pingR(){
pinMode(ultraSoundSignalR, OUTPUT); // Switch signalpin to output
digitalWrite(ultraSoundSignalR, LOW); // Send low pulse
delayMicroseconds(2); // Wait for 2 microseconds
digitalWrite(ultraSoundSignalR, HIGH); // Send high pulse
delayMicroseconds(5); // Wait for 5 microseconds
digitalWrite(ultraSoundSignalR, LOW); // Holdoff
pinMode(ultraSoundSignalR, INPUT); // Switch signalpin to input
digitalWrite(ultraSoundSignalR, HIGH); // Turn on pullup resistor
 echoR = pulseIn(ultraSoundSignalR, HIGH); //Listen for echo
 ultrasoundValueR = (echoR / 58.138) * .39; //convert to CM then to inches
return ultrasoundValueR;
}

void loop()
{
int FL = 0;
int F = 0;
int FR = 0;
int R = 0;
FL = pingFL();
F = pingF();
FR = pingFR();
R = pingR();
 Serial.print(FL);
 Serial.print("in, ");
 Serial.print(F);
 Serial.print("in, ");
 Serial.print(FR);
 Serial.print("in, ");
 Serial.print(R);
 Serial.print("in, ");
 Serial.println();
 delay(250); //delay 1/4 seconds.
}


I'm thinking I might have to add a while loop or something to tell the Arduino to sweep the sensors one-by-one but I'm not sure how to do this. Any help or input would be greatly appreciated.

mem

#1
Mar 05, 2009, 07:59 pm Last Edit: Mar 05, 2009, 08:01 pm by mem Reason: 1
I haven't run the following but I hope it gives you an idea of how you can simplify your sketch and control the delay between each ping

Code: [Select]
int ultraSoundSignalPins[] = {8,7,6,9}; // Front Left,Front, Front Right, Rear Ultrasound signal pins
char *pingString[] = {"Front Left ","Front ", "Front Right ", "Rear "}; // just something to print to indicate direction

void setup()
{
 Serial.begin(9600);
}

//Ping function
unsigned long ping(int index)
{
 unsigned long echo;

 pinMode(index, OUTPUT); // Switch signalpin to output
 digitalWrite(index, LOW); // Send low pulse
 delayMicroseconds(2); // Wait for 2 microseconds
 digitalWrite(index, HIGH); // Send high pulse
 delayMicroseconds(5); // Wait for 5 microseconds
 digitalWrite(index, LOW); // Holdoff
 pinMode(index, INPUT); // Switch signalpin to input
 digitalWrite(index, HIGH); // Turn on pullup resistor
 echo = pulseIn(index, HIGH); //Listen for echo
 return (echo / 58.138) * .39; //convert to CM then to inches
}

void loop()
{
 unsigned long ultrasoundValue;
 for(int i=0; i < 4; i++){
   ultrasoundValue = ping(i);
   Serial.print(pingString[i]);
   Serial.print(ultrasoundValue);
   Serial.print("in, ");    
   delay(50);

 }
 Serial.println();
 delay(50);
}

mjmcondor

Thanks mem, your code is way more awesome and compact. I can follow what's goin on, but when I run it, I get the following in the Serial Monitor:
Code: [Select]

Front Left 0in, Front 0in, Front Right 0in, Rear 0in,
Front Left 0in, Front 0in, Front Right 0in,


After furthur exampining your code, I noticed that there is no relation setup between the int ultraSoundSignalPins[] = {8,7,6,9}; and unsigned long ping(int index). This is important since the ultrasonic code calls upon index to do readings, and the values should be {8,7,6,9}.

I have revised your code and it is now working and includes delays between each sensor reading.

Code: [Select]

int ultraSoundSignalPins[] = {8,7,6,9}; // Front Left,Front, Front Right, Rear Ultrasound signal pins
char *pingString[] = {"Front Left ","Front ", "Front Right ", "Rear "}; // just something to print to indicate direction

void setup()
{
 Serial.begin(9600);
}

//Ping function
unsigned long ping(int index)
{
 unsigned long echo;

 pinMode(ultraSoundSignalPins[index], OUTPUT); // Switch signalpin to output
 digitalWrite(ultraSoundSignalPins[index], LOW); // Send low pulse
 delayMicroseconds(2); // Wait for 2 microseconds
 digitalWrite(ultraSoundSignalPins[index], HIGH); // Send high pulse
 delayMicroseconds(5); // Wait for 5 microseconds
 digitalWrite(ultraSoundSignalPins[index], LOW); // Holdoff
 pinMode(ultraSoundSignalPins[index], INPUT); // Switch signalpin to input
 digitalWrite(ultraSoundSignalPins[index], HIGH); // Turn on pullup resistor
 echo = pulseIn(ultraSoundSignalPins[index], HIGH); //Listen for echo
 return (echo / 58.138) * .39; //convert to CM then to inches
}

void loop()
{
 unsigned long ultrasoundValue;
 for(int i=0; i < 4; i++){
   ultrasoundValue = ping(i);
   Serial.print(pingString[i]);
   Serial.print(ultrasoundValue);
   Serial.print("in, ");    
   delay(50);

 }
 Serial.println();
 delay(50);
}



Thanks again.

mem

Well spotted, that is exactly right. Glad you have it working. I hope you will post more about your project when you have it all working on the vehicle.

Have fun!

mjmcondor

Minor code revision:
-changed index to i in the Ping Function
-put Ping Function code beneath void loop() code

Code: [Select]

#include <Servo.h>
Servo servo; // create servo object to control a servo

int ultraSoundSignalPins[] = {7,8,9,12}; // Front Left,Front, Front Right, Rear Ultrasound signal pins
char *pingString[] = {"Front Left ","Front ", "Front Right ", "Rear "}; // just something to print to indicate direction

void setup()
{
 servo.attach(10); // attaches a servo to pin 10
 Serial.begin(9600);
}

void loop()
{
 unsigned long ultrasoundValue;
 for(int i=0; i < 4; i++)
 {
   ultrasoundValue = ping(i);
   Serial.print(pingString[i]);
   Serial.print(ultrasoundValue);
   Serial.print("in, ");    
   delay(50);
 }
 Serial.println();
 delay(50);
}

//Ping function
unsigned long ping(int i)
{
 unsigned long echo;

 pinMode(ultraSoundSignalPins[i], OUTPUT); // Switch signalpin to output
 digitalWrite(ultraSoundSignalPins[i], LOW); // Send low pulse
 delayMicroseconds(2); // Wait for 2 microseconds
 digitalWrite(ultraSoundSignalPins[i], HIGH); // Send high pulse
 delayMicroseconds(5); // Wait for 5 microseconds
 digitalWrite(ultraSoundSignalPins[i], LOW); // Holdoff
 pinMode(ultraSoundSignalPins[i], INPUT); // Switch signalpin to input
 digitalWrite(ultraSoundSignalPins[i], HIGH); // Turn on pullup resistor
 echo = pulseIn(ultraSoundSignalPins[i], HIGH); //Listen for echo
 return (echo / 58.138) * .39; //convert to CM then to inches
}


Once my project is complete, I will post more details about it.

kyleklip

You guys RULE.  This code is awesome!!! Thanx 4 sharing!!!!!!

manu121

#6
Apr 08, 2010, 07:15 am Last Edit: Apr 08, 2010, 07:21 am by mmmanoha Reason: 1
I have a question. Sorry for budging in. I am trying to use the same code but what I am trying to do is compare the distances from the 4 ping sensors representing Right, Left, Rear and Front direction. I then want to output a HIGH to the corresponding direction pin. So lets say right is the farthest distance...so pin X goes HIGH. Attached is the code that I modified a bit. The problem now is that this code is too slow. If i hook a LED to my direction pins it takes almost 7 seconds for it to update. I hv created another topic for this...a reply anywhere would suffice. Please help. Thanks.
Code: [Select]




int ultraSoundSignalPins[] = {2,3,4,5}; // Left,Front, Front Right, Rear Ultrasound signal pins
char *pingString[] = {"Left ","Front ", "Right ", "Rear "}; // just something to print to indicate direction
int farthest_Dist=ping(0);
int pinFWD=7;
int pinREAR=8;
int pinLEFT=9;
int pinRIGHT=10;

void setup()
{
 
 Serial.begin(9600);
 pinMode(pinFWD,OUTPUT);
 pinMode(pinREAR,OUTPUT);
 pinMode(pinLEFT,OUTPUT);
 pinMode(pinRIGHT,OUTPUT);
 
}

void loop()
{


 unsigned long ultrasoundValue;
 for(int i=0; i < 4; i++)
 {
   ultrasoundValue = ping(i);
   Serial.print(pingString[i]);
   Serial.print(ultrasoundValue);
   Serial.print("in, ");    
   Serial.println();
   
 }
 {
     {

   
   
    if (ping(0)==ping(1)==ping(2)==ping(3))
  {
    digitalWrite(pinLEFT,LOW);
    digitalWrite(pinFWD,LOW);
    digitalWrite(pinRIGHT,LOW);
    digitalWrite(pinREAR,LOW);
  }
  else if (ping(2)>ping(0))
    {
      farthest_Dist=ping(2);
      digitalWrite(pinRIGHT,HIGH);
        digitalWrite(pinLEFT,LOW);
    digitalWrite(pinFWD,LOW);
    digitalWrite(pinREAR,LOW);
    }
    else if (ping(3) > ping(0))
    {
      farthest_Dist=ping(3);
      digitalWrite(pinREAR,HIGH);
        digitalWrite(pinLEFT,LOW);
    digitalWrite(pinFWD,LOW);
    digitalWrite(pinRIGHT,LOW);
  }
    else if (ping(1) > ping(0))
    {
      farthest_Dist=ping(1);
      digitalWrite(pinFWD,HIGH);
        digitalWrite(pinLEFT,LOW);
    digitalWrite(pinRIGHT,LOW);
    digitalWrite(pinREAR,LOW);
    }
    else
    {
      farthest_Dist = ping(0);
      digitalWrite(pinLEFT,HIGH);
    digitalWrite(pinFWD,LOW);
    digitalWrite(pinRIGHT,LOW);
    digitalWrite(pinREAR,LOW);
  }

Serial.print (farthest_Dist);
   Serial.println();
   }
 }
 
}



//Ping function
unsigned long ping(int i)
{
 unsigned long echo;

 pinMode(ultraSoundSignalPins[i], OUTPUT); // Switch signalpin to output
 digitalWrite(ultraSoundSignalPins[i], LOW); // Send low pulse
 delayMicroseconds(2); // Wait for 2 microseconds
 digitalWrite(ultraSoundSignalPins[i], HIGH); // Send high pulse
 delayMicroseconds(5); // Wait for 5 microseconds
 digitalWrite(ultraSoundSignalPins[i], LOW); // Holdoff
 pinMode(ultraSoundSignalPins[i], INPUT); // Switch signalpin to input
 digitalWrite(ultraSoundSignalPins[i], HIGH); // Turn on pullup resistor
 echo = pulseIn(ultraSoundSignalPins[i], HIGH); //Listen for echo
 return (echo / 58.138) * .39; //convert to CM then to inches



}





mem

manu121, asking the same question in more than one place is not a good thing to do. People trying to help you may spend time writing a helpful post that may be already have been answered in the other thread.

Please decide which thread is more appropriate and post a link to that thread in the other one.

You can reduce the delay by reducing the number of times you call the ping function. You do this by storing the ping values in an array: http://www.arduino.cc/en/Reference/Array

You can do this by making the ultrasoundValue an array:
unsigned long ultrasoundValue[4];
 
and in the for loop, set each element of the array:
 ultrasoundValue = ping(i);

then use ultrasoundValue[1] etc instead of ping(1)

mem

miruthanka, the PING))) referred to in this thread is an ultrasonic  sensor for detecting distance.

http://blog.makezine.com/archive/2009/07/how-to_tuesday_arduino_101_the_ping.html

Ryan Hickman

So what is the recommended delay between reading adjacent range sensors?

I can't have my code wait 200ms to read all four so I'm reading one of each during each outer loop. So the rest of my code updates ASAP and the delay in the full loop is my delay between sensor reads. But I'm seeing collisions and need to introduce "some" delay, but hopefully not 50ms.

Go Up