Millis y Leds

¡Hola a todos!

Tengo un pequeño problema y no he podido solucionarlo, tengo 10 Leds, enciendo cada uno con un pulsador hasta recorrer los 10, he buscado la manera y he intentado cambiar el código algunas veces, pero no he podido lograr que al pulsar una vez se prenda el primer led y quedé prendido por 5 segundos por ahora, y al pulsar la segunda vez se prenda el segundo por 5 segundos y así sucesivamente hasta llegar al Led numero 10, donde se reinicia el contador a 1, pero sin apagar los Leds que aún les falta su tiempo y mandando los mensajes a la lcd al prenderse el led correspondiente y también al terminar su tiempo.

También si el contador estaba en 10 o todos los Leds encendidos, de manera aleatoria me prendaria el led que terminó su tiempo y no necesariamente seguir el orden de uno a uno pero no he tenido suerte aun, agradezco su ayuda estoy aprendiendo poco a poco y me encanta la idea de aprender más pero por el momento estoy aprendiendo por tutos y a veces me atasco muy feo, gracias a todos...

#include <LiquidCrystal_I2C.h>

unsigned long DURACION = 5000; // Tiempo que permanecer� encendido cada led

LiquidCrystal_I2C lcd (0X3F,20,4);

int Contador=0; 
const byte Pulsador=2;

