Go Down

Topic: NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.7 (Read 520742 times) previous topic - next topic

zoomx

@teckel,
maybe in NewPing.h you can change this
Code: [Select]
#define US_ROUNDTRIP_CM 57
in this
Code: [Select]
#ifndef US_ROUNDTRIP_CM
#define US_ROUNDTRIP_CM 57
#endif

I am not sure that is written correctly. It mean that if the user doesn't use a define for US_ROUNDTRIP_CM, your library will use the default value of 57.
In this way you don't change the library code, since in every update you will lost any changes.

teckel

@teckel,
maybe in NewPing.h you can change this
Code: [Select]
#define US_ROUNDTRIP_CM 57
in this
Code: [Select]
#ifndef US_ROUNDTRIP_CM
#define US_ROUNDTRIP_CM 57
#endif

I am not sure that is written correctly. It mean that if the user doesn't use a define for US_ROUNDTRIP_CM, your library will use the default value of 57.
In this way you don't change the library code, since in every update you will lost any changes.
NewPing isn't updated very often anyway and you really shouldn't change that value as there's very good reasons why it's set to 57 (speed, accuracy, compiled code size, etc.).

Tim
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

luzcorujo


thehelpdeskguy

To the NewPing Library moderators:

Hello, and thank you (in advance) for your patience.

Hardware used: Genuine Arduino Uno R3 (made in USA); external power supply - 'wall  wart' style 120V in, 5V at 2A out; Arduino IDE ver 1.8.5; breadboard - Jameco JE24.

I have looked through this forum, as well as the main Arduino ones, and have not seen my question asked.  I apologize if I have been obtuse.

Briefly, I have used an HC_SR04 with the NewPing library.  Using the sonar.ping_cm() result(s), I can get and print a reasonably consistent distance from my table to the wall (164 cm, or ca. 64 in).  

Please see attachment "test_us-with-servo_05.ino"

My data output has a few instances like this:

Distance to target: 165 cm 64 in
Distance to target: 165 cm 64 in
Distance to target: 165 cm 64 in
Distance to target: 165 cm 21 in
Distance to target: 165 cm 21 in
Distance to target: 165 cm 64 in
Distance to target: 165 cm 64 in
Distance to target: 165 cm 21 in

My first question is: why does the distance in centimeters appear to be stable, but the distance in inches (the output of sonar.ping_in()) occasionally get to 1/3rd of what it ought to be - 21 instead of 64 inches?  Note that the table support for the HC_SR04 and Arduino is large and unmoving, as is the wall at which the SR04 is pointed.  The processing load on the Arduino should be minimal.  

Larger data file attachment is "test_us-with-servo_05.txt"


So, despite the odd behavior of the distance in inches, the results for distance in cm seems stable enough for my purposes.

My goal though, was to use the distance function in conjunction with a continuous revolution servo motor, an FS90R from FEETECH.  The idea is to have the servo rotating clockwise unless an object comes within the 'thresHold' distance, at which point the servo stops moving.

Adding statements to include the <Servo.h> library, and setting up the servo on Arduino digital pin 7 with range statements did not change the previous results.

However, as soon as my code began to communicate with BOTH the HC_SR04 and the FS90R, the accuracy of the HC_SR04 results was destroyed.

Code with HC_SR04 and FS90R in it: attachment "test_us-with-servo_07.ino"

Here is a sample of the output now:

Distance to target: 43 cm 17 in
Distance to target: 50 cm 10 in
Distance to target: 11 cm 11 in
Distance to target: 50 cm 19 in
Distance to target: 60 cm 15 in
Distance to target: 44 cm 17 in
Distance to target: 40 cm 16 in
Distance to target: 31 cm 19 in
Distance to target: 10 cm 12 in
Distance to target: 29 cm 17 in
Distance to target: 42 cm 20 in
Distance to target: 44 cm 13 in
Distance to target: 59 cm 16 in
Distance to target: 44 cm 19 in
Distance to target: 41 cm 13 in
Distance to target: 51 cm 17 in
Distance to target: 44 cm 19 in

I noticed that as bad as the distance in cm results are (the wall is still 164 cm or 64 inches  away), the problem with the distance in inches is far worse - every distance is stated incorrectly for the inch values, whereas before, this only happened a few times.  How does this relate to the occasional distance in inches problem we saw originally - i.e., without any servo code?

