Convertisseur ArtNet vers DMX basé sur ESP32 : Mise à niveau de votre ancien système DMX

Le protocole ArtNet a propulsé le standard DMX sur le réseau. Les nouveaux systèmes ArtNet sont, bien sûr, compatibles rétroactivement avec le standard DMX, mais pas vice versa. Que faire alors avec un vieux système DMX ? L'interface présentée dans cet article va vous permettre de le mettre à niveau en garantissant une compatibilité avec ce nouveau standard.

L'idée de ce projet est apparu de façon presque spontanée, en pensant à la retro-compatibilité du standard ArtNet. L' univers des deux mondes ArtNet et DMX consiste en 512 canaux dont chaque valeur peut varier de 0 à 255. La plupart des appareils contrôlables à distance (RDM) de la dernière génération, utilisés dans l'industrie du divertissement est compatible avec les deux protocoles, mais comment gérer ceux qui font toujours parfaitement leur boulot et qui ne reçoivent que le signal DMX? L'idée la plus simple est de convertir le signal en externe depuis ArtNet vers DMX au travers d'un système compact, reconfigurable et sans-fil.

Figure 1: Le module ESP32 au cœur du projet. (Source: Elettronica In)

Convertisseur ArtNet vers DMX : La partie matérielle

Tout le projet est construit autour d'un module ESP32 en version 38 broches, montré à la Figure 1, avec le schéma simple du circuit, illustré à la Figure 2. Cette carte a été choisie en raison de sa grande capacité de calcul et de sa mémoire embarquée, de son faible coût, de sa petite taille et de la grande communauté qui la suit. J'ai choisi un convertisseur DC-DC abaisseur 5 V pour l'alimentation.

Figure 2: Le schéma simple du circuit du convertisseur.

Pour la partie DMX, deux convertisseurs TTL-DMX, complets avec connecteurs, peuvent se trouver sur le net (Figure 3), mais à un coût très élevé comparé aux autres composants. Nous avons donc décidé d'utiliser deux convertisseurs TTL-vers-RS-485 (Figure 4) et deux connecteurs panneau XLR femelle à 3 broches. Enfin, nous aurons besoin d'une prise d'alimentation DC, style 9V, et d'un boîtier plastique pour contenir le tout.

Figure 3: Convertisseur TTL-DMX prêt à l'emploi, disponible sur le marché. (Source: Elettronica In)
Figure 4: Le convertisseur TTL-vers-RS-485 utilisé dans ce projet. (Source: Elettronica In)

Création des connexions : Conception simplifiée du circuit

A l'origine, j'avais fabriqué un PCB pour le projet, avec la version 30 broches de l'ESP32 embarqué (voir Figure 5), mais l'extrême simplicité des connexions permet une implémentation, même sans circuit imprimé, en utilisant à la place le module avancé à 38 broches. En fait, le diagramme des connexions est facile à interpréter et est visible à la Figure 6. Commençons par la partie alimentation : La prise DC est branchée à l'entrée du convertisseur DC-DC. La sortie 5 V de ce dernier est branchée à la fois sur VIN sur l'ESP32 (Pin 19) et sur les broches VCC des deux modules RS-485. Un branchement similaire se fait au niveau des broches GND des trois cartes et sera relié à la masse de sortie du convertisseur DC-DC.

Figure 5: Vue du premier prototype avec la version 30 broches.

Pour les signaux, chaque module possède trois broches d'entrée : Les broches RE et DE du module A doivent être branchées sur IO4 (Pin 26) du module ESP32, tandis que la broche DI du transmetteur A doit être branchée sur IO17 (Pin 28) de l'ESP32. La sortie de chaque transmetteur doit être branchée sur un connecteur XLR en fonction du schéma suivant : Les broches A et B du MAX485 doivent être branchées, respectivement, aux broches 3 et 2 du connecteur. La broche 1 du connecteur peut être branchée à la masse.

Figure 6: Schéma de câblage du projet.

Sketch

Le sketch de ce projet est basé sur le sketch GitHub ArtNetWiFiNeopixel GitHub de rstephan et Mitch Weisbord’s DMX_Write. Vous pouvez télécharger le sketch de ce projet directement depuis le dépôt du projet GitHub repository.

Comme d'habitude, nous allons l'analyser comme un tout, divisé en plusieurs listings et s'attarder sur certaines particularités du code. Le Listing 1 s'occupe de l'intégration des bibliothèques et de la configuration DHCP. Voyons cela de plus près. Plusieurs variables, qui sont utiles pour compiler le sketch, sont incluses dans la bibliothèque Arduino.h, ainsi que l'intégration de plusieurs autres bibliothèques contenant des classes de fonctionnalités de base telles que stdlib, stdio, string, etc.

