can't get two urm37 (ultrasonic) sensors to work

Hello,

I’m doing a project for school where I want to build a robot that can drive itsself through a maze. therefore I got three ultrasonic sensors to measure the distance between the walls surrounding the robot. But I can’t get two sensors to work at the same time.

I used this script to get my sensor working:
http://www.botbuilder.co.uk/codeandprojects/bbsonar/index.html

I stripped down the script to the part i needed for the sensor:

// Bot builder BoxBot sonar code for the ultrasonic sensor bar 
#include "URMSerial.h" 


// The measurement we're taking 
#define DISTANCE 1 
#define TEMPERATURE 2 
#define ERROR 3 
#define NOTREADY 4 

int ledPin = 13; 
URMSerial urm; 

void setup() { 
Serial.begin(9600); 
// Sets the baud rate to 9600 
urm.begin(2,3,9600); 
// RX Pin, TX Pin, Baud Rate 
pinMode(ledPin, OUTPUT); 
} 

void loop() 

{ 
// Request a distance reading from the URM37 
urm.requestMeasurement(DISTANCE); // You may call this as many times as you like. It will only send once 
// Avoid fetching the distance until we're sure the reading is ready 

if(urm.hasReading()) 
{ 
int value; // This value will be populated 
switch(urm.getMeasurement(value)) // Find out the type of request 
{ 
case DISTANCE: // Double check the reading we recieve is of DISTANCE type 
Serial.println(value); // Fetch the distance in centimeters from the URM37 
if (value < 25) // Less than 25cms turn, else carry on. 
{ 
digitalWrite(ledPin, HIGH);  
} 
else{
digitalWrite(ledPin, LOW);
} 
delay(200); 
break; 
} 
}
}

and i tested the code with the changes I made in “urm2” and “value2” so there isn’t a problem but when I try to use two sensors simultaniousely the Serial Monitor doesn’t give any output and the led stays LOW

this is the script I’m trying to get it to work, I’ve tried many different positions to place the script part of the second sensor but no luck:

// Bot builder BoxBot sonar code for the ultrasonic sensor bar 
#include "URMSerial.h" 


#define DISTANCE 1 
#define TEMPERATURE 2 
#define ERROR 3 
#define NOTREADY 4 

int ledPin = 13; 
URMSerial urm;
URMSerial urm2;

void setup() { 
Serial.begin(9600); 
urm.begin(2,3,9600); 
urm2.begin(4,5,9600); 
pinMode(ledPin, OUTPUT); 
} 

void loop() 
{ 
urm.requestMeasurement(DISTANCE); 
urm2.requestMeasurement(DISTANCE); 

if(urm.hasReading()) 
  { 
int value; 
switch(urm.getMeasurement(value)) 
    { 
case DISTANCE:
Serial.println(value); 
if (value < 25)
      { 
digitalWrite(ledPin, HIGH);  
      } 
delay(200); 
break; 
    } 
  }else if(urm2.hasReading()) 
  { 
int value2; 
switch(urm2.getMeasurement(value2)) 
    { 
case DISTANCE: 
Serial.println(value2); 
if (value2 < 25) 
      { 
digitalWrite(ledPin, HIGH);  
      } else
        {
digitalWrite(ledPin, LOW);
        } 
delay(200); 
break; 
    } 
  }
}

I hope I’ve just made some simple stupid mistake :stuck_out_tongue:

You need to activate one sensor (requestMeasurement) and get's it's reading (hasReading and getMeasurementValue). Then, active the other sensor and get its value.

Then, make your decision on what to do based on the two readings.

You are mixing stuff up incorrectly.

changed it but no result:
sorry, im a noob in arduino, I got some C programming experience but not enough to see the problem :frowning:

void loop() 
{ 
urm.requestMeasurement(DISTANCE);
int value;
int value2;

if(urm.hasReading())
{
switch(urm.getMeasurement(value))
{
  case DISTANCE:
  Serial.println(value);
delay(200);
break;
}
}
urm2.requestMeasurement(DISTANCE);
if(urm2.hasReading())
{
switch(urm2.getMeasurement(value2))
{
  case DISTANCE:
  Serial.println(value2);
delay(200);
break;
}
}
if(value<25)
{
  digitalWrite(ledPin, HIGH);
} else if(value2<25)
{
digitalWrite(ledPin, HIGH);
}else 
{
digitalWrite(ledPin, LOW);
}
}

Switch statements with only one case are silly. The ultrasonic sensor can't report a temperature, so the output type from that sensor will ALWAYS be DISTANCE. So, get rid of the switch statements.

changed it but no result

