How to stop the code loop and start it again?

Did you try the sketch in post #13 ?

1 Like

Sorry, I thought you want me to tell you what does this code do. I will try it right now.

as pseudo-code

two modes of operation
mode 1: randomly blinking
mode 2: switched off

void setup() {
  make a timestamp **timestamp-blinking** of actual time;
}

void loop() {

  if mode 1 is active {
    do randomly blinking
    check if 2 minutes of time has passed by since storing timestamp-blinking
      when REALLY 2 minutes have passed by since timestamp-blinking was stored 
      switch off LEDs 
      store NEW timestampWaitStart
      set mode 2
  }

  if mode 2 is active 
    check if 1 minute of time has passed by since storing timestampWaitStart
    when REALLY 1 minute has passed by since timestampWaitStart
    update timestamp timestamp-blinking
    set mode 1
  }
}

This is pseudo-code just to get the basic idea how it works.
You will have to learn more details how it is really coded
best regards Stefan

I discourage using delay for several reasons.

But you can do something like this:

You can easily make adjustments so total On time is exactly timeOn

1 Like

OMG it works! Thank you so much.
I've changed this part of the code, form 10 to 60:

unsigned long disableInterval = 60ul * 1000;  //10 seconds (change as needed)
``

One more question, Is it possible to work for a minute and then be off for two? Now it is on for 60s and off for 60s.

It works, it just doesn't do what you are asking us to help you do.

Try the other sketches we have offered. My posted loop is working very well here, even if it isn't very elegant.

a7

1 Like

Thank you, I've tried and succeeded. Thank you all so much for your help.

Read the code that works. Come to enough of an understanding of it to see where and why the times are what they are.

a7

Please for the record post your complete you happy with it sketch!

a7

Thank you for this. It does work for me, but after one minute few LEDs stay on for 2 minutes instead of turn OFF. Not sure why.

I've marked Post #13 as my solution. I will read whole code again and try to adjust it to be on for one minute, and off for two. Thank you again for your patience.

  • You now have several examples which are different from each other.

  • Take the time to see how they work and study how they differ.

  • You have a great opportunity to learn quite a few different programming techniques.

1 Like

Thank you, I agree and I'm very thankful for this community.

Yes.

Take a stab it it and show us your attempt, we can then give you feedback.

Can you tell me if I understand correctly?

This part means for how many seconds will the code stop unsigned long disableInterval = 10ul * 1000; //10 seconds (change as needed), so if I change it to 60ul * 1000, it will stop for a minute. This part is for how long would I like for code loop to be ON: if (millis() - heartbeatTime >= 500ul), if I change it to 120ul * 1000 it will be ON for two minutes? Am I correct? Thank you for your help.

#define ENABLED            true
#define DISABLED           false

#define LEDon              HIGH   //PIN---[220R]---A[LED]K---GND
#define LEDoff             LOW

const byte leds[7]       = {7, 8, 9, 10, 11, 12, 13};
const byte heartbeatLED  = 2;

const byte maxLEDs       = sizeof(leds) / sizeof(byte);

bool timingFlag          = ENABLED;

//timing stuff
unsigned long heartbeatTime;
unsigned long toggleLedTime;
unsigned long disableTime;
unsigned long disableInterval = 10ul * 1000;  //10 seconds (change as needed)
unsigned long LEDinterval;


//                                       s e t u p ( )
//********************************************^************************************************
void setup()
{
  for (byte x = 0; x < maxLEDs; x++)
  {
    pinMode(leds[x], OUTPUT);
  }

  pinMode(heartbeatLED, OUTPUT);

  randomSeed(analogRead(0));

} //END of   setup()


//                                        l o o p ( )
//********************************************^************************************************
void loop()
{
  //************************************************              T I M E R  heartbeatLED
  //is it time to toggle the heartbeat LED ?
  if (millis() - heartbeatTime >= 500ul)
  {
    //restart this TIMER
    heartbeatTime = millis();

    //toggle the heartbeat LED
    if (digitalRead(heartbeatLED) == HIGH) digitalWrite(heartbeatLED, LOW);
    else digitalWrite(heartbeatLED, HIGH);
  }

  //************************************************              T I M E R  toggle LED
  //if enabled, is it time to toggle the a LED ?
  if (timingFlag == ENABLED && millis() - toggleLedTime >= LEDinterval)
  {
    //restart this TIMER
    toggleLedTime = millis();

    digitalWrite(leds[random(0, maxLEDs)], LEDon);
    digitalWrite(leds[random(0, maxLEDs)], LEDoff);
    LEDinterval = random(30, 400);

  }

  //************************************************              T I M E R  disable
  //is it time to toggle the timingFlag ?
  if (millis() - disableTime >= disableInterval)
  {
    //restart this TIMER
    disableTime = millis();

    //LEDs OFF
    for (byte x = 0; x < maxLEDs; x++)
    {
      digitalWrite(leds[x], LEDoff);
    }

    //toggle the timing Flag
    if (timingFlag == ENABLED)timingFlag = DISABLED;
    else timingFlag = ENABLED;
  }


  //************************************************
  //other non blocking code goes here
  //************************************************

} //END of   loop()

