1

I want to create a sketch that counts the days from the moment the "project" start and send and osc message every two days (or more) for 3 weeks. So:

day zero : osc message -> 0
day two. : osc message -> 1
day four : osc message -> 2

etc.

I'm trying to create a state machine to send the messages when the millis reaches a certain time it should print message and so on for the other times. I'm giving a small example:

I went with @jsotola's suggestion and tried out the BlinkWithoutDelay approach. It seemingly works because I get serial prints around the correct millis() they are printed in 4fold or 3fold the messages.

EDITED CODE:

int daytwo = 25920; // for testing purposes other numbers then the actual millis()
int dayfour = 44400;
    
void loop() {  
  unsigned long currentMillis = millis();   // store current time

  if (currentMillis == daytwo) {
    Serial.println("daytwo");
  }
    
  if (currentMillis == dayfour) {
    Serial.println("dayfour");
  }
}

Serial output:

    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.889 -> daytwo
    11:04:39.926 -> daytwo
    11:04:58.366 -> dayfour
    11:04:58.366 -> dayfour
    11:04:58.366 -> dayfour
    11:04:58.366 -> dayfour
8
  • 1
    declare a variable to hold the osc message number .... increment it every 48 hours and transmit message ... refer to the blinkWithoutDelay example sketch for the method of repeating an action in a non-blocking way
    – jsotola
    Jan 15, 2021 at 21:44
  • 2
    And comparison is == not =. What is your question?
    – romkey
    Jan 15, 2021 at 22:40
  • Also, do not compare time with equality, that will never work reliably. (What if the test is not executed at that precise moment?)
    – PMF
    Jan 16, 2021 at 9:07
  • If it “seemingly works”, what exactly is your question? The way you now test for the appropriate time (with a comparison based on equality) is really unreliable. Why do you not use the same logic as the “blink without delay” sketch (i.e. use “equal or greater than”) so you cannot accidentally skip an event?
    – StarCat
    Jan 16, 2021 at 10:15
  • @StarCat if I use == then I thought it would create a single message (I only need 1 message per 2 days as described in the goal of the project before the question on how to achieve this. (first I got the millis() example then the statemachine example and know I tried the blinkwithoutdelay way as the comments advised me to do.)) The >= comparator gives me an overflow of Serial.print (or osc messages) in this case. Any suggestions? Jan 16, 2021 at 10:34

2 Answers 2

1

The following code is not very "clean" but easy to understand. Use a variable to hold the day, you have already printed and check in which interval you are. If you change the 2 day interval print a message and set the actDay variable to the number of the day you have already printed; to avoid repprinting it again.

int daytwo = 25920; 
int dayfour = 44400;

int actDay = -1;

void loop() 
{  
  unsigned long currentMillis = millis();
  if (currentMillis < daytwo) 
  {
    if ( actDay != 0 ) 
    {
      actDay = 0;
      Serial.println("dayzero");
    }
  }
  else if (currentMillis < dayfour ) 
  {
    if ( actDay != 2 ) 
    {
      actDay = 2;
      Serial.println("daytwo");
    }
  }
  else 
  {
    if ( actDay != 4 ) 
    {
      actDay = 4;
      Serial.println("dayfour");
    }
  } 
}
1
  • Thanks your example was most comprehensible for so I'm going to vote this a solve. If others think the above answer is best please up vote that to then! @Peter-Paul-Kiefer thanks again! Jan 16, 2021 at 17:14
0
int day = 0;
unsigned long prevMillis = 0;
const unsigned long MILLIS_PER_DAY = 86400000UL;

void setup()
{
  prevMillis = millis();
}

void loop() {  
  if( millis() - prevMillis > MILLIS_PER_DAY )
  {
    // one whole day has passed
    day++;
    prevMillis += MILLIS_PER_DAY;

    // do the things you want to do at the beginning of a new day
    if( day==2 ) {
      Serial.println("daytwo");
    }
    else if (day == 4) {
      Serial.println("dayfour");
    }
  }
}

This is a more generic version. It checks if 24*60*60*1000 milliseconds have past since the last time the day rolled over. When this occurs, it will increment the current day and update prevMillis to have the value of millis() when the day started.

This also has the advantage that is will only run your "daily code" once.

And will also run, when some other task takes a long time. I your old code, you might miss the exact moment millis() is the value you are looking for, if some other code takes more than 1 ms.

4
  • Myself, I would prefer a solution like your's. But, I thought, it would be better to explain the principple and still think the OP is smart enough to extend the example if only he/she have understood the basics. Again, your solution is the better one. Please let me point you to some issues': You used the undeclared variable dayfour instead of 4. Jan 17, 2021 at 9:54
  • After about 50 days the millis() counter overflows and starts with 0. For about 50 days the if block will not be entered, Then after that period the prevMillis will overflow to a value ~25032704. If only "daytwo" and "dayfour" the is not an error (only if the day variable overflows ;-)). But if the OP tries to add more cases or eventual a more generic solution, this could be a problem. Jan 17, 2021 at 9:54
  • In a comment above you mentioned a very good solution that would bring your already "good" answer to the next level. int day = millis() / 86400000UL. The use a switch statement. It also would be easy extendable. Only, it would make a changes like resetting the days to 0 or whatever a little bit complicate. I regrette not have given that solution. ;-) Jan 17, 2021 at 10:05
  • @PeterPaulKiefer good catch. Changed dayfour to 4. Thanks.
    – Gerben
    Jan 17, 2021 at 17:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.