2

I'm new to Arduino and I'm doing an ultrasonic project where I test for the speed of sound. My code is below and for some reason, this is what the serial port returns:

This is the measured speed of sound: inf m/s This is the measured speed of sound: 0m/s This is the measured speed of sound: 0m/s etc...

Here's my code. Any help's massively appreciated:)

int trig = 13;
int echo = 11;
float target_distance = 0.3;
float recieved;
float speed_of_sound;

void setup() {
    Serial.begin(9600);
    pinMode(trig, OUTPUT);
    pinMode(echo, INPUT);
}

void loop() {
    digitalWrite(trig, LOW);
    delayMicroseconds(2000);
    digitalWrite(trig, HIGH);
    delayMicroseconds(10);
    digitalWrite(trig, LOW);

    recieved=pulseIn(echo, HIGH);
    recieved = recieved*1000000.0;
    speed_of_sound = (2*target_distance)/recieved;
    Serial.print("This is the measured speed of sound: ");
    Serial.print (speed_of_sound);

    Serial.println("m/s");
    delay(3000);
}
1
  • What do you expect the division of 0.6 with 1000000 * some value? – Vaibhav Jun 2 '19 at 17:33
2

Assuming the speed of sound is of the order of 330 m/s, you expect the round-trip to the target and back to last about 1.8 ms. Then

recieved = pulseIn(echo, HIGH);

should give a value close to 1,800, and

recieved = recieved * 1000000.0;

should make received something like 1.8 × 109. Then

speed_of_sound = (2*target_distance)/recieved;

gives a speed of sound of 3.3 × 10−10. It is the correct value if you want that speed in meters per picosecond, but this is inconsistent with your program printing “m/s” after the value.

The Arduino's Serial.print() is quite dumb with floating point numbers. It defaults to printing two digits after the decimal point, irrespective of the order of magnitude of the number. Thus, anything smaller than 0.005 gets printed as “0”.

I don't quite understand why you got ∞ on the first loop. Looks like pulseIn() missed the pulse and returned zero, in which case the speed is computed as 0.6 ÷ 0 = ∞.

The solution is to compute received as

recieved = pulseIn(echo, HIGH) * 1e-6;

This can be remembered by thinking that a quantity (round-trip time) is a numeric value (pulseIn(echo, HIGH)) multiplied by a unit (1e-6, which stands for “microseconds”).

3
  • nice, thorough answer. (voted) – Duncan C Jun 2 '19 at 20:06
  • Ah, a maths error... thats embarrasing. I assumed it was my code. Thanks for taking the time to help though! I just changed the faulty line to: recieved = recieved/1000000 and apart from the first line being "inf", it works well now. – ThisUsernameHasBeenTaken Jun 2 '19 at 20:22
  • @ThisUsernameHasBeenTaken: Scanning the available datasheets didn't turn up any anomalies related the first measurement. I would take a practical approach to it by triggering the device once during setup() and ignoring that result. – JRobert Jun 3 '19 at 12:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.