Trying to add a button in my For Cycle

Hi Arduino Elders!
I'm doing a For Cycle for a project my cousin have. So basically the idea is kind of simple: I have a For Cycle that makes a Led Blink, after 9 blinks, the next led blinks and so on, after the 4th led has blinked 9 times, all leds blink 9 times and the code restart. The code works as it is, but I'm trying to a button to the code that will make the cycle change. (Sorry for my bad English, I'm not native xD). In other words, what I'm trying to do is: The code starts and the first led starts blinking, if I press the button, the first led turns off and the next one starts blinking, so on until every led start blinking and if a press the button, the cycle restarts.

I attach the code for the For Cycle, if you see any problems with it, your recommendations will be more than appreciated (Only try to keep the code as simple as possible as I'm still learning to code well and it's my first time coding after almost a year of not touching Arduino).

int led1 = 2;
int led2 = 3;
int led3 = 4;
int led4 = 5;
int boton = 7;
int estado = 0;
int inter = 8;
int i;
int dt = 250;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(boton, INPUT);
}

void loop() {

  
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  digitalWrite(led3, HIGH);
  digitalWrite(led4, HIGH);
  for (i = 0; i <= inter; i = i + 1) {
    digitalWrite(led1, HIGH);
    delay(dt);
    digitalWrite(led1, LOW);
    delay(dt);
  }
  digitalWrite(led1, LOW);
  digitalWrite(led2, HIGH);
  digitalWrite(led3, HIGH);
  digitalWrite(led4, HIGH);
  for (i = 0; i <= inter; i = i + 1) {
    digitalWrite(led2, HIGH);
    delay(dt);
    digitalWrite(led2, LOW);
    delay(dt);
  }
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, HIGH);
  digitalWrite(led4, HIGH);
  for (i = 0; i <= inter; i = i + 1) {
    digitalWrite(led3, HIGH);
    delay(dt);
    digitalWrite(led3, LOW);
    delay(dt);
  }
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(led4, HIGH);
  for (i = 0; i <= inter; i = i + 1) {
    digitalWrite(led4, HIGH);
    delay(dt);
    digitalWrite(led4, LOW);
    delay(dt);
  }
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(led4, LOW);
  for (i = 0; i <= inter; i = i + 1) {
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    delay(dt);
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    delay(dt);
  }
}

:older_man: :woozy_face:


Hardware

  • As always, show us a good schematic of your proposed circuit. Hand drawn schematics are acceptable.
  • Schematic diagrams are the universal language of electronics
  • We use schematics to communicate hardware design.
  • Show us several good image views of your actual wiring.
  • Give WEB links to your major components.



  • Do you know what happens when you execute delay(dt) ?



  • The sketch below should exhibit the same as your sketch.

  • We still need to add the switch action you need, however, not until you review this sketch to see if you can follow what is happening.

  • Ask questions about the things you do not understand.

//
//================================================^================================================
//
//  https://forum.arduino.cc/t/trying-to-add-a-button-in-my-for-cycle/1295291
//
//
//
//  Version    YY/MM/DD    Comments
//  =======    ========    ========================================================================
//  1.00       24/08/25    Running code, we still need to add button switch action
//
//
//
//  Notes:
//

#define PRESSED            LOW    //+5V---[Internal 50k]---PIN---[Switch]---GND
#define RELEASED           HIGH

//                                            G P I O s
//================================================^================================================
//
const byte led1            = 2;
const byte led2            = 3;
const byte led3            = 4;
const byte led4            = 5;
const byte button          = 7;
const byte heartbeatLED    = 13;

const byte blinkAmount     = 18;       //required number of toggles

byte lastButton            = RELEASED;

int counter                = 0;

//timing stuff
//unsigned long LEDdelay   = 1000ul;   //1 second, for testing
unsigned long LEDdelay     = 250ul;

unsigned long heartbeatTime;
unsigned long switchesTime;
unsigned long commonTime;
unsigned long machineTime;

//                                    S t a t e   M a c h i n e
//================================================^================================================
//the states in our machine
enum STATES : byte
{
  STARTUP, STATE1, STATE2, STATE3, STATE4, STATE5
};
STATES mState = STARTUP;


//                                           s e t u p ( )
//================================================^================================================
void setup()
{
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(heartbeatLED, OUTPUT);

  pinMode(button, INPUT_PULLUP);

} //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
    digitalWrite(heartbeatLED, digitalRead(heartbeatLED) == HIGH ? LOW : HIGH);
  }

  //========================================================================  T I M E R  switches
  //is it time to scan our switches ?
  if (millis() - switchesTime >= 50ul)
  {
    //restart this TIMER
    switchesTime = millis();

    checkSwitches();
  }

  //========================================================================  T I M E R  machine
  //is it time to check our State Machine ?
  if (millis() - machineTime >= 10ul)
  {
    //restart this TIMER
    machineTime = millis();

    checkMachine();
  }

  //================================================
  //other non blocking code goes here
  //================================================


} //END of   loop()