const byte LED[10]={4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; // Array con la definicion de pines
unsigned long tEncendidoLED[10]; // Array donde guardo los respectivos millis de encendido

void setup ( ) {

 lcd.begin (16, 2);
 Serial.begin(9600);   
 pinMode(Pulsador,INPUT_PULLUP); 


 lcd.print ("LEDS>>>");
 lcd.setCursor (0, 1);
 lcd.print ("LEDS ENCENDIDOS");
 // Recorremos el array de pines con un for para establecerlos como salidas
 for (int i=0; i<10; i++) {
 pinMode (LED[i], OUTPUT);
 }
}


void loop ( ) {
 bool Estado=digitalRead(Pulsador); 

 if ( Estado == LOW ) { // Si hay pulsaci�n
 digitalWrite (LED[Contador], HIGH); // Encendemos el led correspondiente al contador
 tEncendidoLED[Contador]=millis(); 
 lcd.setCursor (0, 1);
 lcd.print (  "LED "); lcd.print(Contador+1); lcd.print(" ACTIVADO");
 Contador++;
 if (Contador==9)Contador=0;
 }
 
 for (int i=0; i<10; i++) {
 if (digitalRead(LED[i])) {
 if ( (millis()-tEncendidoLED[i]) >= DURACION) {
 digitalWrite (LED[Contador], LOW);
 lcd.setCursor (0, 1);
 lcd.print (  "LED "); lcd.print(Contador+1); lcd.print(" DESACTIVADO");
 }
 }
 }

}

Gracias...

Pero si al reiniciar todo no deseas que se apaguen los leds que no hayan pasado de los 5 segundos entonces necesitas guardar en variables bool los estados de dichos leds.
Sin eso es imposible que sepas.

Si cada botón está relacionado con un led tampoco necesitarías la variable contador.

bitebyte:
Pero si al reiniciar todo no deseas que se apaguen los leds que no hayan pasado de los 5 segundos entonces necesitas guardar en variables bool los estados de dichos leds.
Sin eso es imposible que sepas.

-Si me parece que eso necesito guardar en un array todos los tiempos, ¿como podría hacer eso?

bitebyte:
Si cada botón está relacionado con un led tampoco necesitarías la variable contador.

-Por eso lo hice con un solo botón y como voy a utilizar relays para manejar focos, así es necesario... Gracias

ArduMyth:
Explica esto por favor:

No puede ser un led aleatorio si enciendes el led que tenía el tiempo acabado...

¿Esto es algo así cómo el típico ejemplo de luces del coche fantástico pero reiniciado el ejemplo con el mismo pulsador y comenzando por último led que finalizó?

El for se encarga de hacer el recorrido y verificar el tiempo que ha transcurrido y me parece que lo que dijo bitebyte es lo correcto necesito un array que guarde los tiempos de los leds pero la verdad no he visto la manera de hacerlo, lo del led aleatorio es un decir; Imaginá que pulso tres veces seguidas y se prenden tres leds por 5 segundos o por 5 minutos, si después de esos 5 minutos vuelvo a pulsar me prendaria el cuarto led por el contador pero quisiera que me prendaria en este caso el que ya está libre que podría ser el Led numero uno o tal vez el dos, el que ya termino su ciclo, ¿más o menos?, pero eso no lo he podido solucionar.

Gracias

Supongamos que tienes 6 LEDs conectados en los pines 2 a 7 y un pulsador entre pin 12 y GND.

Este boceto comprueba si pulsador esta presionado (LOW) y luego pregunta a cada LED si esta apagado (LOW), si lo esta lo prende, guarda la hora y sale del bucle (break).

Finalmente en el siguiente bucle le preguntamos si algún tiempo ya transcurrió para apagar LED.

unsigned long hora[]={0,0,0,0,0,0};
void setup() {
   pinMode(12, INPUT_PULLUP);   //Pulsador aqui
   for (byte n=2; n<8; n++){
      pinMode(n, OUTPUT);
   }
}

void loop() {
   if (digitalRead(12) == LOW){
      for (byte n=2; n<8; n++){
         if (digitalRead(n) == LOW){         
            digitalWrite(n, HIGH);     //Prende LED
            hora[n-2]=millis();         //Guardamos hora de encendido
            delay(50);                   //Pequeño retardo para eliminar rebotes
            break;
         }
      }
   }
   for (byte i=0; i<6; i++){
      if (millis()-hora[i]>5000){
         digitalWrite(i+2, LOW);     //Apaga LED
      }
   }
}

Espero este ejemplo aclare tus dudas.

PD: No debes quedarte presionando mucho tiempo el pulsador o se prendera mas de un LED.

Gracias kike_GL... ArduMyth tienes una mejor idea?

Si claro hacer todo con millis() y sin delay()

¡Gracias a todos!, pero por el momento nadie me ha dicho en que esta mal mi código o que necesito agregarle para que funcione como deseo.

ArduMyth:
Lo que dijo @surbyte.

@CaleBit. la gente tiene; trabajo, familia, una casa, que comprar... :roll_eyes: :open_mouth: Sin usar el látigo por favor.

  • Ok por ahora estudio en línea y trabajo también y en la noche busco la manera de ir aprendiendo más, y entiendo que los demás también tengan mucho trabajo así que los comprendo jaja y disculpa no quise decir eso y suerte con lo de la casa jaja.

Ok gracias...

ArduMyth:
Vaya, posteamos a la vez. Ya arriba lo tienes. Saludos.

Si eso parece...

Gracias, Saludos...

ArduMyth:
Espero que fuese lo que querías. Es lo que entendí de tu enunciado. Cómo ya dije cualquier duda comenta.

Gracias por tu ayuda, he probado el código pero no espera a que presione el botón cada 2 segundos se prende un Led y se apaga para continuar con el siguiente.

No me di a entender, buscó que al presionar el botón una sola vez me encienda el primer Led por 5 minutos y se apague automáticamente al pasar ese tiempo, al presionar el botón por segunda vez prenda el Led numero 2 por 5 minutos también y se apague después de transcurrir ese tiempo, y así sucesivamente hasta llegar a los 10 leds.

Gracias por tu ayuda...

Lee mejor el código de ArduMyth y verás que esos 2 segundos estan ahi. sI te parecen mucho pues cámbialo, por eso el como programador hace las cosas BIEN, da opciones para cambiar tiempos.
2 seg = 2000 mseg.

struct LED{
  byte          pin;
  bool          estado;
  unsigned int  encendido = 2000;
  unsigned long tiempo;
};

Gracias por tu ayuda la verdad si lo tome y lo copie sin analizarlo solo cambié el pin del botón que yo lo tengo en el 3, a lo que me refería y lo pueden verificar en lo que escribí es que cada 2 segundos se prende el Led sin que presione el botón y así lo sigue haciendo hasta el último Led pero sin presionar el botón, no quiero entrar en polémica pero también surbyte no leyó BIEN lo que escribí, y hoy gracias a Dios descanso así que tendré más tiempo para adentrarme, pero agradezco infinitamente que se tomen ese tiempo y me ayuden a seguir aprendiendo más.

Gracias...

Gracias brother por tu tiempo que te tomas y la ayuda que me ofreces...