three states of a led with millis ()

I am new to this programming, someone can guide me to program three states in a led with millis ().

1st LED Status: On 1 min.
I wait a while.
2nd LED status: flashing, 30 seconds. I wait a while.
3rd Status LED: Off 1 min.

const int pinled = 13;

void setup() {
  pinMode(pinled,OUTPUT);
}

void loop() {
  digitalWrite(pinled, HIGH);
  delay(60000);
  digitalWrite(pinled, LOW);
  delay(500);
  digitalWrite(pinled, HIGH);
  delay(500);
  digitalWrite(pinled, LOW);
  delay(500);
  digitalWrite(pinled, HIGH);
  delay(500);
  digitalWrite(pinled, LOW);
  delay(500);
  digitalWrite(pinled, HIGH);
  delay(500);
  digitalWrite(pinled, LOW);
  delay(60000);
}

not sure what you're asking.
it's a crude approach. looks like it will flash for 3, not 30 seconds.
if the LED is never turning on, are you sure it's wired correctly? does it have resistor in series to limit the current and prevent damage?

The demo Several Things at a Time illustrates the use of millis() to manage timing without blocking. It may help with understanding the technique.

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

You should also have a variable that keeps track of the state of the system (you use the word "status", but in programming it is generally referred to as "state" and "state machine". For example you could have char ledState; and it can take the values 'F' for ofF, 'N' for oN and 'F' for Flash.

...R

It is easier to write than describe :

unsigned long periods[] = {6000, 500, 500, 500, 500, 500, 500, 6000}; //reduced long periods for testing
byte periodIndex = 0;
unsigned long startTime;
unsigned long currentTime;

const byte pinLed = 13;

void setup()
{
  Serial.begin(115200);
  pinMode(pinLed, OUTPUT);
  digitalWrite(pinLed, HIGH);
  reportPeriod();
}

void loop()
{
  currentTime = millis();
  if (currentTime - startTime >= periods[periodIndex])
  {
    periodIndex++;
    if (periodIndex > 7)
    {
      periodIndex = 0;
    }
    digitalWrite(pinLed, !digitalRead(pinLed));
    startTime = currentTime;
    reportPeriod();
  }
}

void reportPeriod()
{
  Serial.print("current period : ");
  Serial.println(periods[periodIndex]);
}

To ensure that you understand how it works add comments to each line of code and post it back here

Thank you very much UKHeliBob !!! but I have some doubts regarding the code.

**I have noticed that some use (const int pinLed = 13;) and in the code you have (const byte pinLed = 13;) what is the difference?

unsigned long periods[] = {6000, 500, 500, 500, 500, 500, 500, 6000}; //reduced long periods for testing
byte periodIndex = 0;      // <----**
unsigned long startTime;
unsigned long currentTime;

const byte pinLed = 13;  //   <------ **

void setup()
{
  Serial.begin(115200);
  pinMode(pinLed, OUTPUT);
  digitalWrite(pinLed, HIGH);
  reportPeriod();
}

void loop()
{
  currentTime = millis();
  if (currentTime - startTime >= periods[periodIndex])
  {
    periodIndex++;
    if (periodIndex > 7)
    {
      periodIndex = 0;
    }
    digitalWrite(pinLed, !digitalRead(pinLed));
    startTime = currentTime;
    reportPeriod();
  }
}

void reportPeriod()
{
  Serial.print("current period : ");
  Serial.println(periods[periodIndex]);
}

As the pin number is less that 255 it is more efficient to hold the value in a byte variable rather than an int variable that takes 2 bytes of memory

@OP, that was a good question for a beginner...

Take a good look at ‘bob’s code - as there a few subtle techniques in there that will help your programming as it improves.

He could have done some other ‘tricks’, but as-is, it remains clear for learning.

UKHeliBob thank you very much !! You can send me a link to learn more about topics like if you can use millis, in switch case.

You can try things to see if they work.

When you review other people’s work, including the all example sketches in the IDE, stop and notice the formatting.

And, always properly document your code and add good comments.

lastchancename .Me puedes mandar el enlace para 'bob's code.

Problem solved thank you !!

Now my question is? Can I put a button that, when pressed, turns on the same cycle and when I press it again, turn it off?
I went to the tutorials and saw something interesting that is the state machine.
Can I do it with the state machine?
Or with a button?

Can I put a button that, when pressed, turns on the same cycle and when I press it again, turn it off?

Imagine that the code is controlled by a boolean variable

if (OKToRun == true)
{
  //code here to do what you want
}

Now look at the StateChangeDetection example in the IDE and use the principle to change the state of the boolean variable

Job done

I did this, but it doesn't start if I press the button and it doesn't go out when I press it, and the loop doesn't do the right thing. Can you tell me what's wrong?

unsigned long periods[] = {6000, 500, 500, 500, 500, 500, 500, 500, 500, 6000}; //reduced long periods for testing
byte periodIndex = 0;
unsigned long startTime;
unsigned long currentTime;
const byte pinLed = 13;

int buttonPin = 2;                 // Button
                
int State = 0;                       
int buttonState = 0;
int lastButtonState = 0;

void setup() {
  pinMode(pinLed, OUTPUT);
  pinMode(buttonPin,INPUT);
}

void loop() {
  buttonState = digitalRead(buttonPin);

  if ((buttonState == HIGH) && (lastButtonState == LOW)) {  
    State = 1 - State;
  }
  lastButtonState = buttonState;             // I keep the state of the button
  
  if(State == 1){

   currentTime = millis();
  if (currentTime - startTime >= periods[periodIndex])
  {
    periodIndex++;
    if (periodIndex > 9)
    {
      periodIndex = 0;
    }
    digitalWrite(pinLed, !digitalRead(pinLed));
    startTime = currentTime; 
  }
 }
  else if (State == 0){
    digitalWrite(pinLed,LOW);
  }
}

You need to rethink the way approach this new knowledge.

Your direction is correct, but it’s waaay too complicated,.
Read your code and step through it in your mind.. about half the code can go completely.

Does this do what you want? If so, it might be handy to study the differences between it and yours:

//LED blink toggle rate
#define BLINK_TOGGLE_PER    250ul   //mS    time between LED toggles in blink mode
//LED state names
#define LED_OFF             0
#define LED_ON              1
#define LED_BLINK           2
#define LED_TIME_OFF        3
//LED times
#define LED_ONTIME          60000ul //mS    LED on-time
#define LED_BLINKTIME       30000ul //mS    LED blinking time
#define LED_OFFTIME         60000ul //mS    LED off-time

byte stateBlink;
byte lastSw;
byte nowSw;

const byte pinLED = LED_BUILTIN;
const byte pinSw = 2;

void setup() 
{
    stateBlink = LOW;
    pinMode( pinLED, OUTPUT );
    digitalWrite( pinLED, LOW );

    pinMode( pinSw, INPUT_PULLUP );
    lastSw = digitalRead( pinSw );

}//setup

void loop() 
{
    DoLEDStateMachine();    //service the LED
    DoBlinkyFlag();         //service the blink timing and flag
    
}//loop

void DoLEDStateMachine( void )
{
    static byte
        stateLED=LED_OFF;
    static unsigned long
        timeLED;
    unsigned long
        timeNow;
        
    timeNow = millis();    
    switch( stateLED )
    {
        case    LED_OFF:
            //if switch is closed...
            nowSw = digitalRead( pinSw );
            if( nowSw != lastSw )
            {
                lastSw = nowSw;
                if( nowSw == LOW )
                {
                    //turn on the LED and move to time its on-duration
                    digitalWrite( pinLED, HIGH );
                    timeLED = timeNow;
                    stateLED = LED_ON;
                }//if
                
            }//if
            
        break;

        case    LED_ON:
            //when on duration is done...
            if( (timeNow - timeLED) >= LED_ONTIME )
            {
                //turn off the LED and move to blink state
                digitalWrite( pinLED, LOW );
                timeLED = timeNow;
                stateLED = LED_BLINK;
                
            }//if
            
        break;

        case    LED_BLINK:
            //if we're still blinking...
            if( (timeNow - timeLED) < LED_BLINKTIME )
            {
                //reflect the state of stateBlink on the LED
                digitalWrite( pinLED, stateBlink );
            }                
            else
            {
                //otherwise, turn it off and wait one minute before resetting state machine
                digitalWrite( pinLED, LOW );
                stateLED = LED_TIME_OFF;
                
            }//if
        
        break;

        case    LED_TIME_OFF:
            if( timeNow - timeLED >= LED_OFFTIME )
                stateLED = LED_OFF;
            
        break;
        
    }//switch
    
}//DoLEDStateMachine

void DoBlinkyFlag( void )
{
    static unsigned long
        timeBlink;
    unsigned long
        timeNow;

    timeNow = millis();
    //when it's time for a state toggle...
    if( (timeNow - timeBlink) >= BLINK_TOGGLE_PER )
    {
        //get the time for the next toggle
        timeBlink = timeNow;
        //and use an XOR for a simple way to flip the flag state HIGH-LOW-HIGH-LOW...
        stateBlink ^= HIGH;
    }//if
    
}//DoBlinkyFlag

(Note the switch logic: When closed, the switch should ground the pin. Change to match your circuit…)

If you do all three states when you press the button.
but what I wanted to do is that at the moment of pressing the button, it would start the whole cycle and repeat itself and until it pressed again it would go out.

I never thought it was so much code to make a led do 3 states. :o
If there is much difference between my code and the one you put, but I do not understand some things such as:

//LED blink toggle rate
#define BLINK_TOGGLE_PER    250ul   // <------- #define, what is it for ?
const byte pinLED = LED_BUILTIN;    // <-------- LED_BUILTIN - pinled 13
void loop() 
{
    DoLEDStateMachine();    // <---- Is this a function?
    DoBlinkyFlag();             //
    
}//loop

And everything else… :o

I have researched on arduino switch and also on the famous flags, but I never thought it was so complicated to turn on a led with three states, the code is very good and very explanatory I only have to investigate a little more, if all this is to ignite I don’t want to imagine a LED if I want to do other things.

I tried to do it that way, but it didn't work for me either, to make it as simple as possible, since with the switch I don't know how to understand some things.

unsigned long periods[] = {6000, 500, 500, 500, 500, 500, 500, 500, 500, 6000}; //reduced long periods for testing
byte periodIndex = 0;
unsigned long startTime;
unsigned long currentTime;

const byte pinLed = 13;
const int buttonPin = 2;
int buttonState = 0;
void setup()
{
  pinMode(pinLed, OUTPUT);
  digitalWrite(pinLed, LOW);
  pinMode(buttonPin, INPUT);
  led();
}

void loop()
{
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {
     led();
  } else {
    // turn LED off:
    digitalWrite(pinLed, LOW);
  }
}

void led()
{
  currentTime = millis();
  if (currentTime - startTime >= periods[periodIndex])
  {
    periodIndex++;
    if (periodIndex > 9)
    {
      periodIndex = 0;
    }
    digitalWrite(pinLed, !digitalRead(pinLed));
    startTime = currentTime;  
  }
}

Ronald_Rosales:
If you do all three states when you press the button.
but what I wanted to do is that at the moment of pressing the button, it would start the whole cycle and repeat itself and until it pressed again it would go out.

//LED blink toggle rate
#define BLINK_TOGGLE_PER    250ul   //mS    time between LED toggles in blink mode
#define SW_READ_INTERVAL    50ul    //mS    time between switch reads
//LED state names
#define LED_OFF             0
#define LED_ON              1
#define LED_BLINK           2
#define LED_TIME_OFF        3
//LED times
#define LED_ONTIME          60000ul //mS    LED on-time
#define LED_BLINKTIME       30000ul //mS    LED blinking time
#define LED_OFFTIME         60000ul //mS    LED off-time

byte stateBlink;
byte lastSw;
byte nowSw;
byte stateLED;
bool bCycleActive;

const byte pinLED = LED_BUILTIN;
const byte pinSw = 2;

void setup()
{
    stateLED = LED_OFF;
    stateBlink = LOW;
    bCycleActive = false;
    
    pinMode( pinLED, OUTPUT );
    digitalWrite( pinLED, LOW );

    pinMode( pinSw, INPUT_PULLUP );
    lastSw = digitalRead( pinSw );

}//setup

void loop()
{
    DoSwitch();             //read the switch input
    DoLEDStateMachine();    //service the LED
    DoBlinkyFlag();         //service the blink timing and flag
   
}//loop

void DoLEDStateMachine( void )
{
    static unsigned long
        timeLED;
    unsigned long
        timeNow;
       
    timeNow = millis();   
    switch( stateLED )
    {
        case    LED_OFF:
            //if cycle is active
            if( bCycleActive )
            {
                //turn on the LED and move to time its on-duration
                digitalWrite( pinLED, HIGH );
                timeLED = timeNow;
                stateLED = LED_ON;
                
            }//if
           
        break;

        case    LED_ON:
            //when on duration is done...
            if( (timeNow - timeLED) >= LED_ONTIME )
            {
                //turn off the LED and move to blink state
                digitalWrite( pinLED, LOW );
                timeLED = timeNow;
                stateLED = LED_BLINK;
               
            }//if
           
        break;

        case    LED_BLINK:
            //if we're still blinking...
            if( (timeNow - timeLED) < LED_BLINKTIME )
            {
                //reflect the state of stateBlink on the LED
                digitalWrite( pinLED, stateBlink );
            }               
            else
            {
                //otherwise, turn it off and wait one minute before resetting state machine
                digitalWrite( pinLED, LOW );
                stateLED = LED_TIME_OFF;
               
            }//if
       
        break;

        case    LED_TIME_OFF:
            if( timeNow - timeLED >= LED_OFFTIME )
                stateLED = LED_OFF;
           
        break;
       
    }//switch
   
}//DoLEDStateMachine

void DoBlinkyFlag( void )
{
    static unsigned long
        timeBlink=0;
    unsigned long
        timeNow;

    timeNow = millis();
    //when it's time for a state toggle...
    if( (timeNow - timeBlink) >= BLINK_TOGGLE_PER )
    {
        //get the time for the next toggle
        timeBlink = timeNow;
        //and use an XOR for a simple way to flip the flag state HIGH-LOW-HIGH-LOW...
        stateBlink ^= HIGH;
    }//if
   
}//DoBlinkyFlag

void DoSwitch( void )
{
    static unsigned long
        timeSwitch=0;
    unsigned long
        timeNow;

    timeNow = millis();
    //is it time for a switch read?
    if( timeNow - timeSwitch >= SW_READ_INTERVAL )
    {
        //yes; save time now for next read
        timeSwitch = timeNow;
        
        //read the switch
        nowSw = digitalRead( pinSw );
        //not the same as last read?
        if( nowSw != lastSw )
        {
            //no; save new state            
            lastSw = nowSw;
            //is reading low now, indicating press?
            if( nowSw == LOW )
            {
                //yes; toggle the cycle state
                bCycleActive ^= true;

                //if we're switching off the cycle, turn off the LED and set the LED state to LED_OFF
                if( !bCycleActive )
                {
                    digitalWrite( pinLED, LOW );
                    stateLED = LED_OFF;
                    
                }//if
                
            }//if
           
        }//if
        
    }//if    
    
}//DoSwitch