Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenCr 1.0 HC-SR04 Sonar (NewPing) issue #291

Open
usaotearoa opened this issue Dec 29, 2021 · 0 comments
Open

OpenCr 1.0 HC-SR04 Sonar (NewPing) issue #291

usaotearoa opened this issue Dec 29, 2021 · 0 comments

Comments

@usaotearoa
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant