Problema con los tiempos en Millis

Hola buenas tardes.
Estoy preparando un secuenciador luminoso para un playbak de la escuela.
El arduino tiene que reproducir exactamente la secuencia de las 9 letras “BURLESQUE” durante
todo el vídeo.
No logro hacer que se inicie al apretar el pulsador. Sí, hace la secuencia si alimento al mismo
tiempo que tengo apretado el pulsador.
Al alimentarlo no tiene que hacer nada y estar a la espera de que se le pulse para iniciar secuencia. Una pista por favor.
Gracias.

El vídeo es este: Christina Aguilera-Show Me How You Burlesque HD - YouTube

//Encender  9leds diferentes tiempos



unsigned long tiempo; 
int leds[9]= {2,3,4,5,6,7,8,9,10};
int pin_boton= A0; // Pin para el boton
boolean activa = false; //Variable de control de encendido


void setup(){
   
    for(int i =0; i<9;i++){ //Configura salida de leds en pines 2, 3,4,5, 6,7,8,9,10 como salida
  pinMode(leds[i],OUTPUT);
  }
  pinMode(pin_boton,INPUT);
 tiempo= millis();
   digitalWrite(pin_boton,HIGH);
 
  }
     
void loop(){
  if (digitalRead(pin_boton) == LOW){ //Revisa que has presioando el boton
    delay(50);
    if (digitalRead(pin_boton) == LOW) { // Espera 50 milisegundos para evitar antirrebotes.
      while(pin_boton == LOW){} //Espera que sueltes el boton
      if(activa==true){activa = false;} //Si esta activo se apaga
      if(activa==false){activa = true;} // Sie sta apagado se activa   
    }
  }
  if(activa == true){ //Si esta activo llama a la fucion encender_leds();
        encender_leds();
  }
   
}

//////////////////////////////////////////////// encendido de todos los led
void encender_leds(){

   if(millis()-tiempo>1 && millis()-tiempo <780){  //26,13
    for(int i=0; i<=10;i++)
     digitalWrite(i,HIGH);
  }else
 if (millis()-tiempo > 780){
   for(int i=0; i<=10;i++)
     digitalWrite(i,LOW);                           //26,91                       780milis
     
  } 
  //letra  E  
  if(millis()-tiempo>1781 && millis()-tiempo < 2051){  //27,92
    digitalWrite(leds[4],HIGH);
  }else
  if (millis()-tiempo > 2051 ){                                         
    digitalWrite(leds[4],LOW);                                //28,19              270milis
  }
   //letra  S  
  if(millis()-tiempo> 2051&& millis()-tiempo < 2311){    //28,45
    digitalWrite(leds[5],HIGH);
  }else                                                                   
  if (millis()-tiempo > 2311 ){
    digitalWrite(leds[5],LOW);                        //28,64                       260milis
  }  
  //todas
   if(millis()-tiempo>2921 && millis()-tiempo <3081){            //29,23 a 29,45
    for(int i=0; i<=10;i++)
     digitalWrite(i,HIGH);
  }else                                                                    
  if (millis()-tiempo > 3081){
   for(int i=0; i<=10;i++)
     digitalWrite(i,LOW);   
                                                                           //29,45    160milis
  } 
  //todas parpadeo 2 veces
  if(millis()-tiempo>3151 && millis()-tiempo <3581){            //29,52 a 29,95
    for(int i=0; i<=10;i++)
     digitalWrite(i,HIGH);
  }else                                                                                                   
 if (millis()-tiempo > 3581){
   for(int i=0; i<=10;i++)
     digitalWrite(i,LOW);                           //29,95                             730milis  
  } 
  if(millis()-tiempo>3586 && millis()-tiempo <4088){  //30,00 a 30,52
    for(int i=0; i<=10;i++)
     digitalWrite(i,HIGH);
  }else
 if (millis()-tiempo > 4088){
   for(int i=0; i<=10;i++)
     digitalWrite(i,LOW);                               //30,52                          502milis
  } 
  //Letra R 
   if(millis()-tiempo>4368 && millis()-tiempo <4688 ){    //30,80 a 31,12  .320
    digitalWrite(leds[2],HIGH);
  }else
  if (millis()-tiempo >4688 ){
    digitalWrite(leds[2],LOW);                                     //31,12                320milis
   
  }
  //Letra U
  if(millis()-tiempo>4658 && millis()-tiempo < 5058){              //31,09
    digitalWrite(leds[7],HIGH);
  }else
  if (millis()-tiempo > 5058 ){
    digitalWrite(leds[7],LOW);                                        //400mils
   } 
    //letra  todas
   if(millis()-tiempo>4898 && millis()-tiempo <5058){          //31,33
   for(int i=0; i<=10;i++)
     digitalWrite(i,HIGH);
  }else
  if (millis()-tiempo > 5058){
   for(int i=0; i<=10;i++)
     digitalWrite(i,LOW);                                      //31,49           160milis
  }
  //Letra Q 
  if(millis()-tiempo>5078 && millis()-tiempo <5168){           //31,51
    digitalWrite(leds[6],HIGH);
  }else
  if (millis()-tiempo > 5168){
    digitalWrite(leds[6],LOW);                                  //31,60        90milis
  } 
  //Letra U
   if(millis()-tiempo>5118 && millis()-tiempo <5378 ){          //31,55
    digitalWrite(leds[7],HIGH);
  }else
  if (millis()-tiempo > 5378){
    digitalWrite(leds[7],LOW);                                  //31,81     260milis
  }
    //letra  S  
  if(millis()-tiempo>5298&& millis()-tiempo < 5488){              //31,73
    digitalWrite(leds[5],HIGH);
  }else
  if (millis()-tiempo > 5488 ){
    digitalWrite(leds[5],LOW);                                   //31,92
  }
   //letra  E+todas
  if(millis()-tiempo>5458 && millis()-tiempo < 6248){              //31,89  a 32,68
    digitalWrite(leds[8],HIGH);}
  if(millis()-tiempo>5868 && millis()-tiempo <6248){                // 32,30
    for(int i=0; i<=10;i++)
     digitalWrite(i,HIGH);
  }else
 if (millis()-tiempo > 6248){
   for(int i=0; i<=10;i++)
     digitalWrite(i,LOW);                                           //32,68
  }  //Letra R 
   if(millis()-tiempo>6248 && millis()-tiempo <6358 ){
    digitalWrite(leds[2],HIGH);
  }else
  if (millis()-tiempo >6358){
    digitalWrite(leds[2],LOW);                                 //32,78
    
  }
  //Letra U
  if(millis()-tiempo>6358 && millis()-tiempo <6488 ){
    digitalWrite(leds[7],HIGH);
  }else
  if (millis()-tiempo > 6488 ){
    digitalWrite(leds[7],LOW);                                       //32,91.............
  }
  //letra E
   if(millis()-tiempo>6538 && millis()-tiempo < 6728){             //32,86//36,00
    digitalWrite(leds[8],HIGH);
  }else
  if (millis()-tiempo > 6728 ){
    digitalWrite(leds[8],LOW);                                  //33,05     //36,19
  }
   //Letra Q 
  if(millis()-tiempo>6678 && millis()-tiempo < 6918){                      //33,00//36,88
    digitalWrite(leds[6],HIGH);
  }else
  if (millis()-tiempo > 6918){                                                //33.24 //37,12
    digitalWrite(leds[6],LOW);
  } 
  //Letra U
   if(millis()-tiempo>6838 && millis()-tiempo <7078 ){                  //33,16//37,04
    digitalWrite(leds[7],HIGH);
  }else
  if (millis()-tiempo > 7078){
    digitalWrite(leds[7],LOW);                                         //33,40//37,28
                                            // 39,75//37,45
 
      tiempo= millis();           
  }
  }

secuencia_con_la_funcion_mille.ino (29.2 KB)

