Making certain loops delay longer

Hello, I'm lost on how to make a loop have a 24hour delay, witouth stopping main loop. I wanted an event to happen only once per 24hour per case.

Would a switch case work? or would it stop?

void loop()
{
  valorsensor = analogRead(analogPin);
  Serial.println(valorsensor);
 if(valorsensor > 300)
    {
  Sendingtext();
  delay(86400000);
    }
}

void Sendingtext()
{
  Serial.println("Something...");
  sim800l.print("AT+CMGF=1\r");
  delay(100);
  //switch case (valor dos bits for 0001)
switch(var) //variable would be the bits/byte in decimal value
case 1:
{
  sim800l.print("AT+CMGS=\"+xxxxxxxxxxxx1\"\r"); 
  delay(500);
  sim800l.print("Value");
  sim800l.print("\r"); 
  delay(500);
  sim800l.print((char)26);
  delay(100);
  sim800l.println();
  Serial.println("Value Sent");
  delay(86400000);
break;
}
case 2: //if bits in decimal would be 2
{
  sim800l.print("AT+CMGS=\"+xxxxxxxxxxxx2\"\r"); 
  delay(500);
  sim800l.print("Value");
  sim800l.print("\r"); 
  delay(500);
  sim800l.print((char)26);
  delay(100);
  sim800l.println();
  Serial.println("Value Sent");
  delay(86400000);
break;
}

}

would this work? ( I currently am waiting on a MUX to test this ) i mean, even if case 1 did its thing, would it stop from case 2 from working at same time/between the 24 hour delay?

See the “Blink Without Delay” example. You’ll have to give up on the idea of using delay. Take advantage of the fact that the loop function repeats. On every pass through the loop, you can check and see if it has been 24 hours since the last time you did something as long as you know what time it was last time you did it. The millis function is good for getting the time as the number of milliseconds since the last time the board reset.

saringeti: Hello, I'm lost on how to make a loop have a 24hour delay, witouth stopping main loop. I wanted an event to happen only once per 24hour per case.

Would a switch case work? or would it stop?

void loop()
{
  valorsensor = analogRead(analogPin);
  Serial.println(valorsensor);
 if(valorsensor > 300)
    {
  Sendingtext();
  delay(86400000);
    }
}

void Sendingtext() {  Serial.println("Something...");  sim800l.print("AT+CMGF=1\r");  delay(100);  //switch case (valor dos bits for 0001) switch(var) //variable would be the bits/byte in decimal value case 1: {  sim800l.print("AT+CMGS=\"+xxxxxxxxxxxx1\"\r");  delay(500);  sim800l.print("Value");  sim800l.print("\r");  delay(500);  sim800l.print((char)26);  delay(100);  sim800l.println();  Serial.println("Value Sent");  delay(86400000); break; } case 2: //if bits in decimal would be 2 {  sim800l.print("AT+CMGS=\"+xxxxxxxxxxxx2\"\r");  delay(500);  sim800l.print("Value");  sim800l.print("\r");  delay(500);  sim800l.print((char)26);  delay(100);  sim800l.println();  Serial.println("Value Sent");  delay(86400000); break; }

}




would this work? ( I currently am waiting on a MUX to test this ) i mean, even if case 1 did its thing, would it stop from case 2 from working at same time/between the 24 hour delay?

I was not able to verify compilation because not all your code is present but this should give you an idea on how to use blink without delay.

void loop()
{
  valorsensor = analogRead(analogPin);

  static unsigned long SpamTimer;
  unsigned long SpamDelay = 100;
  if ((millis() - SpamTimer) >= (SpamDelay)) { // This is here because the serial buffer looping as fast as the uno can run will not be able to keep up so 10 times a second us usually fast enough
    SpamTimer = millis();
    Serial.println(valorsensor);
  }
  // static variables keep ther value between loops and do not get re-initialized
  static unsigned long T = 0; // Lets start out testing now so that we can start the time now not tomorrow
  static unsigned long ExactTimer;
  if ( (millis() - ExactTimer >= (t)) && (valorsensor > 300)) {
    ExactTimer += (t);
    Sendingtext();
    T = 86400000;
  }

}