Listing 1: Library inclusion and DHCP configuration.

#include <Arduino.h>
#include <esp_dmx.h>
#include "ArtnetWifi.h"
#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
//#define DHCP_DISABLED
#ifdef DHCP_DISABLED
IPAddress local_IP(192, 168, 1, 154);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(192, 168, 1, 1); //optional
IPAddress secondaryDNS(1, 1, 1, 1); //optional
#endi


La bibliothèque esp_dmx.h

possède tout le jeu des instructions traitant l'envoi des signaux vers le module TTL-vers-RS-485


Puis nous avons les bibliothèques ArtnetWifi.h et WiFi.h pour recevoir, respectivement, les paquets ArtNet et gérer la connexion vers le point d'accès. D'autre part, les bibliothèques ESPmDNS.h, WiFiUdp.h, et ArduinoOTA.h sont fonctionnelles pour le chargement du firmware OTA et définir le nom de l'appareil dans le réseau à l'aide du protocole mDNS.

Vient ensuite #define DHCP_DISABLED: par cette directive, nous allons choisir si nous voulons une adresse IP statique ou si nous déléguons tout au serveur DHCP (supprimez le commentaire de la ligne). Si nous décidons d'utiliser une adresse IP statique dans les lignes suivantes du code, il est nécessaire de définir toutes les constantes liées, vers l'IP, la passerelle et le sous-réseau désirés. De plus, vous pouvez choisir les serveurs DNS. Si nous choisissons une IP dynamique, ce sera d'autant plus utile (mais non essentiel) de connaître l'adresse IP de l'ESP32.


Tableau 1: Connexions du module ESP32 vers RS-485-A
ESP32 Pin MAX485 Pin
4 DE
17 DI
4 RE

 

Tableau 2: Connexions du module ESP32 vers RS-485-B
ESP32 Pin MAX485 Pin
21 DE
19 DI
21 RE

Nous donnerons plus d'explications à ce sujet plus tard. Le Listing 2 comprend le reste de la pré-programmation. Les objets liés aux bibliothèques WiFiUDP et ArtnetWifi sont créés initialement. Ensuite, par les constantes de type chaîne ssid et password, sont définis le nom du réseau Wi-Fi auquel l'ESP se connecte ainsi que son mot de passe. Les

broches de l'ESP seront branchées sur les deux transmetteurs RS-485 comme indiqué sur les Tableau 1 et Tableau 2.

Listing 2: “WiFiUDP” and “ArtnetWifi” libraries object creation.

WiFiUDP UdpSend;
ArtnetWifi artnet;
const char* ssid = "MyArtNetNetwork";
const char* password = "MyArtNetNetwork";

/* First, lets define the hardware pins that we are using with our ESP32. We need to define which pin is transmitting data and which pin is receiving data. DMX circuits also often need to be told when we are transmitting and when we are receiving data. We can do this by defining an enable pin.*/

int transmitPinA = 17;
int receivePinA = 16; //Not connected
int enablePinA = 4;
int transmitPinB = 21;
int receivePinB = 16; //Not connected
int enablePinB = 19;

/* Make sure to double-check that these pins are compatible with your ESP32! Some ESP32s, such as the ESP32-WROVER series, do not allow you to read or write data on pins 16 or 17, so it’s always good to read the manuals.*/
/* Next, let's decide which DMX port to use. The ESP32 has either 2 or 3 ports. Port 0 is typically used to transmit serial data back to your Serial Monitor, so we shouldn’t use that port. Let's use port 1! */

dmx_port_t dmxPortA = 1;
dmx_port_t dmxPortB = 2;

/* Now we want somewhere to store our DMX data. Since a single packet of DMX data can be up to 513 bytes long, we want our array to be at least that long. This library knows that the max DMX packet size is 513, so we can fill in the array size with DMX_PACKET_SIZE. */

byte dataA[DMX_PACKET_SIZE];
byte dataB[DMX_PACKET_SIZE];

//ArtNet settings const int startUniverse = 0;
// CHANGE FOR YOUR SETUP most software this is 1,
//some software send out artnet first universe as 0.

const int maxUniverses = 2;
const int numberOfChannels = 1024;
bool universesReceived[maxUniverses];
bool sendFrame = 1;
int previousDataLength = 0;


