Seting start time for timer

i have a timer:

unsigned long TimePeriod = 60000;
unsigned long LastCellNumber = 20000;
void setup() {
  Serial.begin(9600);
  Serial.println("Start sketch");
  /* Please add EEPROM reading code at this line. */
}
void loop() {
  myDelay();
}
void myDelay() {
  delay(2000);
   Serial.println("enter my delay");
   Serial.println("StartTime");
  static unsigned long StartTime = millis();
  Serial.println(StartTime);
  unsigned long now = millis();
  if (now - StartTime < TimePeriod - LastCellNumber) return;
  LastCellNumber = 0;
  StartTime = now;
  myTask();
}
void myTask() {
  Serial.println("Do something here");
}

now this works fine if timer is being constantly being called, however this timer will be called at random intervals, how do i set the start time to refresh each time the function is called? previously i have used something like this

   if (ReadActivationStartTime == false)
        {
          ReadActivationStartTime = true;
          StartTime = millis();

        }

is there a better method?

I would use millis() as the start of a timer.

what do you mean (to my knowledge i'm already using millis() )?

What is this LastCellNumber ?

Have to say ‘don’t understand what you are trying to do’.

Can you make a bulleted list that describes exactly what you are trying to achieve.

Suggest you never ever intermix delay( ) with millis( ) type TIMERS.

It's a continuation of this topic, right?

The function to handle the state machine should keep calling at short intervals.
Loops repeat at high speed, even if they require delayed processing.
The millis() is used to perform delayed processing even in repeated loops.
Otherwise coding with millis makes no sense.
That's why people avoid delay() function.

1 Like

Whenever You want to start a timer let it have the value of millis().
It takes some 47, or 49 days before it raps around.

  • Timer activates

  • then at timer finishes does void mytask()

  • after void mytask() has been complete Timer waits for next activation. Could be 5 seconds after timer last finished or 5 days.

  • When timer activates again it updates the new start time

my issue is if there is a better way to designate the starttime for the timer than through he use f a boolean.

ahh... I understand.
You need a "one-shot timer" right?
Those that do not restart automatically.
Is that right all?

1 Like

yes it is

yes and i have done it using a boolean, was just curious if there was a better way.

Trying to expand my coding knowledge and what not.

I think that is fine. :wink:
Can write as even more means as you like.
Yes, maybe it's like a trick...
I think It is standard to use flags to determine the condition of a state machine.

1 Like

You have already figured out that in order to control the timer you must put the reset code in a conditional statement.
An if statement is only one kind of conditional statement.

1 Like

How and when do you know the actual length of that next interval?

The usual pattern is
if (now - starttime > interval) ...
to call myTask and reset starttime.

If the delay shall start only when the next interval length has been determined:
if (armed && now - starttime > interval) ...
Then reset armed when myTask is started and set it again when the next interval shall begin.

Does this make sense ?

const byte startSwitch       = 2;

unsigned long TimePeriod     = 6000;
unsigned long LastCellNumber = 2000;

bool timingFlag = false;

unsigned long StartTime;
  
//********************************************************
void setup()
{
  Serial.begin(9600);

  pinMode(startSwitch, INPUT_PULLUP);
  
  Serial.println("Start sketch \n");
  /* Please add EEPROM reading code at this line. */
  
} //END of setup()

//********************************************************
void loop()
{
  //if we are not timing, should we start the TIMER ?
  if(timingFlag == false && digitalRead(startSwitch) == LOW)
  {
    Serial.println("Timer has started");
    
    //enable TIMER
    timingFlag = true;

    //restart the TIMER
    StartTime = millis();
  }
  
  //if TIMER is enabled, check to see if it has timed out
  if (timingFlag == true)
  {
    myDelay();
  }

} //END of loop()

//********************************************************
//a one shot TIMER that starts when the startSwitch is first closed
void myDelay()
{
  if (millis() - StartTime < TimePeriod - LastCellNumber)
  {
    //the TIMER has not timed out yet
    return;
  }

  Serial.println("Timer has finished \n");
  
  //don't know what this is  ????????
  LastCellNumber = 0;

  //proceed to the task
  myTask();

  //disable the TIMER
  timingFlag = false;
  
} //END of myDelay()

//********************************************************
void myTask()
{
  Serial.println("Executing my Task \n");
  
} //END of myTask()

Boolean is fine.

unsigned long TimePeriod = 10000;
unsigned long LastCellNumber = 5000;

void myDelay(boolean = false);

void setup() {
  Serial.begin(9600);
  Serial.println("Start sketch");
}

void loop() {
  myDelay();
  if (Serial.available()) { // Timer restart when any 1 byte serial data received.
    myDelay(true);
    Serial.println("Restart Timer");
    while (Serial.available()) Serial.read();
  }
}

void myDelay(boolean Restart) {
  static boolean TimerActive = true;
  static unsigned long StartTime = 0;
  if (Restart) {
    StartTime = millis();
    TimerActive = true;
  }
  if (TimerActive) {
    unsigned long now = millis();
    if (now - StartTime >= TimePeriod - LastCellNumber) {
      TimerActive = false;
      LastCellNumber = 0;
      myTask();
    }
  }
}

inline void myTask() {
  Serial.println("Do Task");
}

Note To Test:
Be careful with the CR / LF settings on your serial monitor.
They send additional 1 byte each option enabled.

EDIT:
Normally, always loop myDelay();.
Add myDelay(true); where you want the timer to restart or reset.

By the way, if you start it for about 49 days or more in a row, there is a risk that something strange will happen.
This is what @Railroader explains.

1 Like

yeah that makes sense similar approach to how i did it which is nice to hear. Thanks.