EXTRACTO:
El autor propopone una manera sencilla de usar un soft-delay para cambiar los estados de una maquina de estados finitos, sin necesidad de librerias o descargas extras.
Bueno, me encuentro trabajando en dos proyectos que hacen necesario y extensivo el uso de maquinas de estados finitas, Normalmente las escribo como una lista en el Swtich /case y pongo condicionales para ir a la parte del programa que quiero usar, no he tenido mayores problemas.
El problema me vino hoy cuando me di cuenta de que la maquina de estados se efectuaria demasiado rapido (no me mal entiendan, debe ser muy rapida) lo que no debe ser tan rapido es la activación de relevadores mecanicos y cambios en el sistema.
Un ejemplo sencillo:
void setup() {
// put your setup code here, to run once:
}
void loop() {
void maquina();
}
void maquina()
{
switch(var):
case 0: Serial.println("Maquina en estado 0");
var = 1;
break;
case 1: Serial.println("Maquina en estado 1");
var = 2;
break;
case 2: Serial.println("Maquina en estado 1");
var = 0;
break;
}
Entonces, digamos que necesitamos que entre el estado 0 y el 1 haya un retardo de 3 segundos,
normalmente meteremos un if(millis() - tiempo < delay), y una vez que expire cambiamos la variable a la siguiente.
Este proceso reuqueriria de muchas lineas de codigo, asi que me he escrito una función que toma el delay para hacer el cambio entre una y otra variable, de manera automatica;
byte var = 0;
byte var_2 = 0;
unsigned long var_time = 0;
unsigned long var_delay = 3000UL;
void setup()
{
Serial.begin(9600);
Serial.println("inciando programa");
}
void loop() {
switch (var_2)
{
case 0:
Serial.println("Maquina en estado 0");
var_2 = changueVar(var, 1);
//var_time = millis();
break;
case 1:
Serial.println("Maquina en estado 1");
var_2 = changueVar(var, 2);
break;
case 2:
Serial.println("Maquina en estado 2");
var_2 = changueVar(var, 3);
break;
case 3:
Serial.println("Maquina en estado 3");
changueVar(var, 1);
break;
}
}
byte changueVar(byte var, byte n_var)
{
static bool first_time = true;
if(first_time == true)
{
//Serial.println("Estamos en el true");
if(n_var != var) var_time = millis(); //Serial.println("tomamos el tiempo");
first_time = false;
}
if(millis() - var_time < 3000UL)
{
//Serial.print("Millis "); Serial.println(millis());
//Serial.print("var time "); Serial.println(var_time);
//Serial.print("diferencia "); Serial.println(millis()-var_time);
//Serial.println("el timmer no se cumple ");
return var;
}
else
{
Serial.println("Se cumplio el timmer");
first_time = true;
return n_var;
}
}
De esta manera me es mucho mas rapido, es reutilizable y debido a que no requiere librerías, podemos usarlo cuando nos de la gana.
Con un poco mas de trabajo se puede evitar que se "re-imprima" el serial print, o lo que es lo mismo, si ya paso el estado anterior, no hacer nada hasta que expire el timmer, haciendo la espera, sin encender o apagar nada, pero de momento me funciona como esta.
Se los dejo por que me ha costado un poco implementarlo, y les puede ahorrar algo de tiempo.
-Alex.