Pour chacun des modules, nous avons défini la broche 16 pour la réception, bien qu'elles ne soient pas réellement branchées et qu'elles n'aient aucune utilité dans notre conception. Pour continuer, nous définissons les ports matériels TTL de l'ESP : Nous utiliserons, respectivement, les ports 1 et 2 pour les univers A et B. Les données des deux univers DMX seront encapsulées dans deux matrices d'octets, dataA et dataB, dont les tailles sont définies dans DMX_PACKET_SIZE. DMX_PACKET_SIZE est défini dans la bibliothèque esp_dmx.h et porte la valeur 513. Enfin, toutes les variables utilisées dans les paquets de traitement ArtNet sont définies. Nous portons une attention spéciale à la constante startUniverse : Elle indique, en fait, à partir de quel univers nous voulons commencer à gérer les données. 

Elle devrait être modifiée dans le cas où nous désirions créer une installation avec plusieurs récepteurs de différents univers. Elle pourrait aussi être modifiée dans le cas où le programme qui envoie les paquets a une numérotation commençant par 1 au lieu de 0. Les constantes sont alors définies en considérant le nombre maximal d'univers, de canaux et d'autres variables utilisées pour contrôler les états et les boucles de processus.

Le Listing 3 contient toutes les instructions incluses dans setup(). Le port série est d'abord initialisé à 115,200 bits par seconde pour permettre la mise au point de la carte, telle que la vérification de l'IP obtenue. Ensuite, s'ils sont définis, tous les paramètres sont configurés pour obtenir une IP statique et, si une erreur apparaît, un message est envoyé sur le port série. Une connexion en boucle sur le réseau est alors tentée et, si elle est fructueuse, l'IP de la carte est inscrite dans le port série. Le nom d'hôte ESP32-ArtNetto-DMX-Converter est alors défini et sera affiché dans la section Board Manager des différents IDEs. Cette fonction est très utile car elle permet de reconnaître un appareil parmi tous les autres dans une "flotte". La gestion du chargement du firmware OTA est alors initialisé et nous arrivons à la bibliothèque ArtNet.

Listing 3: setup() function.

void setup() {
/* Start the serial connection back to the computer so that we can log
messages to the Serial Monitor. Let's set the baud rate to 115200. */

Serial.begin(115200);
// Setup wifi
WiFi.mode(WIFI_STA);
#ifdef DHCP_DISABLED
//Comment to use DHCP instead of static IP
if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
Serial.println("STA Failed to configure");
}
#endif
WiFi.begin(ssid, password);
delay(1000);
Serial.println("\nConnecting");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(100);
}
Serial.println("\nConnected to the WiFi network");
Serial.print("Local ESP32 IP: ");
Serial.println(WiFi.localIP());
// Port defaults to 3232
// ArduinoOTA.setPort(3232);
// Hostname defaults to esp3232-[MAC]
ArduinoOTA.setHostname("ESP32-ArtNet-to-DMX-Converter");
// No authentication by default
// ArduinoOTA.setPassword("admin");
// Password can be set with it’s md5 value as well
// MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
ArduinoOTA
.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH)
type = "sketch";
else // U_SPIFFS
type = "filesystem";
// NOTE: if updating SPIFFS this would be the

// place to unmount SPIFFS using SPIFFS.end()
Serial.println("Start updating " + type);
})
.onEnd([]() {
Serial.println("\nEnd");
})
.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
})
.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR)
Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR)
Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR)
Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR)
Serial.println("Receive Failed");
else if (error == OTA_END_ERROR)
Serial.println("End Failed");
});
ArduinoOTA.begin();
artnet.setArtDmxCallback(onArtNetFrame);
artnet.begin("ESP32-ArtNet-to-DMX-Converter");
/* Set the DMX hardware pins to the pins that we want to use. */
dmx_set_pin(dmxPortA, transmitPinA, receivePinA, enablePinA);
dmx_set_pin(dmxPortB, transmitPinB, receivePinB, enablePinB);

/* Now we can install the DMX driver! We’ll tell it which DMX port to use and which interrupt priority it should have. If you aren’t sure which interrupt priority to use, you can use the macro DMX_DEFAULT_INTR_FLAG to set the interrupt to its default settings.*/

dmx_driver_install(dmxPortA, DMX_DEFAULT_INTR_FLAGS);
dmx_driver_install(dmxPortB, DMX_DEFAULT_INTR_FLAGS);

Enfin, les broches de sortie de l'ESP et le port série qui sera alloué à chaque transmetteur sont définis et la priorité des interruptions utilisées est également définie. Le Listing 4 contient toute la partie destinée à la fonction onArtNetFrame() . D'abord, on vérifie que la valeur de chacun des univers reçus appartient bien aux univers qui nous intéressent. Si c'est le cas, le drapeau de la cellule correspondante du tableau est défini à 1. La procédure vérifie que tous les univers concernés sont reçus sinon, on quitte la fonction. Ensuite, nous vérifions que chaque canal reçu appartient bien à l'univers A ou à l'univers B et sera inclus dans le tableau correspondant.

