MAX485 - DMX

Este montaje nos permitirá conectar un chip MAX485 a una red de datos DMX para poder leer los canales disponibles. En este montaje usamos el MAX485 como conversor de niveles entre la señal DMX y la UART 1 de la placa Arduino MEGA2560. Además cómo el Arduino MEGA2560 tiene 4 UART usaremos la 0 para comunicarnos con el ordenador a través del puerto USB y la UART 1 para comunicarnos con el sistema DMX. Usaremos la librería Conceptinetics o, si el enlace no está disponible desde aquí.
Ya hemos usado esta librería al programar el DMX Shield.

Tendríamos a grandes rasgos un montaje:
- Funciona a 5V
- Chip de adaptador de señal: MAX485
- No está isolado

CARACTERISTICAS MAX485

El Chip MAX485 es un transceptor de nivel desde un nivel TTL (0 a 5V) a nivel RS-422 o RS-485 (-8V a 12V). Podemos consultar en el datasheet más datos del chip. En nuestro caso del MAX485 tenemos las siguientes características:
- Tensión Alimentación: hasta 12V
- Niveles TTL de entrada/salida hacia el sistema informático: desde -0,5V hasta Vcc+0,5V
- Niveles de entrada/salida hacia el sistema RS-422/485: desde -8V hasta 12,5V
- Máxima velocidad de funcionamiento: 2,5Mbps
- Protección contra cortocircuitos
En nuestro caso vamos a conectarnos a una red de datos DMX y adaptar sus niveles a los de la placa Arduino MEGA (0V a 5V), por lo que alimentaremos el MAX485 a 5V.
Para interpretar los datos de la red DMX usaremos la librería DMX Library desarrollada por el fabricante del Shield DMX o, cualquier otra compatible. En el ejemplo que montaremos explicaré algunos cambios que necesitaremos hacer en la librería para que funcione correctamente.

PINEADO

El MAX485 viene en un encapsulado DIL de 8 pines.

Pin 1: RO - Receiver Output - Salida TTL al Arduino
Pin 2: /RE - Receiver Enable - Habilita la salida TTL a nivel bajo
Pin 3: DE - Driver Enable - Habilita la entrada TTL a nivel alto
Pin 4: DI - Driver Input - Entrada TTL desde el Arduino
Pin 5: GND - Entrada de alimentación - Masa
Pin 6: A - Entrada/Salida A (RS-422/485)
Pin 7: B - Entrada/Salida B (RS-422/485)
Pin 8: Vcc - Entrada de alimentación - Positivo


ESQUEMA

Este es el esquema que vamos a montar para tener un receptor DMX funcional


Fotos del montaje terminado:

¡

¡

¡


PROBEMOS EL MONTAJE

Cuando el montaje esté terminado tendremos un receptor DMX funcional que tendrá las siguientes funciones:
- Lee los tres primeros canales del sistema DMX
- Manda la lectura en tiempo real de los tres canales al ordenador que esta conectado el Arduino Mega, a través del puerto USB abriendo el monitor serie. Recordemos que los valores pueden variar entre 000 a 255
- El LED que esta conectado a la salida 13 lo encenderemos cuando el valor del canal 1 supere la mitad (más de 127)

Lo primero será descargarnos una librería DMX (si no la tenemos descarga, he instalada ya), que en nuestro caso será la misma que hemos utilizado en la programación del DMX Shield, que ademas usaremos como generador de señal DMX. La modificaremos para que funcione correctamente con el Arduino Mega, ademas de ver como se instala en el ordenador para que aparezca correctamente en el IDE y podamos usarla.
Iremos a la página web: DMX Library for Arduino y descargaremos la última versión de la librería, en el momento de escribir estas lineas es la versión 3.2Alpha. Si no funciona el enlace correctamente podemos descargar esta versión desde aquí.

Una vez descargada tenemos varias opciones para instalarla o añadirla a nuestro IDE y poder usarla en los sketch que realicemos. En mi caso descomprimo el ZIP y genera el árbol de carpetas que vemos a la izquierda. Esta carpeta principal "Conceptinetics" la copiaremos, dependiendo del sistema operativo que usemos, en uno de los siguientes lugares:
Windows 10: soltaremos esta carpeta en "Documentos/Arduino/libraries"
MacOs: soltaremos esta carpeta en "Documentos/Arduino/libraries"
Linux Ubuntu 16.04: soltaremos esta carpeta en "Carpeta personal/Arduino/libraries"
Podemos ver en el video del DMX Shield, mas detalladamente como se copia la librería en su sitio.

