If-Switch-Array-Millis-For

Cerco di spiegartelo.

Ti serve un flag per ogni azione perché se l'azione da compiere è molto veloce, rischi (come hai visto anche tu), di rieseguirla più volte, finché il controllo fra il tempo attuale ed il tempo impostato per l'azione sono uguali

Detto questo, potresti forse anche affrontare il discorso in un altro modo. Usi la seconds() che ho fatto giorni fa e poi pianifichi gli intervalli.

mettiamo così:

unsigned long pianificazioni[5];
byte intervallo[5]={3, 4, 6, 8 ,9};

setup:
for (byte i=0; i<5; i++) {
    pianificazioni[i]=seconds()+intervallo[i];
}

loop:
unsigned long secondi=seconds();
for (byte i=0; i<5; i++) {
  if (secondi>pianificazioni[i]) {
    eseguiAzione(i);
    pianificazioni[i]=seconds()+intervallo[i];
  }
}
....

void eseguiAzione(byte i) {
switch (i) {
....
}

In questo modo, una volta eseguita l'azione, non la riesegue un'altra volta nello stesso secondo perché l'intervallo viene subito spostato in avanti. Prova, non so, l'ho scritto mentre sono in fase quasi REM...