blink senza delay()

Ciao a tutti.
Ho la necessità di far accendere dei led intermittenti senza usare la delay, perchè il programma non deve smettere di girare per altri motivi.
Inoltre avrei la necessità di accendere il led alla pressione di un tastino e la prima volta dovrebbe rimanere acceso diciamo per 6 secondi e poi cominciare a lampeggiare ogni 3.
Faccio un esempio che è più chiaro.

Pulsante tenuto premuto --> led acceso 6 secondi --> spento 3 secondi --> acceso 3 secondi --> spento 3 secondi --> acceso 3 secondi e cosi via fino a quando non rilascio il pulsante che spegne il led definitivamente.

Io sono partito da qui (dove manca la lettura del tasto ma quella è una if) ma non mi è chiaro come faccio a tenerlo acceso per 6 secondi e poi ogni 3:

int ledPin = 13;
int value = LOW;
long previousMillis = 0;
long interval = 1000;
 
void setup()
{
  pinMode(ledPin, OUTPUT);
}
 
void loop()
{
  if (millis() - previousMillis > interval) {
    previousMillis = millis();
 
    if (value == LOW)
      value = HIGH;
    else
      value = LOW;
 
    digitalWrite(ledPin, value);
  }
}]
int ledPin = 13;
int value = LOW;
long previousMillis = 0;
long interval = 1000;
 
void setup()
{
  pinMode(ledPin, OUTPUT);
}
 
void loop()
{
  if (millis() - previousMillis > interval) {
    previousMillis = millis();
 
    if (value == LOW)
      value = HIGH;
    else
      value = LOW;
 
    digitalWrite(ledPin, value);
  }
}

Una cosa del genere può andare?

const int ledPin =  13;      // the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 6000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);      
  Serial.begin(57600);
}

void loop()
{
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
  unsigned long currentMillis = millis();
  Serial.write(currentMillis - previousMillis + "\n");
  if(currentMillis - previousMillis > interval ) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    interval=3000;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW){
      ledState = HIGH;
    }
    else
      ledState = LOW;
  }
  else{
    if (previousMillis==0)
      ledState = HIGH;
  }
  // set the LED with the ledState of the variable:
  digitalWrite(ledPin, ledState);

}

A me sembra che funzioni.

Potresti anche pensare al leOS, è fatto apposta per svolgere piccoli compiti in background in modo indipendente dal codice principale. Negli esempi allegati c'è anche il pilotaggio di led al di fuori del loop.

Sembra interessante e sicuramente lascia il codice più pulito.
Una cosa non ho capito, ma se schedulo il task ogni 1 secondo e lo fermo dopo 1,5 secondi se lo riattivo riparte dopo 500 ms o sempre dopo 1 secondo?

Grazie non lo consocevo.

Se lo metti in pausa, lo blocchi al punto in cui era. Però puoi anche modificare un task, cambiargli cioè l'intervallo e lo stato. Se gli cambi l'intervallo, resetti il suo contatore. Se modifichi un task reimpostandogli però lo stesso intervallo, non fai altro che riportare a 0 il suo contatore :wink:

Ottimo. Si deve provare