I am trying to measure distance in CM using an ultrasonic srf05 ranger:
http://www.robot-electronics.co.uk/htm/srf05tech.htm
Based on this tutorial
I am using Mode 2 (from the srf05 page) to use one pin as input and output.
Here is the hacked together code I'm currently using
void ultrasoundLoop(){
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(10); // Wait for 10 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);
}
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('U'); // Example identifier for the sensor
printInteger(ultrasoundValue);
serialWrite(10);
serialWrite(13);
}
"You only need to supply a short 10uS pulse to the trigger input to start the ranging".
First of all, can anyone see any problems in the above code?
My code to convert this into cm needs more explaining, so will post that seperately. If you have any suggestions on this topic let me know.
I used the same device with this code which is based on the cound from the arduino playground site, I remember that being a more useful tutorial for some reason. http://webzone.k3.mah.se/projects/arduino-workshop/projects/arduino_meets_processing/instructions/ultrasound.html
(i was using 6 ultrasounds, so I trimmed the code down, hopefully all the bits are there to make it work with one):
#define aultraSoundSignal 2 // UltraSound 1
int aval = 0;
int aultrasoundValue = 0; //UltraSound1 Value
int atimecount = 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() {
// UltraSound A:
atimecount = 0;
aval = 0;
pinMode(aultraSoundSignal, OUTPUT); // Switch signalpin to output
/* Send low-high-low pulse to activate the trigger pulse of the sensor
-------------------------------------------------------------------
*/
digitalWrite(aultraSoundSignal, LOW); // Send low pulse
delayMicroseconds(2); // Wait for 2 microsecond
digitalWrite(aultraSoundSignal, HIGH); // Send high pulse
delayMicroseconds(5); // Wait for 5 microseconds
digitalWrite(aultraSoundSignal, LOW); // Holdoff
/* Listening for echo pulse
-------------------------------------------------------------------
*/
pinMode(aultraSoundSignal, INPUT); // Switch signalpin to input
aval = digitalRead(aultraSoundSignal); // Append signal value to val
while(aval == LOW) { // Loop until pin reads a high value
aval = digitalRead(aultraSoundSignal);
}
while(aval == HIGH) { // Loop until pin reads a high value
aval = digitalRead(aultraSoundSignal);
atimecount = atimecount +1; // Count echo pulse time
}
// Write values to Serial port:
aultrasoundValue = atimecount; // Append echo pulse time to ultrasoundValue
serialWrite('A'); //Sensor Identifier
printInteger(aultrasoundValue);
serialWrite(10);
delay(10);
if(atimecount > 0){ // if the first sensor works make the LED flash.
digitalWrite(ledPin, HIGH);
}
delay(100); // delay before you do it all again.
}
I don't know what cm is, but I was reading the data in processing and then sending it all over the place (to SuperCollider servers) using OSC. If that sounds like what you;re trying to do I can send you the processing OSC stuff.
Thanks. By cm I mean centimeters. I'm trying to accurately measure distance.
Your code is the same as mine, or the tutorials to be exact.
Although actually your code has
delayMicroseconds(5); // Wait for 5 microseconds
I believe you need to wait for 10 microseconds, if you read the data page for the srf05. 'You only need to supply a short 10uS pulse to the trigger input to start the ranging'
I'm looking for the best way to convert this timing data into a measurement of centimeters.
haha, grand. i'm used to SC = supercollider.... oh well.
5 worked fine actually, it's just what comes with the playground tutorial.
The digitalWrite statement takes about 9uS to execute so that is probably why the 5 or 10 uS delay doesn't matter.
To get centimetres from the ultrasound reading, one should divide the time value by 58, cm = time / 58
http://www.robot-electronics.co.uk/htm/srf05tech.htm
the numbers I get back from the ultrasound into Arduino don't match with this theory.
For example, the maximum value I get back is 3552 microseconds ( via Serial.println(val) ). This sensor is supposed to do 4 metres, which would be 23,200 microseconds (400cm * 58). I've moved the sensor in many ways pointing into empty space, the same maximum reading each time. 3552 / 58 = 61cm by the way.
The sensor timesout at 30 miliseconds (30,000 microseconds), but 3552 is much lower than 30,000 so it cant be this.
Any ideas anyone?
Just to restate, the ultrasound works as a reading of something getting closer and further away, but I am trying to convert this reading into centimetres.
Thanks
[update 1]
If I divide by 5.8 and not 58, I get much better readings for centimetres.
3552 though / 5.8 is still only 612cm.
Holding a book at 1m away, being careful not to cross the beam, I get a reading of 115cm.
Any advice on this most welcome.
Thanks to a support email from Robot Electronics, they said why not use PulseIn. I didn't realise this had been added to Arduino. Its been added since version7.
Here is my new code, seems to work much better...
int ultraSoundpin = 7;
unsigned long ultrasoundDuration;
void setup() {
beginSerial(9600);
}
void loop() {
// switch pin to output
pinMode(ultraSoundpin, OUTPUT);
// send a low, wait 2 microseconds, send a high then wait 10 microseconds
digitalWrite(ultraSoundpin, LOW);
delayMicroseconds(2);
digitalWrite(ultraSoundpin, HIGH);
delayMicroseconds(10);
digitalWrite(ultraSoundpin, LOW);
// switch pin to input
pinMode(ultraSoundpin, INPUT);
// wait for a pulse to come in as high
ultrasoundDuration = pulseIn(ultraSoundpin, HIGH);
// output
Serial.print(ultrasoundDuration);
Serial.print("\t");
Serial.print(ultrasoundDuration/58, DEC);
Serial.print(" cm");
Serial.println();
delay(100);
}