The code can be structured into senseful sub-units as there are

  • toggle heartbeat LED
  • check if random-blink is active and if active do random blinking
  • check if random-blinking time is over if yes set timingFlag to disabled
  • switch leds off
  • check of led-off-time is over if yes set timingflag to enabled

No this part of the code does something different. Read the words of the code

//is it time to toggle the heartbeat LED ?

Oh, I see now. So I should probably change //timing stuff :sweat_smile:

unsigned long heartbeatTime;
unsigned long toggleLedTime;
unsigned long disableTime;
unsigned long disableInterval = 10ul * 1000;  //10 seconds (change as needed)
unsigned long LEDinterval;

and do it like this

//timing stuff
unsigned long heartbeatTime = 10ul * 1000;  //10 seconds (change as needed);
unsigned long toggleLedTime;
unsigned long disableTime;
unsigned long disableInterval = 10ul * 1000;  //10 seconds (change as needed)
unsigned long LEDinterval;

@LarryD

in my humble opinion it makes sense to write multiple functions to give the code more structure
and to make it easier to see what belongs to what

There are three main parts of the code

void loop() {
  toggleHeartbeatLED();

  //if blinking is enabled,
  if (timingFlag == ENABLED) {
    ledRandomlyBlinking();
  }
  
  check_if_its_time_for_pausing();

} //END of   loop()

Looking at this gives the overview

and then looking into the functions shows the details of each function

#define ENABLED            true
#define DISABLED           false

#define LEDon              HIGH   //PIN---[220R]---A[LED]K---GND
#define LEDoff             LOW

const byte leds[7]       = {7, 8, 9, 10, 11, 12, 13};
const byte heartbeatLED  = 2;

const byte maxLEDs       = sizeof(leds) / sizeof(byte);

bool timingFlag          = ENABLED;

//timing stuff
unsigned long heartbeatTime;
unsigned long toggleLedTime;
unsigned long disableTime;
unsigned long disableInterval = 60ul * 1000;  //10 seconds (change as needed)
unsigned long LEDinterval;


//                                       s e t u p ( )
//********************************************^************************************************
void setup() {
  for (byte x = 0; x < maxLEDs; x++) {
    pinMode(leds[x], OUTPUT);
  }

  pinMode(heartbeatLED, OUTPUT);

  randomSeed(analogRead(0));

} //END of   setup()

//                                        l o o p ( )
//********************************************^************************************************
void loop() {
  toggleHeartbeatLED();

  //if blinking is enabled,
  if (timingFlag == ENABLED) {
    ledRandomlyBlinking();
  }
  
  check_if_its_time_for_pausing();

} //END of   loop()




// NEW FUNCTION NEW FUNCTION NEW FUNCTION NEW FUNCTION NEW FUNCTION NEW FUNCTION NEW FUNCTION 
void toggleHeartbeatLED() {
  //************************************************              T I M E R  heartbeatLED
  //is it time to toggle the heartbeat LED ?
  if (millis() - heartbeatTime >= 500ul) {
    //restart this TIMER
    heartbeatTime = millis();

    //toggle the heartbeat LED
    if (digitalRead(heartbeatLED) == HIGH)
      digitalWrite(heartbeatLED, LOW);
    else
      digitalWrite(heartbeatLED, HIGH);
  }
}





// NEW FUNCTION NEW FUNCTION NEW FUNCTION NEW FUNCTION NEW FUNCTION NEW FUNCTION NEW FUNCTION 
void ledRandomlyBlinking() {
  // check is it time to toggle the a LED ?
  if ( millis() - toggleLedTime >= LEDinterval) {
    //restart this TIMER through updating the timestamp
    toggleLedTime = millis();

    digitalWrite(leds[random(0, maxLEDs)], LEDon);
    digitalWrite(leds[random(0, maxLEDs)], LEDoff);
    LEDinterval = random(30, 400);
  }
}





// NEW FUNCTION NEW FUNCTION NEW FUNCTION NEW FUNCTION NEW FUNCTION NEW FUNCTION NEW FUNCTION 
void check_if_its_time_for_pausing() {
  //is it time to toggle the timingFlag ?
  if (millis() - disableTime >= disableInterval) {
    //restart this TIMER through updating the timestamp
    disableTime = millis();

    //LEDs OFF
    for (byte x = 0; x < maxLEDs; x++) {
      digitalWrite(leds[x], LEDoff);
    }

    //toggle the timing Flag
    if (timingFlag == ENABLED)
      timingFlag = DISABLED;
    else
      timingFlag = ENABLED;
  }
}

no not at all.

everything with names that have heartbeat in it make the onboard LED blink and has nothing to do with your external LEDs

@LarryD

As you can see now getting the overview with all code written in loop() using this
"standard"-blink-without-delay-pattern is hard to understand.

1 Like
  • Yes
unsigned long disableInterval = 60ul * 1000;   //60 seconds
  • No, That part of the code belongs to a heartbeat TIMER. if you place a LED on pin #2, it will toggle every 1/2 second, 500ms.
    We often use a TIMER like this to show if our code is executing.
    It should toggle every 500ms all the time.
    If it does not flash or it shows stuttering, there is probably something not right in our code.

  • What's needed to have 1 minute and 2 minutes is to manipulate the disableInterval variable; alternately form 60000 to 120000 to 60000 . . . etc.

  • See if you can come up with the solution to change disableInterval from 60000 to 120000 . . . .