Problema con temporizadores.

Buenos días a todos.

En primer lugar gracias por todo lo que estoy aprendiendo con esta comunidad, es una gozada. En mi empresa me han encomendado la tarea de aprender a programar en Arduino, con la idea de sustituir algunos autómatas S7 1200. Y no tengo mucha idea, más que algunos conocimientos de C de la universidad.

Actualmente voy poco a poco, y estoy sustituyendo unos temporizadores T ON. (Retardo a la conexión), usando millis. Estoy haciendo una prueba fácil (después de ver todos los tutoriales y ejemplos del foro), pero no funciona. Quiero que el led 13 se encienda 10s después de que una entrada sea activada.

El código no me funciona. Activo la entrada directamente con 5V externos.

¿En qué me estoy equivocando?

unsigned long currentMillis;     

void setup() {
  // Definición de variables como I/O.

pinMode(13,OUTPUT);
pinMode(5, INPUT);
digitalWrite (13,LOW);
}
 
void loop() {

if (digitalRead (5) == HIGH)  {
  currentMillis = millis();

  if (millis()-currentMillis >= 10000) {
  digitalWrite (13,HIGH);
}
}
else {
  digitalWrite (13, LOW);
}
}

Muchas gracias.

  if (digitalRead (5) == HIGH)  {
    currentMillis = millis();

    if (millis() - currentMillis >= 10000) {
      digitalWrite (13, HIGH);
    }
  }

Cuando la entrada esté en alto lees el contador de millis, y siempre!! con lo que currentMillis en cada loop se guarda con el valor actual de millis, y nunca va a llegar a ser mayor de 10000!!

Te recomiendo veas mis tutoriales sobre millis y botones. El de botones te vendrá muy bien porque te servirá para tratar las entradas.

Como NO leer un botón y como SI debemos hacerlo.
Entender millis y no morir en el intento

Y como regalo te dejo esta función:

// Retardo al encendido. Hay que declarar un temporizador t para usar como 
// parametro. Si la condición de cumple, la salida será cierta transcurrido un 
// tiempo especificado.
unsigned int onDelayTimer(bool condicion, unsigned long &timer, unsigned long duracion) {
  if (condicion == false) { timer=0; return 0; }                   
  else                     
    if (timer == 0) { timer = millis(); return 0; }                 
    else              
      if (millis() > (timer + duracion)) return 1;  
      else return 0;
}
// Uso:
unsigned long t; // temporizador declarado fuera del setup o loop.

// en el loop:
if (  onDelayTimer(digitalRead(5)==HIGH), t, 10000 ) 
  digitalWrite(13, HIGH);
else
  digitalWrite(13, LOW);

Muchísimas gracias Victor.

He conseguido tratar las entradas decentemente, y configurar tres temporizadores funcionando independientemente. El post de usar millis() lo había leído un par de veces, pero el de los botones ha sido clave.

Al menos he conseguido que funcione todo correctamente, gracias otra vez.

Ahora a seguir depurando el código. Había pensado crear una función o una librería para tratar entradas, crearme una para temporizadores... poco a poco. Estoy aprendiendo un montón con vosotros!

Dejo mi código por si en un futuro a alguien puede servirle de utilidad. Lectura de una entrada, y posterior activación de una salida 10s después:

// DEFINICIÓN DE CONSTANTES.

// GLOBALES
unsigned long tiemporebote = 50; // Tiempo de rebote para la depuración de lectura de entradas.

// ENTRADA 2____________________________________________________________________________

int anterior2;  // Guardo el estado anterior
int estado2;    
unsigned long temporizador2;  // Almacenamiento de tiempo para la depuración de entradas.

            // TEMPORIZADOR ENTRADA 2____________________________________________________
            unsigned long currentMillis2;
            unsigned long Ton2 = 10000;


void setup() {

// ENTRADAS
pinMode(2, INPUT);
estado2 = LOW;
anterior2 = LOW;

// SALIDAS
pinMode(13, OUTPUT);
digitalWrite (13,LOW);

// PUERTO SERIE
Serial.begin(9600);

}

void loop() {

// ENTRADA 2________________________________________________________________________________________

// LECTURA DE ENTRADA.
if (estado2 == digitalRead(2))   {
  temporizador2 = 0;
}
else {                              // Hemos tenido un cambio en la lectura de la entrada. Marco evento.
  if (temporizador2 == 0)   {
  temporizador2 = millis();
    }
  else 
      if (millis() - temporizador2 > tiemporebote) {
       estado2 = !estado2;               // Cambio en el estado de la entrada.
}
}

// ACCIONES. 
if (anterior2 == LOW && estado2 == HIGH) {
  Serial.println("Entrada2 Activa");
  currentMillis2 = millis();      // Evento para temporizador.
  anterior2 = estado2;
}
if (anterior2 == HIGH && estado2 == LOW) {
  Serial.println("Entrada2 Inactiva");
  anterior2 = estado2;
  digitalWrite (13,LOW);  // Desactivación de la salida asociada.
}
if (millis() - currentMillis2 >= Ton2 && estado2 == HIGH) {
  digitalWrite (13,HIGH);
}
}

Soy consciente de que se podrá mejorar, poco a poco :slight_smile:

PD: Muchas gracias por la función que me has dejado, voy a analizarla bien porque hay partes que no entiendo correctamente. Soy de los que les gusta comprender cada línea de código antes de utilizar cosas más avanzadas jeje.

Un saludo!!!!