The Arduino Psychic Network has closed for the weekend. If you need help from the non-psychic members of the forum, you need to be more specific. Do you not see anything in the Serial Monitor? If data is appearing in the Serial Monitor, how do you know which sensor any given number came from?

What unit of measure is 25? Inches? Feet? Parsecs? Angstroms?

stripped it down even further but still no response from the sensors (no values in the serial monitor):

void setup() { 
Serial.begin(9600); 
urm.begin(2,3,9600); 
urm2.begin(4,5,9600); 
pinMode(ledPin, OUTPUT); 
} 

void loop() 
{ 

int value;
int value2;

urm.requestMeasurement(DISTANCE);
if(urm.hasReading())
{
urm.getMeasurement(value);
  Serial.println(value);
}
delay(200);

urm2.requestMeasurement(DISTANCE);
if(urm2.hasReading())
{
urm2.getMeasurement(value2);
  Serial.println(value2);
}
delay(200);

if(value<25)
{
  digitalWrite(ledPin, HIGH);
} else if(value2<25)
{
digitalWrite(ledPin, HIGH);
}else 
{
digitalWrite(ledPin, LOW);
}
}

edit:
I tried to put as much of the second sensor code in by writing one line of code and then testing the script gets stuck at the
urm2.requestMeasurement(DISTANCE);

So only the lines “URMSerial urm2;” and “urm2.begin(4,5,9600);” don’t cause the problem :frowning:

edit2: the values the sensor gives are in centimeters but when i remove the switch statement I get numbers in the 5000+ through the serial monitor ones in a while

There is a requestMeasurementOrTimeout() method that you could use. It appears that the requestMeasurement() method blocks. The requestMeasurementOrTimeout() will return after the specified time, even if no response was received.

Are you able to get readings from each sensor independently? This would confirm that both sensors are working.

One thing that I saw from looking at the library is that the URM37 library includes a copy of the NewSoftSerial library - version 8. The latest available is version 10. It would not be a bad idea to replace the NewSoftSerial files in the URM37 folder with the latest versions.

BIG thanks to you PaulS!!!

the requestMeasurementOrTimeout command works :stuck_out_tongue:

this is my code:

#include "URMSerial.h" 


// The measurement we're taking 
#define DISTANCE 1 
#define TEMPERATURE 2 
#define ERROR 3 
#define NOTREADY 4 

int ledPin = 13; 
int ledPin2 = 12;
URMSerial urm; 
URMSerial urm2;

void setup() { 
Serial.begin(9600); 
urm.begin(2,3,9600); 
urm2.begin(4,5,9600);
pinMode(ledPin, OUTPUT); 
pinMode(ledPin2, OUTPUT);
} 

void loop() 

{ 
int value;
urm.requestMeasurementOrTimeout(DISTANCE, value);
Serial.println(value);
if(value < 25)
{
digitalWrite(ledPin, HIGH);
}else
{
digitalWrite(ledPin, LOW);
}
delay(200);
int value2;
urm2.requestMeasurementOrTimeout(DISTANCE, value2);
Serial.println(value2);
if(value2 < 25)
{
digitalWrite(ledPin2, HIGH);
}else
{
digitalWrite(ledPin2, LOW);
}
delay(200);
}

Thank you very much :smiley:

I currently have 3 Urm32 sensors working, have code for 4 sensors also. If you are interested I can show an example of code and wiring.

Yes I am interested.

I've sended you a mail so you don't have to post it on the forum if you don't want to (I know a man who really didn't want me to post the script he gave me but I dont know why)

If you have no problems with it I think the best thing is to post it here so other people can learn from it to.

For future readers of this topic...

The ultrasonic sensor can't report a temperature

This is incorrect, the URM37 sensor does in fact have temperature measuring capabilities. This capability can only be accessed through the serial interface, not through any of the other interfaces it provides.

URM37 Ultrasonic/Temperature Sensor ver3.2 (5m sensor)Downloaded the original code from yerobot.com First written by Ricky on 2008 08 13, modified by Crystal on 2008 09 27 Original Code Description-[Reads values from an ultrasonic sensor and writes the values to the serialport.] Thanks to Yerobot for Hardware and Original Example Code. New Version written by Adz on 22 11 2008. Thanks also to Arduino Reference Coders you all helped heaps. needed to rewrite provided example code to use 4 sensors. I Changed ultraData variables to include the 4 sensors in position mounted on my robots head. New code Gives 4 independant simultaneous distances from 4 cardinal directions(ie:North,South,East,West) Using the interfacing URM37 to Robodruino photo from yerobot as reference. Each URM37 requires Red(+5V),Black(GND),Green(UltraData),Yellow(UltraTrigger)P10 and Blue(UltraEnable)P9 total of 5 fly leads per sensor. My friend Bruce made a suggestion to make a few paired or double leads [(+5v),GND],[UltraTrigger and UltraEnable] that go from Robodruino to all 4 sensors in a chain to save alot of PWM i/o’s and single F-F fly leads. Using the method described above I have saved 4 fly leads per sensor, so I only require 1 for the Green(UltraData) as a result I have the right amount of PWM i/o’s for 4 sensors simultaneously on a single Roboduino. can supply a wiring diagram and the sensor map I made also if you like.