Tienes muchos solapamientos. Las condiciones para algunos tiempos solapan otros
Deberías intentar explicarlo porque asi es dificil poner a corregir algo que no se entiende de donde viene

Puedes indicar que tiene que hacer cada secuencia?

Luego en algunos casos veo

digitalWrite(i,LOW);

y en otros veo

digitalWrite(led[i],LOW);

cual es el criterio?

Perdona surbyte pero soy novato en esto, no me había dado cuenta de los solapamientos.

El problema lo tengo al principio del sketch que los milis siguen contando y cuando le doy al pulsador se salta

varias secuencias .

Lo que tiene es que comenzar cuando pulsemos en la primera secuencia de 780miliseg.

Te mando el sketch mas escueto y correjido.

Gracias de antemano

//Encender  9leds diferentes tiempos



unsigned long tiempo; 
int leds[9]= {2,3,4,5,6,7,8,9,10};
int pin_boton= A0; // Pin para el boton
boolean activa = false; //Variable de control de encendido


void setup(){
   
    for(int i =0; i<9;i++){ //Configura salida de leds en pines 2, 3,4,5, 6,7,8,9,10 como salida
  pinMode(leds[i],OUTPUT);
  }
  pinMode(pin_boton,INPUT);
   
   digitalWrite(pin_boton,HIGH);
   tiempo= millis();
  }
     
void loop(){
    if (digitalRead(pin_boton) == LOW){ //Revisa que has presioando el boton
    delay(50);
    if (digitalRead(pin_boton) == LOW) { // Espera 50 milisegundos para evitar antirrebotes.
      while(pin_boton == LOW){} //Espera que sueltes el boton
      if(activa==true){activa = false;} //Si esta activo se apaga
      if(activa==false){activa = true;} // Sie sta apagado se activa   
    }
  }
  if(activa == true){ //Si esta activo llama a la fucion encender_leds();
        encender_leds();
  }
   
}


void encender_leds(){

   if(millis()-tiempo>1 && millis()-tiempo <780){  //26,13
    for(int i=0; i<=10;i++)
     digitalWrite(i,HIGH);
  }else
  if (millis()-tiempo > 780){
   for(int i=0; i<=10;i++)
     digitalWrite(i,LOW);                           //26,91                       780milis
     
  } 
  //letra  E  
  if (millis()-tiempo>1781 && millis()-tiempo < 2051){  //27,92
    digitalWrite(leds[4],HIGH);
  }else
  if (millis()-tiempo > 2051 ){                                         
    digitalWrite(4,LOW);                                //28,19              270milis
    
  }
   //letra  S  
  if (millis()-tiempo>2051&& millis()-tiempo < 2311){    //28,45
    digitalWrite(leds[5],HIGH);
  }else                                                                   
  if (millis()-tiempo > 2311 ){
    digitalWrite(5,LOW);                        //28,64                       260milis
  }  
  //todas
   if(millis()-tiempo>2921 && millis()-tiempo <3081){            //29,23 a 29,45
    for(int i=0; i<=10;i++)
     digitalWrite(i,HIGH);
  }else                                                                    
  if (millis()-tiempo > 3081){
   for(int i=0; i<=10;i++)
     digitalWrite(i,LOW);   
                                                                           //29,45    160milis
  } 
  //todas parpadeo 2 veces
  if(millis()-tiempo>3151 && millis()-tiempo <3581){            //29,52 a 29,95
    for(int i=0; i<=10;i++)
     digitalWrite(i,HIGH);
  }else                                                                                                   
 if (millis()-tiempo > 3581){
   for(int i=0; i<=10;i++)
     digitalWrite(i,LOW);                           //29,95                             730milis  
  } 
  if(millis()-tiempo>3586 && millis()-tiempo <4088){  //30,00 a 30,52
    for(int i=0; i<=10;i++)
     digitalWrite(i,HIGH);
  }else
 if (millis()-tiempo > 4088){
   for(int i=0; i<=10;i++)
     digitalWrite(i,LOW);                               //30,52                          502milis
  } 
  //Letra R 
   if(millis()-tiempo>4368 && millis()-tiempo <4688 ){    //30,80 a 31,12  .320
    digitalWrite(2,HIGH);
  }else
  if (millis()-tiempo >4688 ){
    digitalWrite(2,LOW);                                     //31,12                320milis
   
  }
  //Letra U
  if(millis()-tiempo>4658 && millis()-tiempo < 5058){              //31,09
    digitalWrite(7,HIGH);
  }else
  if (millis()-tiempo > 5058 ){
    digitalWrite(7,LOW);                                        //400mils
   } 
    //letra  todas
   if(millis()-tiempo>4898 && millis()-tiempo <5058){          //31,33
   for(int i=0; i<=10;i++)
     digitalWrite(i,HIGH);
  }else
  if (millis()-tiempo > 5058){
   for(int i=0; i<=10;i++)
     digitalWrite(i,LOW);                                      //31,49           160milis
  }
  //Letra Q 
  if(millis()-tiempo>5078 && millis()-tiempo <5168){           //31,51
    digitalWrite(6,HIGH);
  }else
  if (millis()-tiempo > 5168){
    digitalWrite(6,LOW);                                  //31,60        90milis
     tiempo= millis();           
  }
  }

