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

matt121187:
sorry, im new with arduino..what do u mean by " First step, make Arduino work with basic code for NewPing."? from the ping sensor coding, i can get the distance, but how to get the value of times?

You create a time stamp for each ping. Then, looking at multiple ping times, and the comparison to the ping time stamp, you can easily calculate the speed (also if it's getting closer or further away). For example, you have two pings like the following:

Ping 1: Timestamp 50,000uS - Ping time 8,000uS
Ping 2: Timestamp 100,000uS - Ping time 7,000uS

So, two pings that are 50ms apart, the first distance is 8000uS (140cm), sencond ping is 7,000uS (123cm). So, in 50ms, it got 17cm closer (140-123). 17cm/50ms = .17/0.05 m/s or 3.4 m/s or 7.6 miles/hour.

Only the previous and current ping timestamp and distance are needed. If you use scheduled polling so you always know exactly how far apart each ping is (for example, exactly 50,000uS) then you don't even need to know the timestamp, just the current and previous ping distance. Just don't use delay(50) to make them 50ms apart, that won't be accurate. You'll need to either use an interrupt timer or polling to keep things accurate. Interrupt timer would be ideal but more complicated unless you used a timer library would would greatly simplify things.

I've written a little sketch for you that uses the NewPing and TimerOne library that outputs the speed via serial and uses the timer interrupt to make the ping timing very accurate. I added lots of comments so you should be able to follow along. Speed values are in meters per second, with positive values coming at you and negative moving away. Anyway, here's the sketch:

#include <TimerOne.h>
#include <NewPing.h>

#define TRIGGER_PIN  12 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     11 // Arduino pin tied to echo pin on the ultrasonic sensor.

NewPing sonar(TRIGGER_PIN, ECHO_PIN); // NewPing setup of pins.

volatile int previous = 0, current = 0; // Must be volatile because these change inside the interrupt code.
volatile float mps = 0.0;
volatile boolean newping = false;

void setup() {
  delay(1000);                        // Wait a second before we start.
  Timer1.initialize(50000);           // 50000uS = 50ms.
  Timer1.attachInterrupt(pingSensor); // pingSensor to run every 50ms.
  Serial.begin(115200);               // Open serial monitor at 115200 baud to see ping results.
}

void loop() {
  if (newping) { // There a new ping, print speed.
    /* START - This section would be replaced with code that would do something with the result other than just output to serial. */
    if (mps) {   // Non-zero speed, show result.
      Serial.print(mps);
      Serial.println(" m/s");
    } else Serial.println("-"); // Can't determine speed, output "-" instead of speed.
    /* END */
    newping = false; // Set to false till next ping.
  }
}

void pingSensor() {
  previous = current;
  current = sonar.ping_cm(); // Send out a ping and get the results in CM.
  if (previous && current) { // If either are zero, we had a no-ping result or on the first ping.
    mps = (float) (previous - current) * 0.2; // Calculate speed in m/s (positive values are coming at you, negative moving away).
  } else mps = 0; // Can't calculate speed.
  newping = true; // Flag that there's a new ping.
}

Hope this helps!

Tim