//                                                                               // Code Begins.
// Variable Declarations
int aCount = 0;                                                                // Array Counter--variable counts zero to 3(allow for zero indexing)
int lCount = 1;                                                               // Loop Counter-variable to test how many loops
int tCount = 1;                                                              // Trigger Counter-debug variable to test how many triggers per loop 
int sensorDirection=4;                                                      // Ultrasonic Sensor Location Direction,1=Front,2=Rear,3=Left,4=Right
int val[5]={0,0,0,0};                                                      // values by direction 
int timeCount=0;                                                          // Ultrasonic Echo counter
int ultraValue[5]={0,0,0,0};                                             // sets intial values to zero
// Robodruino Pin Designations
int ultraData[5]={11,6,5,3};                                           // Ultrasonic data pins 11=Front,6=Rear,5=Left,3=Right
int ultraTrigger=10;                                                  // Ultrasonic trigger pin
int ultraEnable=9;                                                   // Ultrasonic enable pin
int ultraPower=12;                                                  // Ultrasonic power pin
int ledPin = 13;                                                   // LED connected to digital pin 13
// Create New Function 
int ActivateTrigger(){;//>>>>>>>>Function - ActivateTrigger() -// Called each loop to Trigger Ultrasonic Pulse.
tCount++;                                                     // Increment Trigger Counter
pinMode(ultraTrigger,OUTPUT);                                // Switch signalpin to output
                                                            /* Send high-low-high pulse to activate the trigger pulse of the sensor
                                                            * -------------------------------------------------------------------*/
digitalWrite(ultraTrigger,HIGH);                          // Send high pulse HIGH
delayMicroseconds(500);                                  //Can be trimmed to 64 to speedup,adz.Orignal Value 500.
digitalWrite(ultraTrigger,LOW);                         // Send low pulse LOW
delayMicroseconds(200);                                //Can be trimmed to 26 to speedup,adz.Original Value 200.
digitalWrite(ultraTrigger,HIGH);                      // Send high pulse HIGH
delayMicroseconds(200);                              //Can be trimmed to 26 to speedup,adz.Original Value 200.
}//>>>>>>>>End Function - ActivateTrigger().

void setup() {
  Serial.begin(9600);                            // Sets the baud rate to 9600
  pinMode(ledPin,OUTPUT);                       // Sets the digital pin as output
  pinMode(ultraPower,OUTPUT);                  // Sets Power On to sensors
  digitalWrite(ultraPower,HIGH);              // Set to HIGH to provide 5V power 
  pinMode(ultraEnable,OUTPUT);               // Sets the digital Enable pin as output
  digitalWrite(ultraEnable,HIGH);           // Set Enable Pin to HIGH
  delay(200);//Can be trimmed to 50 to speedup,adz.200msGive sensor some time to start up --Added By crystal  from Singapo, Thanks Crystal.
   }
