I'm playing with a HC-SR04 (ultrasonic distance measurement) and Arduino UNO or Seeeduino Lite (Arduino Leonardo equivalent). I observe the same problem: the returned pulse microsecond is too short, I must add about 20%.
Here is the shetch:
// READ CODE for Arduino UNO
// Trigger pin connected to pin 7
// echo pin connected to pin 8
// Vcc connected to 5v pin
// GND connected to GND pin
const int trigPin = 7;
const int echoPin = 8;
long duration = 0;
float cm = 0;
void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
digitalWrite(trigPin, LOW);
Serial.begin(9600);
}
void loop()
{
// PING is triggered by a HIGH pulse of 10 or more microseconds.
digitalWrite(trigPin, HIGH);
delayMicroseconds(12);
digitalWrite(trigPin, LOW);
// read the signal from the PING))): a HIGH
// pulse whose duration is the time (in microseconds) from the sending
// of the ping to the reception of its echo off of an object.
duration = pulseIn(echoPin, HIGH);
// convert the time into a distance
cm = (float) duration / 1000000 * 340 / 2 * 100 * 1.2 - 1.0;
Serial.print(duration);
Serial.print(" us, ");
Serial.print(cm);
Serial.print(" cm");
Serial.println();
delay(100);
}
I've studied the disassembly avr-objdump. The pulseIn code is:
...
0000079a <pulseIn>:
...
// wait for the pulse to stop
while ((*portInputRegister(port) & bit) == stateMask) {
1 848: fb 01 movw r30, r22
3 84a: e5 90 lpm r14, Z+
3 84c: f4 90 lpm r15, Z
1 84e: f7 01 movw r30, r14
2 850: f0 80 ld r15, Z
1 852: fd 22 and r15, r29
1 854: fc 12 cpse r15, r28
2 856: 0a c0 rjmp .+20 ; 0x86c <pulseIn+0xd2>
if (numloops++ == maxloops)
1 858: 28 17 cp r18, r24
1 85a: 39 07 cpc r19, r25
1 85c: 4a 07 cpc r20, r26
1 85e: 5b 07 cpc r21, r27
1 860: a9 f0 breq .+42 ; 0x88c <pulseIn+0xf2>
return 0;
width++;
1 862: 2f 5f subi r18, 0xFF ; 255
1 864: 3f 4f sbci r19, 0xFF ; 255
1 866: 4f 4f sbci r20, 0xFF ; 255
1 868: 5f 4f sbci r21, 0xFF ; 255
2 86a: ee cf rjmp .-36 ; 0x848 <pulseIn+0xae>
...
I've added the instruction cycles in front of lines.
The comment says that they are 21 processor clocks. I count 25 and that explains the 20%.