Te vuelvo a consultar

for (int i=0; i<=10;i++)
               digitalWrite(i,LOW);

esto va desde 0 a 10 y tienes 9 leds y ahi estas accionando sobre 11 leds.
Desde pin 0 a pin 10.

En tu declaración de leds dices

int leds[9]= {2,3,4,5,6,7,8,9,10};

Llendo a tus tiempos.

Todos los else terminan en > que algo y todos se solapan.
Debes comenzar a comentarlos y veras como comienza a funcionar todo.
Luego analiza bien que debería hacer tu código en esas circunstancias.

Como no lo explicas no puedo sugerir nada.

Te pedí por privado que leyeras las normas!

El vídeo es este: https://m.youtube.com/watch?v=U3APrqTKtcA

Esto debe verse asi

El vídeo es este: https://m.youtube.com/watch?v=U3APrqTKtcA

1er hilo de cada foro, Normas del foro

Ahora ve y edítalo por favor!!

He modificado tu código usando una máquina de estados.
Para entenderla ve a documentación y verás ahi de que se trata. Tienes el indices de temas tutoriales para encontrarlo.

//Encender  9leds diferentes tiempos

unsigned long tiempo; 
int leds[9]= {2,3,4,5,6,7,8,9,10};
int pin_boton       = A0;           // Pin para el boton
boolean activa      = false;        // Variable de control de encendido
byte estado         = 0;            // define que hara el sistema
int i;

void setup(){
 
  for (int i =0; i<9;i++){          // Configura salida de leds en pines 2, 3,4,5, 6,7,8,9,10 como salida
       pinMode(leds[i],OUTPUT);
  }
  pinMode(pin_boton,INPUT);
   
  digitalWrite(pin_boton, HIGH);    // esto para que? Se define como INPUT_PULLUP ?
  tiempo = millis();
}
     
void loop(){
  if (digitalRead(pin_boton) == LOW){ //Revisa que has presioando el boton
      delay(50);
      if (digitalRead(pin_boton) == LOW) { // Espera 50 milisegundos para evitar antirrebotes.
      while(pin_boton == LOW){} //Espera que sueltes el boton
      activa = !activa;
    }
  }
  if (activa){ //Si esta activo llama a la fucion encender_leds();
      encender_leds();
  }
   
}