void Sendingtext()
{
  Serial.println("Something...");
  sim800l.print("AT+CMGF=1\r");
  delay(100);
  //switch case (valor dos bits for 0001)
  switch (var) //variable would be the bits/byte in decimal value
  case 1:
  {
    sim800l.print("AT+CMGS=\"+xxxxxxxxxxxx1\"\r");
    delay(500);
    sim800l.print("Value");
    sim800l.print("\r");
    delay(500);
    sim800l.print((char)26);
    delay(100);
    sim800l.println();
    Serial.println("Value Sent");
    delay(86400000);
    break;
  }
case 2: //if bits in decimal would be 2
  {
    sim800l.print("AT+CMGS=\"+xxxxxxxxxxxx2\"\r");
    delay(500);
    sim800l.print("Value");
    sim800l.print("\r");
    delay(500);
    sim800l.print((char)26);
    delay(100);
    sim800l.println();
    Serial.println("Value Sent");
    delay(86400000);
    break;
  }
}

I used the 2 types of blink without delay I know of. I call them After (_ATimer) and Exact (_ETimer) one is great for counting intervals and the other is great for preventing spam to the serial port. each have there advantages and disadvantages and both work 100000% better than delay() :)

  static unsigned long _ATimer;
  if ((millis() - _ATimer) >= (t)) {
    _ATimer = millis();

  }


  static unsigned long _EATimer;
  if (  millis() - _ETimer >= (t)) {
    _EATimer += (t) * (1 + ((int)  (millis() - _EATimer) / (t)));


  }

Z

The demo Several Things at a Time is an extended example of BWoD and illustrates the use of millis() to manage timing. It may help with understanding the technique.

...R

Thank you all for the quick and simple answers, I'll see Blink witouth delay and i'll try to integrate it! thank you once again!

EDIT: should i make a vector since i need to use different delays? (each case needs its own delay) and i'm going for about maybe 100+ cases

should i make a vector

Do you mean an array ?

UKHeliBob: Do you mean an array ?

yeah, my bad

saringeti: Thank you all for the quick and simple answers, I'll see Blink witouth delay and i'll try to integrate it! thank you once again!

EDIT: should i make a vector since i need to use different delays? (each case needs its own delay) and i'm going for about maybe 100+ cases

If this code Sendingtext triggers once every 24 hours and no other code is needed to run at that time a delay within that function is reasonable to handle the transmission. You probibly don't want to leave the Sendingtext function until your transition is complete. In my prior post I gave you enough code to accomplish the task. did you understand how it worked? Z

zhomeslice: If this code Sendingtext triggers once every 24 hours and no other code is needed to run at that time a delay within that function is reasonable to handle the transmission. You probibly don't want to leave the Sendingtext function until your transition is complete. In my prior post I gave you enough code to accomplish the task. did you understand how it worked? Z

but since there's only 1 time variable, if case 1 happened, case 2 wouldnt be able to work for the 24 hours too right? so i would have to input T1 = 86400000; and T2 = 86400000; and so on and so forth? unless i did an array and would get the array positions for each case?

saringeti: but since there's only 1 time variable, if case 1 happened, case 2 wouldnt be able to work for the 24 hours too right? so i would have to input T1 = 86400000; and T2 = 86400000; and so on and so forth? unless i did an array and would get the array positions for each case?

unsigned long DelayTime = 0; // Lets start out testing now so that we can start the time now not tomorrow

void loop()
{
  int valorsensor = analogRead(analogPin);

  static unsigned long SpamTimer;
  unsigned long SpamDelay = 100;
  if ((millis() - SpamTimer) >= (SpamDelay)) { // This is here because the serial buffer looping as fast as the uno can run will not be able to keep up so 10 times a second us usually fast enough
    SpamTimer = millis();
    Serial.println(valorsensor);
  }
  // static variables keep ther value between loops and do not get re-initialized
  static unsigned long ExactTimer;
  if ( (millis() - ExactTimer >= (DelayTime)) && (valorsensor > 300)) {
   
    Sendingtext();
    ExactTimer += (DelayTime);
  }
}

void Sendingtext()
{
  Serial.println("Something...");
  sim800l.print("AT+CMGF=1\r");
  delay(100);
  //switch case (valor dos bits for 0001)
  switch (var) //variable would be the bits/byte in decimal value
  case 1:
  {
    sim800l.print("AT+CMGS=\"+xxxxxxxxxxxx1\"\r");
    delay(500);
    sim800l.print("Value");
    sim800l.print("\r");
    delay(500);
    sim800l.print((char)26);
    delay(100);
    sim800l.println();
    Serial.println("Value Sent");
        DelayTime = 86400000; // this requires 24 hour delay until anything will run again
    break;
  }
case 2: //if bits in decimal would be 2
  {
    sim800l.print("AT+CMGS=\"+xxxxxxxxxxxx2\"\r");
    delay(500);
    sim800l.print("Value");
    sim800l.print("\r");
    delay(500);
    sim800l.print((char)26);
    delay(100);
    sim800l.println();
    Serial.println("Value Sent");
        DelayTime = 1000 * 60 * 60;  // This only waits 1 Hour
    break;
  }

}

