Millis() funcion

Hola buenas, queria hacer funcionar una lavadora sin LCD, lo he diseñado implementando el método de máquina de estados/GRAFCET. Las primeras etapas que transitan con la acción del pulsador, selector.. Sin embargo en la etapa 4 que ya irían transiciones con tiempo, no consigo que transite. He programado dos funciones(ya que dos temporizadores) para la activación y reseteo. He probado establecer las funciones antes del void loop y nada, y despues del void loop tampoco hay resultado.
Os adjunto el código haber si sois capaces de echarme una mano que llevo una semana intentando poner en marcha el proyecto y no soy capaz:

//Asigno un nombre a las variables de entrada asociadas a cada pin 

int M=2; 
int P=3; 
int EM=4; 
int SELECTOR=5;
int TERMOSTATO=6; 
int PRESOSTATO=7;


//Designo variables donde invertiré el valor de la entrada, ya que la placa conversora 24V to 5V utiliza lógica inversa

int MARCHA;
int PARO;
int SETA;
int FC;
int TERM;
int PRES;


//Asigno un nombre a las variables de salida asociadas a cada pin 

int DER= 8; 
int IZQ=9; 
int CENT=10; 
int VACIO=11; 
int CAL=12; 
int EV=13;


//Defino las etapas de mi proceso

int E0;
int E1;
int E2;
int E3;
int E4;
int E5;
int E6;
int E7;
int E8;
int E9;
int E10;
int E11;
int E12;
int E13;

//Declaración variables del temporizador 1

int activado1;
unsigned long actual1;
unsigned long final1;
unsigned long inicio1;
int T1;

//Declaración variables del temporizador 2

int activado2;
unsigned long actual2;
unsigned long final2;
unsigned long inicio2;
int T2;

                                 //Establecemos la configuración incial del programa, este solo se ejecutará una vez, en el arranque
void setup() {
   Serial.begin(9600);           //Abro monitor serie                    
pinMode(MARCHA,INPUT);          //Asigno a los pines la configuración de entradas
pinMode(PARO,INPUT);
pinMode(SETA,INPUT);
pinMode(FC,INPUT);
pinMode(TERM,INPUT);
pinMode(PRES,INPUT);
                                //Asigno a los pines la configuración de salidas
pinMode(DER,OUTPUT);
pinMode(IZQ,OUTPUT); 
pinMode(CENT,OUTPUT); 
pinMode(VACIO,OUTPUT); 
pinMode(CAL,OUTPUT);
pinMode(EV,OUTPUT);
                                //Asigno un valor inicial a las salidas, esto lo hacemos para evitar que se activen todos los relés al iniciar el programa
digitalWrite(DER,HIGH);          //El módulo de relés usado, utiliza lógica inversa, por lo que en estado high se encuentra activado
digitalWrite(IZQ,HIGH);
digitalWrite(CENT,HIGH);
digitalWrite(VACIO,HIGH);
digitalWrite(CAL,HIGH);
digitalWrite(EV,HIGH); 
                              // Estado inicial de las etapas
E0=HIGH;                       // Es la etapa inicial, debe estar activa en el arranque del programa
E1=LOW;
E2=LOW;
E3=LOW;
E4=LOW;
E5=LOW;
E6=LOW;
E7=LOW;
E8=LOW;
E9=LOW;
E10=LOW;
E11=LOW;
E12=LOW;
E13=LOW;
}


