En esta entrada voy a tratar de sistematizar una forma de hacer los programas de Arduino basada en la teoría de autómatas finitos. Lo haré aplicándolo a la puerta de garaje y en concreto para la siguiente secuencia:
La puerta está cerrada, tocamos el pulsador y se va abriendo cuando toca el final de carrera de puerta abierta, la puerta se detiene.
Con la puerta abierta, tocamos el pulsador y se va cerrando, cuando toca el final de carrera de puerta cerrada, la puerta se detiene.
Para esa secuencia tenemos las siguientes entradas, salidas y estados:
Entradas: Pulsador, final de carrera de puerta cerrada (FCC) y final de carrera de puerta abierta(FCA).
Salidas: Motor parado, motor abriendo, motor cerrado.
Estados:Puerta cerrada, puerta abriéndose, puerta abierta, puerta cerrándose.
DIAGRAMA DE TRANSICIÓN DE ESTADOS.
Los estados los represento con círculos y junto a las flechas de las transiciones he dibujado un rectángulo dividido en dos celdas. En la superior en escrito la entrada que produce ese cambio de estado y en la inferior la salida correspondiente
PROGRAMA DE ARDUINO.
A partir del diagrama de transición se pasa al programa de Arduino con el selector SWITCH. Los CASE, son los estados y las transiciones se hacen con el selector IF en el que la condición es la entrada y en el bloque se incluye la salida y el cambio de estado/CASE.
Con la sentencia ENUM, se pone nombre a los estados. Para las salidas he usado funciones.
#define PinAv 9
#define PinRe 6
#define FCA 4 //Final de carrera puerta abierta
#define Pulsador 11 //Para iniciar las maniobras
#define FCC 2 //Final de carrera puerta cerrada
int antirrebotes = 200;
void setup()
{
pinMode(PinAv, OUTPUT);
pinMode(PinRe, OUTPUT);
pinMode(FCA, INPUT_PULLUP);
pinMode(Pulsador, INPUT_PULLUP);
pinMode(FCC, INPUT_PULLUP);
}
//MANIOBRAS DEL MOTOR
void motor_abriendo(){
digitalWrite(PinAv, HIGH);
digitalWrite(PinRe, LOW);}
void motor_cerrando(){
digitalWrite(PinAv, LOW);
digitalWrite(PinRe, HIGH);}
void motor_parado(){
digitalWrite(PinAv, LOW);
digitalWrite(PinRe, LOW);}
enum {puertaCerrada, puertaAbriendose, puertaAbierta, puertaCerrandose};
int estado = puertaCerrada; //El programa empieza con la puerta //cerrada
void loop(){
switch (estado){
case puertaCerrada:
if (digitalRead(Pulsador) == 0 ){
delay(antirrebotes);
motor_abriendo();
estado= puertaAbriendose;}
break;
case puertaAbriendose:
if (digitalRead(FCA) == 0){
delay(antirrebotes);
motor_parado();
estado= puertaAbierta;}
break;
case puertaAbierta:
if (digitalRead(Pulsador) == 0)
{delay(antirrebotes);
motor_cerrando();
estado= puertaCerrandose;}
break;
case puertaCerrandose:
if (digitalRead(FCC)==0){
motor_parado();
delay(antirrebotes);
estado= puertaCerrada;}
break;
}}
DETALLE DE LAS CONEXIONES ELÉCTRICAS
Conexiones eléctricas
Hay algún ligero cambio entre los cableados de la foto y del plano.
MÁS DIAGRAMAS DE ESTADOS QUE CORRESPONDEN A OTRAS FUNCIONALIDADES DE LA PUERTA,
OBSERVACIONES
El motor que aparece en la foto y el video es distinto a de la entrada anterior. Lo he tenido que sustituir por que el con otro se producía un fenómeno denominado ruido eléctrico que afectaba al Arduino evitando que funcionara correctamente.
No hay comentarios:
Publicar un comentario