Receptor DMX (DMX512)

17 diciembre, 2007

El protocolo DMX es muy utilizado en sistemas de iluminación y efectos especiales para eventos, discotecas, escenarios, …

 

El ReceptorDMX que os presento tiene un objetivo puramente experimental, y sólo sirve para eso, para probar a interpretar el protocolo DMX512 y mostrar en su display el valor del canal seleccionado en cada momento.


PROTOCOLO DMX

Consiste en un sistema de muy fácil instalación, ya que permite encadenar muchos dispositivos esclavos a un cable de sólo 3 hilos:
– DMX+
– DMX-
– GND

La información se divide en 512 canales. Cada canal contiene un byte. Los dispositivos que están conectados al bus, están identificados con uno o más canales, y sólo atenderán a las instrucciones que les lleguen en esos canales. Lo habitual es que un dispositivo utilice varios de ellos, y se identifique físicamente con el código del canal de inicio. De esta manera, si un cabezal proyector utiliza, por ejemplo, 16 canales, y está identificado con el código 128, automáticamente reservará los canales 128 a 143 para sí mismo.

La información se transmite siguiendo este diagrama de tiempos:

Como se observa, la trama completa tiene varias partes:
señal BREAK: es un nivel bajo con un mínimo de 88us
marca tras BREAK: nivel alto con un mínimo de 8us
byte Start: el byte Start siempre vale 0
tiempo entre bytes: es un nivel alto que puede llegar hasta 1 s
trama de 512 bytes: aquí aparecen los datos de los 512 canales

Cada byte se transmite con:
– un bit de start a nivel bajo
– los 8 bits de datos
dos bits de stop a nivel alto

De esta manera, algunas consideraciones de tiempo respecto al protocolo son las siguientes:
– duración mínima para una trama completa: 22,7ms
– máxima velocidad de refresco de la información: 44 veces por segundo

 

DISEÑO

El circuito está compuesto por un PIC como corazón, un ULN2003 para los displays y un MAX485 para el bus DMX. He elegido un 18F2550 porque es el que tenía a mano, pero el software podría modificarse para entrar en un micro mucho más peque porque ocupa muy poquito.

El PIC almacena en su RAM los 512 valores de todos los canales DMX, lo que le permite “absorber” la información de la trama completa.

El canal DMX se selecciona mediante el teclado matricial.

Hay otro dispositivo de salida: el led. Ese led está gestionado por PWM y su Duty cicle viene dado por el dato DMX del canal seleccionado. En este caso, no hay esperas: la información se muestra en tiempo real a la vez que se está escribiendo el canal seleccionado.

El conector DMX sólo necesita tres señales: DMX+, DMX- y GND. Yo he añadido Vdd porque me permite también alimentar algún circuito auxiliar que pueda conectar al bus, aunque no es imprescindible.

USO

Utilizar el dispositivo es muy fácil. Al encender el dispositivo ya se pone internamente a capturar toda la trama que le llegue por el conector DMX. En el display aparece la palabra «OFF» mientras el usuario no seleccione ningún canal con el teclado matricial.

A medida que se va pulsando el teclado, el display va mostrando el canal seleccionado.

Mientras se toca el teclado, parpadean los puntos decimales de los displays para advertir que estamos viendo el selector de canal, en lugar del dato DMX. Al cabo de unos segundos la información aparece en los displays.

El valor del canal seleccionado también se representa en el led, cuya intensidad es regulada mediante PWM.

Puesto que el dispositivo memoriza toda la trama (512 bytes) puede ser desconectado del bus y examinado a posteriori como si estuviera físicamente conectado.

En este vídeo se puede observar el funcionamiento descrito:

Construcción

La construcción del receptor se basa en este esquema:

Del código fuente pegaré aquí sólo la rutina de atención a la interrupción de la USART, que es donde está el meollo de la cuestión. El programa completo está disponible para descargar en el link que puse antes. El código está comentado, así que me ahorro explicarlo.

/************************************************************************
*  Interrupción RDA: dato recibido por la USART                         *
*  Esta interrupción se activa cada vez que se recibe un dato en la     *
*  USART. Mediante el control de una máquina de estados se determina    *
*  la validez y el significado del dato recibido, y se obra en          *
*  consecuencia.
*************************************************************************/