Listing 4: onArtNetFrame() function.

void onArtNetFrame(uint16_t universe, uint16_t numberOfChannels,
   uint8_t sequence, uint8_t* dmxData) {
sendFrame = 1;
// Store which universe has got in
if ((universe - startUniverse) < maxUniverses)
universesReceived[universe - startUniverse] = 1;
for (int i = 0; i < maxUniverses; i++) {
if (universesReceived[i] == 0) {
//Serial.println("Broke");
sendFrame = 0;
break;
}
}
// read universe and put into the right array of data
for (int i = 0; i < numberOfChannels; i++) {
if (universe == startUniverse)
dataA[i + 1] = dmxData[i];
else if (universe == startUniverse + 1)
dataB[i + 1] = dmxData[i];
}
previousDataLength = numberOfChannels;
dmx_write(dmxPortA, dataA, DMX_MAX_PACKET_SIZE);
dmx_write(dmxPortB, dataB, DMX_MAX_PACKET_SIZE);
dmx_send(dmxPortA, DMX_PACKET_SIZE);
dmx_send(dmxPortB, DMX_PACKET_SIZE);
dmx_wait_sent(dmxPortA, DMX_TIMEOUT_TICK);
dmx_wait_sent(dmxPortB, DMX_TIMEOUT_TICK);
// Reset universeReceived to 0
memset(universesReceived, 0, maxUniverses);
}

Les données de chaque univers sont ensuite insérées dans le buffer d'envoi respectif et attendent la fin de la transmission. Enfin, les drapeaux liés aux univers reçus sont remis à zéro. Le Listing 5 est le plus court et ne contient que la fonction loop() . Dans cette boucle, on vérifie que l'ESP est bien branché au point d'accès et, dans le cas favorable, les paquets ArtNet sont reçus et traités.

Listing 5: loop() function.
void loop() {
  if ((WiFi.status() == WL_CONNECTED)) {
    artnet.read();
  }
}

Assemblage: Du Prototype à la Conception Définitive

Il est temps maintenant de monter le convertisseur. Suivez simplement les connexions montrées précédemment à la Figure 6. Souvenez-vous de ponter les broches DE et RE sur les transmetteurs RS-485. Ensuite, préparez les connecteurs XLR en soudant les trois fils (Tableau 3).

Tableau 3: Module RS485 vers prise XLR.
MAX485 Pin DMX Signal XLR Connector Pin
GND Gnd/Shield 1
A Data+ 3
B Data- 2


Percez le boîtier plastique, deux petits trous pour les vis et un grand trou pour chaque connecteur. Percez un dernier trou pour la prise d'alimentation à laquelle vous aurez préalablement souder deux fils. Maintenant, branchez les fils de la prise d'alimentation à l'entrée du convertisseur DC-DC. La sortie de celui-ci sera branchée à l'alimentation de l'ESP32 et des deux transmetteurs en utilisant des ponts et une paire de terminaux à vis. Chargez le firmware, fermez le boîtier, branchez l'alimentation puis entamez la configuration du logiciel de contrôle.


Je m'abonne
Abonnez-vous à la balise thématique ESP32 pour être averti dès qu'une information relative à ce sujet sera publiée par Elektor !

Configuration Logicielle : Projecteurs ArtNet avec MagicQ

Beaucoup de programmes existent pour gérer les projecteurs d'ArtNet : open source, freemium, et payant. Parmi les logiciels gratuits (ou gratuit pour une utilisation non commerciale) que nous vous recommandons se trouve, sans aucune hésitation, MagicQ, produit par Chamsys. Dans notre cas, nous allons juste expliquer l'utilisation de MagicQ. C'est un​​​​​​​ programme téléchargeable gratuitement multi-plateforme (Windows, Mac and Ubuntu) permettant de contrôler jusqu'à 256 univers, de gérer le mapping de pixel et de lire des vidéos HD arrangées jusqu'à 8 couches.

Figure 7: Capture d'écran du menu d'accueil de MagiQ.

Nous procédons à l'inscription sur le site web et téléchargeons le logiciel d'installation. Lorsque l'installation est terminée, nous aurons plusieurs applications : Lancez MagicQ PC et attendez l'apparition de l'écran d'accueil, comme montré sur la Figure 7. Cliquez sur Simple generic console. Dans le nouvel écran qui apparaît, nous allons dans le menu et sélectionnons Setup → DMX I/O. Dans l'écran suivant, comme sur la Figure 8, nous allons pouvoir définir les sorties des différents univers DMX. Dans le choix Out Type , nous sélectionnons Art-Net et choisissons Art 0 dans le choix Out Uni . La partie critique de la configuration arrive lorsqu'il faut choisir les options Unicast et Unicast2 .

