Perdido con millis

Salud@s....

he leído y buscado info sobre millis, pero a la hora de aplicarlo me vuelvo loco. Lo que pretendo es desactivar un relé y pasados 2 minutos desactivar otro relé, el problema es que no me aclaro con milis, y delay no me vale.

   if (tempDespacho >= tempDeseadaDespacho + histeresis  ){
            digitalWrite(releCaldera, LOW);
               
             ------ AQUÍ EL RETRASO DE 2 MINUTOS -------
       
            digitalWrite(releDespacho, LOW);
            }

Gracias y disculpar por la solicitud....

Hola nakuadak, no veo ningun millis en tu ejemplo, pero si pretendes el retraso dentro del 'if' no creo que pueda ser porque una de las caracteristicas de millis es que el programa continua, asi como esta es mas para un delay y esa no es la idea. ¿has buscado en la documentacion de este Foro?, es muy buena la explicacion de millis. Saludos.

Si luego de 5 o 6 tutoriales de millis() en Documentación => Indice de temas tutoriales => millis() no se entiende, la verdad estamos fritos.
Es mas, @victorjam ahora implementó ejercicios con millis().
Pero tienes el de max_saeta, de PeterKanTropus, noter, en inglés de UKHeliBob que es fabuloso y ahora de victorjam

Hola,

te recomiendo algo así:

int interval = 120000; // Cantidad de tiempo en milisegundos
int elapsed = 0;
bool flag_caldera = false;



void setup(){
	
	/* tu código de setup */
	
}


void loop(){

	if (tempDespacho >= tempDeseadaDespacho + histeresis  ){
		digitalWrite(releCaldera, LOW);
		flag_caldera = true;
	}

	if( flag_caldera == true ){
		unsigned long currentMillis = millis();
		if( currentMillis - elapsed > interval ){
                        elapsed = currentMillis;
			digitalWrite(releDespacho, LOW);
			flag_caldera = false;
		}
	}
	
	/* resto del código */
}

@hypernovat

muchas gracias por la aclaración del tema del IF.

@surbyte

el problema es que no sé programar, y del simple DELAY al los MILLIS hay una gran diferencia, y me cuesta, pero ahí vamos, sigo mirando cosas.

@MaxiCane

mil gracias, creo que explotaré tus líneas de código y a ver si consigo adaptarlo a mi programa.

Muchas gracias a todos. Un saludo.

nakuadak:
el problema es que no sé programar...

Tranquilo, eso lo solucionas con tiempo, deja por un momento tu problema coyuntural y como ya sabes que Millis es algo que aun no comprendes puedes "jugar" y programar solo con millis cosas simples, hasta que lo entiendas.

@hypernovat

gracias, estoy trasteando y si no tengo un IF de por medio consigo trabajar con milis, pero claro, cuando el programa se complica...bufffffff

@MaxiCane

gracias por la ayuda, lo he implementado en mi código, pero no me funciona. Más que nada porque para poder tener la caldera en marcha le digo que si hay una electroválvula abierta, no me cierre la caldera. Es un gran problema que no había comunicado, hasta que se me ha dado el caso. Así que en vez de ir a mejor, voy a peor, jajajaja

Adjunto mi código, por si os apetece echar una ojeada.

P.D.: Lo adjunto como archivo, me dice que me paso de 9000 palabras

caldera2.ino (15.5 KB)

Hola @nakuadak,

el problema es que no sé programar, y del simple DELAY al los MILLIS hay una gran diferencia, y me cuesta, pero ahí vamos, sigo mirando cosas.

No te preocupes, todos arrancamos sin saber programar alguna vez. Pero te recomiendo que leas algunos tutoriales básicos, porque por lo que veo, hay varios errores de concepto en el código.

Espero no lo tomes a mal, pero lo que te recomiendo es que vayas armando el código de a poco y probándolo. Es decir, si no sabes programar, desarrollar la lógica de un programa extenso puede generar muchos problemas, entonces lo ideal sería que vayas de a poco pero a paso firme.

También te recomiendo el uso de funciones, es más sencillo y prolijo que meter todo un código extenso dentro del loop().

Esta tarde me sentaré a ver tu código y intentar darte una mano.

Saludos y éxitos con tu proyecto!

Para nada me molesta, todo lo contrario, se agradece.

El programa es totalmente funcional, al menos para controlar la caldera y los radiadores de mi casa. Lo único que no me funciona es la última implementación por el tema de los millis....

Gracias por la ayuda.

@MaxiCane
También te recomiendo el uso de funciones, es más sencillo y prolijo que meter todo un código extenso dentro del loop().

