Trouble with millis() and NewPing interrupt sketches

Issue #35 resolved
Former user created an issue

I'm on the latest version of NewPing. Using the interrupt method, I can't seem to use the millis() function properly. Here's the basics for my sketch:

#include <NewPing.h>
const int requestPin = 5;
const int receivePin = 6;
const int maxDistance = 400;
NewPing sonar(requestPin, receivePin, maxDistance);

unsigned int pingSpeed = 50;
unsigned long pingTimer;

unsigned long endAlert = 0, alertProgress = 0;

void setup()
{
  Serial.begin(115200);
  Serial.println ("Starting");
  pinMode(requestPin, OUTPUT);
  pingTimer = millis();
}

void loop()
{
  if (millis() >= pingTimer)
  {
    pingTimer += pingSpeed;
    sonar.ping_timer(receiveCheck);
  }
}

void receiveCheck()
{
  if (sonar.check_timer())
  {
      if (conditionBasedOnSensor)
      {
        alert();
      }
  }
}

void alert()
{
  endAlert = millis() + 1000;
  alertProgress = millis();
  while (alertProgress < endAlert)
  {
    Serial.println("alert");
    alertProgress = millis();
  }
}

Once the alert function, runs, the program hangs constantly printing "alert." The problem seems to relate to this information, but the ISR stuff is beyond me. How can I use delays or timing with NewPing effectively? Thanks!

Comments (3)

  1. Tim Eckel repo owner

    This is not a bug with the library, it's a problem with your sketch. The problem is that you're trying to assign variables from within the receiveCheck() routine, which is triggered from an event. This is a no-no with the Arduino. It doesn't matter that you broke it out into the alert() function, what you're doing is exactly the same as this:

    void receiveCheck() {
       if (sonar.check_timer()) {
          if (conditionBasedOnSensor) {
            endAlert = millis() + 1000;
            alertProgress = millis();
            while (alertProgress < endAlert) {
              Serial.println("alert");
              alertProgress = millis();
            }
          }
       }
    }
    

    You can't do this type of thing from within an event triggered function. Also, what is this conditionBasedOnSensor variable? You never define or change it. I also don't know what you're trying to do with your code. But, I'm assuming you're trying to something like this, I simplified things a bit as I wasn't sure what you were going for:

    #include <NewPing.h>
    const int requestPin = 5;
    const int receivePin = 6;
    const int maxDistance = 400;
    NewPing sonar(requestPin, receivePin, maxDistance);
    
    unsigned int pingSpeed = 50;
    unsigned long pingTimer;
    volatile bool pingReceived = false;
    
    void setup() {
      Serial.begin(115200);
      Serial.println ("Starting");
      pinMode(requestPin, OUTPUT);
      pingTimer = millis();
    }
    
    void loop() {
      if (millis() >= pingTimer) {
        pingTimer += pingSpeed;
        sonar.ping_timer(receiveCheck);
      }
      if (pingReceived) {
        sonar.timer_stop();
        Serial.println("alert");
        pingReceived = false;
      }
    }
    
    void receiveCheck() {
      if (sonar.check_timer()) {
        pingReceived = true;
      }
    }
    

    In any case, it's not a bug with the library, it's a sketch issue. If you still have an issue, I'd suggest posting to the NewPing Support Forum: https://forum.arduino.cc/index.php?topic=106043.0

    Tim

  2. Log in to comment