Figure 8: Fenêtre de configuration des sorties ArtNet.

Ces entrées sont utilisées pour indiquer vers quelles adresses IP nous allons transmettre nos paquets. Supposons que nous soyons connecté à un réseau avec un sous-réseau 24-bit (255.255.255.0) et que nous diffusions l'IP XXX.XXX.XXX.255, nous pouvons entrer cette adresse pour être sûr que tous les appareils du réseau reçoivent les paquets. Si, par contre, nous voulons éviter de surcharger tous les appareils du réseau en envoyant systématiquement tous les paquets, nous pouvons définir directement l'IP de l'appareil désiré mais, dans ce cas, nous recommandons de définir une IP statique.

Nous avons appliqué cette configuration à l'univers ArtNet 2, qui utilise la même que l'Univers 1 comme source de données, en le définissant dans la colonne copy . Vous pouvez constater que nous avons défini l'adresse localhost du PC comme celle du champ Unicast 2 . Nous avons utiliser cette configuration afin de pouvoir vérifier la transmission réelle des paquets dans le logiciel de débogage tel que ArtNetominator, téléchargeable ici. Nous n'avons pas entré cette option dans l'Univers 1 puisque, en utilisant la diffusion IP, les paquets "reviennent" automatiquement vers le PC. Maintenant, déplaçons le curseur dans le coin supérieur droit et cliquons sur Single : des curseurs vont apparaître comme montrés sur la Figure 9.

Figure 9: Panneau de contrôle des curseurs MagiQ.

Pour commencer la transmission des paquets, nous sélectionnons enable et confirm. Essayons maintenant d’exécuter une configuration simple de projecteur, en déplaçant la souris vers la gauche, à peu près à la moitié de l'écran et en cliquant sur Test show. Sur l'écran, vous allez voir une grande liste de cellules représentant les fabricants des projecteurs, comme sur la Figure 10. Nous sélectionnons la marque et tous les modèles pré-configurés disponibles vont apparaître.

Figure 10: Fenêtre de sélection des projecteurs, par marque et type.

Après avoir fait notre choix, nous accédons à une fenêtre comme celle montrée à la Figure 11, dans laquelle nous aurons soit des curseurs individuels pour les commandes de base ou quelques macros qui comprennent un défilement varié . Testons le fonctionnement pour s'assurer que les appareils et le logiciel sont configurés correctement. Pour profiter de tout l'avantage du potentiel de l'application, nous vous recommandons vivement de prendre des cours de formation en ligne accessible gratuitement.

Figure 11: Un projecteur configuré, avec les macros disponibles.

Convertisseur ArtNet vers DMX : Réflexions Finales

Nous avons testé le fonctionnement du système dans différentes conditions et rencontré plusieurs problèmes, suivant les points d'accès utilisés. En fait, il peut arriver que — suivant le point d'accès — après quelques heures, la carte tombe dans un état d'erreur et nous avons du la réinitialiser manuellement. Ce problème peut arriver en considérant que c'est une solution de bricoleur, mais en changeant de projecteur, le problème a été résolu et la carte a fonctionné plusieurs jours sans interruption. De plus, nous recommandons d'utiliser un réseau dédié pour éviter des plantages possibles du système.


Mise à Niveau DMX : Liste des Composants

Condensateurs

  • C1, C4 = 100 nF, céramique
  • C2, C3 = 220 µF, 16 V, électrolytique
  • C5 = 10 µF, 63 V, électrolytique

 

Modules

  • U1, U2 = convertisseur TTL-vers-RS-485
  • U3 = ESP32
  • U4 = convertisseur DC-DC abaisseur 5 V MP1584

 

Divers

  • DMX1, DMX2 = connecteur XLR, femelle, type PCB
  • PWR = prise alimentation, femelle, type PCB
  • 4× 2-pin connecteur plat, femelle, pitch 2.54 mm
  • 4× 4-pin connecteur plat, femelle, pitch 2.54 mm
  • 2× 15-pin connecteur plat, femelle, pitch 2.54 mm
  • 4× 2-pin connecteur plat, femelle, pitch 2.54 mm
  • PCB S1716 (102×61 mm)

Notes de l'éditeur : Intéressé par l'ESP32 et par des projets DIY ? Ce projet a été publié à l'origine dans Elettronica IN
 
 
  
Traducteur:  Chris Elsass