Try this :) Z

zhomeslice: [spoiler]

unsigned long DelayTime = 0; // Lets start out testing now so that we can start the time now not tomorrow

void loop() {   int valorsensor = analogRead(analogPin);

  static unsigned long SpamTimer;   unsigned long SpamDelay = 100;   if ((millis() - SpamTimer) >= (SpamDelay)) { // This is here because the serial buffer looping as fast as the uno can run will not be able to keep up so 10 times a second us usually fast enough     SpamTimer = millis();     Serial.println(valorsensor);   }   // static variables keep ther value between loops and do not get re-initialized   static unsigned long ExactTimer;   if ( (millis() - ExactTimer >= (DelayTime)) && (valorsensor > 300)) {  
    Sendingtext();     ExactTimer += (DelayTime);   } }

void Sendingtext() {   Serial.println("Something...");   sim800l.print("AT+CMGF=1\r");   delay(100);   //switch case (valor dos bits for 0001)   switch (var) //variable would be the bits/byte in decimal value   case 1:   {     sim800l.print("AT+CMGS=\"+xxxxxxxxxxxx1\"\r");     delay(500);     sim800l.print("Value");     sim800l.print("\r");     delay(500);     sim800l.print((char)26);     delay(100);     sim800l.println();     Serial.println("Value Sent");         DelayTime = 86400000; // this requires 24 hour delay until anything will run again     break;   } case 2: //if bits in decimal would be 2   {     sim800l.print("AT+CMGS=\"+xxxxxxxxxxxx2\"\r");     delay(500);     sim800l.print("Value");     sim800l.print("\r");     delay(500);     sim800l.print((char)26);     delay(100);     sim800l.println();     Serial.println("Value Sent");         DelayTime = 1000 * 60 * 60;  // This only waits 1 Hour     break;   }

}



[/spoiler]



Try this :)
Z

I don't think I'm explaining myself good enough

What I'm looking for is for a Loop function, where each case has its own timer and they don't add to each other so:

if case 1 is done it waits 24 hours until it can be done again. Meanwhile all other cases are free to be done.

So imagine case 2 is done after 12 hours of case 1. Case 1 would still be doable in 12 hours, BUT, case 2 would only be able to repeat itself in 24 hours.

That would be for any other cases too, the code you showed, seemed to me like the delay would be for every single case, if 1 was done.

I really suck at explaining myself.

So Maybe

unsigned long DelayTime[] ={0,0,0,0,0,0};

   switch(var)
    
    case 1:
   if (DelayTime[1] > 0)
    break;
   else
    {
   sim800l.print("AT+CMGS=\"+xxxxxxxxxxx\"\r"); //
  delay(200);
  sim800l.print("value);
  sim800l.print("\r"); // o 
  delay(500);
  sim800l.print((char)26);//preciso )
  delay(100);
  sim800l.println();
  Serial.println("value sent");
  delay(500);
  DelayTimer[1] = 86400000;
break;

and do the same for the other cases? each with its own array position?

I would think that a for loop to iterate through the arrays would be a better solution.

This example

unsigned long startTimes[] = {0, 0};
unsigned long periods[] = {1001, 1005};    //examples
const byte ledPins[] = {10, 11};
const int numberOfLeds = sizeof(ledPins) / sizeof(ledPins[0]);

void setup()
{
  Serial.begin(115200);
  Serial.print("Number of LEDs : ");
  Serial.println(numberOfLeds);
  for (int pin = 0; pin < numberOfLeds; pin++)
  {
    pinMode(ledPins[pin], OUTPUT);
  }
}

void loop()
{
  unsigned long currentTime = millis();
  for (int led = 0; led < numberOfLeds; led++)
  {
    if (currentTime - startTimes[led] > periods[led])
    {
      digitalWrite(ledPins[led], !digitalRead(ledPins[led]));
      startTimes[led] = startTimes[led] + periods[led];
    }
  }
}

blinks 2 LEDs at different intervals but could be extended to as many different time periods as required and could trigger different code based on which time period has expired. Just make sure that none of the action code blocks the free running of loop()