void loop() {
 
MARCHA=!digitalRead(2); PARO=!digitalRead(3); SETA=!digitalRead(4); //Leo estado inicial de las etapas al inicio del programa y guardo su valor inverso en unas marcas con la que operare después

FC=!digitalRead(5); TERM=!digitalRead(6); PRES=!digitalRead(7);

//Establezco las ecuaciones de cada etapa

E0=((E0|(E13&T2&SETA))&(~E1));
E1=((E1|(E0&MARCHA&SETA))&(~E2)&(~E3));
E2=((E2|(E1&FC&SETA)|(E3&TERM&~SETA))&(~E4));
E3=((E3|(E1&~FC&SETA))&(~E2));
E4=((E4|(E2&~PRES&SETA))&(~E5));
E5=((E5|(E4&T1&SETA))&(~E6));
E6=((E6|(E5&T2&SETA))&(~E7));
E7=((E7|(E6&T1&SETA))&(~E8));
E8=((E8|(E7&T2&SETA))&(~E9));
E9=((E9|(E8&T1&SETA))&(~E10));
E10=((E10|(E9&T2&SETA))&(~E11));
E11=((E11|E10&T1&SETA)&(~E12));
E12=((E12|(E11&T2&SETA))&(~E13));
E13=((E13|(E12&PRES&SETA))&(~E0));





                                //Activación de componentes en función de la etapa que nos encontremos 
if(E0==HIGH){
Serial.println("etapa 0");
}
  if(E1==HIGH){
    Serial.println("etapa 1");
  }

  
  //Llenado de lavadora 
if(E2==HIGH){

Serial.println("etapa 2"); 
}


//Calentamiento previo de agua que entrará al tambor
if(E3==HIGH){
  
 Serial.println("etapa 3");
}
//FUNCIÓN DE LAVADO

//Giro del motor a derechas durante 5 segundos

if(E4==HIGH){
   actemp1();                 //Inicia la subrutina de temporización 1
   Serial.println("etapa 4");
  
  }
  else {
    destemp1();
    }
 //Paro del motor durante 10 segundos
 
  if(E5==HIGH){ 
    actemp2();                 
Serial.println("etapa 5");

}
else{
 destemp2();
}
//Giro del motor a izquierdas durante 5 segundos
  if(E6==HIGH){
     actemp1();                   //Inicia la subrutina de temporización 1
    Serial.println("etapa 6");
    
  }
  else {
    destemp1();
  }

 //Parada del motor durante 10 segundos
 
if(E7==HIGH){
 actemp2();                       //Inicia la subrutina de temprización 2
Serial.println("etapa 7"); 
}
else{
  destemp2();
}
//Giro a derechas durante 5 segundos 

if(E8==HIGH){
  actemp1();                     //Inicia la subrutina de temporización 1                  
 Serial.println("etapa 8");
 
}
else{
  destemp1();
}
//Parada motor durante 10 segundos 
if(E9==HIGH){
   actemp2();                   //Inicia la subrutina de temprización 2
   Serial.println("etapa 9");
   
  }
  else{
    destemp2();
  }
 //Giro del motor a izquierdas durante 5 segundos
 
 if(E10==HIGH){
 actemp1();                 //Inicia la subrutina de temporización 1
Serial.println("etapa 10");

}
else{
    //Resetea el temporizador 1
destemp1();
}
 //Parada de motor durante 10 segundos
if(E11==HIGH){
actemp2();                       //Inicia la subrutina de temprización 2
Serial.println("etapa 11");

}
else{
  destemp2();
}
//Vaciado de tambor a través de la bomba de vacío 

if(E12==HIGH){
  
 Serial.println("etapa 12");
}

//CENRTRIFUGADO 
//A la vez se activará la bomba de vacio para secar la ropa durante 10 segundos
if(E13==HIGH){
   actemp2();
   Serial.println("etapa 13");
   
  }
  else{
   destemp2();
  }
}

  void actemp1(){
 if ((E4==HIGH|E6==HIGH|E8==HIGH|E10==HIGH)&&activado1==0){   //Si estoy en alguna etapa donde se necesita el temporizador y el bit de marca no está activado
  activado1=1;                                             //Activo el bit de marca
  inicio1=millis();      //Guardo el tiempo de programa en la variable inicio1
  final1=inicio1+5000;   //Establezco que el final1 tiene que ser el tiempo de programa más 5000 milisegundos(5 segundos)
 }
 actual1=millis();    //Consulta el tiempo actual
 if (activado1==1 &&(actual1>final1)){       //Si el tiempo actual supera al final, y el bit de marca esta activo 
  T1=HIGH;                                  //Activa el temporizador
 }
 else {
  T1=LOW;                                   //Desactiva el temporizador
 }
}

//Subrutina para reinicio de variables del temporizador y desactivación