Larger data file attachment is: "test_us-with-servo_07.txt"  If you look at the larger data file, you will notice I put a book in front of the SR04 a couple of times to verify the FS90R stopped rotating.

In fact, the servo DOES stop moving when the 'thresHold' value is reached [there is a slight stutter every 20 seconds or so as well], but the distance results seem completely unreliable.  What have I done incorrectly?  I thought I used the NewPing library correctly, but I am not pleased with my results.  I have spent a fair amount of time attempting to correct this problem, but it seems as soon as I interact with both devices, my programming skills aren't up to the challenge.

I would appreciate any suggestions.  Sorry for the long-winded explanations.  Thank you.



teckel

To the NewPing Library moderators:

Hello, and thank you (in advance) for your patience.

Hardware used: Genuine Arduino Uno R3 (made in USA); external power supply - 'wall  wart' style 120V in, 5V at 2A out; Arduino IDE ver 1.8.5; breadboard - Jameco JE24.

I have looked through this forum, as well as the main Arduino ones, and have not seen my question asked.  I apologize if I have been obtuse.

Briefly, I have used an HC_SR04 with the NewPing library.  Using the sonar.ping_cm() result(s), I can get and print a reasonably consistent distance from my table to the wall (164 cm, or ca. 64 in). 

Please see attachment "test_us-with-servo_05.ino"

My data output has a few instances like this:

Distance to target: 165 cm 64 in
Distance to target: 165 cm 64 in
Distance to target: 165 cm 64 in
Distance to target: 165 cm 21 in
Distance to target: 165 cm 21 in
Distance to target: 165 cm 64 in
Distance to target: 165 cm 64 in
Distance to target: 165 cm 21 in

My first question is: why does the distance in centimeters appear to be stable, but the distance in inches (the output of sonar.ping_in()) occasionally get to 1/3rd of what it ought to be - 21 instead of 64 inches?  Note that the table support for the HC_SR04 and Arduino is large and unmoving, as is the wall at which the SR04 is pointed.  The processing load on the Arduino should be minimal. 

Larger data file attachment is "test_us-with-servo_05.txt"


So, despite the odd behavior of the distance in inches, the results for distance in cm seems stable enough for my purposes.

My goal though, was to use the distance function in conjunction with a continuous revolution servo motor, an FS90R from FEETECH.  The idea is to have the servo rotating clockwise unless an object comes within the 'thresHold' distance, at which point the servo stops moving.

Adding statements to include the <Servo.h> library, and setting up the servo on Arduino digital pin 7 with range statements did not change the previous results.

However, as soon as my code began to communicate with BOTH the HC_SR04 and the FS90R, the accuracy of the HC_SR04 results was destroyed.

Code with HC_SR04 and FS90R in it: attachment "test_us-with-servo_07.ino"

Here is a sample of the output now:

Distance to target: 43 cm 17 in
Distance to target: 50 cm 10 in
Distance to target: 11 cm 11 in
Distance to target: 50 cm 19 in
Distance to target: 60 cm 15 in
Distance to target: 44 cm 17 in
Distance to target: 40 cm 16 in
Distance to target: 31 cm 19 in
Distance to target: 10 cm 12 in
Distance to target: 29 cm 17 in
Distance to target: 42 cm 20 in
Distance to target: 44 cm 13 in
Distance to target: 59 cm 16 in
Distance to target: 44 cm 19 in
Distance to target: 41 cm 13 in
Distance to target: 51 cm 17 in
Distance to target: 44 cm 19 in

I noticed that as bad as the distance in cm results are (the wall is still 164 cm or 64 inches  away), the problem with the distance in inches is far worse - every distance is stated incorrectly for the inch values, whereas before, this only happened a few times.  How does this relate to the occasional distance in inches problem we saw originally - i.e., without any servo code?

Larger data file attachment is: "test_us-with-servo_07.txt"  If you look at the larger data file, you will notice I put a book in front of the SR04 a couple of times to verify the FS90R stopped rotating.

In fact, the servo DOES stop moving when the 'thresHold' value is reached [there is a slight stutter every 20 seconds or so as well], but the distance results seem completely unreliable.  What have I done incorrectly?  I thought I used the NewPing library correctly, but I am not pleased with my results.  I have spent a fair amount of time attempting to correct this problem, but it seems as soon as I interact with both devices, my programming skills aren't up to the challenge.