void encender_leds(){

  switch(estado) {
      case 0: for (i=0; i<9; i++) // prendo todos los leds
                   digitalWrite(leds[i],HIGH);
              estado = 1;
              break;
      case 1: if (!consulta(1,780)) {  // devuelve TRUE si esta entre esos valores y false
                  for (i=0; i<9; i++) 
                       digitalWrite(leds[i], LOW); // apago todos
                  estado = 2;
              }
              break;
      case 2: if (consulta(1781, 2051)) {  // enciendo letra  E  
                  digitalWrite(leds[4], HIGH); 
                  estado = 3;
              }
              break;
      case 3: if (!consulta(1781, 2051)) {  // apago letra  E  
                  digitalWrite(leds[4], LOW); 
                  estado = 4;
              }
              break;
      case 4: if (consulta(2051, 2311)) {  // enciendo letra S  
                  digitalWrite(leds[5], HIGH); 
                  estado = 5;
              }
              break;
      case 5: if (!consulta(2051, 2311)) {  // apago letra  S  
                  digitalWrite(leds[5], LOW); 
                  estado = 6;
              }
              break;
      case 6: if (consulta(2921, 3081)) {  // Enciendo todas
                  for (i=0; i<9; i++) // prendo todos los leds
                       digitalWrite(leds[i],HIGH); 
                  estado = 7;
              }
              break;
      case 7: if (!consulta(2921, 3081)) {  // Apago todas
                  for (i=0; i<9; i++) // apago todos los leds
                       digitalWrite(leds[i],LOW); 
                  estado = 8;
              }
              break;
      case 8: if (consulta(3151, 3581)) {    //todas parpadeo 2 veces
                  for (i=0; i<9; i++) // prendo todos los leds
                       digitalWrite(leds[i],HIGH); 
                  estado = 9;
              }
              break;
      case 9: if (!consulta(3151, 3581)) {  // todas parpadeo 2 veces
                  for (i=0; i<9; i++) // apago todos los leds
                       digitalWrite(leds[i],LOW); 
                  estado = 10;
              }
              break;
      case 10: if (consulta(3151, 4088)) {    //todas parpadeo 2 veces
                  for (i=0; i<9; i++) // prendo todos los leds
                       digitalWrite(leds[i],HIGH); 
                  estado = 11;
              }
              break;
      case 11: if (!consulta(3586, 4088)) {  // todas parpadeo 2 veces
                  for (i=0; i<9; i++) // apago todos los leds
                       digitalWrite(leds[i],LOW); 
                  estado = 12;
              }
              break;
      case 12: if (consulta(4368, 4688)) {  // enciendo Letra R  
                  digitalWrite(leds[2], HIGH); 
                  estado = 13;
              }
              break;
      case 13: if (!consulta(4368, 4688)) {  // apago Letra R  
                  digitalWrite(leds[2], LOW); 
                  estado = 14;
              }
              break;
      case 14: if (consulta(4898, 5058)) {    //todas parpadeo 2 veces
                  for (i=0; i<9; i++) // prendo todos los leds
                       digitalWrite(leds[i],HIGH); 
                  estado = 15;
              }
              break;
      case 15: if (!consulta(4898, 5058)) {  // todas parpadeo 2 veces
                  for (i=0; i<9; i++) // apago todos los leds
                       digitalWrite(leds[i],LOW); 
                  estado = 16;
              }
              break;
      case 16: if (consulta(5078, 5168)) {    //Letra Q 
                   digitalWrite(leds[6],HIGH); 
                   estado = 17;
              }
              break;
      case 17: if (!consulta(5078, 5168)) {  //Letra Q 
                   digitalWrite(leds[6],LOW); 
                   estado = 0;               // vuelvo al primer estado supongo? y repito
                   tiempo = millis(); 
              }
              break;
  }
}

bool consulta(unsigned long t1, unsigned long t2) {
  return (millis()-tiempo>t1 && millis()-tiempo <t2;)
}

Muchas gracias Surbyte eres un crack. Lo pruebo todo y cuando lo tenga montado pongo los resultados

Con la máquina de estados es el único modo fácil que veo que haga lo que tu esperabas hacer.
Al ver el video me quedó claro lo que estabas intentando.
Luego hice algunas simplificaciones para no tener que ponerte tantos if y el modo implementado debería resultar.
No lo probé pero espeo funcione.

Esta linea tiene un error

 return (millis()-tiempo>t1 && millis()-tiempo <t2;)

