check_timer option to return ping_result NO_ECHO

Issue #32 resolved
Former user created an issue

In order to determine when the background ping_timer has finished, I propose to return false only when the time limit has not been exceeded. This brings the function in line with the ping(), returning ping_result = 0 for no echo. In order not to break existing code, it could be implemented by a define, here #define DIST_NO_ECHO true, which could be default false.

#define DIST_NO_ECHO true

    boolean NewPing::check_timer() {
        if (micros() > _max_time) { // Outside the time-out limit.
            timer_stop();           // Disable timer interrupt
  #if DIST_NO_ECHO == true
      ping_result = NO_ECHO;
      return true;
  #endif
            return false;           // Cancel ping timer.
        }

    #if URM37_ENABLED == false
        if (!(*_echoInput & _echoBit)) { // Ping echo received.
    #else
        if (*_echoInput & _echoBit) {    // Ping echo received.
    #endif
            timer_stop();                // Disable timer interrupt
            ping_result = (micros() - (_max_time - _maxEchoTime) - PING_TIMER_OVERHEAD); // Calculate ping time including overhead.
            return true;                 // Return ping echo true.
        }

        return false; // Return false because there's no ping echo yet.
    }

Comments (3)

  1. Carl Pedersen

    Having looked deeper into the NewPing code, I realised that the ping_result is a public member. Hence it can be assigned an out of range value before calling ping_timer(). And as the check_timer() is an interrupt function, the NewPingEventTimer ought to handle the printing in the loop. With this in mind, the option to let check_timer() return true, but without touching ping_result would be appreciated. With multiple sensors, a flag to indicate end can be used to quickly fire one after the other.

    As an example, here is a modified NewPingEventTimer using the option for check_timer to return true in case of out of range:

    #include <NewPing.h>
    
    #define TRIGGER_PIN   12 // Arduino pin tied to trigger pin on ping sensor.
    #define ECHO_PIN      11 // Arduino pin tied to echo pin on ping sensor.
    #define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
    
    NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
    
    unsigned int pingSpeed = 50; // 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.
    volatile bool ping_done = false;
    
    void setup() {
      Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
      pingTimer = millis(); // Start now.
    }
    
    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.
        if(ping_done) {
          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");
        }
        pingTimer += pingSpeed;      // Set the next ping time.
        sonar.ping_result = (MAX_DISTANCE +1 ) * US_ROUNDTRIP_CM;  //Example of out of range value.
        ping_done = false;
        sonar.ping_timer(echoCheck); // Send out the ping, calls "echoCheck" function every 24uS where you can check the ping status.
    
      }
      // Do other stuff here, really. Think of it as multi-tasking.
    }
    
    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.
        ping_done = true;
      }
      // Don't do anything here!
    }
    

    I do apologise in case you feel this is a waste of time.

  2. Tim Eckel repo owner

    If it returns a ping, it's in range. If it doesn't return a ping, there's nothing in range. ping_result doesn't have a value so you also know this. There's no reason to have additional information to let you know what you already know.

    It was programmed in this way on purpose. If you feel you need something special, creating a private fork would be the way to go.

  3. Log in to comment