I would appreciate any suggestions.  Sorry for the long-winded explanations.  Thank you.



You're just getting random values as you've never setup NewPing.  You open the library and then try to use it without setting it up.  Something like this is missing:

NewPing sonar(trigPin, echoPin, maxDist);

Please see the NewPing example code.  Basically, you're never setting up which pins to even ping with nor setting up NewPing at all.  Surprised it even compiled as you've never setup sonar.

Tim
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

thehelpdeskguy

Mr. Teckel:

Thank you for the response.  If I did not set up the NewPing correctly, would you please tell me what is incorrect with the code from my attached file "test_us-with-servo_07.ino, which I used to generate those results:


#include <NewPing.h>
#include <Servo.h>

Servo myservo;

const int trigPin = 9;        // Arduino pin tied to trigger pin on the ultrasonic sensor.
const int echoPin = 10;       // Arduino pin tied to echo pin on the ultrasonic sensor.
const int maxDist = 400;      // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated as 400-500cm.
long unsigned thresHold;     // if object closer than this (in cms), do something

void setup() {
 
 Serial.begin(9600);               // Open serial monitor at 9600 baud to see ping results (NOTE: 115200 *DOES NOT WORK*).
 myservo.attach(7, 544, 2400);     //attach the servo, set the pin for the servo control, and range if desired
 thresHold = 20;                  // when an object is closer than 20 cm (ca. 8 inches), we will do something - stop the motor
}

void loop() {
 NewPing sonar(trigPin, echoPin, maxDist); // NewPing setup of pins and maximum distance.
 delay(100);                               // Wait 100ms between pings (about 10 pings/sec). 29ms should be the shortest delay between pings.
 long unsigned distIn_in;
 long unsigned distIn_cm;
 distIn_in = sonar.ping_in();
 distIn_cm = sonar.ping_cm();
 Serial.print("Distance to target: \t ");
 Serial.print(sonar.ping_cm());            // Send ping, get distance in cm (centimeters) and print result (0 = outside set distance range)
 Serial.print(" cm \t");
 Serial.print(sonar.ping_in());            // Send ping, get distance in in (inches) and print result (0 = outside set distance range)
 Serial.println(" in");
 myservo.write(180);
 if ( (distIn_cm <= thresHold) && (distIn_cm != 0) )
 {
   myservo.write(90);
 }
}


I believe the first line after "void loop() {" has the suggested setup.

I am sorry if I have misunderstood something.  Thank you for your time.


teckel

Mr. Teckel:

Thank you for the response.  If I did not set up the NewPing correctly, would you please tell me what is incorrect with the code from my attached file "test_us-with-servo_07.ino, which I used to generate those results:


#include <NewPing.h>
#include <Servo.h>

Servo myservo;

const int trigPin = 9;        // Arduino pin tied to trigger pin on the ultrasonic sensor.
const int echoPin = 10;       // Arduino pin tied to echo pin on the ultrasonic sensor.
const int maxDist = 400;      // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated as 400-500cm.
long unsigned thresHold;     // if object closer than this (in cms), do something

void setup() {
 
 Serial.begin(9600);               // Open serial monitor at 9600 baud to see ping results (NOTE: 115200 *DOES NOT WORK*).
 myservo.attach(7, 544, 2400);     //attach the servo, set the pin for the servo control, and range if desired
 thresHold = 20;                  // when an object is closer than 20 cm (ca. 8 inches), we will do something - stop the motor
}

void loop() {
 NewPing sonar(trigPin, echoPin, maxDist); // NewPing setup of pins and maximum distance.
 delay(100);                               // Wait 100ms between pings (about 10 pings/sec). 29ms should be the shortest delay between pings.
 long unsigned distIn_in;
 long unsigned distIn_cm;
 distIn_in = sonar.ping_in();
 distIn_cm = sonar.ping_cm();
 Serial.print("Distance to target: \t ");
 Serial.print(sonar.ping_cm());            // Send ping, get distance in cm (centimeters) and print result (0 = outside set distance range)
 Serial.print(" cm \t");
 Serial.print(sonar.ping_in());            // Send ping, get distance in in (inches) and print result (0 = outside set distance range)
 Serial.println(" in");
 myservo.write(180);
 if ( (distIn_cm <= thresHold) && (distIn_cm != 0) )
 {
   myservo.write(90);
 }
}


