NewPing Library: HC-SR04, SRF05, SRF06, DYP-ME007, Parallax PING))) - v1.7

Do your sensors look like these?:

carsensors.jpg

The 1 pulse / 10uS width is just to trigger the sensor. The sensor detects this and then sends out it's own multiple pulses. In other words, the sensor doesn't just send out one 10uS pulse, we just trigger it. I have not seen a sensor that doesn't automatically send out multiple pulses from a trigger.

i know it how the sensor works but this sensor dosnt operate with 1 pulse / 10 us it works with 16 pulses with period of 21us and frequency of 40KHZ if i can apply this to my sensor it will work, now i just want to know how should i produce this 16 pulses(40KHZ)

Do you even know the maximum sensor distance? Maybe it's only 40cm

the maximum is 5 meter , it reads 40cm but not accurate it has 13cm error.

CyklKent: Do your sensors look like these?:

exactly the same

bulut:

CyklKent: Do your sensors look like these?:

exactly the same

So, you're trying to use just the sensor without the control board? Many people have tried doing this and I have yet to hear of anyone who was successful. The same is true with the typical HC-SR04 type sensors. You can't just use the sensors without the control board.

Basically, if you want to use these sensors, you're going to need to interface with the control board, not the sensors directly. It's not something that can be fixed with software. You need hardware to amplify the signals, issue the pings, etc. You can't just connect them to an Arduino, they won't work that way.

Tim

So, you’re trying to use just the sensor without the control board?

no i am not trying to use the sensor without the board , in my first post i noted that i am using the sensor board . i know if i connect the sensor directly to the arduino it wont work.

It’s not something that can be fixed with software

believe me if we apply the 16 pulses with 21us period with 40KHZ frequency i will be work i am sure, so please tell me how to change the code to produce this pulses .

You need hardware to amplify the signals

the sensor board has the amplifyer inside.

check the pictures

untitled.JPG

bulut: believe me if we apply the 16 pulses with 21us period with 40KHZ frequency i will be work i am sure, so please tell me how to change the code to produce this pulses .

The NewPing library doesn't do the ultrasonic pulses. It only triggers the control board which does the pulses. It's very odd that this control board doesn't do these pulses (that's one of the duties of the control board). I've never heard of a control board that doesn't do the required pulses that the control board's decoder requires. It only makes sense that the control board would issue the correct pulses that it needs on the decode side. It could be how you're doing the ping trigger. Maybe you're not doing the trigger, but actually just a single fire? In other words, maybe you're connecting to the wrong place on the control board.

In any case, doing these pulses is outside the scope of the NewPing library as it would drastically change things and be specific to one individual control board.

What you'll need to do is create your own control function or library. In order to do the pulses with accuracy, you'll need to look into PWM. I don't think the standard Arduino PWM will work as you need to set a frequency of around 47 kHz (21uS) while the maximum Arduino PWM is 1 kHz. Using timers you can get as high as 64 kHz, but I believe the next step would be 32 kHz so you could still have a problem.

I'd really try to get the control board to do the correct pulses (that's its job anyway). If you can't, try looking for PWM library that can do high frequency pulses.

Tim

