Libreria timer o funcion millis , para llamar otra funcion que dure x tiempo

hola un saludos , para todos

Conseguí una librería en Internet llamada EmonLib.h para usar un sensor ZMPT101 que le he ido agregando otras funciones, el problema es que también estoy usado otra librería MillisTimer , para que se ejecute una función en x tiempo (editable pero fija ) después que el sensor detecte una caída o subida de tensión , resulta que el tiempo no es exacto y tenido problema con eso , este es la parte del codigo que necesito al salirse de los valores establecidos 90 y 130 ejecute la función tiempo_reconexion() ,

quisiera usar la funcion millis en vez de la libreria
alguna sugerencia gracias…

#include <MillisTimer.h>



MillisTimer timer(180000);   //tiempo de Reconexion 3min 180000


void setup() {

 timer.setTimer();

}


void loop() {




 if ( (emon1.Vrms >= 90)  &&  (emon1.Vrms <= 130) )
  {
    
    tiempo_reconexion();
    lcd.setCursor(0, 0);
    lcd.print("FASE 110");
    lcd.setCursor(0, 1);
    lcd.print("NORMAL");
    lcd.setCursor(0, 2);
    lcd.print(emon1.Vrms);
    lcd.setCursor(7, 2);
    lcd.print("V");
    //Serial.print( " Voltage Normal" );
    digitalWrite(normal_led, HIGH); 
    digitalWrite(under_led, LOW); 
    digitalWrite(over_led, LOW); 
  }




void tiempo_reconexion() {
  if (timer.checkTimer()) {
    digitalWrite(contactor1, HIGH);

    //timer.setTimer //Recomiendo usar esto si tu accion al pasar el tiempo tiene muchas instrucciones
  }
}

Mira lo principal que debes entender es que la seccion setup() se ejecuta una sola vez cada vez que prendes el Arduino.

El resto del tiempo debes "permitir" que loop() corra libremente una y otra vez, simplemente preguntando si se cumplio el tiempo entre otras cosas.

void loop(){
  if (condicion de disparo){
     t = millis();
  }
  if(millis()-t == 3000 && t>0){
     //lo que corresponda
  }
}

"condicion de disparo" es lo que quieres que dispare el evento, por ejemplo pulsar un boton conectado al pin digital 2 con INPUT_PULLUP seria !digitaRead(2);

La primera vez que se corre t=0 entonces cuando transcurran 3000 ms tendras millis()=3000 y se cumplira la primera parte del 2 if pero no la segunda parte por lo que no pasara nada.

Luego que se cumpla la condicion de disparo tendra fijado t a un nuevo valor por ejempo 10000 y millis() ira incrementando hasta llegar a 13000 - 10000 = 3000 el tiempo fijado en mi ejemplo y como 10000 > 0 ahora si se ejecuta "lo que correspone"

Millis() simplemente vas a

Documentación => Indice de temas tutoriales => millis() y tienes 4 o 5 tutoriales.

hola un saludo disculpen que me halla tardado , pero vivo en Venezuela , tenemos otros tipo de problemas , luz, Internet , etc

todavía me confunde el uso de millis , y pude usar esta librería <RBD_Timer.h>, y funciona bien , pero quiero aprender a usar con millis voy a incluir parte del código para que tenga una idea. en vez de usar la libreria hacerlo en millis

Explico el proceso este código funciona como un protector de voltaje coloco mi tiempo de conexionar de 3 minutos , uso un sensor que me mide el voltaje de 110v / 220 de mi casa , uso las estructura if para poder medir los umbrales de voltaje 0v y 90v ocurre una desconexion y espera los 3 min para poder activar mi rele , la otra estructura if 90v y 135v es normal , la estructura if mayor a 135v apara rele y vuelve a espera los 3 min

saludos u abrazo

#include <RBD_Timer.h>
RBD::Timer timer;




void setup() {

  timer.setTimeout(180000); // Reconexion  3 min
  timer.restart();

}

void loop() {

  if ( (emon1.Vrms > 0)  &&  (emon1.Vrms < 90) )
  {

    timer.restart(); // si se cumple el if  apaga rele y reiniciar contador
    digitalWrite(rele, LOW);


  }

  if ( (emon1.Vrms >= 90)  &&  (emon1.Vrms <= 130) ) // si se cumple el if , llama fumcion void tiempo reconexion
  {
    tiempo_reconexion();
    digitalWrite(led_normal, HIGH);
  }


  if ( emon1.Vrms > 130 ) //si se cumple el  if,  apaga rele y reiniciar contador
  {
    timer.restart();
    digitalWrite(rele, LOW);
  }


}

void tiempo_reconexion() {
  if (timer.isExpired()) {
    digitalWrite(rele, HIGH);
    timer.restart(); //
  }
}

Si te confunde solo ve a a Documentación y lee el Indice de Temas Tutoriales => millis() todo lo concerniente al mismo. Tienes 4 o 5 visiones que supongo despejaran tus dudas. Hacerlo otra vez me parece un insulto a los compañeros que se tomaron la molestia de explicarlo con tantos ejemplos. Te los recomiendo.

ok gracias , solo que soy auto didacta y aveces tengo dudas que no las entiendo , ya me documentare

Hola, yo intentaría algo así

uint32_t lowVoltageT;
void setup() {
}
void loop() {
  if ((emon1.Vrms >= 90)  &&  (emon1.Vrms <= 130)) {
    uint32_t t = millis() - lowVoltageT;
    if (t  > 180000 || t < 0) {
      //hacer lo propio con tensión en rango por mas de 180 seg
    }
  }
  else  {
    // hacer lo propio cuando la tensión esta fuera de rango
    lowVoltageT = millis(); //setear cuando fue la última medición fuera de rango
  }
}

SALUDOS..

Ya pude entender el uso de millis , con el regaño de surbyte y la sugerencia de todos, pude resolver el problema , las librería en algún momento de tiene que usar .

gracias a todos

No lo tomes como regaño, si observas todos te respondieron con la misma idea => millis(). Entiendo tu situación pero es cuestión de leer y luego consultar si no se comprende.
Me alegro que lo hayas resuelto.