I believe the first line after "void loop() {" has the suggested setup.

I am sorry if I have misunderstood something.  Thank you for your time.


See the example sketch for NewPing.  Here's an example: https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home#!simple-newping-sketch

Notice where the NewPing sonar() is located.  It's not in the loop() as you're doing.  I'm surprised it works at all as you're not following how you setup a library.  Nowhere do I setup NewPing inside the loop().  That would run on each loop.  You only need to setup the library once.  Again, just look at the example sketches (one is linked above) and it should be obvious.

Tim
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

Luthiano

Tim, congrats for the great library! Helped me a lot.


I'm using two HC-SR04 to return me the angle of inclination of a given wall, it's working great, but the angles i need to read are very small and the round numbers that ping_cm gives me doesnt help.

My question is: how do i get measures to the mm level? maybe a silly question but i'm not familiar with programing...

Many THanks.

teckel

Tim, congrats for the great library! Helped me a lot.


I'm using two HC-SR04 to return me the angle of inclination of a given wall, it's working great, but the angles i need to read are very small and the round numbers that ping_cm gives me doesnt help.

My question is: how do i get measures to the mm level? maybe a silly question but i'm not familiar with programing...

Many THanks.
First, you really can't as the sensor isn't really that accurate (see the spec sheet of the sensor).  But, if you'd really like to calculate distance to the mm, just use the ping() method and then divide that number by the speed of sound at your sampling temp to convert time to mm.

But like I said, it's kinda pointless as the sensor isn't mm accurate, which is why there's a ping_cm() and not a ping_mm() as it really wouldn't be more valuable.

Please read the spec sheet for your sensor, and the bitbucket page for NewPing, everything is explained there.

Tim
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

mimansamaheshwari

Hello,

The NewPing is amazing and it worked great with Arduino mega I used single pin of Mega for Trigger and Echo signals of Ultrasonic sensor HC-sr04 and it worked fine.

However when I try to use one pin for signals in ESP32 I get 0cm value in result everytime. If I use two pins for sensor on esp32 everything works fine but I am unable to use single pin of esp32.

Please help  me in understanding what is wrong here? Are there any changes to be made in library for using one pin functionality on esp32.

I have also attached the code I am using.

teckel

Hello,

The NewPing is amazing and it worked great with Arduino mega I used single pin of Mega for Trigger and Echo signals of Ultrasonic sensor HC-sr04 and it worked fine.

However when I try to use one pin for signals in ESP32 I get 0cm value in result everytime. If I use two pins for sensor on esp32 everything works fine but I am unable to use single pin of esp32.

Please help  me in understanding what is wrong here? Are there any changes to be made in library for using one pin functionality on esp32.

I have also attached the code I am using.
It's possible that the sensor or the ESP32 isn't compatible with single pin control.  This is a hardware thing that can't be resolved with software.  The single pin method typically only works with an Arduino Uno and a HC-SR04 sensor.  But, at the top of the single pin sketch in the comments it does give you a suggestion on how to possibly get it working with a single pin (installing a cap).  If that doesn't work, you're out of luck as your hardware doesn't support it.

Tim
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

Greenie-0424

Hi Tim

I have been trying out some HC-SR04's with your example codes that you have provided and everything is working quite well. I am however having trouble working out how to blend them together to achieve my goals.

My project basically has 3 sensors measuring height above ground, with one of them being a fixed reference sensor and the other 2 being separate variable height sensors.

I was trying to use the 3 sensor example and mix it with the event timer example and the timer median example to provide an average measurement for all 3 sensors 4 or 5 times a second.

Does this seem like a good idea, and do you have any suggestions about how to mix them together?

This is what i have tried so far without success

Code: [Select]

#include <NewPing.h>

#define SONAR_NUM 3
#define MAX_DISTANCE 200
#define PING_INTERVAL 33

NewPing sonar[SONAR_NUM]={
  NewPing(7,7,MAX_DISTANCE),
  NewPing(8,8,MAX_DISTANCE),
  NewPing(9,9,MAX_DISTANCE)
};

unsigned int pingSpeed = 50;
unsigned long pingTimer;

void setup() {
  Serial.begin(115200);
  pingTimer = millis();
}