I am using the new Ping library with my code and have hit a dead end. My code is running a SparkFun stepper motor in a loop where it slowly increments the RPM. I eventually want to control the speed based on the distance measurement from my Ping((( sensor, but I've dumbed it down to find the error. It's not the best code for my motor, but for example sake it works. The problem is that even though I use the ping_timer like in the example calling:

sonar.ping_timer(echoCheck);

stops the motor from moving. once I comment that line out the motor starts working again. below is the code. any ideas?

#include 
#include 


#define TRIGGER_PIN  7  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     7  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

AF_Stepper motor(200, 1);
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
unsigned int pingSpeed = 1000; // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
unsigned long pingTimer;     // Holds the next ping time.
int rpm =10;

void setup(){
  Serial.begin(115200);
  pingTimer = millis(); // Start now.
  
  Serial.println("Stepper test!");
  motor.setSpeed(100);  // 100 rpm   
  motor.step(100, FORWARD, SINGLE); 
  Serial.println("step done");
  motor.release();
  delay(1000);
  
}

void loop(){
  // Notice how there's no delays in this sketch to allow you to do other processing in-line while doing distance pings.
  
  if (millis() >= pingTimer) {   // pingSpeed milliseconds since last ping, do another ping.
    pingTimer += pingSpeed;      // Set the next ping time.
    sonar.ping_timer(echoCheck); // Send out the ping, calls "echoCheck" function every 24uS where you can check the ping status.
  }
  
  
  Serial.print("setting RMP = ");
  Serial.println(rpm);
  motor.setSpeed(rpm);
  Serial.println();
  Serial.println();
  motor.step(100, FORWARD, SINGLE);
  rpm = rpm +10;
  delay(1000);
}
  void echoCheck() { // Timer2 interrupt calls this function every 24uS where you can check the ping status.
  // Don't do anything here!
  if (sonar.check_timer()) { // This is how you check to see if the ping was received.
    // Here's where you can add code.
    Serial.print("Ping: ");
    Serial.print(sonar.ping_result / US_ROUNDTRIP_CM); // Ping returned, uS result in ping_result, convert to cm with US_ROUNDTRIP_CM.
    Serial.println("cm");
  }
  
  
}

I think this part of the code is incorrect. It will always check as true. That is all that I have found at the moment.

if (millis() >= pingTimer) {   // pingSpeed milliseconds since last ping, do another ping.
    pingTimer += pingSpeed;      // Set the next ping time.
    sonar.ping_timer(echoCheck); // Send out the ping, calls "echoCheck" function every 24uS where you can check the ping status.
  }

Take a look at the blink without delay example.

 unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;  
    
    
    // run function here
    
  }

that code was taken straight from the NewPingEventTimer example code, and as far as I can tell should not always be true.

hbaxton: I am using the new Ping library with my code and have hit a dead end. My code is running a SparkFun stepper motor in a loop where it slowly increments the RPM. I eventually want to control the speed based on the distance measurement from my Ping((( sensor, but I've dumbed it down to find the error. It's not the best code for my motor, but for example sake it works. The problem is that even though I use the ping_timer like in the example calling:

sonar.ping_timer(echoCheck);

stops the motor from moving. once I comment that line out the motor starts working again. below is the code. any ideas?

I'd start debugging this by removing the Serial.print/Serial.println stuff inside the echoCheck subroutine. This is only there for a test, you should eventually replace it with code that processes the ping result. But for now you can simply delete it. If it still doesn't work correctly, it could be that the AFMotor library is also using the same timer that NewPing is using to do the stepper motor control.

Also, cyclegadget is correct, you're not really using the pingTimer correctly. Both ping_timer() and the pingTimer variable are designed to be used WITHOUT delays. If you're using delays, it's going to not work correctly.

Basically, if you're going to use delays, you should not use any of the polling (pingTimer) stuff and shouldn't use the ping_timer() method. You should just use the standard ping() method. If you want to create a more event driven sketch, you need to be comfortable with not using delay commands.

I simplified your sketch and used the standard ping() method (well, ping_cm() which is ping that converts the result to centimeters). This may make more sense and be a closer fit to what you're trying to do.

#include 
#include 

AF_Stepper motor(200, 1);
NewPing sonar(7, 7, 200); // NewPing setup of pins and maximum distance.
int rpm = 10;

void setup(){
  Serial.begin(115200);
  Serial.println("Stepper test!");
  motor.setSpeed(100);  // 100 rpm   
  motor.step(100, FORWARD, SINGLE); 
  Serial.println("step done");
  motor.release();
  delay(1000);
}

void loop(){
  int cm = sonar.ping_cm();
  Serial.print(cm);
  Serial.println(" cm");
  
  Serial.print("setting RMP = ");
  Serial.println(rpm);
  motor.setSpeed(rpm);
  Serial.println();
  Serial.println();
  motor.step(100, FORWARD, SINGLE);
  rpm += 10;
  delay(1000);
}

hbaxton: that code was taken straight from the NewPingEventTimer example code, and as far as I can tell should not always be true.

It is always true, because you're adding delays and telling it to start right away, yet then adding a full second delay. Basically, you need to either create an event driven/polling type sketch, or one with delays. Combining the two could give you problems.

It doesn't seem you're comfortable with an event driven/polling type sketch. So, you shouldn't really try to use any example NewPing sketch that uses the ping_timer() method. Stick with ping(), ping_cm(), ping_in(), and ping_median() till you're comfortable with not using the delay() command in your sketch.

Tim

hi teckel & cyclegadget,

thank you for your response. i am new to events. so i tried taking out all the delays and also tried calling the ping function directly but i had the same results. i’m going to look into the adafruit motor library to see if it is using the timer as the new ping library.

thanks again! i’ll report back.

@hbaxton

Take a look at this sketch. I reworked your sketch and put the motor running part into a function then, made it work with blink without delay style. It is untested but, I think it will work.

#include 
#include 


#define TRIGGER_PIN  7  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     7  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

AF_Stepper motor(200, 1);
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

unsigned int pingSpeed = 1000;  // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
unsigned long pingTimer;        // Holds the next ping time.
unsigned long motorTimer;       // Holds the place for motor speed adjusts
unsigned int adjustTime = 1000; // how often to adjust the speed of the motor
int rpm =10;

void setup(){
  Serial.begin(115200);
  pingTimer = millis(); // Start now.

  Serial.println("Stepper test!");
  motor.setSpeed(100);  // 100 rpm   
  motor.step(100, FORWARD, SINGLE); 
  Serial.println("step done");
  motor.release();
  delay(1000);
}

void loop(){
  // Notice how there's no delays in this sketch to allow you to do other processing in-line while doing distance pings.
  if (millis() >= pingTimer) // pingSpeed milliseconds since last ping, do another ping.
  {   
    pingTimer = millis() + pingSpeed;      // Set the next ping time.
    sonar.ping_timer(echoCheck); // Send out the ping, calls "echoCheck" function every 24uS where you can check the ping status.
  }

////////////////////////////////////////Here is the new part that will run your motor on a timer
  if (millis() >= motorTimer)
  {
    motorrun();
    motorTimer = millis() + adjustTime;
  }
}

void motorrun()
{ // this is the function that will run your motor when called
  Serial.print("setting RMP = ");
  Serial.println(rpm);
  motor.setSpeed(rpm);
  Serial.println();
  Serial.println();
  motor.step(100, FORWARD, SINGLE);
  rpm = rpm +10;
}


void echoCheck() { // Timer2 interrupt calls this function every 24uS where you can check the ping status.
  // Don't do anything here!
  if (sonar.check_timer()) { // This is how you check to see if the ping was received.
    // Here's where you can add code.
    Serial.print("Ping: ");
    Serial.print(sonar.ping_result / US_ROUNDTRIP_CM); // Ping returned, uS result in ping_result, convert to cm with US_ROUNDTRIP_CM.
    Serial.println("cm");
  }  
}

hbaxton: hi teckel & cyclegadget,

thank you for your response. i am new to events. so i tried taking out all the delays and also tried calling the ping function directly but i had the same results. i'm going to look into the adafruit motor library to see if it is using the timer as the new ping library.

thanks again! i'll report back.

You can't just remove the delays and expect it to work as then you'll have other problems. Instead, try using the replacement sketch I provided in a previous post that includes delays, but does so correctly. Your sketch was a hybrid, but used bad logic. To simplify things for you, my sketch does it the standard way, with the ping() method and delays. This is how you should use NewPing unless you know what you're doing and know how to write event-driven sketches. I do highly suggest that you learn this programming paradigm as you'll have a hard time graduating beyond "hello world" tests otherwise. But, maybe try something simple at first.

Tim

Hello… i wrote a code that uses this library, and isn’t 100% reliable when debugging…
I’d be grateful if you comment it.

#include <NewPing.h>

#define BAUD 9600
#define MIN_DISTANCE 6      //Minimum distance to ping (cm)
#define MAX_DISTANCE 60     //Maximum distance to ping (cm)
#define THRESHOLD 10        //Treshold (cm)
#define HOLD_TIME 15        //Delay between each step (ms)
#define STEP_TIME 33        //Delay between ultrasonic's

//Creating ultrasonic objects
NewPing SONAR_L(TRIG_PIN_L, ECHO_PIN_L, 2000);
NewPing SONAR_R(TRIG_PIN_R, ECHO_PIN_R, 2000);

//Creating debugg function
void debugg(int val_l, int val_r)
{
  Serial.print(val_l);
  Serial.print(" ");
  Serial.print(val_r);
  Serial.println();
}

//Creating setup function
void setup() 
{
  Serial.begin(BAUD);
  
  pinMode(ECHO_PIN_L, INPUT);
  pinMode(ECHO_PIN_R, INPUT);
  pinMode(TRIG_PIN_L, OUTPUT);
  pinMode(TRIG_PIN_R, OUTPUT);
}

//Program
void loop() 
{
  //Declaring local static variables
  static bool hold = false;
  static int val_l, val_r;
  static int per_l, per_r;
  static int prev_per_l = MIN_DISTANCE, prev_per_r = MIN_DISTANCE;

  //Reading ultrasonic values
  delay(STEP_TIME);
  unsigned int uS1 = SONAR_L.ping();
  per_l = uS1 / US_ROUNDTRIP_CM;
  
  delay(STEP_TIME);
  unsigned int uS2 = SONAR_R.ping();
  per_r = uS2 / US_ROUNDTRIP_CM;
  
  //Limiting the effective range of ultrasonics
  per_l = constrain(per_l, MIN_DISTANCE, MAX_DISTANCE);
  per_r = constrain(per_r, MIN_DISTANCE, MAX_DISTANCE);
  
  //This part of code is used to save the distance of ultrasonic sensors
  //when the hand is moved away from the beam ) ) ) of the sensor
  if( (per_l - prev_per_l) > THRESHOLD )
  {
    per_l = prev_per_l;
    hold=false;
  }

  if( (per_r - prev_per_r) > THRESHOLD )
  {
    per_r = prev_per_r;
    hold=false;
  }
  
  prev_per_l = per_l;
  prev_per_r = per_r;

  //Modifying the data using linear math (used for servo motors)
  per_l = map(per_l, MIN_DISTANCE, MAX_DISTANCE, 100, 0);

  val_l = map(per_r, MIN_DISTANCE, MAX_DISTANCE, 90, 0);
  val_r = map(per_r, MIN_DISTANCE, MAX_DISTANCE, 0, 90);
  
  val_l = val_l * (per_l / 100.0);
  val_r = val_r * (per_l / 100.0);

  //Writing final data to servo motors
  servo_l.write(val_l);
  servo_r.write(val_r);
  
  //Debugging the final data
  debugg(val_l, val_r);

  //Applying the final delay (due to servo speed characteristics)
  hold=true;
  if(hold==true) delay(HOLD_TIME);
}

xvjeko: Hello.. i wrote a code that uses this library, and isn't 100% reliable when debugging... I'd be grateful if you comment it.

1) TRIG_PIN_L, TRIG_PIN_R, ECHO_PIN_L and ECHO_PIN_R are never defined. 2) No reason to set the pin modes, NewPing does that for you. 3) You shouldn't set the maximum distance to 2000cm on the "NewPing SONAR" lines. The sensor won't work beyond 500cm and setting it to 2000 could make the time between pings from 33ms to 115ms or just cause problems in general. Just remove the ,2000 and it will default to the sensor's maximum distance, which is 500cm and will allow for 33ms between pings as you have it set. 4) The "constrain" commands will give you problems as out of range results (which are zero) would change to 6. Out of range would typically be beyond 500cm, making it 6cm will probably not give what you're looking for. Instead, do something like "if (per_l > 0) per_l = constrain(per_l, MIN_DISTANCE, MAX_DISTANCE);" so there can still be a zero result (out of range). 5) The rest of your code then needs to accommodate what to do with out of range results. It doesn't appear that you have considered that. If anything, a zero result should be changed to MAX_DISTANCE + 1, as that's what it means. Without considering a zero result (out of range), your sketch will probably never work.

That should give you a good start to diagnose what's going on. 1, 3, 4 & 5 are real problems that will seriously cause problems for your sketch.

Tim

teckel:

xvjeko:
Hello… i wrote a code that uses this library, and isn’t 100% reliable when debugging…
I’d be grateful if you comment it.

  1. TRIG_PIN_L, TRIG_PIN_R, ECHO_PIN_L and ECHO_PIN_R are never defined.
  2. No reason to set the pin modes, NewPing does that for you.
  3. You shouldn’t set the maximum distance to 2000cm on the “NewPing SONAR” lines. The sensor won’t work beyond 500cm and setting it to 2000 could make the time between pings from 33ms to 115ms or just cause problems in general. Just remove the ,2000 and it will default to the sensor’s maximum distance, which is 500cm and will allow for 33ms between pings as you have it set.
  4. The “constrain” commands will give you problems as out of range results (which are zero) would change to 6. Out of range would typically be beyond 500cm, making it 6cm will probably not give you want you’re looking for. Instead, do something like “if (per_l > 0) per_l = constrain(per_l, MIN_DISTANCE, MAX_DISTANCE);” so there can still be a zero result (out of range).
  5. The rest of your code then needs to accommodate what to do with out of range results. It doesn’t appear that you have considered that. If anything, a zero result should be changed to MAX_DISTANCE + 1, as that’s what it means. Without considering a zero result (out of range), your sketch will probably never work.

That should give you a good start to diagnose what’s going on. 1, 3, 4 & 5 are real problems that will seriously cause problems for your sketch.

Tim

thank you sir

EDIT: I got everything to work now… I hope it will run flawlessly in the real life… Thanks again

xvjeko: thank you sir

EDIT: I got everything to work now... I hope it will run flawlessly in the real life... Thanks again

Glad to help! Always satisfying when a project starts to come together. Pictures of your final project are always appreciated by the community.

Tim

hello…im using ultrasonic parallax ping))) sensor.can someone share to me coding for velocity (speed) sensor? km/h

matt121187: hello..im using ultrasonic parallax ping))) sensor.can someone share to me coding for velocity (speed) sensor? km/h

What's the size and speed of the object you're trying to track the speed of? Will the object always be heading straight for the sensor or at an angle? If at an angle, is the angle consistent and known?

Tim