Desarrollar un proyecto con microcontrolador puede ser hecho de muchas formas o maneras. Cada programador o grupo de programadores usara probablemente la forma mas adecua a su manera de trabajar. En los ultimos años, esta tomando popularidad el lenguaje UML o Lenguaje Unificado de Modelage, como metodo de programacion para proyectos basados en microcontroladores. Algunos compiladores, ya ofrecen herramientas para este lenguje, como el compilador de la empresa iar, ofreciendo soporte a los diagramas y maquinas de estado, que son uno de los diagramas usados en la lenguaje uml.
Para tener una idea general de lo que puede ser un proyecto con microcontrolador, sin usar el lenguaje UML (Unified Modeling Lenguage) o un método similar, es comparable a quien quiere construir un edificio y no hace uso de un arquitecto para dar forma al edificio. También es comparable, a quien quiere hacer una pieza mecánica y no hace antes un plano, dibujo o diagrama de esa pieza. Se puede decir que el lenguaje UML es como la arquitectura o plano de un proyecto con microcontrolador. Inicialmente el lenguaje fue creado para poder desarrollar programas y proyectos de software para computadores, pero en los días de hoy, está siendo usada para el desarrollo de programas o proyectos con microcontrolador. Como la lenguaje UML fue desarrollada para lenguajes orientados a objeto (clases) como C++/C# y la mayoría de proyectos con microcontroladores está escrita en lenguaje C, es necesario hacer algunas adaptaciones para soportar UML en la lenguaje C. y la mayoría de proyectos con microcontroladores está escrita en lenguaje C, es necesario hacer algunas adaptaciones para soportar UML en la lenguaje C.
La lenguaje UML es formada por una serie de diagramas para poder describir, organizar, formatear, clasificar, etc, el proyecto que se pretende desarrollar. Para el caso de proyectos con microcontrolador, los diagramas más usados son:
Diagramas de Casos de Uso.
Diagramas de Clases.
Diagramas de Estado.
En este este artículo, explicaremos como usar estos diagramas en el desarrollo de un proyecto o idea que use microcontroladores.
DIAGRAMAS DE CASO DE USO (USE CASE DIAGRAM)
Los diagramas de caso de uso, indica los usos que el proyecto permite utilizar, es decir, para qué sirve el proyecto y quienes lo van usar. Por este motivo este diagrama tiene 2 componentes importantes.
Los Usuarios son representados en el diagrama por un símbolo similar al de la Figura 1. Los Casos de Uso son representados en el diagrama por un símbolo similar al de la Figura 2. Al lado de los símbolos Usuarios, se coloca un texto describiendo su papel (rol) y dentro de los símbolos Casos de Uso, se coloca un texto describiendo su función.
La Figura 3 muestra un ejemplo de un diagrama de Casos de Uso para un proyecto de una alarma básica para carro. En este diagrama, la línea con fecha indica que Usuario (actor) hace uso del proyecto.
DIAGRAMA DE CLASES (CLASS DIAGRAM).
Los Diagramas de Clases describen las funciones y datos (variables) del proyecto. Este diagrama se encarga de clasificar las funciones (rutinas) en módulos o bloques para una mejor organización de software. A estos módulos o bloques se les da el nombre de Clases.
Cada Clase en el diagrama es formada por 3 partes principales:
1- Nombre de la clase.
2- Propiedades o variables.
3- Funciones o Rutinas.
La Figura 4 describe donde van ubicados cada una de las partes de una clase. El Nombre de la Clase debe indicar a quien están orientadas las variables y las funciones. Por ejemplo en una alarma, esta clase puede llamarse Alarm. Las Variables son los datos necesarios para que el modulo o clase trabaje. Estas variables se pueden organizar en una estructura. Para la clase Alarm esta estructura se codifica en el archivo cabecera (Alarm.h) y seria asi:
typedef struct
{
uint32_t state;
}Alarm;
Las Funciones son código organizado por rutinas. La Figura 5 muestra un ejemplo de un diagrama de clase para una alarma de carro. De este diagrama podemos generar el código para cada clase. Por ejemplo para la clase Alarm, el código seria asi:
#include "Alarm.h"
Alarm a;
void Alarm_StateMachine(Event event)
{
}
void Alarm_Init(void)
{
}
Para las demás clase se generan códigos similares. La Figura 6 muestra el diagrama en bloques para una alarma de carro básica. Se puede notar que hay una relación entre los bloques y las clases en los diagramas. Esto es una guía, mas dependiendo del proyecto, pueden resultar más clases.
DIAGRAMA DE ESTADO DE MAQUINA (STATE MACHINE DIAGRAM).
Este diagrama describe el funcionamiento dinámico del proyecto, es decir como el proyecto debe funcionar. Este diagrama es formado por los siguientes símbolos:
1- Estados.
2- Transiciones.
3- Eventos.
4- Acciones.
En la Figura 7 muestra el símbolo para los Estados. La Figura 8 muestra el símbolo para las Transiciones. La Figura 9 muestra los Eventos, siendo nombres (texto) que se colocan al lado de las transiciones. La Figura 10 muestra las Acciones, las cuales son rutinas o funciones del diagrama de clases.
La Figura 11 muestra un diagrama de estado para la alarma de carro.
Una vez diseñado el diagrama de estado, es necesario codificarlo. Para esto, a cada estado, se le asigna un case en una instrucción switch. El código para el diagrama de estado de la Figura 11, seria así:
switch(a.state)
{
case Alarm_Disarmed:
break;
case Alarm_Armed:
break;
case Alarm_Triggered:
break;
}
Ahora dentro de cada case correspondiente a cada estado, es necesario tratar los eventos que ese estado puede manejar. Por ejemplo, para el estado Alarm_Disarmed, los eventos que se manejan serian:
case Alarm_Disarmed:
switch(event)
{
case BUTTON:
a.state = Alarm_Armed;
break;
}
break;
Para el estado Alarm_Armed, los eventos que se manejan serian:
case Alarm_Armed:
switch(event)
{
case BUTTON:
a.state = Alarm_Disarmed;
break;
}
break;
Para el estado Alarm_Triggered, los eventos que se manejan serian:
case Alarm_Triggered:
switch(event)
{
case DOOR_OPEN:
Siren_On();
a.state = Alarm_Triggered;
break;
case ULTRASONIC:
Siren_On();
a.state = Alarm_Triggered;
break;
case BUTTON:
a.state = Alarm_Disarmed;
break;
}
break;
A este forma de codificación se le da el nombre de Maquina de Estado. Ahora, es necesario unir todo este código en una sola función, para crear la máquina de estado del proyecto. La función seria así:
void Alarm_StateMachine(Event event)
{
switch(a.state)
{
case Alarm_Disarmed:
switch(event)
{
case BUTTON:
a.state = Alarm_Armed;
break;
}
break;
case Alarm_Armed:
switch(event)
{
case BUTTON:
a.state = Alarm_Disarmed;
break;
}
break;
case Alarm_Triggered:
switch(event)
{
case DOOR_OPEN:
Siren_On();
a.state = Alarm_Triggered;
break;
case ULTRASONIC:
Siren_On();
a.state = Alarm_Triggered;
break;
case BUTTON:
a.state = Alarm_Disarmed;
break;
}
break;
}
}
Tanto para los estados, como para los eventos, es necesario crear enumeradores (enum) para que el código en el archivo Alarm.c reconozca esos nombres. Esto se hace en el archivo cabecera (head), es decir en Alarm.h y el código seria así:
enum ALARM_EVENTS
{
BUTTON,
DOOR_OPEN,
ULTRASONIC
};
enum Alarm_State
{
Alarm_Disarmed,
Alarm_Armed,
Alarm_Triggered
};
El archivo main.c para el proyecto de alarma de carro, seria así:
#include "Alarm.h"
#include "RemoteControl.h"
#include "Ignition.h"
#include "Door.h"
#include "UltraSonic.h"
#include "Siren.h"
int main()
{
Init_IO();
Alarm_Init();
RemoteControl_Init();
UltraSonic_Init();
while(1)
{
RemoteControl_Events();
Ignition_Events();
Door_Events();
UltraSonic_Events():
}
}
Notemos en el loop principal, las llamadas a las funciones Events() de cada clase. Es en esta función o rutina, donde se codifican los eventos para el proyecto. El siguiente código muestra un ejemplo para la clase Door.
void Door_Events(void)
{
if( Door_IsOpen() )
{
Alarm_StateMachine( DOOR_OPEN );
}
}
Así, si cualquier puerta del carro se abre, es enviado a la función Alarm_StateMachine() el evento DOOR_OPEN y la máquina de estado se encarga de procesar el evento de acuerdo al estado en que se encuentre.
El ejemplo de este artículo es sencillo, pero demuestra cómo usar los diagramas UML para crear un proyecto con microcontrolador. En un proyecto real, normalmente se tienen más funciones, como por ejemplo bloquear las puertas del carro, elevar los vidrios de las puertas, caso estos estén abiertos, o bloquear el carro, caso se detecte que ha sido robado.
Existen programas para editar los diagramas UML. Algunos ejemplos son: Visual Paradigm, Enterprise Architect, Visual Studio de Microsoft y muchos mas. La Figura 12 muestra el editor de diagrama de clases del programa Visual Paradigma. Estos programas son de fácil uso y muy intuitivos en su manejo.