void loop() {
  for (uint8_t i=0; i<SONAR_NUM; i++){
    if (millis() >= pingTimer){
    pingTimer += pingSpeed;
    sonar.ping_timer(echoCheck);
    }
  }
 
}

void echoCheck() {
  if (sonar.check_timer()){
    Serial.print(sonar.ping_result/US_ROUNDTRIP_CM);
    Serial.println("cm");
  }
}



Thanks

Tony

teckel

Hi Tim

I have been trying out some HC-SR04's with your example codes that you have provided and everything is working quite well. I am however having trouble working out how to blend them together to achieve my goals.

My project basically has 3 sensors measuring height above ground, with one of them being a fixed reference sensor and the other 2 being separate variable height sensors.

I was trying to use the 3 sensor example and mix it with the event timer example and the timer median example to provide an average measurement for all 3 sensors 4 or 5 times a second.

Does this seem like a good idea, and do you have any suggestions about how to mix them together?

This is what i have tried so far without success

Code: [Select]

#include <NewPing.h>

#define SONAR_NUM 3
#define MAX_DISTANCE 200
#define PING_INTERVAL 33

NewPing sonar[SONAR_NUM]={
  NewPing(7,7,MAX_DISTANCE),
  NewPing(8,8,MAX_DISTANCE),
  NewPing(9,9,MAX_DISTANCE)
};

unsigned int pingSpeed = 50;
unsigned long pingTimer;

void setup() {
  Serial.begin(115200);
  pingTimer = millis();
}

void loop() {
  for (uint8_t i=0; i<SONAR_NUM; i++){
    if (millis() >= pingTimer){
    pingTimer += pingSpeed;
    sonar.ping_timer(echoCheck);
    }
  }
  
}

void echoCheck() {
  if (sonar.check_timer()){
    Serial.print(sonar.ping_result/US_ROUNDTRIP_CM);
    Serial.println("cm");
  }
}



Thanks

Tony
You're probably complicating things by trying to use the ping_timer() method based on the 15 sensor example.  I would suggest NOT going this route if you're having problems sorting out your logic as this is a much more complicated programming paradigm to understand.  Please see the following Wiki which tries to talk you out of using the 15 sensor sketch ad nauseam:

Help with 15 Sensor Example Sketch


Instead, do what it suggests and use this sketch as a guide:
Ping 3 sensors sketch


And if you want to do averaging for each sensor, you can replace:

Code: [Select]
Serial.print(sonar[i].ping_cm());

with :

Code: [Select]
Serial.print(sonar[i].ping_median() / US_ROUNDTRIP_CM);


As I continue to get support questions from people trying to use the 15 sensor sketch that have no business trying, and I've tried everything to guild people in the right direction, could you let me know why you decided to use the 15 sensor sketch as a starting point instead of the MUCH more easy to understand 3 sensor sketch?  Even after all the warnings and you're still trying to use it?  I'm really at a loss as to what to do other than remove the 15 sensor sketch.  Even though it's useful for the expert coders, it seems to totally wreck the minds of new coders, to a point where they don't follow any of my warnings or suggestions.  Any help would be appreciated.

Tim
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

enjoyneering

quick question. why 99.99% of HC-SR04 code put trigger pin LOW for 2us-5us?


the datasheet tells to set trigger pin HIGH for 10us..100us to start measurement. why LOW?

teckel

quick question. why 99.99% of HC-SR04 code put trigger pin LOW for 2us-5us?


the datasheet tells to set trigger pin HIGH for 10us..100us to start measurement. why LOW?
The sensor is triggered when trig is high for around 10us.  But, in order to see that, we should first be sure the pin is low.  So, it's set to low, then set to high for the required 10us to trigger the sensor.  If, for example, it was already high, it would never trigger the ping.

This really shouldn't be required, as the pin should be low already.  But, it's just insurance that nothing else set it high.  I believe NewPing is the only library that does this (due to the single pin connection method).  NewPing also does this because it can be used as a background timer so the pin may not be in the state you believe it's in at the time the ping is triggered.

Tim
My platforms Arduino, Teensy 3.2, Arduino Pro Mini, ATmega328
My libraries: NewPing, LCDBitmap, toneAC, toneAC2, NewTone, TimerFreeTone
My projects: https://dogblocker.com & https://baconorbeer.com
My beer: Great Lakes Brewing Co. Lake Erie Monster

Go Up