En esta entrada se comenzará la implementación el controlador siguiendo el paradigma de Máquina de Estados introducido anteriormente. Esto permite que las situaciones en las que se encuentra el programa (estados), se encuentren bien definidas evitando así, situaciones no esperadas que puedan saltarse el correcto funcionamiento del mismo produciendo incongruencias en los resultados.
Como se mencionó en la entrada anterior, se hará uso de la librería FSM implementada por Igor Real. Será necesario importarla usando el Arduino IDE y hay que tener claro el funcionamiento constante que sigue:
1) Leer eventos.
2) Actualizar la máquina de estado.
3) Ejecutar el comportamiento del estado.
4) Actualización de estados.
Lo primero que se necesita conocer es el diagrama de estados que se quiere implementar, en nuestro caso tendríamos:
Una vez definido el diagrama, en este caso se ha comenzado modificando el fichero myStates.h . A través de cuatro zonas bien diferenciadas es posible indicar cual será el funcionamiento que tendrá el programa:
1) Declaración de funciones: en esta parte se indican las funciones que van a ser llamadas dentro de los estados, esto se abordará más adelante.
2) Declaración del nombre de los estados y los eventos: en esta parte, se asigna un valor hexadecimal y a través de un mnemotécnico se establece el nombre del estado o el evento.
3) Estructuras descriptivas del diagrama de flujo: como se comentó en el primer punto, las funciones definidas van ligadas a un estado. Esto viene dado de la siguiente forma: {ESTADO, FUNCION}.
4) Transiciones entre estados: en esta última zona, se indican los cambios de estados y que evento es el que lo produce, la estructura que tiene es: {ESTADO_ACTUAL, EVENTO, ESTADO_SIGUIENTE}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #ifndef myStates_H #define myStates_H //Declaracion de las funciones extern void abrir(void); extern void cerrar(void); extern void verPlazas(void); extern void calibrar(void); extern void inicio(void); //Declaracion del nombre de ESTADOS y de EVENTOS #define STATE1 0x01 #define STATE2 0x02 #define STATE3 0x03 #define STATE4 0x04 #define STATE5 0x05 #define PETICION0 0x21 #define PETICION1 0x23 #define PETICION2 0x25 #define TIEMPO 0x42 // Estructuras descriptivas de mi diagrama de flujo const FSMClass::FSM_State_t FSM_State[] PROGMEM= { // STATE,STATE_FUNC {STATE1,inicio}, {STATE2,calibrar}, {STATE3,abrir}, {STATE4,cerrar}, {STATE5,verPlazas}, }; //Transiciones entre estados const FSMClass::FSM_NextState_t FSM_NextState[] PROGMEM= { // STATE,EVENT,NEXT_STATE {STATE1,PETICION0,STATE2}, {STATE2,0,STATE1}, {STATE1,PETICION1,STATE3}, {STATE3,0,STATE4}, {STATE4,0,STATE1}, {STATE1,PETICION2,STATE5}, {STATE5,0,STATE1}, }; //Macros para el cálculo de los tamaños de las estructuras #define nStateFcn sizeof(FSM_State)/sizeof(FSMClass::FSM_State_t) #define nStateMachine sizeof(FSM_NextState)/sizeof(FSMClass::FSM_NextState_t) #endif |
Una vez terminado de editar el archivo myStates.h, se comienza a modificar el fichero del controlador. Como no podría ser de otra forma, se añaden la librería FCM.h y el fichero myStates.h
En mi caso ha sido necesario modificar en el fichero FSM.cpp la línea #include "WProgram.h" y cambiarla por #include "Arduino.h".
En el setup se añade la siguiente línea:
1 | FSM.begin(FSM_NextState,nStateMachine,FSM_State,nStateFcn,STATE1); |
La idea es que el loop quede de la siguiente forma, ofreciendo el control del programa únicamente a las transiciones que definimos:
1 2 3 4 5 | void loop() { ReadEvents(); FSM.Update(); } |
En las funciones que llamamos es importante añadir un detalle al final para el correcto funcionamiento, este detalle viene dado por a siguiente línea:
1 | FSM.AddEvent(0);
|
Uno de los pasos más importantes es la función ReadEvents() en la cual se define como van cambiando los eventos que producen los cambios de estado:
1 2 3 4 5 6 7 8 9 10 11 | void ReadEvents(void){ myEvent=0; if(pos==0){ myEvent=PETICION0; }else if(pos==1 && plazasOcupadas<2 ){ myEvent=PETICION1; }else if(pos==2){ myEvent=PETICION2; } FSM.AddEvent(myEvent); } |
Para más información : https://github.com/iiotUHU/iiot
No hay comentarios:
Publicar un comentario