void loop() {                           // Main Loop
digitalWrite(ledPin,LOW);              // Switches off Led Hearbeat Pin to Low
aCount = 0,lCount=1,timeCount=0,sensorDirection=4;// Sets Array count to start at zero index, Loop count aligns Sensor Value to correct Array
int combine;                          // Initialize Combine Variable to enable calling Functions from within the Loop
for(lCount=1;lCount<=sensorDirection;){// Loops thorugh sensor1(Front),sensor2(Rear),sensor3(Left),sensor4(Right),
if (aCount>3) {aCount=0;}           // Ensures Array stays between 0-3 to align to Correct Sensor 
val[aCount]=0;
pinMode(ultraData[aCount],INPUT);  // Switch signalpin to input
combine=ActivateTrigger();        // Calls ActivateTrigger() Function to command Sensors Ultrasonic Ping to happen prior to each reading. 
                                 // while sensor output is HIGH do update Value
   while (digitalRead(ultraData[aCount])==HIGH) {val[aCount]=digitalRead(ultraData[aCount]);}  // if read HIGH update Value
                               // while sensor output is LOW do update Value, increment timecount and delay(dont change delay alters values somehow) 
   while  (digitalRead(ultraData[aCount])==LOW) {val[aCount]=digitalRead(ultraData[aCount]),timeCount++,delayMicroseconds(50);} // if read LOW update Value
   ultraValue[aCount]=timeCount;                                                     // Append echo pulse time to ultraValue[aCount]
//                                                                                  //not sure if these LCD commands will effect anything else
//  Serial.write(254,HEX),Serial.write(1,HEX);                                     //Clear the LCD(seetron users manual commands)
//  Serial.write(254,HEX),(2,HEX);                                                //Set the LCD cursor to home
//  Serial.write(254,HEX),(2,HEX);                                               //Set the LCD cursor position to top left
//  Serial.write(254,HEX),(192,HEX);                                            //Set the LCD cursor position to bottom left
//
// URM37 Datasheet "Pin PWM will output pulses every 50us represents 1cm,If the reading is invalid, a 50000us pulse will be returned."
// Need an Error Trap here for Sensor Readings out of range. something like if error then tell me else display reading.
// if ultraValue[acount]<4||if ultraValue[acount]>5000 then Serial.print("Error")
// if distance < min possible reading(4cm) or distance > max possible reading(5000cm) then must be invalid reading or error
if (aCount==0) {Serial.print(" Fr="),Serial.print(ultraValue[aCount]);}                     // Display Read Value for Front Sensor Array0
  else                                                                                     // Loop is not Front Sensor
     if (aCount==1) {Serial.print(" Re="),Serial.print(ultraValue[aCount]);}              // Display Read Value for Rear Sensor Array1
      else                                                                               // Loop is not Rear Sensor
         if (aCount==2) {Serial.print(" Le="),Serial.print(ultraValue[aCount]);}        // Display Read Value for Left Sensor Array2
          else                                                                         // Loop is not Left Sensor
             if (aCount==3) {Serial.print(" Ri="),Serial.print(ultraValue[aCount]);}  // Display Read Value for Right Sensor Array3
Serial.flush();                                                                      // flush the serial buffer
if(ultraValue[aCount] > 20){digitalWrite(ledPin, HIGH);}                            // Lite up LED if any value is passed by the echo pulse
aCount++;lCount++;}                                                                // increment Array Counter and Loop Counter
delay(500);                                                                       //  Delay of program
return;                                                                          // Return to Start of Loop
}//                                                                             //Code Ends.

Here is the layout and distance chart I made from the urm32 reference.

adzuniverse.com/adzrobotpage/R0D0UltraSonicInformation.JPG

Wiring Sensors to RoboDruino: Using the interfacing URM37 to Robodruino photo from yerobot as reference. Each URM37 requires Red(+5V),Black(GND),Green(UltraData),Yellow(UltraTrigger)P10 and Blue(UltraEnable)P9 total of 5 fly leads per sensor. My friend Bruce made a suggestion to make a few paired or double leads [(+5v),GND],[UltraTrigger and UltraEnable] that go from Robodruino to all 4 sensors in a chain to save alot of PWM i/o's and single F-F fly leads. Thanks to Bruce who soldered me some 4 way fly leads for this purpous using salvaged pc front panel wires and ends. Using the method described above I have saved 4 fly leads per sensor, so I only require 1 for the Green(UltraData) as a result I have the right amount of PWM i/o's for 4 sensors simultaneously on a single Roboduino. Here is the wiring loom diagram of how I linked the 4 urm32 sensors together.

http://adzuniverse.com/adzrobotpage/robodruinowith4URM32.jpg

The fly leads I saved I will use in future Versions as I hope to make use of the URM37's built in servo angle control pins next to independantly tilt each URM37 with my servos using an adapted for Robodruino servo controlling proto-sheild. I will just use the head rotation of my robot to handle the sensors pan and robots my pan/tilt ultrasonics will be almost complete. Code changes and challenges: As a result of the wiring looms I can Power, Enable and Trigger all four sensors together from the same line. Basically I broke the original code up into 4 sections, Activate Trigger, Read High, Read Low and Display Data. then I refined from there. One of the challenges I faced duplicating this code for the 4 directions was trying to run four loops concurrently was giving false readings and accuracy seemed to be effected by changes therefore another friend Big Al suggested to break it up into Functions that I call later as I need, this seems to have worked great. Now I have each sensors data being passed to the LCD via serial I am now working on sending the data to an arduino controlling my sure24x16 Led display to represent the distances in a more meaningful way. I will post this project in its own thread soon.