1

I have a sketch that uses two timers using millis() from a library I created to keep time. The timers seem to be working correctly, but when I print the start time of each timer, it is clearly wrong.

E.g. the timer is set to run for 3 seconds. When I start the timer the first time, it reads that it started at 0. The next time I start the timer, right after it has finished running once, it reads that it started at 2 seconds. This should not be possible.

I have even tried timing it on my phone, and have seen the timerStart value read 5 seconds, when the sketch has been running for 10.

Does anyone have any idea what could be going wrong? Code below.

Here is the library's .h file:

#ifndef Timer_h
#define Timer_h

#include <Arduino.h>

class Timer {
  public:
    Timer(unsigned long timerLength);
    unsigned long timerStart;
    unsigned long timeElapsed;
    boolean isFinished = true;
    boolean timerStarted = false;
    void startTimer();
    void checkTimer();
  private:
    unsigned long _timerLength;
};

#endif

Here is the library's .cpp file:

#include <Arduino.h>
#include <Timer.h>

Timer::Timer(unsigned long timerLength) {
  _timerLength = timerLength;  
}

void Timer::startTimer() {
  if (!timerStarted) {
    timerStart = millis();
    timerStarted = true;
  }
}

void Timer::checkTimer() {
  timeElapsed = millis() - timerStart;
  if (timeElapsed >= _timerLength) {
    isFinished = true;
    timerStarted = false;
  } else {
    isFinished = false;
  }
}

And here is part of my sketch code, where the timerStart value is wrong:

#include <Timer.h>

Timer breathTimer(3000);
Timer betweenTimer(1000);

// this part determines if a turbine is spinning or not
SIGNAL(TIMER0_COMPA_vect) {
  uint8_t x = digitalRead(FLOWSENSORPIN);

  //if the turbine is spinning
  if (x == HIGH) {

    //start the breath timer
    if (betweenTimer.isFinished) {
      if (breathTimer.isFinished) {
        Serial.print("Breath Timer Started @ ");
        Serial.println(breathTimer.timerStart);
      }
      breathTimer.startTimer();
    }
  }
}

void setup() {
   Serial.begin(9600);
   pinMode(FLOWSENSORPIN, INPUT);
   digitalWrite(FLOWSENSORPIN, HIGH);
   betweenTimer.isFinished = true;
}

void loop() { 

  // check the breath timer
  if (breathTimer.timerStarted) {
    breathTimer.checkTimer();
    if (breathTimer.isFinished) {
      Serial.println("Breath Timer is Finished");
      betweenTimer.startTimer();
      Serial.println("Between Timer Started");
    }
  }

  if (betweenTimer.timerStarted) {
    betweenTimer.checkTimer();
    if (betweenTimer.isFinished) {
      Serial.println("Between Timer is Finished");
    }
  }
}
  • Sorry, I just edited my post to hopefully include all the necessary information – Tarlyo Feb 21 at 3:14
  • Where is Timer.h? Which arduino board do you use, or is this in a simulation? – Jot Feb 21 at 3:17
  • Timer.h is included in the libraries folder along with Timer.cpp. I can include it here if you'd like to see it. I am running this on an Arduino Uno. Not a simulation. – Tarlyo Feb 21 at 3:35
  • I would like to see it, for example to see the type of the variables in the class. – Jot Feb 21 at 3:56
  • 1
    The c++ variable is a 'bool', we prefer that. The 'boolean' is made up by Arduino, we think that is silly. You have isFinished and timerStarted, yet the timer is busy or not. The class is initialized with isFinished as true, but the timer has not run yet. In the ISR you check the isFinished (which is true at start) and the value is printed. There is somehow a wrong way in the logic of that. Start over and first figure out what you want to know and what you want to do with the timer. Using the Serial library inside an ISR is never a good idea, try to move that to the loop() if possible. – Jot Feb 21 at 4:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.