Una vez copiada la librería ya tenemos el IDE preparado para utilizar fácilmente nuestro montaje como generador o receptor DMX.
Solo debemos conocer una característica de la librería y es la posibilidad de poder elegir la uart de la placa Arduino que vamos a usar para comunicarnos con el chip MAX485 y a su vez con la red de datos DMX. Abrimos con un editor de textos el archivo "Conceptinetics.h" que tenemos en la carpeta de la librería. Buscamos las lineas de configuración que vemos en la imagen de la derecha y comprobamos que la librería esta diseñada para poder comunicarse con placas Arduino con hasta 4 uart (como por ejemplo la MEGA2560 de nuestro montaje).
Tenemos estas cuatro lineas de código de las cuales solo tiene que estar activa una de ellas. En el montaje que vamos a realizar vamos a usar una placa Arduino MEGA. Este Arduino tiene 4 uart, donde usaremos la uart-0 para comunicarnos con el ordenador a través del puerto USB y la uart-1 (pines 18 y 19 del Arduino Mega) para comunicarnos con el chip MAX485 y la red DMX. Para informar a la librería del uso de la uart-1 dejamos activa la linea "#define USE_DMX_SERIAL_1", que indica que usaremos la segunda uart de la placa Arduino MEGA. Realmente solo usaremos el pin 19 (recepción de datos de la uart-2) ya que nuestro montaje es de recepción de datos DMX.
Las otras tres lineas las dejaremos con las barras dobles para que no se ejecuten. Guardaremos el resultado y cerraremos el editor.


PROGRAMACIÓN

A continuación tenemos el código fuente del Sketch terminado para consultarlo. Se puede escribir copiándolo o descargarlo desde aquí
Notar que he añadido comentarios en cada sección para simplificar la compresión del programa.

