Animación de maqueta con DCCpp LMD

Muy buenas a todos y todas!
Hace unos días vino un familiar a casa y mientras estábamos mirando la maqueta me pregunto ¿pero funciona? y bueno la respuesta fue, si pero no…
Y bueno lo malo de estar todo el día trasteando con Arduino y la maqueta es que directamente no tiene fin… siempre estoy probando poniendo cosas nuevas o quitando algunas que no terminan de convencerme.
Funcionar funciona, pero tengo que conectar alguno de los sistemas de control y después activar luces, efectos, etc…
Esto me hizo pensar en como se podrían automatizar todos estos procesos.
La estructura de las animaciones
Y bueno gracias a Arduino es relativamente sencillo. Lo primero es generar un estructura de datos:
struct Animations
{
Turnout turnout; // Turnout or accessory
uint8_t state; // Animation state true/false
unsigned long tDuration; // Start time
unsigned long tFinish; // Finish time
uint8_t type; // Accessory type
char comment[18]; // Comment
};
Con esto tenemos que cada animación será un desvío de la clase Turnout.h pero tambíen podemos usar la clase Outputs.h.
En las animaciones tenemos los siguientes parámetros:
- Turnout:
Desvío o accesorio que queremos animar, tiene que estar definido anteriormente como desvío. Puedes ver como se define un desvío en aquí. - state:
Estado del desvío o accesorio 0=off 1=on - tDuratión:
Tiempo en segundos en la que se encenderá la animación. También se apagara una vez haya pasado el tiempo establecido - tFinish
para la gestión interna del tiempo, siempre es 0. - type:
Tipo de accesorio, desvío, luces, semáforos. Sin implementado. - comment:
Brebe comentario sobre el accesorio, se puede dejar en blanco.
Si quieres consultar la estructura la puedes encontrar en el archivo Animation-DCCpp.h.
Primero tenemos que definir el número de animaciones que van a correr en total:
// Number of animations
#define NUM_ANIMAT 7
Este número tiene que coincidir con el número de animaciones que vamos a utilizar. Si declaramos más o menos es posible que la animación (y la central en general) no funcione correctamente.
Ahora solo tenemos que declarar cada animación por separado en su array, esto lo encontramos en el archivo .ino que subamos a la central. No es necesario modificar nada en la librería DCCpp LMD.
Animations animation[NUM_ANIMAT] =
{
// Turnour | Status | St1 | Et2 | Type | Comment
{ACC1, false, 30, 0, LIGHT, "Soldador"}, // Iluminación exteriores
{ACC3, false, 60, 0, LIGHT, "Ilum. calles"}, // Iluminación casas
{ACC4, false, 65, 0, LIGHT, "Ilum. casas"}, // Iluminación taller
{ACC5, false, 60, 0, EFFECT, "Paso a nivel"}, // Iluminación televisor
{ACC6, false, 59, 0, LIGHT, "Ilun. talleres"}, // Iluminación barriada
{ACC7, false, 35, 0, EFFECT, "Tv Talleres"}, // Iluminación soldador
{ACC9, false, 50, 0, EFFECT, "Barriada"} // Iluminación soldador
};
Encender la central DCCpp con código:
Antes de empezar las animaciones tenemos que encender la central DCCpp LMD. Esto se puede hacer desde la función “setup()” con:
DCCpp::powerOn();
De la misma manera podemos apagar la central DCCpp LMD con:
DCCpp::powerOff();
Iniciando los desvíos o accesorios
Esto ya lo hemos visto en la entrada del blog Cargar desvíos al iniciar central DCCpp.
Pero esta vez usaremos los datos de la estructura que hemos creado:
// Accesorie ID DIR SUBDIR
animation[0].turnout.begin(1, 2, 1); // Efecto soldador B1
animation[1].turnout.begin(3, 1, 1); // Iluminación exteriores
animation[2].turnout.begin(4, 1, 2); // Iluminación casas
...
En el monitor serial tenemos que recibir la respuesta a cada inicialización correcta con el comando:
<O> // O máyuscula
Temporización:
El tiempo que se mantiene encendido o apagado un desvío o accesorio viene dado en segundos y posteriormente lo multiplicamos por 1000 para poder usar la correctamente la función millis().
A partir de este punto todo se gestiona automáticamente desde la función updateAnimation() en la función principal void loop()
Para tener una mayor certeza a la hora de encender o apagar los accesorios se envían dos veces para que no haya problemas en la recepción de los datos por parte de los decodificadores.
for (uint8_t resend = 0; resend < 2; resend++)
{
animation[index].turnout.activate(animation[index].state);
}
Conclusión:
Ahora ya no tengo excusas para enseñar la maqueta a cualquiera que pase por casa, y para disfrutar de como todo el trabajo realizado cobra sentido sin tener que mandar ni un solo comando a la central o conectar ningún controlador o software adicional.
Espero que os haya gustado como crear animaciones en la central DCCpp LMD y muy seguramente sea compatible con centrales como DCCpp S88 o DCC-EX, pero es algo que aún no he probado.
Saludos a todos y todas!!!