Debe ser asi

 return (millis()-tiempo>t1 && millis()-tiempo <t2);

He modificado para poderlo compilar.
Asi:

return (millis()-tiempo>t1 && millis()-tiempo <t2);

Pero no funciona.
Algunas veces inicia y se quedan todos los leds encendidos o inicia y se para.

Hola. Perdón por la intromisión. Esta es mi propuesta. Siento no tener tiempo para ahondar en las explicaciones de su funcionamiento. Básicamente la idea es guardar la secuencia de luces y tiempos en un array en la memoria de programa del Arduino para no consumir toda la RAM del Arduino.

He puesto una secuencia sin mucho sentido, a modo de demostración. Deberías de cambiarla y adaptar su forma y tamaño a tus necesidades.

Se define con un array de grupos de tres bytes. Los dos primeros indican qué LEDs queremos que estén encendidos y cuales apagados. El tercero indica el tiempo, en décimas de segundos, que ha de estar en ese estado. El tiempo máximo que se puede poner es de 255 décimas de segundos (25 segundos y medio) ya que se guarda en un byte.

Los LEDs se indican con ceros o unos en los ocho bits del primer byte de cada terna y el bit menos significativo del segundo byte. Por eso he puesto en binario el primero y son únicamente útiles los valores 0 y 1 en el segundo.

Lo de usar un único pulsador para activar la secuencia y pararlo me parece una mala idea. Preferiría uno para parar y apagar todo y otro para iniciar siempre la secuencia aunque esta no hubiera terminado.

No sé si tendré tiempo de explicarlo con detenimiento. Si surge alguna duda es probable que alguien del foro pueda explicarlo, si no, trataré de buscar tiempo para aclararla.

Lo he hecho algo a las prisas, con lo que no me extrañaría que hubiera algún fallo.

Adjunto programa.

foro_burlesque.ino (4.11 KB)

Hola buenos días para nada te entrometes al contrario agradecido por dedicar tiempo a esto.
El único problema con las array es que por ejemplo 780 milis tendría que poner 8 décimas. Corrígeme si me equivoco. Pero por lo demás el código que has puesto funciona.

Me meto en el thread porque vi algo que me llamo la atención, quizás no comprenda el funcionamiento de millis(), o no logro entender lo que queres hacer, pero en el código veo que a la variable "tiempo", le asignas el valor millis() y se lo restas al mismo valor?, o sea no resulta siempre 0? y el valor de "tiempo" no lo reasignas nunca en el loop.

catv:

unsigned long tiempo; 

void setup(){ 
tiempo= millis();
  }
