OpenCr 1.0 HC-SR04 Sonar (NewPing) issue
usaotearoa opened this issue · 0 comments
Good day everyone,
I have been working on implementing Ultrasonic sensors with my OpenCR board
and have found the issue liste below, where users have explored different
approaches. However, no detais have been made available.
(ultrasonic sensor hc-sr04) TRIG and ECHO individual pins, not shared
The wiring has been verified with a single "stand-alone" test sketch from the examples. And it works flawlessly
and very accurate readings
I have followed some of the advise / approaches outlined in
#233
The example using the original approach by lslabon
has worked, but created very unreliable results, where the reading jumps
sporadically between values in the range of +/- 20cm.
The second approach taken, was using the NewPing.h/NewPing.cpp library.
But even with this library I noticed issues, despite a (blieved to be) proper
implementation.
What I have noticed is that in "NewPing.cpp" function "unsigned long NewPing::ping_cm(unsigned int max_cm_distance)"
calls the NewPing::ping(max_cm_distance) function, which always aborts right at the beginning, when
invoking if (!ping_trigger()) returning "NO_ECHO"
unsigned int NewPing::ping(unsigned int max_cm_distance) {
if (max_cm_distance > 0) set_max_distance(max_cm_distance); // Call function to set a new max sensor distance.
if (!ping_trigger())
{
return NO_ECHO; // Trigger a ping, if it returns false, return NO_ECHO to the calling function.
}
#if URM37_ENABLED == true
#if DO_BITWISE == true
while (!(*_echoInput & _echoBit)) // Wait for the ping echo.
#else
while (!digitalRead(_echoPin)) // Wait for the ping echo.
#endif
if (micros() > _max_time) return NO_ECHO; // Stop the loop and return NO_ECHO (false) if we're beyond the set maximum distance.
#else
#if DO_BITWISE == true
while (*_echoInput & _echoBit) // Wait for the ping echo.
#else
while (digitalRead(_echoPin)) // Wait for the ping echo.
#endif
if (micros() > _max_time) return NO_ECHO; // Stop the loop and return NO_ECHO (false) if we're beyond the set maximum distance.
#endif
return (micros() - (_max_time - _maxEchoTime) - PING_OVERHEAD); // Calculate ping time, include overhead.
}
Below part of the pin_trigger function
digitalWrite(_triggerPin, LOW); // Set the trigger pin low, should already be low, but this will make sure it is.
delayMicroseconds(4); // Wait for pin to go low.
digitalWrite(_triggerPin, HIGH); // Set trigger pin high, this tells the sensor to send out a ping.
delayMicroseconds(10); // Wait long enough for the sensor to realize the trigger pin is high. Sensor specs say to wait 10uS.
digitalWrite(_triggerPin, LOW); // Set trigger pin back to low.
#if ONE_PIN_ENABLED == true
pinMode(_triggerPin, INPUT); // Set trigger pin to input (when using one Arduino pin, this is technically setting the echo pin to input as both are tied to the same Arduino pin).
#endif
#if URM37_ENABLED == true
if (!digitalRead(_echoPin)) return false; // Previous ping hasn't finished, abort.
_max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!)
while (digitalRead(_echoPin)) // Wait for ping to start.
if (micros() > _max_time) return false; // Took too long to start, abort.
#else
if (digitalRead(_echoPin)) return false; // Previous ping hasn't finished, abort.
_max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!)
while (!digitalRead(_echoPin)) // Wait for ping to start.
if (micros() > _max_time) return false; // Took too long to start, abort.
#endif
Here the part where the code aborts:
if (digitalRead(_echoPin)) return false; // Previous ping hasn't finished, abort.
_max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!)
This is where I believe the code breaks (aka aborts) due to previous ping not finished.
however, I looked at the interval the
void Turtlebot3Sensor::updateSonar1(uint32_t t)
float Turtlebot3Sensor::getSonarData(void)
are triggered and first noticed that updateSonar was called repeatedly in short intervals (<<100ms)
So I increased the amount of time between the calls, as I thought this is the casue of the problem and now it still doesn't work.
These specs are set:
URM37_ENABLED = false
DO_BITWISE = false
ONE_PIN_ENABLED = false
Did anyone get the NewPing.h to work properly and if so, would you mind sharing your implementation please?
As mentioned, using the conventional message returns unreliable results and therefore can not be uses.
Thanks.