void destemp1(){
  T1=LOW;
  activado1=0;
  inicio1=0;
  final1=0;
  actual1=0;
}
void actemp2(){
 if ((E5==HIGH|E7==HIGH|E9==HIGH|E11==HIGH|E13==HIGH)&&activado2==0){   //Si estoy en alguna etapa donde se necesita el temporizador y el bit de marca no está activado
  activado2=1;                                             //Activo el bit de marca
  inicio2=millis();      //Guardo el tiempo de programa en la variable inicio1
  final2=inicio2+5000;   //Establezco que el final1 tiene que ser el tiempo de programa más 5000 milisegundos(5 segundos)
 }
 actual2=millis();    //Consulta el tiempo actual
 if (activado2==1 &&(actual2>final2)){       //Si el tiempo actual supera al final, y el bit de marca esta activo 
  T2=HIGH;                                  //Activa el temporizador
 }
 else {
  T2=LOW;                                   //Desactiva el temporizador
 }
}

//Subrutina para reinicio de variables del temporizador y desactivación

void destemp2(){
  T2=LOW;
  activado2=0;
  inicio2=0;
  final2=0;
  actual2=0;
}`Texto preformateado`

Que complicado lo has hecho!!!!!!! Por favor.
Una máquina de estados se puede programar de forma mas simple al menos para mi gusto.
Ya tienes los estados que son E0 a E13 pero me quedo con el número asi que uso una variable que llamo estado
luego en el loop solo cambio de estado cuando se cumpla cierta condición.