/////////////////////////////////////////////// encendido de todos los led
void encender_leds(){

if(millis()-tiempo>1 && millis()-tiempo <780){  //26,13
    for(int i=0; i<=10;i++)
    digitalWrite(i,HIGH);
  }else
if (millis()-tiempo > 780){
  for(int i=0; i<=10;i++)
    digitalWrite(i,LOW);                          //26,91                      780milis
   
  }

Por lo que entiendo Millis coge el valor de inicio de la placa en mili segundos y time coge el valor de ese momento y se resta a Millis por lo demás es lo que consulte

catv:
Por lo que entiendo Millis coge el valor de inicio de la placa en mili segundos y time coge el valor de ese momento y se resta a Millis por lo demás es lo que consulte

Tenes razón, tiempo=millis() en el setup captura los milisegundos de inicio y me disculpo porque no había visto la reasignacion de tiempo al final de la función, pero está.

catv:
El único problema con las array es que por ejemplo 780 milis tendría que poner 8 décimas. Corrígeme si me equivoco.

Puedes cambiar el código para que en lugar de ser décimas de segundo sean centésimas de segundo. Lo que el tiempo máximo es de poco más de dos segundos y medio (2.55 segundos para ser exactos).

Para ello has de cambiar el 100UL por 10UL en la línea:

    return (static_cast<unsigned long>(dato) * 100UL);

Y que quede asi:

    return (static_cast<unsigned long>(dato) * 10UL);

Y luego añade un cero a cada tiempo de la última columna de datos (si tenías 8 décimas ahora has de poner 80 centésimas). Y si quieres luego ajustas y en lugar de 80 centésimas pones 78 centésimas.

Si necesitas más precisión habría que guardar enteros de 32 bits en lugar de 8 bits.

Aún así, el programa no es muy exacto ya que mira sólo si como mínimo ha transcurrido el tiempo indicado, cambia a la siguiente representación y espera el nuevo tiempo... pero, si transcurrió unos milisegundos de más no lo tiene en cuenta y ese tiempo extra se va sumando poco a poco a la duración total de la secuencia. Para corregir esa desviación habría que hacer una corrección en el tiempo que ha de esperar en cada pausa, restando el tiempo excedido en la pausa anterior. Si encuentro un hueco, tal vez le haga esa mejora al programa.

Ya me dirás si necesitas más precisión o si con las centésimas ya tienes. Y recuerda que como máximo podrás poner 255 centésimas de pausa.

Lo estoy probando y el efecto corrido de luces no lo puedo crear porque hay veces que un Led entra y seguidamente entra el siguiente y el anterior no se apaga hasta pasados unos milisegundos.
Asi:

  //Letra Q 
  if(millis()-tiempo>5078 && millis()-tiempo <5168){           //31,51
    digitalWrite(6,HIGH);
  }else
  if (millis()-tiempo > 5168){
    digitalWrite(6,LOW);                                  //31,60        90milis
  } //....................................................................................
  //Letra U
   if(millis()-tiempo>5118 && millis()-tiempo <5378 ){          //31,55
    digitalWrite(leds[7],HIGH);
  }else
  if (millis()-tiempo > 5378){
    digitalWrite(leds[7],LOW);                                  //31,81     260milis
  }
    //letra  S  
  if(millis()-tiempo>5298&& millis()-tiempo < 5488){              //31,73
    digitalWrite(leds[5],HIGH);
  }else
  if (millis()-tiempo > 5488 ){
    digitalWrite(leds[5],LOW);                                   //31,92
  }

Aquí tienes una nueva versión. Esta vez el tiempo se indica en milisegundos (añade otro cero si lo tenías en centésimas o dos ceros si aún lo tenías en décimas). El máximo tiempo de espera que se le puede poner es de 65535 milisegundos (un poco más de 65 segundos y medio). Tiene más resolución que la versión anterior, pero ocupa un 33% más de memoria de programa cada instrucción. Antes eran tres bytes por instrucción y ahora son cuatro. Sólo usa memoria de programa y no RAM ya que usa PROGMEM - Arduino Reference

Por otro lado, antes estaba organizado de tres en tres bytes siendo los dos primeros la configuración de los LEDs y el tercero el tiempo. Ahora son dos enteros de 32 bits, uno para la configuración de los LEDs y el otro para el tiempo. Para hacerlo "más legible", y porque ya no son bytes, en lugar de utilizar las macros de Arduinio de los bytes en binario (ejemplo: B10101100) he usado la "nueva" notación de números en binario de C++ utilizando el prefijo 0b (ejemplo 0b10101100). Además de ser "mas estándar" tiene como ventaja poder poner números más grandes que un byte (en este caso se necesitan hasta 9 bits).

La línea que en la primera versión (en centésimas) era así:

    B11010001, 1,   3,

Ahora es ha de ser así:

    0b110100011,   300,

Otra modificación es que ahora el código admite modificar fácilmente el número de LEDs a controlar. Sólo hay que modificar el array PINES_LEDS[] quitando o añadiendo valores (hasta un máximo de 16).

También he corregido el posible "desfase" que se podría producir al ir acumulando pequeños retardos de tiempos.

Adjunto fichero de la nueva versión.

foro_burlesque_v2.ino (4.44 KB)

Has planteado la solución controlando cuándo se ha de encender y de apagar cada LED en función del tiempo transcurrido desde el inicio de la secuencia. Eso significa que por cada vez que se ha de encender cada uno de los LEDs has de escribir (copiar y pegar cambiando un par de números) la parte del programa que lo controla. ¿Cuantas veces se van a apagar y encender todos los LEDs durante toda la secuencia? ¿Cuántos if vas a tener que poner?

Mi planteamiento es indicar cuales LEDs han de estar apagados, cuales encendidos cada vez y durante cuanto tiempo. Codificando una a una cada transición o cambios de LEDs (si cambian dos o más a la vez es una misma transición).

En tu ejemplo has puesto que la Q ha de estar encendida desde la milésima 5078 hasta la milésima 5168,la U desde la 5118 a la 5378 y la S desde la 5298 a la 5488. Algo que defines con tres if. Que "simplificando" sería conceptualmente algo así:

5078 5168 Q
5118 5378 U
5298 5488 S

Eso significa que en la milésima 5078 ha de estar sólo encendida la Q. Transcurrida 40 milésimas (en la milésima 5118) ha de permanecer encendida la Q y encenderse la U. Durante 50 milésimas estarán encendidas las dos, transcurrido ese tiempo (en la milésima 5168) se ha de apagar la Q, quedando sólo la U. 130 milésimas después (en la milésima 5298) se enciende la S. Durante 80 milésimas están las dos encendidas y luego (en la milésima 5378) se apaga la S. Permanece sólo la S encendida durante 80 milésimas más y se apaga en la milésima 5488. Por último estarán todas apagadas por un tiempo indeterminado. Esto se podría representar algo tal que así:

5078 -> -Q- ->  40
5118 -> -QU ->  50
5168 -> --U -> 130
5298 -> S-U ->  80
5378 -> S-- ->  80
5488 -> --- ->  ¿?

Pues eso es lo que yo hago, decir qué está encendido y qué apagado, y durante cuánto tiempo. Sólo la Q ha de estar 40 milésimas encendida. Después la Q y la U han de estar 50 milésimas encendidas. Luego sólo la U 130 milésimas. Seguidamente la S y la U 80 milésimas. Continúa sólo la S encendida durante 80 milésimas. Se apagan todas durante un tiempo que falta por determinar. Así hasta que se llega al final de la secuencia y se queda encendido lo último que se indique. Todo esto se indica en el programa sin necesidad de modificar ningún if, sólo hay que añadir/modificar las líneas:

    0b000000100,    40,
    0b000000110,    50,
    0b000000010,   130,
    0b000001010,    80,
    0b000001000,    80,
    0b000000000,    ¿?,

No sé si me he explicado bien y se me ha entendido.

Eso sí. Ten en cuenta que si modificas el tiempo de una línea, quitas o pones una línea de datos del array, a partir de ahí se adelantan o atrasa la "ejecución" de las siguientes. Con lo que tal vez sea complicado definir correctamente los tiempos de la secuencia.

Lo que sí que no sé es si ya tienes calculado todos los tiempos o si los estás calculando "a mano" empíricamente a base de prueba y error. Porque si ya tienes calculado todos los tiempos de cada uno de los LEDs se podría hacer un pequeño programa que "traduzca" esos tiempos a "mi formato".

Es bastante engorroso así pero estoy sacando los tiempos y poniendolos al mismo tiempo.
Yo los tengo sacados con tiempos, voy a intentar sacarlo todo en una excel y lo vemos.

Me he dado cuenta que en mis ansias de ahorrar memoria he definido TOTAL_SECUENCIA de tipo byte con lo que limita a 255 las combinaciones posibles. Así que es mejor definirlo de tipo size_t, con lo que se gastará la memoria antes que desbordarse la variable.

Se ha de cambiar en la línea:

const byte TOTAL_SECUENCIA = ((sizeof(SECUENCIA) / sizeof(SECUENCIA[0])) / 2);

Para que quede asi:

const size_t TOTAL_SECUENCIA = ((sizeof(SECUENCIA) / sizeof(SECUENCIA[0])) / 2);