switch-case-maquina-estados-arduino

Hasta ahora la “reacción” o comportamiento de los ejemplos que hemos programado venía dada por una cierta entrada o condición. Hasta ahora cuanto teníamos hambre comíamos, cuando teníamos sueño dormíamos y cuando apretábamos el pulsador movíamos el ascensor (movíamos un servo, pero imaginación que no falte).

El problema es que no siempre que tenemos sueño podemos dormir, y no siempre que llamemos al ascensor éste podrá responder. Depende del lugar y situación en qué estemos, podremos o no dormirnos; depende de en qué piso esté el ascensor, o si está ocupado por otra persona de que pueda venir a buscarnos a nuestro piso. Esto es precisamente una máquina de estados.

Una máquina de estados es un programa que reacciona no solo en función de las entradas que tiene, sino también del estado en que se encuentra. A partir de ahora no solo evaluaremos el sueño que tengamos, sino el lugar y situación en que estemos, ¡ya no nos dormiremos en la escuela ni en el trabajo!

Un diagrama de estados es un esquema gráfico de una máquina de estados donde se representan los estados y las condiciones para pasar de un estado a otro. Normalmente se representa mediante texto y números, pero para simplificarlo hemos hecho un diagrama ilustrado de estados. Puedes ver los tres estados del Profesor Dante: estado despierto, estado dormido y… ¡hombre lobo! Las flechas representan los cambios de un estado a otro, y la condición que se tiene que cumplir para este cambio: luna llena, día o noche.
arduino-maquina-de-estados

Para entender cómo programarlo vamos verlo sobre un ejemplo: programar una lavadora. Tranquilo, vamos a recrear un modelo simplificado así que no tienes que preocuparte por mezclar ropa blanca y ropa de color.

¿Cómo funciona nuestra máquina de estados?

Nuestra lavadora tendrá tres estados: Standby, Lavado y Centrifugado. Esta lavadora funciona solo con un botón, depende en que estado estemos el resultado de pulsarlo será uno:

  1. Standby. Estado de pausa. Nuestra lavadora estará quieta. Cuando pulsemos un botón pasará al estado de Lavado.
  2. Lavado. Nuestra lavadora empieza a girar y ejecutará el programa de lavado. En este caso cuando pulsemos el botón podremos ir el sentido de giro. Cuando acabe el tiempo de lavado la máquina dejara de girar unos segundos y pasará al estado de Centrifugado.
  3. Centrifugado. Aquí hemos innovado un poco y nuestra lavadora girará a trompicones, para sacudir bien la ropa. Si pulsamos el botón acabará el programa y volverá al estado de Standby.

Como puedes ver, una misma entrada (nuestro botón) tendrá diferentes consecuencias dependiendo del estado en que nos encontramos. Una máquina de estados se puede programar de varias formas, pero vamos a aprovechar a estudiar la estructura Switch case.

Switch case

El Switch case es una estructura de control que nos permitirá ejecutar un fragmento de código u otro en función del valor de una variable de nuestra elección. Esto ya podíamos hacerlo con sentencias condicionales if-else, pero esta nueva estructura nos lo va a facilitar. Veamos la sintaxis básica:

  • En función del valor de variable entrará en uno de los case y ejecutará lo que haya a continuación saltándose todo lo anterior.
  • Si variable = valor3, se saltará todo lo que haya antes de “case valor3:“, y ejecutará a partir de este punto hasta el final.
  • Si nosotros lo que queremos es que solamente ejecute el “case valor3″, sin llegar al que haya en el “case valor4″ tendremos que decirle que pare. Para ello utilizamos la sentencia break;. Al ejecutarse, cuando encuentre la sentencia break; saldrá fuera de la estructura switch (fuera de las llaves {}).
  • ¿Y qué pasa si la variable toma un valor que no se contempla en ninguno de los case? En principio nada, simplemente no se cumple la condición y no ejecutará nada. En muchos casos nos puede interesar introducir un caso de error, para esto podemos utilizar la sentencia default, que ejecutará en caso de no cumplirse ninguno de los casos.
OJO

RECUERDA: Si nuestra variable es numérica pondremos “case número:“, por ejemplo “case 5:“, pero si nuestra variable es de tipo char tendremos que poner el carácter entre comillas simples (”): “case ‘caracter':“, por ejemplo, “case ‘C':“.

Modelo de la lavadora

Para recrear el modelo que hemos descrito al principio y comprobar su funcionamiento vamos a usar:

  • Placa Zum Core.
  • Un servo de rotación continua (conectado al pin digital 6).
  • Un pulsador (conectado al pin digital 3).

servo-rotacion-continua

Para identificar nuestros estados en el código vamos a utilizar los números: 1 = Standby, 2 = Lavado y 3 = Centrifugado de forma que nuestro código quedará estructurado de la siguiente forma:

Vamos a desgranar un poco lo que ocurrirá en cada estado, pero antes sería conveniente que repases las lecciones sobre Servo de rotación contínua, y la lección sobre el Bucle While y el pulsador.

  • El estado 1 es el más sencillo de programar, solamente tenemos que leer el pulsador y esperar hasta que se pulse, cuando se pulsa, cambiamos el estado al estado 1, Lavado:
  • El estado 2 es un poco más complejo. Tenemos que medir el tiempo y a la vez leer el pulsador. Si se pulsa, el sentido de giro se invierte. Una vez acabado el tiempo se para la lavadora 1 segundo y luego se cambia al siguiente estado.
  • El estado 3 se programa para que cada segundo invierta el sentido de giro, así se mantendrá hasta que lo paremos y pongamos el sistema en Standby pulsando el botón.

Recuerda que para utilizar los servos debes incluir la librería Servo.h y que las variables para medir el tiempo deben ser unsigned long (las variables tic y toc). Si tienes alguna duda puedes descargar el código completo en la sección de descargas.

Ya estás listo para usar de manera efectiva las máquinas de estado y los switch case. No siempre es malo dejar que las reacciones se vean influidas por el estado de ánimo.