CÓDIGO ARDUINO
/*
  DMX_Slave.ino - Example code for using the Conceptinetics DMX library
  Copyright (c) 2013 W.A. van der Meeren <danny@illogic.nl>.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 3 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

// Cargo la librería para poder usarla
#include <Conceptinetics.h>

//
// CTC-DRA-13-1 ISOLATED DMX-RDM SHIELD JUMPER INSTRUCTIONS
//
// If you are using the above mentioned shield you should 
// place the RXEN jumper towards G (Ground), This will turn
// the shield into read mode without using up an IO pin
//
// The !EN Jumper should be either placed in the G (GROUND) 
// position to enable the shield circuitry 
//   OR
// if one of the pins is selected the selected pin should be
// set to OUTPUT mode and set to LOGIC LOW in order for the 
// shield to work
//

//
// The slave device will use a block of 10 channels counting from
// its start address.
//
// If the start address is for example 56, then the channels kept
// by the dmx_slave object is channel 56-66
//
// Este es el número de canales que vamos a leer. Puede ser desde 1 a 512.
// En nuestro montaje solo vamos a leer 10 canales (1 al 10) que dependerá de la declaración
// esta más adelante "dmx_slave.setStartAddress", que nos indica a partir de que canal vamos
// a leer
#define DMX_SLAVE_CHANNELS   10 

//
// Pin number to change read or write mode on the shield
// Uncomment the following line if you choose to control 
// read and write via a pin
//
// On the CTC-DRA-13-1 shield this will always be pin 2,
// if you are using other shields you should look it up 
// yourself
//
// No usamos este pin, ya que en el montaje lo llevamos a masa al tener esta placa esclava
// solo en modo lectura, nunca va a transmitir
///// #define RXEN_PIN                2

// Configura el sistema como esclavo para recibir la señal de DMX
// Configure a DMX slave controller
DMX_Slave dmx_slave ( DMX_SLAVE_CHANNELS );

// If you are using an IO pin to control the shields RXEN
// the use the following line instead
///// DMX_Slave dmx_slave ( DMX_SLAVE_CHANNELS , RXEN_PIN );

// Defino las constantes y variables que luego usaré en el programa
const int ledPin = 13;  //pin del led montado en la placa MEGA
int ch1 = 0;            //variable donde guardaremos la lectura del canal 1
int ch2 = 0;            //variable donde guardaremos la lectura del canal 2
int ch3 = 0;            //variable donde guardaremos la lectura del canal 3

// the setup routine runs once when you press reset:
void setup() {             

  // inicializo el puerto serie del MEGA hacia el IDE para mostrar las lecturas leidas
  Serial.begin(9600);
  Serial.println("puerto serie abierto");
  

  // Enable DMX slave interface and start recording
  // DMX data
  // Habilita la placa y comienza la recepción
  dmx_slave.enable ();  
  
  // Set start address to 1, this is also the default setting
  // You can change this address at any time during the program
  // el canal de comienzo de lectura es el 1 y como le informamos que ibamos a leer 10
  // canales, leeremos del 1 al 10
  dmx_slave.setStartAddress (1);
  
  // Set led pin as output pin
  // Configuramos los pines de entrada y salida
  pinMode ( ledPin, OUTPUT );
}

// the loop routine runs over and over again forever:
void loop() 
{
  // leemos los tres primero canales
  ch1 = dmx_slave.getChannelValue (1);
  ch2 = dmx_slave.getChannelValue (2);
  ch3 = dmx_slave.getChannelValue (3);

  //mandamos al puerto serie las lecturas
  Serial.print("ch1= ");
  Serial.print(ch1);
  Serial.print("  ch2= ");
  Serial.print(ch2);
  Serial.print("  ch3= ");
  Serial.println(ch3);

  //encendemos el led incluido en la placa cuando el canal 1 supere la mitad
  if ( dmx_slave.getChannelValue (1) > 127 )
    digitalWrite ( ledPin, HIGH );
  else
    digitalWrite ( ledPin, LOW );
    
  
}

CÓDIGO ARDUINO

SISTEMAS DMX

Antes de seguir vamos a hacer una breve explicación del protocolo DMX.
En un sistema DMX (Digital Multiplex) solo puede haber un generador o master que genera el flujo de datos en el sistema. En un sistema DMX estándar podemos transmitir hasta 512 canales independientes. Esto no significa que tengamos que transmitirlos todos, también podemos transmitir, por ejemplo solo 10 canales (como en nuestro caso).
El proceso de transmisión es bastante sencillo, básicamente se transmiten uno detrás de otro: el número de canal y su valor asociado. Detectar que el transmisor no es consciente de si estos datos son recibidos por el aparato o sistema receptor, simplemente los transmite y cada receptor ya cojera el canal que necesite y su valor. Lo normal es que los receptores tengan asignado un número de canal sin repetirse y podamos controlarlos independientemente, aunque tenemos al opción de asignar a dos o más receptores el mismo valor de canal y que reaccionen al mismo tiempo los dos.


EXPLICACIÓN CÓDIGO

Lo primero es cargar la librería:
// Cargo la librería para poder usarla
#include <Conceptinetics.h>

Con esta linea estamos cargando en el IDE la librería que instalamos para que este disponible en nuestro Sketch.
Ahora vamos a definir una constante basada en el comando #define para asignarle el valor del número de canales a leer.
En nuestro caso vamos a leer 10 canales solamente. Tenemos la posibilidad de leer estos diez canales a partir de un canal dado. Veremos esta opción mas adelante
// Este es el número de canales que vamos a leer. Puede ser desde 1 a 512.
// En nuestro montaje solo vamos a leer 10 canales (1 al 10) que dependerá de la declaración
// esta más adelante "dmx_slave.setStartAddress", que nos indica a partir de que canal vamos
// a leer
#define DMX_SLAVE_CHANNELS   10

Esto tiene la ventaja de poder usar las constantes en el programa y si mas adelante las queremos modificar, solo tendremos que hacerlo en la declaración de los #define y no hacerlo en todo el programa.

Ahora tenemos que informar a la librería si vamos a diseñar un sistema de transmisión o recepción. En nuestro caso es de recepción o esclavo (SLAVE en ingles). // Configura el sistema como esclavo para recibir la señal de DMX
// Configure a DMX slave controller
DMX_Slave dmx_slave ( DMX_SLAVE_CHANNELS );

Lo siguiente es definir una constante y tres variables tipo int.

// Defino las constantes y variables que luego usaré en el programa
const int ledPin = 13;  //pin del led montado en la placa MEGA
int ch1 = 0;            //variable donde guardaremos la lectura del canal 1
int ch2 = 0;            //variable donde guardaremos la lectura del canal 2
int ch3 = 0;            //variable donde guardaremos la lectura del canal 3

Como vemos hemos asignado a una constante el número del pin donde esta el Led en la placa Arduino Mega, en este caso el 13.
También hemos creado e inicializado tres variables para guardar los valores de los canales leidos.
Ahora se va a ejecutar la parte de configuración del Sketch, void setup
 // inicializo el puerto serie del MEGA hacia el IDE para mostrar las lecturas leidas
 Serial.begin(9600);
 Serial.println("puerto serie abierto");
 
 // Enable DMX slave interface and start recording
 // DMX data
 // Habilita la placa y comienza la recepción
 dmx_slave.enable ();  
 
 // Set start address to 1, this is also the default setting
 // You can change this address at any time during the program
 // el canal de comienzo de lectura es el 1 y como le informamos que íbamos a leer 10
 // canales, leeremos del 1 al 10
 dmx_slave.setStartAddress (1);
 
 // Set led pin as output pin
 // Configuramos los pines de entrada y salida
 pinMode ( ledPin, OUTPUT );
}

Está dividido en cuatro partes:
- Configuramos el puerto serie y enviamos un mensaje indicando que esta configurado y abierto. Este mensaje se debería ver en el monitor serie del ordenador al que este conectado el Arduino Mega.
- Inicializamos la librería como esclava o receptora.
- Definimos el canal desde el cual vamos a leer los 10 canales, una y otra vez. En nuestro caso desde el canal 1, por lo que leeremos desde el canal 1 al 10.
- Configuramos el pin donde está conectado el led en la placa Arduino Mega (13) como salida, para poder enviarle estados lógicos.

Hecho esto hemos terminado con el void setup y pasamos al programa que se repetirá mientras tengamos el Arduino encendido, y como ya sabemos es el código que se encuentra dentro de las llaves de void loop.

{
 // leemos los tres primero canales
 ch1 = dmx_slave.getChannelValue (1);
 ch2 = dmx_slave.getChannelValue (2);
 ch3 = dmx_slave.getChannelValue (3);

 //mandamos al puerto serie las lecturas
 Serial.print("ch1= ");
 Serial.print(ch1);
 Serial.print("  ch2= ");
 Serial.print(ch2);
 Serial.print("  ch3= ");
 Serial.println(ch3);

 //encendemos el led incluido en la placa cuando el canal 1 supere la mitad
 if ( dmx_slave.getChannelValue (1) > 127 )
   digitalWrite ( ledPin, HIGH );
 else
   digitalWrite ( ledPin, LOW );
   

Tenemos tres partes bien diferenciadas:
- La primera se encarga de leer los tres canales y asignarles su valor a las variables que creamos para ello.
- La segunda se encarga de mandar al puerto serie, anteriormente configurado y abierto, los datos recién leídos de los canales, debidamente formateados para que sea fácil leerlos en el ordenador
- La tercera se encarga mediante un condicional "if-else" de comprobar si el valor del canal 1 es mayor de 127. En el caso de que lo sea enciende el led de la Placa Arduino y si no lo apaga.
Recordemos de nuevo que estas tres partes se ejecutarán infinitamente mientras el Arduino tenga alimentación.

Con esto ya tenemos el sketch terminado y lo podemos enviar de la manera habitual, después de cambiar el modelo de Placa a Mega2560 y seleccionar el puerto USB correcto.

Enviando el Sketch...

Una vez enviado tenemos la placa funcionando y cuando reciba una señal DMX válida la interpretará. Aquí tenemos un problema, ya que para probar correctamente el montaje que hemos realizado tenemos que conectarlo a un sistema DMX funcional. Podemos conectarlo a una mesa de luces, por ejemplo si disponemos de ella o como en mi caso como hemos realizado antes un generador con el Shield DMX y un Arduino UNO, los voy a conectar entre si para que se comuniquen y asi ver si funcionan correctamente ambos.
Recordemos que el generador contaba con un potenciomentro que modificaba el canal 3 y dos pulsadores que llevaban los canales 1 y 2 desde 000 a 255 al ser pulsados. Esto nos viene perfecto para probar el receptor.
El montaje del Arduino UNO como generador lo alimentaremos con un cargador de móvil cualquiera con salida USB, usaremos un cable DMX para unir uno de los conectores XLR de la placa Shield DMX a nuestro montaje del Arduino Mega que esta conectado y alimentado desde un ordenador (MAC en este caso) y desde el que tendremos abierto el monitor serie para ver los mensajes que nos manda el receptor con las lecturas de los tres canales monitorizados.

Si todo ha funcionado correctamente al activar el pulsador central veremos cómo el canal 1 se va a 255 y se enciende el led del Arduino MEGA. Al activar el pulsador de la derecha el canal 2 se ira a 255 y al mover el potenciómetro veremos como cambia el valor del canal 3 entre 0 y 255.
También recordar que los conectores DMX de 3 pines tienen el siguiente pineado:
Pin 1: Masa
Pin 2: Data -
Pin 3: Data +
Y los conectores de 5 pines tienen el siguiente pineado:
Pin 1: Masa
Pin 2: Data -
Pin 3: Data +
Pin 4: no conectado
Pin 5: no conectado


En este video podemos ver el montaje completo y como funciona