#int_rda
void Dato_Recibido_USART(void)
{
while (RCIF) // ejecutamos mientras haya un dato pendiente de procesar
{
// Hacemos una copia del registro RCSTA porque sus bits cambian de valor
// al leer RCREG y modificar CREN
Copia_RCSTA.registro = RCSTA;
// En RCREG está el dato que acaba de recibir la USART
DatoRX = RCREG;
// Si se reciben más de 3 bytes sin haberlos procesado, se produce un error
// de Overrun. En este caso, se borra el error reiniciando CREN y dejamos
// la interrupción preparada para procesar la siguiente trama DMX
if (Copia_RCSTA.bits.OERR)
{
CREN=0;
CREN=1;
DMX_Estado = DMX_ESPERA_BYTE;
return;
}
// Máquina de estados
switch (DMX_Estado)
{
case DMX_ESPERA_BYTE: // si estamos en este estado y hay error FRAME
// es que nos ha pillado en medio de un Byte. Hay que seguir esperando
// hasta que desaparezca el error.
if (!Copia_RCSTA.bits.FERR)
// Ha llegado un byte. Ahora esperaremos la señal Break
DMX_Estado = DMX_ESPERA_BREAK;
break;
case DMX_ESPERA_BREAK: // estamos esperando la señal Break
// Esta señal se identifica porque aparece el error de Frame
if (Copia_RCSTA.bits.FERR)
// Tras recibir el error de Break, hay que esperar un byte de valor 0
if (!DatoRX)
DMX_Estado = DMX_ESPERA_START;
break;
case DMX_ESPERA_START: // ya hemos recibido el Break y ahora hay que
// esperar un Byte con valor 0, que será la señal de Start
// Mientras tanto, si recibimos un error de Frame, hay que volver a
// empezar para recibir la señal de comienzo de trama.
if (Copia_RCSTA.bits.FERR)
DMX_Estado = DMX_ESPERA_BYTE;
else {
if (!DatoRX)
{
// Llegados a este punto, ya hemos recibido el Byte Start=0
// y comenzamos la trama de valores DMX.
DMX_Indice = 0;
DMX_Estado = DMX_RECEPCION_DATOS;
} else
// Si el dato recibido no es 0, volvemos a empezar
DMX_Estado = DMX_ESPERA_BREAK;
}
break;
case DMX_RECEPCION_DATOS:
// En este estado estamos recibiendo la trama de datos DMX
// Si se detecta un error de Frame es que ha habido un error y estamos
// al principio
if (Copia_RCSTA.bits.FERR)
if (!DatoRX)
DMX_Estado = DMX_ESPERA_START;
else
DMX_Estado = DMX_ESPERA_BYTE;
else
{
// Almacenamos el dato recibido en nuestro array
TramaDMX[DMX_Indice++] = DatoRX;
// Si ha llegado al final de la capacidad, cambiamos al estado de espera
// de nueva trama
if (DMX_Indice >= TotalCanales)
DMX_Estado = DMX_ESPERA_BREAK;
}
break;
}
}
return;
}

Ambos ficheros, tanto el esquema como el código fuente completo están disponibles en la zona de descargas: Descarga ReceptorDMX

Emisor DMX

Obviamente, para la realización del proyecto, es conveniente contar con un emisor DMX para las pruebas. En mi caso no me comí mucho el coco y busqué algo que fuera simple y que ya estuviera hecho.

Encontré esta web www.freedmx.com y monté su proyecto Manolator 256 (sí, el autor también se llama Manolo y ha tenido los santos cojones de llamar Manolator a su proyecto  lol )
El Manolator 256 es un circuito sencillo, basado en un PIC 16F88 y un MAX485 que se conectan al puerto paralelo y nos generan las señales adecuadas:

Es una interface bastante estandarizada y se encuentra disponible en muchas aplicaciones comerciales y gratuitas. Por cierto, hay verdaderas virguerías en interfaces para DMX; recomiendo echar un vistazo a este link: MORE

Yo preferí utilizar esta, porque es simple pero perfectamente válida, y es la que se observa en el vídeo:

Hay alguna que enamora:

Y sin duda la más potente y recomendable para usos complejos: FreeStyler

Share

Etiquetas: , , ,