dears Engineers.. i got stuck with this issue couldn't understand.. please help with explanations.
first i was upset of my ultrasonic sensor reading deviations, that is i examine my sensor indoor and at quite environment,, so what makes this noisy output readings??!!!
so i tried to dig into the pulseIn function and tracking the timing of each instruction in the code.. after reading the library.., i decided to use pulseInLong function. following is a result of some iterations timing in microseconds:
Ultrasonic Sensor HC-SR04 Test
with Arduino UNO R3
Start ~ trig LOW ~ 10us delay ~ trig High ~ 10us delay~ trig High ~ pulseIn ~ Duration
0 8 12 8 12 4 7352 137976
4 4 12 8 12 8 7336 137960
4 8 12 8 12 8 7352 137976
4 8 12 8 12 8 7356 137980
4 8 12 8 12 8 7352 137976
4 8 12 8 12 8 7356 137980
4 8 12 8 12 8 7360 137984
4 8 12 8 12 8 7364 137996
0 8 12 8 12 8 7364 137992
4 8 12 8 12 8 7372 137996
4 8 12 4 12 8 7380 138004
0 4 12 8 12 8 7372 137996
0 4 12 8 12 8 7348 137968
4 8 12 4 12 8 7372 137996
4 8 12 8 12 4 7376 138004
4 8 12 8 12 8 7380 138008
0 8 12 8 8 8 7352 137980
4 8 12 4 12 8 7352 137976
4 8 12 4 12 8 7368 137992
4 8 12 8 12 8 7340 137964
4 8 12 4 12 8 7352 137980
4 8 12 4 12 8 7360 137984
12 8 12 8 12 8 7368 137996
4 8 12 8 12 8 7348 137972
4 8 12 8 12 12 7360 137984
0 8 12 8 12 8 7344 137968
4 8 12 8 12 8 7352 137976
4 8 12 8 12 8 7364 137988
4 8 12 4 12 8 7360 137984
4 8 12 8 12 4 7372 138000
first i wondered why there are different execution time for the same instruction??! for example digitalWrite(trig_pin,LOW or High) varies in range 4 ~ 12 microseconds!!????
more strange when i found elapsed time after delay 10us, micros() function shows only 8 us??!!!
all these in range of 16 us,, so i expected maybe due to some instruction cycles or unprecise clock...etc.
but the BigBang i shocked when read this huuuuuge difference in pulseIn timing measurment; i reset the timer befor the function and just after it, so i got an elapsed time in range of 7350 us. in the same time the resultant measured time from the function in range of the 138000 us?????!!!!!!
put in mind that pulseInLong is a blocking function..as you will see below, it loops in a while loop until timeout (so return 0) or pulse generated and measured before timeout then return pulse elapsed time.
first i suspected in this number maybe not microseconds. inspected the function deeply, ??!!! i found it using the exact micros() function such i do in the code?
* this function relies on micros() so cannot be used in noInterrupt() context
*/
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout)
{
// cache the port and bit of the pin in order to speed up the
// pulse width measuring loop and achieve finer resolution. calling
// digitalRead() instead yields much coarser resolution.
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
uint8_t stateMask = (state ? bit : 0);
unsigned long startMicros = micros();
// wait for any previous pulse to end
while ((*portInputRegister(port) & bit) == stateMask) {
if (micros() - startMicros > timeout)
return 0;
}
// wait for the pulse to start
while ((*portInputRegister(port) & bit) != stateMask) {
if (micros() - startMicros > timeout)
return 0;
}
unsigned long start = micros();
// wait for the pulse to stop
while ((*portInputRegister(port) & bit) == stateMask) {
if (micros() - startMicros > timeout)
return 0;
}
return micros() - start;
}
anyway..i dont want to make this story long.. can someone explain what is going on to me please?!
thanx
here is arduino code i used
#define trigPin 3 //attach pin D3 Arduino to pin Trig of HC-SR04
// defines variables
long duration; // variable for the duration of sound wave travel
int distance; // variable for the distance measurement
void setup() {
// put your setup code here, to run once:
pinMode(trigPin, OUTPUT); // Sets the trigPin as an OUTPUT
pinMode(echoPin, INPUT); // Sets the echoPin as an INPUT
Serial.begin(9600); // // Serial Communication is starting with 9600 of baudrate speed
Serial.println("Ultrasonic Sensor HC-SR04 Test"); // print some text in Serial Monitor
Serial.println("with Arduino UNO R3");
Serial.println("Start ~ trig LOW ~ 10us delay ~ trig High ~ 10us delay ~ trig High ~ pulseIn ~ Duration");
}
void loop() {
// put your main code here, to run repeatedly:
// Clears the trigPin condition
int indx = 0;
int arr[7] = {0};
double last = micros();
arr[indx] = micros() - last;
indx++;
last = micros();
digitalWrite(trigPin, LOW);
arr[indx] = micros() - last;
indx++;
last = micros();
delayMicroseconds(10);
arr[indx] = micros() - last;
indx++;
last = micros();
// Sets the trigPin HIGH (ACTIVE) for 10 microseconds
digitalWrite(trigPin, HIGH);
arr[indx] = micros() - last;
indx++;
last = micros();
delayMicroseconds(10);
arr[indx] = micros() - last;
indx++;
last = micros();
digitalWrite(trigPin, LOW);
arr[indx] = micros() - last;
indx++;
last = micros();
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseInLong(echoPin, HIGH);
arr[indx] = micros() - last;
// Calculating the distance
distance = duration * 0.034 / 2; // Speed of sound wave divided by 2 (go and back)
// Displays the distance on the Serial Monitor
for (int i = 0; i <= indx; i++)
{
Serial.print(arr[i]);
Serial.print(" \t ");
}
Serial.print(duration);
Serial.println();
}