MAQUINA DE ESTADOSLa gran mayoría del código del útil, se va a escribir en Python, este código va a estar estructurado como una máquina de estados finita, a continuación se expone lo que es una máquina de estados finita.
Una máquina de estados es un modelo de comportamiento de un sistema con entradas y salidas en dónde las salidas no dependen únicamente de las entradas actuales, sino que dependen también de las entradas anteriores. Se llama máquina de estados finita debido a que tiene un número de estados finito.
Esta máquina de estados, va a tener dos estados, un estado en el cual posicionaremos el servo, y otro estado en el que leeremos distancia. En estos estados, se realizan mas tareas, como reconocimiento de voz, salida de audio, publicación en los Topics del MQTT.
CODIGO
El código correspondiente a esta máquina de estados, se divide en dos partes, una primera en la que se definen todas las funciones del programa, y una segunda que se puede decir que es la máquina de estados en sí, en esta segunda parte: Se crean los estados, se establecen las transiciones de un estado a otro, se llaman a las distintas funciones, etc. A continuación se expone la parte del código que contiene las funciones.
Funciones (estados) FSM
En primer lugar, se importan todas las librerías que se van a utilizar en la máquina de estados, estas librerías, solamente será necesario importarlas en el sketch que contiene las funciones de la máquina de estados.
|
Estados fsm |
Las librerías que se importan son para distintas aplicaciones, como la representación de tiempos, el reconocimiento de voz, el control de los GPIO, salida de audio, publicación en MQTT, interactuar con el sistema operativo.
Estado 0 - Lectura sensor de ultrasonidos
|
Estado 0 |
En primer lugar, se configuran los GPIO que vamos a utilizar, en este caso, para este sensor, dos pines, el pin de trigger o disparo, y el pin de echo. El pin de trigger va a ser una salida, ya que será por donde se emita el pulso. El pin de echo, será una entrada ya que será por donde se reciba el rebote del pulso emitido por el trigger.
Dentro de un While true (bucle infinito), encontramos las líneas de código correspondientes a la lectura de distancia mediante el sensor de ultrasonidos. El funcionamiento de este sensor es bastante sencillo, por un lado se emite un pulso de ultrasonidos y se guarda el tiempo en el que se ha emitido el pulso. Por otro lado, recibe el rebote del pulso emitido y guarda el tiempo en el momento en el que se ha recibido el pulso, resta los dos tiempos y se obtiene el tiempo que ha tardado en ir, rebotar y volver. Sabiendo que la señal viaja a la velocidad del sonido, podemos saber la distancia aplicando al fórmula de distancia = (velocidad*tiempo)/2, se divide entre dos porque al medir el tiempo de ida y el de vuelta, se obtiene una lectura del doble de la distancia real.
|
Estado 0 |
La primera línea del código de la imagen superior, es la correspondiente a la publicación de la distancia en el MQTT. Por un lado, indicamos el topic en el que vamos a publicar, que en este caso es ('MQTT_DISTANCIA'), por otro lado indicamos el payload o carga, que es el valor de la variable distancia. Finalmente indicamos la IP donde se encuentra el MQTT, es la IP pública del router al que esta conectada la raspi con el servidor MQTT.
La función de este estado, devuelve un argumento, este argumento es el valor de la variable salida. Una vez publicamos un valor, se pone la variable salida a True y se sale del bucle, devolviendo el valor de la variable salida.
Estado 1- Posicionamiento del servo
|
Estado 1 |
En las líneas de código de la imagen superior, se muestra la función de posicionamiento del servo, en primer lugar, se llama a un archivo mp3, el cual solicita que se indique un numero entre 0 y 180. A continuación se abre el recurso que permite captar voz por medio del micrófono y almacenarla como texto, indicamos la posición y la almacena como tipo entero. En función del valor obtenido del reconocimiento de voz hace una cosa u otra, por ejemplo, si no te ha entendido, indica que ha ocurrido un error de lectura y te pide que lo intentes otra vez, en el caso de que se indique un valor superior a los límites del servo, lo indicara también, diciendo que posiciones el servo entre 0 u 180 grados. En el caso favorable de que te entienda y además el valor este entre 0 y 180 grados, se publicara en el topic 'MQTT_GRADOS_SERV' , el valor de la variable grados. Una vez publicado el valor de grados, se pondrá la variable salida en true y saldremos del bucle.
Sketch máquina de estados
A continuación se va a exponer el sketch de la máquina de estados finita.
|
Máquina de estados |
En el fragmento de código que se muestra en la imagen superior, se importan las librerías necesarias para el funcionamiento de la máquina de estados, como se puede ver no es necesario importar las librerías utilizadas en el sketch de los estados. La librería fysom es la necesaria para la creación de la máquina de estados, el sketch realizado previamente llamado 'estados_fsm', se importa en este programa como una librería mas. La variable salida, la inicializamos a False.
|
Máquina de estados |
En el fragmento de código que se muestra en la imagen superior, se definen todos los parámetros de la máquina de estados, como el estado inicial, el nombre de los estados, y la fuente y el destino de cada uno de los estados.
|
Máquina de estados |
El fragmento de código que se muestra en la imagen superior, es el correspondiente al estado uno de la máquina de estados, es decir, a la lectura de distancia por medio del sensor de ultrasonidos.
En primer lugar, mostramos en que estado se encuentra la máquina, a continuación llamamos a la función uno_dos, que si recordamos, se encuentra en el sketch 'estados_fsm' y es la correspondiente a la lectura de distancia por medio del sensor de ultrasonidos. El parámetro que devuelve esta función, lo guardamos en la variable salida y va a ser el valor de esta variable el que determine si se permanece en el estado o si se sale del mismo y se transiciona la siguiente. En caso de que la variable salida sea True, transicionamos al estado dos mediante la función UNO_DOS() de la máquina de estados.
|
Máquina de estados
|
El código que se muestra en la imagen superior es el correspondiente a el estado dos, es decir al posicionamiento del servo, como se puede ver es igual que el estado anterior. En las últimas líneas, podemos ver las instrucciones de salida, estas líneas son necesarias para cerrar correctamente el programa, cerrando los recursos correctamente.
Sketch ESP-32
A continuación se muestra el código correspondiente a la subscripción al topic 'MQTT_GRADOS_SERV' de MQTT en el cual se publicaba la posición en grados del servo. En este caso y con este sketch, nos vamos a subscribir para obtener la posición en la que se desea posicionar el servo para después posicionarlo.
|
Sketch ESP |
Como se muestra en las líneas de código de la imagen superior, se van a importar las librerías correspondientes para conectar el ESP 32 a la red wifi, para controlar el servo y para subscribirnos al topic. Vamos también a introducir las credenciales wifi de la red a la que nos vamos a conectar así como la dirección IP del dispositivo en el que se encuentra el MQTT. Si nos encontramos dentro de la misma red que el dispositivo, pondremos la IP local del mismo, si estamos conectados a una red distinta, lo que haremos será indicar la IP pública del router al que esta conectado el dispositivo, y como hemos visto anteriormente, el router gestiona a que dispositivo envía la orden que le enviemos. También en estas líneas, podemos ver la función de conexión a la red wifi (setup_wifi()).
|
Sketch ESP |
En la función callback() vemos si ha llegado algún mensaje, si el topic al que llega el mensaje es igual a 'MQTT_GRADOS_SERV' entonces guardamos el contenido de este mensaje como tipo int en la variable pos. Después con la función Write() de la librería Esp32Servo, enviaremos el servo a una posición igual al valor que se ha recogido en la variable pos.
|
Sketch ESP |
Finalmente en estas últimas líneas de código, lo que hacemos es llamar a las funciones definidas previamente como setup_wifi() o callback. Además, definimos el servidor al que vamos nos vamos a conectar. Para conectarnos debemos indicar el socket, es decir, la dirección IP más el puerto. El puerto para MQTT como se ha indicado anteriormente es el 1883.
Comentarios
Publicar un comentario