No estoy de acuerdo con tu comentario pero el no estar de acuerdo no quiere decir que a ti no te funcione y a mi no.
Cuando veo un código con todo cargado en el loop siempre pienso que desordenado es esta persona. Claro.. nadie conoce mi taller y si vieran mi taller dirían que desordenado es surbyte. Son cosas distintas no?
Bien, a mi me gusta ver un loop corto donde se vean las cosas que hace el loop y entonces poder trabajar sobre las tareas a cumplir en forma individual e incluso mejorar su eficacia sin tener que perderme entre tantas líneas de código en un loop colmado de instrucciones.
Es lo mismo? Si lo es pero organizado de forma diferente.

Ahora bien.

@nakuadak no te hemos respondido porque tu pregunta no tiene contexto

Esto

 if (tempDespacho >= tempDeseadaDespacho + histeresis  ){
            digitalWrite(releCaldera, LOW);
               
             ------ AQUÍ EL RETRASO DE 2 MINUTOS -------
       
            digitalWrite(releDespacho, LOW);
            }

En que contexto lo preguntas, que hace el resto del programa?
No se puede usar millis() sinconsiderar lo demas. No es como bien has dicho como meter un delay(2x60*1000) y me despreocupo.

Qué hace el resto del código, no hay retardos.. bueno.
El tema de millis() obliga a que en algun momento tu almacenes el valor de millis() con el que empiezas a considerar tus 2 minutos. Cual es el momento? cuando tempDespacho supera tempDeseadaDespacho + Histeresis? Si es así entonces requieres de un flag
Uhhh que complicado!!! bueno asi son las cosas

Repasemos millis().
millis() es un cronómetro que expresa tiempo en milisegundos desde que arduino se energizó. O sea.. imagina que arrancas tu Arduino y ya esta corriendo millis().
Ahora se produce tu situación de tempDespacho que llamaré temp > teseada + H ahi debes almacenar el valor de millis()
y como haces eso....
Eso es facil pero si lo haces como a cada momento la condicion sigue siendo TRUE tu variable de comparacion de millis() se volverá a cargar y nunca podras hacer la diferencia para saber si han transcurrido 2 minutos.

Es lo mismo que en una pista de atletismo, supongamos que se inicial la carrera de 10km en ese momento (igual que la energización del Arduino) arranca tu cronometro (millis()), en cada vuelta tu quieres saber la diferncia entre corredores, como haces... pues cuand pasa tu corredor tomas el tiempo, ese tiempo lo guardas... y desde ahi esperas a que pase el otro corredor y le tomas el tiempo. Estableces la diferencia entre ambos y diras.. le lleva x segundos.
Aca es igual
Tu corredor es el evento que inicializa algo para cargar el estado de millis() en una variable que vas a conservar.
Mientras milis() sigue corriendo... y tu comparas el valor que almacenaste contra el de milis()
cuando la diferencia sea de 2601000 = 120000 mseg entonces dices.. Ahhh transcurrieron 2 minutos.

Voy a olvidarme del contexto como te dije. Si no funciona es tu problema por no hacer lo que ya te he pedido antes.
Supongo que esto lo estas pensando en un programa mas grande y te has atorado o estancado en esta parte.

vas a definir estas variables necesarias

bool flag = false;      // variable que controla la carga de millis() en la variable de almacenamiento start
unsigned long start;           // variable que almacena valor de milis() en el evento.

En tu código

 if (tempDespacho >= tempDeseadaDespacho + histeresis  ){
              if (digitalRead(releCaldera)) {  // si esta en 1 es porque aun no se actuo
                 start = millis();
              }
              digitalWrite(releCaldera, LOW);
              if (millis() - start > 120000UL) {
                  digitalWrite(releDespacho, LOW);
              }
            }

Ahora como no conozco el resto del código la condición que use en lugar del flag como te venía contando puede que no sirva

if (digitalRead(releCaldera)) {  // si esta en 1 es porque aun no se actuo

si por alguna razón releCaldera se acciona en HIGH en otra parte del código esto no va a funcionar porque de nuevo se va a accionar start = millis()

En ese caso lo mas lógico sería usar la variable flag boolean.

    if (tempDespacho >= tempDeseadaDespacho + histeresis  ){
        if (flag) {  // si esta en 1 es porque aun no se actuo
            digitalWrite(releCaldera, LOW);
            start = millis();
            flag = false;
        }      
        if (millis() - start > 120000UL) {
            digitalWrite(releDespacho, LOW);
        }
    }

faltaría que flag se vuelva a poner en true cuando se sale de la situacion tempDespacho >= tempDeseadaDespacho + histeresis

1 Like

Muchísimas gracias, me ha quedado muy claro. De todas formas a mi código no se puede aplicar de esa forma, por supuesto que faltaba daros información, es por eso que colgué el archivo con el código.
Me va a tocar reescribir todo el código para hacerlo más funcional, pero eso me va a costar una eternidad. Pero poco a poco. De momento mi código me vale, sólo que es mejorable......