Using 2 ping))) ultrasonic sensors?

Hi there,

I'm new to the arduino, and not that experienced in programming, so apologies if i ask stupid questions.

For my project I want to attach 2 ultrasonic range finder sensors. I already bought 2 ping)) sensors as used in the tutorial(http://www.arduino.cc/en/Tutorial/UltrasoundSensor) I get one sensor working fine (ofcourse), and I can even activate 2 sensors. however when I try to read both sensors the program does nothing. No error, it uploads perfectly, but the board doesn't do anything. I tried to use a second set of the 2 while commands, but didn;t get it to work. Can anybody help me figuring this out?

Regards
carl

hello karl.

please give us your code... and we take a look to track bugs :wink:

eric

that's Carl with a C, but that's allright. OK here is my code:

int ultraSoundSignal = 8; // Ultrasound signal pin
int ultraSoundSignall = 7;
int val = 0;
int vall = 0;
int ultrasoundValue = 0;
int ultrasoundValuee = 0;
int timecount = 0; // Echo counter
int timecountt = 0; // Echo counter
int ledPin = 13; // LED connected to digital pin 13
int Aen = 4;
int Aplus = 5;
int Amin = 6;

void setup() {
beginSerial(9600); // Sets the baud rate to 9600
pinMode(ledPin, OUTPUT); // Sets the digital pin as output
pinMode(Aen, OUTPUT);
pinMode(Aplus, OUTPUT);
pinMode(Amin, OUTPUT);
}

void loop() {
timecount = 0;
val = 0;
vall = 0;
pinMode(ultraSoundSignal, OUTPUT); // Switch signalpin to output
pinMode(ultraSoundSignall, OUTPUT);
/* Send low-high-low pulse to activate the trigger pulse of the sensor


*/

digitalWrite(ultraSoundSignal, LOW); // Send low pulse
digitalWrite(ultraSoundSignall, LOW);
delayMicroseconds(2); // Wait for 2 microseconds
digitalWrite(ultraSoundSignal, HIGH); // Send high pulse
digitalWrite(ultraSoundSignall, HIGH); // Send high pulse
delayMicroseconds(5); // Wait for 5 microseconds
digitalWrite(ultraSoundSignal, LOW); // Holdoff
digitalWrite(ultraSoundSignall, LOW); // Holdoff

/* Listening for echo pulse


*/

pinMode(ultraSoundSignal, INPUT); // Switch signalpin to input
val = digitalRead(ultraSoundSignal); // Append signal value to val
while(val == LOW) { // Loop until pin reads a high value
val = digitalRead(ultraSoundSignal);
}

while(val == HIGH) { // Loop until pin reads a high value
val = digitalRead(ultraSoundSignal);
timecount = timecount +1; // Count echo pulse time
}

pinMode(ultraSoundSignall, INPUT); // Switch signalpin to input
vall = digitalRead(ultraSoundSignall); // Append signal value to val
while(vall == LOW) { // Loop until pin reads a high value
vall = digitalRead(ultraSoundSignall);
}

while(vall == HIGH) { // Loop until pin reads a high value
vall = digitalRead(ultraSoundSignall);
timecountt = timecountt +1; // Count echo pulse time
}

/* Writing out values to the serial port


*/

ultrasoundValue = timecount; // Append echo pulse time to ultrasoundValue
//ultrasoundValuee = timecountt; // Append echo pulse time to ultrasoundValue
serialWrite('S'); // Example identifier for the sensor
printInteger(ultrasoundValue);
serialWrite(10);
serialWrite(13);

/* Lite up LED if any value is passed by the echo pulse


*/
if(timecount < 100){
digitalWrite(Aen, HIGH);
digitalWrite(Aplus, HIGH);
digitalWrite(Amin, LOW);
}
if(timecount > 100){
digitalWrite(Aen, HIGH); // Send low pulse
delay(5); // Wait for 2 microseconds
digitalWrite(Aen, LOW); // Send high pulse
delay(5); // Wait for 5 microseconds
digitalWrite(Aen, HIGH); // Holdoff
digitalWrite(Aplus, HIGH);
digitalWrite(Amin, HIGH);
}

if(timecount > 0){
digitalWrite(ledPin, HIGH);
}
/* Delay of program


*/

delay(100);
}

Now I know that I can't use 2 sets of while loops to read the two different sensors, but I don't know how to do it the right way. In the end i want to use the two sensors to keep an object aligned with a walking person in one direction. Please help me!

you can use a while loop that checks for EITHER one condition OR the other
the operand that you need is || which means OR

somenthing like

while ( condition_on_sensor1 || condition_on_sensor2 ) {
val1 = read sensor 1;
val2 = read sensor 2;
}

it's abstract...I haven't checked the exact working of your code..

obviously your code will look more like

while ( (val1 == HIGH) || (val2 == LOW) ) {
//your actions here
}

you can add as many conditions as you want
while ( condition1 || condition2 || condition3 ) {
}

if instead you need to wait that BOTH conditions are true, you must use the AND operand
wich is written in code &&

while( condition1 && condition2 ) {
}

if this is new to you I suggest you read through the excellent
C tutorial posted on the playground wiki
http://www.arduino.cc/playground/Learning/Programming

look under the "logical operators" section.

b.

Thanks for your reply, but i still have a small question:

With the OR operand wouldn't it result in both increasing val 1 and val 2 if either sensor 1 or sensor 2 is doing something? In the end I want to get a seperate timecount for sensor 1 and sensor 2. Just checking?

Tested it, but doesn't work. As soon as I start to try to read sensor 2 next to sensor 1 the board doesn't work anymore? Could it be too much to handle for the arduino board? or am i doing something really wrong?

Could I also use 2 arduino boards, and pass the analog signal from one board to the other?

Regards
Carl

describe a bit better what you want to obtain...
what are the conditions?
what do you want to measure?

are the 2 sensor exclusive? if you get the right value in one do you still need to read the second?
do you need to count how long the high value stays for?
for both?

first describe in words your project
then see if the tech is the right for you...you might not need these sensors/method for what you want to get.

cheers
b.

Ok, i can't tell too much about all the details, but here is basically the idea:

Sensor number one will measure the distance to a walking human being, walking towards and from the sensor.

Sensor number two will measure a motor driven vehicle. The DC motor is also connected to the system. The idea is basically that the system compares both sensor values and then drives the motor in the right speed and direction to keep the vehicle parallel to the human being. So basically I want to mimic the motion of the human on one axis. Therefore I need the 2 sensors to continuously measure both distances seperate from each other. I already figured out how the drive the motor in both directions in different speeds (using the L298N and the PWM outputs). So if somebody could help me out with the sensors that would be great, because I don't get it right now.....

so you need to have BOTH readings before going into the next step
that "both" is already giving you a hint of the behaviour

in pseudocode it would be described more or less as

sendpulse1
sendpulse2

do untill you have both readings {
     listenpulse1
     countpulse1Distance
     check_if_Sensor1_is_completely_read
     listenpulse2
     countpulse2Distance
     check_if_Sensor2_is_completely_read
}

go on with your program

now there are a number of ways of doing this
the first than I can think of right now is this... (maybe not the most appropriate...when checking multiple conditions it's almost always a russian roulette where the result can be completely unexpected, expecially if you are not bertrand russel and master the logical flow... note that my name is beltran :wink: hehehe)

//I'm skipping to the read both sensor code ... I assume all variable declaration for the code herafter

//create two pseudo boolean variables that tell us if the sensors have COMPLETED the reading
//completed means that after having started the counting process they receive a low value to stop counting
int readSensor1 = 0; // zero acts as boolean false  ... 1 acts as boolean true
int readSensor2 = 0;
//wait untill BOTH variables are true-> untill both sensors have been completely read
while ( (readSensor1 != 1)  &&  (readSensor2 != 1) ) {
      //read both sensors
      val1 = digitalRead(sensor1); 
      val2 = digitalRead(sensor2); 
      //count sensor1 only if it's high
      if (val1 == HIGH) {
            //add one to the count
            timecount1++;
            //check again inside this loop if it is actually LOW - this means that the echo has completely arrived
            //note that we are not storing it into a variable because we don't need to reuse it
            //it's just used to mark the boolean value to not perform the timecount operation again
            if( digitalRead(sensor1) == LOW)   readSensor1 = 1;
      }
      //count sensor 2
      if (val2 == HIGH) {
            timecount2++;
            if( digitalRead(sensor2) == LOW)   readSensor2 = 1;
      }

      /*NOW we either have one of the 4 following cases:
      1- both sensors are still LOW  -> so the readSensor1 and 2 variables haven't been marked  -> hence repeat the loop
      2- one of the 2 sensors or both are still HIGH -> the timing has started but not completed -> continue in the loop
      3- one of the 2 sensors has been marked as "read" but not the other -> continue in the loop BUT don't perform the count on the first of the sensor marked as "read"
      4- both sensors are marked as "read" -> exit the loop and continue with the program
        */
}

I haven't tryed it...it might contain mistakes :slight_smile:
as I said it might not be the most appropriate method...there is always more than a way to skin a cat...
here you see how the && condition is applied.

try it and tell us if it works..

another thing...why don't you write a small tutorial or give us some reference for the wiki about
driving "the motor in both directions in different speeds (using the L298N and the PWM outputs)"
:wink:
that would be very helpfull
wiki -> www.arduino.cc/playground

hope it helps
b.

Ok i've tried your suggestion but it doesn't work, and I can't find out what is going wrong. My SerialMonitor does give a distance number twice, but then it stops. What am I doing wrong?

anyway here is my code

int ultraSoundSignal1 = 6;
int ultraSoundSignal2 = 7; // Ultrasound signal pin
int val1 = 0;
int val2 = 0;
int ultrasoundValue1 = 0;
int ultrasoundValue2 = 0;
int timecount1 = 0; // Echo counter 1
int timecount2 = 0; // Echo counter 1
int ledPin = 13; // LED connected to digital pin 13
int readSensor1 = 0;
int readSensor2 = 0;


void setup() {
  beginSerial(9600);                  // Sets the baud rate to 9600
  pinMode(ledPin, OUTPUT);            // Sets the digital pin as output
}

void loop() {
 timecount1 = 0;
 timecount2 = 0;
 val1 = 0;
 val2 = 0;
 readSensor1 = 0;
 readSensor2 = 0;
 pinMode(ultraSoundSignal1, OUTPUT); // Switch signalpin to output
 pinMode(ultraSoundSignal2, OUTPUT); // Switch signalpin to output

/* Send low-high-low pulse to activate the trigger pulse of the sensor
 * -------------------------------------------------------------------
 */

digitalWrite(ultraSoundSignal1, LOW); // Send low pulse
digitalWrite(ultraSoundSignal2, LOW); // Send low pulse
delayMicroseconds(2); // Wait for 2 microseconds
digitalWrite(ultraSoundSignal1, HIGH); // Send high pulse
digitalWrite(ultraSoundSignal2, HIGH); // Send high pulse
delayMicroseconds(5); // Wait for 5 microseconds
digitalWrite(ultraSoundSignal1, LOW); // Holdoff
digitalWrite(ultraSoundSignal2, LOW); // Holdoff

/* Listening for echo pulse
 * -------------------------------------------------------------------
 */

pinMode(ultraSoundSignal1, INPUT); // Switch signalpin to input
pinMode(ultraSoundSignal2, INPUT); // Switch signalpin to input


while((readSensor1 != 1) && (readSensor2 != 1)) {
  val1 = digitalRead(ultraSoundSignal1); // Append signal value to val
  val2 = digitalRead(ultraSoundSignal2); // Append signal value to val 
  if (val1 == HIGH) {
    timecount1++;
    if(digitalRead(ultraSoundSignal1) == LOW){
    readSensor1 = 1;
    }
  }
  if (val2 == HIGH){
    timecount2++;
    if (digitalRead(ultraSoundSignal2) == LOW){
      readSensor2 = 1;
    }
  }
}


ultrasoundValue2 = timecount2; // Append echo pulse time to ultrasoundValue

serialWrite('A'); // Example identifier for the sensor
printInteger(ultrasoundValue2);
serialWrite(10);
serialWrite(13);

/* Lite up LED if any value is passed by the echo pulse
 * -------------------------------------------------------------------
 */

if(timecount2 > 0){
  digitalWrite(ledPin, HIGH);
}

/* Delay of program
 * -------------------------------------------------------------------
 */

delay(100);
}

Can Somebody help me?

Edit:

Ok after trying something else this seems to do something:

int ultraSoundSignal1 = 6; // Ultrasound signal pin
int ultraSoundSignal2 = 7;
int val1 = 0;
int val2 = 0;
int ultrasoundValue1 = 0;
int ultrasoundValue2 = 0;
int timecount1 = 0; // Echo counter
int timecount2 = 0; // Echo counter
int ledPin = 13; // LED connected to digital pin 13


void setup() {
  beginSerial(9600);                  // Sets the baud rate to 9600
  pinMode(ledPin, OUTPUT);            // Sets the digital pin as output
}

void loop() {
 timecount1 = 0;
 timecount2 = 0;
 val1 = 0;
 val2 = 0;
 pinMode(ultraSoundSignal1, OUTPUT); // Switch signalpin to output
 pinMode(ultraSoundSignal2, OUTPUT);
/* Send low-high-low pulse to activate the trigger pulse of the sensor
 * -------------------------------------------------------------------
 */

digitalWrite(ultraSoundSignal1, LOW); // Send low pulse
digitalWrite(ultraSoundSignal2, LOW);
delayMicroseconds(2); // Wait for 2 microseconds
digitalWrite(ultraSoundSignal1, HIGH); // Send high pulse
digitalWrite(ultraSoundSignal2, HIGH); // Send high pulse
delayMicroseconds(5); // Wait for 5 microseconds
digitalWrite(ultraSoundSignal1, LOW); // Holdoff
digitalWrite(ultraSoundSignal2, LOW); // Holdoff

/* Listening for echo pulse
 * -------------------------------------------------------------------
 */

pinMode(ultraSoundSignal1, INPUT); // Switch signalpin to input
pinMode(ultraSoundSignal2, INPUT); // Switch signalpin to input
val1 = digitalRead(ultraSoundSignal1); // Append signal value to val
val2 = digitalRead(ultraSoundSignal2); // Append signal value to val

while((val1 == LOW) && (val2 == LOW) ) { // Loop until pin reads a high value
  val1 = digitalRead(ultraSoundSignal1);
  val2 = digitalRead(ultraSoundSignal2);
}

while((val1 == HIGH) || (val2 == HIGH)) { // Loop until pin reads a high value
  val1 = digitalRead(ultraSoundSignal1);
  val2 = digitalRead(ultraSoundSignal2);
  timecount1 = timecount1 +1;            // Count echo pulse time
}


/* Writing out values to the serial port
 * -------------------------------------------------------------------
 */

ultrasoundValue1 = timecount1; // Append echo pulse time to ultrasoundValue
//ultrasoundValuee = timecountt; // Append echo pulse time to ultrasoundValue
serialWrite('S'); // Example identifier for the sensor
printInteger(ultrasoundValue1);
serialWrite(10);
serialWrite(13);



/* Lite up LED if any value is passed by the echo pulse
 * -------------------------------------------------------------------
 */

if(timecount1 > 0){
  digitalWrite(ledPin, HIGH);
}
/* Delay of program
 * -------------------------------------------------------------------
 */

delay(100);
}

This isn't yet doing what it is supposed to do, but it is the first program that actually sends and receives a pulse on both sensors. Can anybody help me how I should program it to work with two sensors completely? In the end I just want a system that works like the one in the tutorial (http://www.arduino.cc/en/Tutorial/UltrasoundSensor ), but then with 2 sensors at the same time. Who can help me out here?

got it ( i think :))

int ultraSoundSignal1 = 6; // Ultrasound signal pin
int ultraSoundSignal2 = 7;
int val1 = 0;
int val2 = 0;
int ultrasoundValue1 = 0;
int ultrasoundValue2 = 0;
int timecount1 = 0; // Echo counter
int timecount2 = 0; // Echo counter
int ledPin = 13; // LED connected to digital pin 13


void setup() {
  beginSerial(9600);                  // Sets the baud rate to 9600
  pinMode(ledPin, OUTPUT);            // Sets the digital pin as output
}

void loop() {
 timecount1 = 0;
 timecount2 = 0;
 val1 = 0;
 val2 = 0;
 pinMode(ultraSoundSignal1, OUTPUT); // Switch signalpin to output
 pinMode(ultraSoundSignal2, OUTPUT);
/* Send low-high-low pulse to activate the trigger pulse of the sensor
 * -------------------------------------------------------------------
 */

digitalWrite(ultraSoundSignal1, LOW); // Send low pulse
digitalWrite(ultraSoundSignal2, LOW);
delayMicroseconds(2); // Wait for 2 microseconds
digitalWrite(ultraSoundSignal1, HIGH); // Send high pulse
digitalWrite(ultraSoundSignal2, HIGH); // Send high pulse
delayMicroseconds(5); // Wait for 5 microseconds
digitalWrite(ultraSoundSignal1, LOW); // Holdoff
digitalWrite(ultraSoundSignal2, LOW); // Holdoff

/* Listening for echo pulse
 * -------------------------------------------------------------------
 */

pinMode(ultraSoundSignal1, INPUT); // Switch signalpin to input
pinMode(ultraSoundSignal2, INPUT); // Switch signalpin to input
val1 = digitalRead(ultraSoundSignal1); // Append signal value to val
val2 = digitalRead(ultraSoundSignal2); // Append signal value to val

while((val1 == LOW) || (val2 == LOW) ) { // Loop until pin reads a high value
 if (val1 == LOW){
   val1 = digitalRead(ultraSoundSignal1);
   }
 if (val2 == LOW){
   val2 = digitalRead(ultraSoundSignal2);
  }
}

while((val1 == HIGH) || (val2 == HIGH)) { // Loop until pin reads a high value
 if (val1 == HIGH){
   val1 = digitalRead(ultraSoundSignal1);
   timecount1 = timecount1 + 1;
 }
 if (val2 == HIGH){
   val2 = digitalRead(ultraSoundSignal2);
   timecount2 = timecount2 + 1;
 }
}

 
//  val1 = digitalRead(ultraSoundSignal1);
 // val2 = digitalRead(ultraSoundSignal2);
//  timecount1 = timecount1 +1;            // Count echo pulse time
//}


/* Writing out values to the serial port
 * -------------------------------------------------------------------
 */

ultrasoundValue1 = timecount1; // Append echo pulse time to ultrasoundValue
ultrasoundValue2 = timecount2;
//ultrasoundValuee = timecountt; // Append echo pulse time to ultrasoundValue
serialWrite('S'); // Example identifier for the sensor
printInteger(ultrasoundValue2 - ultrasoundValue1);
serialWrite(10);
serialWrite(13);



/* Lite up LED if any value is passed by the echo pulse
 * -------------------------------------------------------------------
 */

if(timecount1 > 0){
  digitalWrite(ledPin, HIGH);
}
/* Delay of program
 * -------------------------------------------------------------------
 */

delay(100);
}

I did a project in the spring for school that used 3 pings, but they were taking turns. They were pointing inward (ie at each other) and I didn't want one giving a signal to another. The URL for the project is here. Anyhow, it worked really well, but with the limited range I gave it (within a picture frame) I only had a resolution on the ping values of 100, which translated to a lot of jumpiness on an 800x600 digital canvas...

The code I used was based on the single ping example floating around somewhere; I just cut and pasted to talk to three sensors. The method is based on the playground rule of "taking turns":

/* Ultrasound Sensor
 * Reads values (00014-01199) from an ultrasound sensor (3m sensor)
 * and writes the values to the serialport
 * http://www.xlab.se | http://www.0j0.org
 * copyleft 2005 Mackie for XLAB | DojoDave for DojoCorp
 */

int ultraSoundSignal = 3; // Ultrasound signal pin- Y
int ultraSoundSignal2 = 5; // Ultrasound signal pin- X1
int ultraSoundSignal3 = 7; // Ultrasound signal pin- X2
int val = 0;
int ultrasoundValue = 0;
int timecount = 0; // Echo counter
int ledPin = 13; // LED connected to digital pin 13
int waitingroom = 50;

void setup() {
  beginSerial(19200); // Sets the baud rate to 9600
  pinMode(ledPin, OUTPUT);  // Sets the digital pin as output
}

void loop() {
  timecount = 0;
  val = 0;
  pinMode(ultraSoundSignal, OUTPUT); // Switch signalpin to output
  // Send low-high-low pulse to activate the trigger pulse of the sensor
  digitalWrite(ultraSoundSignal, LOW); // Send low pulse
  delayMicroseconds(2); // Wait for 2 microseconds
  digitalWrite(ultraSoundSignal, HIGH); // Send high pulse
  delayMicroseconds(5); // Wait for 5 microseconds
  digitalWrite(ultraSoundSignal, LOW); // Holdoff
  // Listening for echo pulse
  pinMode(ultraSoundSignal, INPUT); // Switch signalpin to input
  val = digitalRead(ultraSoundSignal); // Append signal value to val
  while(val == LOW) { // Loop until pin reads a high value
    val = digitalRead(ultraSoundSignal);
  }
  digitalWrite(ledPin, LOW);
  while(val == HIGH) { // Loop until pin reads a high value
    val = digitalRead(ultraSoundSignal);
    timecount = timecount +1;            // Count echo pulse time
  }
  // Writing out values to the serial port
  ultrasoundValue = timecount; // Append echo pulse time to ultrasoundValue
  serialWrite('Y'); // Example identifier for the sensor
  printInteger(ultrasoundValue);
  serialWrite(10);
  serialWrite(13);
  // Lite up LED if any value is passed by the echo pulse
  if(timecount > 0){
    digitalWrite(ledPin, HIGH);
  }
  delay(waitingroom);
  
  timecount = 0;
  val = 0;
  pinMode(ultraSoundSignal2, OUTPUT); // Switch signalpin to output
  // Send low-high-low pulse to activate the trigger pulse of the sensor
  digitalWrite(ultraSoundSignal2, LOW); // Send low pulse
  delayMicroseconds(2); // Wait for 2 microseconds
  digitalWrite(ultraSoundSignal2, HIGH); // Send high pulse
  delayMicroseconds(5); // Wait for 5 microseconds
  digitalWrite(ultraSoundSignal2, LOW); // Holdoff
  // Listening for echo pulse
  pinMode(ultraSoundSignal2, INPUT); // Switch signalpin to input
  val = digitalRead(ultraSoundSignal2); // Append signal value to val
  while(val == LOW) { // Loop until pin reads a high value
    val = digitalRead(ultraSoundSignal2);
  }
  digitalWrite(ledPin, LOW);
  while(val == HIGH) { // Loop until pin reads a high value
    val = digitalRead(ultraSoundSignal2);
    timecount = timecount +1;            // Count echo pulse time
  }
  // Writing out values to the serial port
  ultrasoundValue = timecount; // Append echo pulse time to ultrasoundValue
  serialWrite('X'); // Example identifier for the sensor
  printInteger(ultrasoundValue);
  serialWrite(10);
  serialWrite(13);
  // Lite up LED if any value is passed by the echo pulse
  if(timecount > 0){
    digitalWrite(ledPin, HIGH);
  }
  delay(waitingroom);
  
  timecount = 0;
  val = 0;
  pinMode(ultraSoundSignal3, OUTPUT); // Switch signalpin to output
  // Send low-high-low pulse to activate the trigger pulse of the sensor
  digitalWrite(ultraSoundSignal3, LOW); // Send low pulse
  delayMicroseconds(2); // Wait for 2 microseconds
  digitalWrite(ultraSoundSignal3, HIGH); // Send high pulse
  delayMicroseconds(5); // Wait for 5 microseconds
  digitalWrite(ultraSoundSignal3, LOW); // Holdoff
  // Listening for echo pulse
  pinMode(ultraSoundSignal3, INPUT); // Switch signalpin to input
  val = digitalRead(ultraSoundSignal3); // Append signal value to val
  while(val == LOW) { // Loop until pin reads a high value
    val = digitalRead(ultraSoundSignal3);
  }
  digitalWrite(ledPin, LOW);
  while(val == HIGH) { // Loop until pin reads a high value
    val = digitalRead(ultraSoundSignal3);
    timecount = timecount +1;            // Count echo pulse time
  }
  // Writing out values to the serial port
  ultrasoundValue = timecount; // Append echo pulse time to ultrasoundValue
  serialWrite('Z'); // Example identifier for the sensor
  printInteger(ultrasoundValue);
  serialWrite(10);
  serialWrite(13);
  // Lite up LED if any value is passed by the echo pulse
  if(timecount > 0){
    digitalWrite(ledPin, HIGH);
  }
  delay(waitingroom);
}

Anyhow, this passed values to Flash prefixed with X, Y, and Z (sort of not accurate, since it's not a 3d setup, but using single characters made the flash translation work easier).

Hope this helps some...
-richard