while(estado) {
     case 0: // primer estado y su lógica
                      if (condición) 
                           estado = 1;
                     break;
     case 1: // segundo estado
                  if (condicion2 == 1) 
                       estado = 4;
                  break;

Ve a Documentación y lee sobre máquina de estados.

En las condiciones del programa resulta dificil aconsejarte sobre que puede ocurrir con millis().
Ahora lo miro y si no respondes edito este mismo post.

CONSEJO:
Lo primero que te voy a pedir es que presentes un código ordenado. Usa el autoformat del IDE para que nosotros podamos leer tu código con facilidad. Resulta tedioso tener que ordenarlo para entenderlo. Lo digo constructivamente.

Analizo esta parte de código

  //Giro del motor a derechas durante 5 segundos

  if (E4 == HIGH) {
    actemp1();                 //Inicia la subrutina de temporización 1
    Serial.println("etapa 4");

  }
  else {
    destemp1();
  }

Lo primero que veo es que tu rutina ejecuta en cada loop una de dos cosas o actemp1() o destemp1(). Eso es raro.
Porque destemp1 inicializa variables y me llama la atención que requieras en cada loop iniciarlizarlas.

void actemp1() {
  if ((E4 == HIGH | E6 == HIGH | E8 == HIGH | E10 == HIGH) && activado1 == 0) { //Si estoy en alguna etapa donde se necesita el temporizador y el bit de marca no está activado
    activado1 = 1;                                           //Activo el bit de marca
    inicio1 = millis();    //Guardo el tiempo de programa en la variable inicio1
    final1 = inicio1 + 5000; //Establezco que el final1 tiene que ser el tiempo de programa más 5000 milisegundos(5 segundos)
  }
  actual1 = millis();  //Consulta el tiempo actual
  if (activado1 == 1 && (actual1 > final1)) { //Si el tiempo actual supera al final, y el bit de marca esta activo
    T1 = HIGH;                                //Activa el temporizador
  }
  else {
    T1 = LOW;                                 //Desactiva el temporizador
  }
}

En tu rutina actemp1 me encuentro con que inicias bien millis() con activado pero jamas desactivas si se cumple la condición de tiempo. En algun punto debes bloquear al temporizador.
algo como

activado1 = 0;

Ahora bien pones T1 = HIGH siempre y cuando se cumple la condición del temporizador y entonces supongo que las instrucciones con los polinomios de Boole son los que deciden que pasará o no. Complicado de seguir para mi gusto.
Cuando no se cumple pones T1 = LOW o sea lo mismo que con destemp1().

Sorry, me pierde tu forma de programar.

Dejo el código autoformateado para quien tenga ganas de verlo.

#include <Wire.h>
//Asigno un nombre a las variables de entrada asociadas a cada pin

int M = 2;
int P = 3;
int EM = 4;
int SELECTOR = 5;
int TERMOSTATO = 6;
int PRESOSTATO = 7;


//Designo variables donde invertiré el valor de la entrada, ya que la placa conversora 24V to 5V utiliza lógica inversa

int MARCHA;
int PARO;
int SETA;
int FC;
int TERM;
int PRES;


//Asigno un nombre a las variables de salida asociadas a cada pin

int DER = 8;
int IZQ = 9;
int CENT = 10;
int VACIO = 11;
int CAL = 12;
int EV = 13;


//Defino las etapas de mi proceso

int E0;
int E1;
int E2;
int E3;
int E4;
int E5;
int E6;
int E7;
int E8;
int E9;
int E10;
int E11;
int E12;
int E13;

//Declaración variables del temporizador 1

int activado1;
unsigned long actual1;
unsigned long final1;
unsigned long inicio1;
int T1;

//Declaración variables del temporizador 2

int activado2;
unsigned long actual2;
unsigned long final2;
unsigned long inicio2;
int T2;

//Establecemos la configuración incial del programa, este solo se ejecutará una vez, en el arranque
void setup() {
  Serial.begin(9600);           //Abro monitor serie
  pinMode(MARCHA, INPUT);         //Asigno a los pines la configuración de entradas
  pinMode(PARO, INPUT);
  pinMode(SETA, INPUT);
  pinMode(FC, INPUT);
  pinMode(TERM, INPUT);
  pinMode(PRES, INPUT);
  //Asigno a los pines la configuración de salidas
  pinMode(DER, OUTPUT);
  pinMode(IZQ, OUTPUT);
  pinMode(CENT, OUTPUT);
  pinMode(VACIO, OUTPUT);
  pinMode(CAL, OUTPUT);
  pinMode(EV, OUTPUT);
  //Asigno un valor inicial a las salidas, esto lo hacemos para evitar que se activen todos los relés al iniciar el programa
  digitalWrite(DER, HIGH);         //El módulo de relés usado, utiliza lógica inversa, por lo que en estado high se encuentra activado
  digitalWrite(IZQ, HIGH);
  digitalWrite(CENT, HIGH);
  digitalWrite(VACIO, HIGH);
  digitalWrite(CAL, HIGH);
  digitalWrite(EV, HIGH);
  // Estado inicial de las etapas
  E0 = HIGH;                     // Es la etapa inicial, debe estar activa en el arranque del programa
  E1 = LOW;
  E2 = LOW;
  E3 = LOW;
  E4 = LOW;
  E5 = LOW;
  E6 = LOW;
  E7 = LOW;
  E8 = LOW;
  E9 = LOW;
  E10 = LOW;
  E11 = LOW;
  E12 = LOW;
  E13 = LOW;
}


void loop() {

  MARCHA = !digitalRead(2); PARO = !digitalRead(3); SETA = !digitalRead(4); //Leo estado inicial de las etapas al inicio del programa y guardo su valor inverso en unas marcas con la que operare después

  FC = !digitalRead(5); TERM = !digitalRead(6); PRES = !digitalRead(7);

  //Establezco las ecuaciones de cada etapa

  E0 = ((E0 | (E13 & T2 & SETA)) & (~E1));
  E1 = ((E1 | (E0 & MARCHA & SETA)) & (~E2) & (~E3));
  E2 = ((E2 | (E1 & FC & SETA) | (E3 & TERM & ~SETA)) & (~E4));
  E3 = ((E3 | (E1 & ~FC & SETA)) & (~E2));
  E4 = ((E4 | (E2 & ~PRES & SETA)) & (~E5));
  E5 = ((E5 | (E4 & T1 & SETA)) & (~E6));
  E6 = ((E6 | (E5 & T2 & SETA)) & (~E7));
  E7 = ((E7 | (E6 & T1 & SETA)) & (~E8));
  E8 = ((E8 | (E7 & T2 & SETA)) & (~E9));
  E9 = ((E9 | (E8 & T1 & SETA)) & (~E10));
  E10 = ((E10 | (E9 & T2 & SETA)) & (~E11));
  E11 = ((E11 | E10 & T1 & SETA) & (~E12));
  E12 = ((E12 | (E11 & T2 & SETA)) & (~E13));
  E13 = ((E13 | (E12 & PRES & SETA)) & (~E0));





  //Activación de componentes en función de la etapa que nos encontremos
  if (E0 == HIGH) {
    Serial.println("etapa 0");
  }
  if (E1 == HIGH) {
    Serial.println("etapa 1");
  }


  //Llenado de lavadora
  if (E2 == HIGH) {

    Serial.println("etapa 2");
  }


  //Calentamiento previo de agua que entrará al tambor
  if (E3 == HIGH) {

    Serial.println("etapa 3");
  }
  //FUNCIÓN DE LAVADO

  //Giro del motor a derechas durante 5 segundos

  if (E4 == HIGH) {
    actemp1();                 //Inicia la subrutina de temporización 1
    Serial.println("etapa 4");

  }
  else {
    destemp1();
  }
  //Paro del motor durante 10 segundos

  if (E5 == HIGH) {
    actemp2();
    Serial.println("etapa 5");

  }
  else {
    destemp2();
  }
  //Giro del motor a izquierdas durante 5 segundos
  if (E6 == HIGH) {
    actemp1();                   //Inicia la subrutina de temporización 1
    Serial.println("etapa 6");

  }
  else {
    destemp1();
  }

  //Parada del motor durante 10 segundos

  if (E7 == HIGH) {
    actemp2();                       //Inicia la subrutina de temprización 2
    Serial.println("etapa 7");
  }
  else {
    destemp2();
  }
  //Giro a derechas durante 5 segundos

  if (E8 == HIGH) {
    actemp1();                     //Inicia la subrutina de temporización 1
    Serial.println("etapa 8");

  }
  else {
    destemp1();
  }
  //Parada motor durante 10 segundos
  if (E9 == HIGH) {
    actemp2();                   //Inicia la subrutina de temprización 2
    Serial.println("etapa 9");

  }
  else {
    destemp2();
  }
  //Giro del motor a izquierdas durante 5 segundos

  if (E10 == HIGH) {
    actemp1();                 //Inicia la subrutina de temporización 1
    Serial.println("etapa 10");

  }
  else {
    //Resetea el temporizador 1
    destemp1();
  }
  //Parada de motor durante 10 segundos
  if (E11 == HIGH) {
    actemp2();                       //Inicia la subrutina de temprización 2
    Serial.println("etapa 11");

  }
  else {
    destemp2();
  }
  //Vaciado de tambor a través de la bomba de vacío

  if (E12 == HIGH) {

    Serial.println("etapa 12");
  }

  //CENRTRIFUGADO
  //A la vez se activará la bomba de vacio para secar la ropa durante 10 segundos
  if (E13 == HIGH) {
    actemp2();
    Serial.println("etapa 13");

  }
  else {
    destemp2();
  }
}

void actemp1() {
  if ((E4 == HIGH | E6 == HIGH | E8 == HIGH | E10 == HIGH) && activado1 == 0) { //Si estoy en alguna etapa donde se necesita el temporizador y el bit de marca no está activado
    activado1 = 1;                                           //Activo el bit de marca
    inicio1 = millis();    //Guardo el tiempo de programa en la variable inicio1
    final1 = inicio1 + 5000; //Establezco que el final1 tiene que ser el tiempo de programa más 5000 milisegundos(5 segundos)
  }
  actual1 = millis();  //Consulta el tiempo actual
  if (activado1 == 1 && (actual1 > final1)) { //Si el tiempo actual supera al final, y el bit de marca esta activo
    T1 = HIGH;                                //Activa el temporizador
  }
  else {
    T1 = LOW;                                 //Desactiva el temporizador
  }
}

//Subrutina para reinicio de variables del temporizador y desactivación

void destemp1() {
  T1 = LOW;
  activado1 = 0;
  inicio1 = 0;
  final1 = 0;
  actual1 = 0;
}

void actemp2() {
  if ((E5 == HIGH | E7 == HIGH | E9 == HIGH | E11 == HIGH | E13 == HIGH) && activado2 == 0) { //Si estoy en alguna etapa donde se necesita el temporizador y el bit de marca no está activado
    activado2 = 1;                                           //Activo el bit de marca
    inicio2 = millis();    //Guardo el tiempo de programa en la variable inicio1
    final2 = inicio2 + 5000; //Establezco que el final1 tiene que ser el tiempo de programa más 5000 milisegundos(5 segundos)
  }
  actual2 = millis();  //Consulta el tiempo actual
  if (activado2 == 1 && (actual2 > final2)) { //Si el tiempo actual supera al final, y el bit de marca esta activo
    T2 = HIGH;                                //Activa el temporizador
  }
  else {
    T2 = LOW;                                 //Desactiva el temporizador
  }
}

//Subrutina para reinicio de variables del temporizador y desactivación

void destemp2() {
  T2 = LOW;
  activado2 = 0;
  inicio2 = 0;
  final2 = 0;
  actual2 = 0;
}`Texto preformateado`
1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.