Pages: [1]   Go Down
Author Topic: Using Multiple PING))) Ultrasonic sensors  (Read 5288 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 4
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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.
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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);
}
« Last Edit: March 05, 2009, 02:01:29 pm by mem » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 4
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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:
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.
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 4
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
#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.
Logged

Chicago
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Eager Novice.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:



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



}


 
« Last Edit: April 08, 2010, 12:21:12 am by mmmanoha » Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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)
Logged

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Pages: [1]   Go Up
Jump to: