accurate Ultrasound reading

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 http://www.arduino.cc/en/Tutorial/UltrasoundSensor

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);
}