//                                    c h e c k M a c h i n e ( )
//================================================^================================================
void checkMachine()
{
  //================================================
  //service the current "state"
  switch (mState)
  {
    //========================
    case STARTUP:
      {
        //do startup stuff

        digitalWrite(led1, HIGH);
        digitalWrite(led2, HIGH);
        digitalWrite(led3, HIGH);
        digitalWrite(led4, HIGH);

        //restart the common TIMER
        commonTime = millis();

        counter = 0;

        //next state
        mState = STATE1;
      }
      break;

    //========================   Toggling LED1
    case STATE1:
      {
        //has the common TIMER expired ?
        if (millis() - commonTime >= LEDdelay)
        {
          //restart the common TIMER
          commonTime = millis();

          //toggle led1
          digitalWrite(led1, digitalRead(led1) == HIGH ? LOW : HIGH);

          counter = counter + 1;

          //have we finished the sequence ?
          if (counter > blinkAmount)
          {
            //get ready for the next State sequence
            counter = 0;

            digitalWrite(led1, LOW);
            digitalWrite(led2, HIGH);
            digitalWrite(led3, HIGH);
            digitalWrite(led4, HIGH);

            //restart the common TIMER
            commonTime = millis();

            //next state
            mState = STATE2;

            break;
          }
        }
      }
      break;

    //========================   Toggling LED2
    case STATE2:
      {
        //has the common TIMER expired ?
        if (millis() - commonTime >= LEDdelay)
        {
          //restart the common TIMER
          commonTime = millis();

          //toggle led2
          digitalWrite(led2, digitalRead(led2) == HIGH ? LOW : HIGH);

          counter = counter + 1;

          //have we finished the sequence ?
          if (counter > blinkAmount)
          {
            //get ready for the next State sequence
            counter = 0;

            digitalWrite(led1, LOW);
            digitalWrite(led2, LOW);
            digitalWrite(led3, HIGH);
            digitalWrite(led4, HIGH);

            //restart the common TIMER
            commonTime = millis();

            //next state
            mState = STATE3;

            break;
          }
        }
      }
      break;

    //========================   Toggling LED3
    case STATE3:
      {
        //has the common TIMER expired ?
        if (millis() - commonTime >= LEDdelay)
        {
          //restart the common TIMER
          commonTime = millis();

          //toggle led3
          digitalWrite(led3, digitalRead(led3) == HIGH ? LOW : HIGH);

          counter = counter + 1;

          //have we finished the sequence ?
          if (counter > blinkAmount)
          {
            //get ready for the next State sequence
            counter = 0;

            digitalWrite(led1, LOW);
            digitalWrite(led2, LOW);
            digitalWrite(led3, LOW);
            digitalWrite(led4, HIGH);

            //restart the common TIMER
            commonTime = millis();

            //next state
            mState = STATE4;

            break;
          }
        }
      }
      break;

    //========================   Toggling LED4
    case STATE4:
      {
        //has the common TIMER expired ?
        if (millis() - commonTime >= LEDdelay)
        {
          //restart the common TIMER
          commonTime = millis();

          //toggle led4
          digitalWrite(led4, digitalRead(led4) == HIGH ? LOW : HIGH);

          counter = counter + 1;

          //have we finished the sequence ?
          if (counter > blinkAmount)
          {
            //get ready for the next State sequence
            counter = 0;

            digitalWrite(led1, LOW);
            digitalWrite(led2, LOW);
            digitalWrite(led3, LOW);
            digitalWrite(led4, LOW);

            //next state
            mState = STATE5;

            break;
          }
        }
      }
      break;

    //========================   Toggling LEDs 1,2,3,4
    case STATE5:
      {
        //has the common TIMER expired ?
        if (millis() - commonTime >= LEDdelay)
        {
          //restart the common TIMER
          commonTime = millis();

          //toggle leds 1,2,3,4
          digitalWrite(led1, digitalRead(led1) == HIGH ? LOW : HIGH);
          digitalWrite(led2, digitalRead(led2) == HIGH ? LOW : HIGH);
          digitalWrite(led3, digitalRead(led3) == HIGH ? LOW : HIGH);
          digitalWrite(led4, digitalRead(led4) == HIGH ? LOW : HIGH);

          counter = counter + 1;

          //have we finished the sequence ?
          if (counter > blinkAmount)
          {
            //restart the LED sequence
            mState = STARTUP;

            break;
          }
        }
      }
      break;

  } //END of   switch/case

} //END of   checkMachine()

//                                   c h e c k S w i t c h e s ( )
//================================================^================================================
void checkSwitches()
{

} //END of   checkSwitches()





//
//================================================^================================================
1 Like

Normally the answer to this would be to recommend you use a state machine to perform a simple form of multitasking. This is often hard for a beginner to get there head round. So I came up with an alternative, but perhaps it is equally as hard to understand.

See for your self at:-

1 Like

That’s a reasonable solution to the problem of trying to do two things at the same time. @alexkool17023 ’s for loops are tightly focused on looping through the animation, but at the same time they need to be able to monitor the button pin and change focus onto something completely different.

Instead of a complete rewrite to make the animations more cooperative, the delay substitution could handle the switching.

  • The partial solution in post #2, using a State Machine, should demonstrate to the OP how the code can be written.
    Once the OP fully understands what is happening in this State Machine sketch, the required switch code is a simple addition and will be discussed.
1 Like

I'll check the State Machine post and I will change my code to be more adequate. Wish me luck, and I keep you updated!

:smiley:

1 Like

There are many tutorials, I suggest you read more than a few of them and find one or two you can spend some real time with. Here's one


There are a handful of tricks to get things happening at the same time, or to allow switching between stuff compromised by use of delay() without going to a finite state machine design.

The trouble I have with all of them is not that they don't work, or are aesthetically unpleasing, rather it is the complexity of the solutions.

No one who can figure out any of the hacks would have any trouble learning how to code a state machine solution and be done with it.

Conversely, I think, one who could not or would not take the time to get into state machines is not likely to get very far with the hacks.

And while the hacks do what they claim, but they may not be flexible enough to do more than the one or two tricks they embody. Not generally useful or applicable.

Imma bet that the ppl who design the hacks don't use them much themselves, if at all.

a7

3 Likes
  • Post #2 has the State Machine conversion of your original sketch done for you already.

  • Review the sketch, ask questions, the requested switch addition can be added once you fully understand how the State Machine in Post #2 works.

3 Likes