Dans ce second billet de la série, nous allons poser les bases qui permettront de relier deux univers DMX séparés en allant piocher des informations d’intensité dans le premier pour les transférer dans le second avec lequel nous contrôlerons 15 Robe ParFect 150™ RGBW.
Nous allons installer deux shields DMX sur un Arduino MEGA : un pour réception, l’autre pour émission. On détaille pourquoi ce setup est nécessaire, comment combiner les bibliothèques Conceptinetics et DMXSerial (avec modification), et comment tout câbler correctement — jumpers inclus.
Le protocole DMX est strictement unidirectionnel : un bus DMX est soit en émission, soit en réception. Sur un shield unique, les prises XLR IN et XLR OUT sont pontées selon la norme et ne peuvent donc pas gérer deux univers distincts sans conflit.
👉 On utilise donc deux shields séparés :
Seuls les Arduino MEGA possèdent plusieurs ports UART matériels (Serial0, Serial1, etc.).
Serial0 (UART0) est utilisé pour la connexion USB (programmation, debug, log, …) et pour contrôler le Shield DMX OUT.
Serial1 (UART1) (inexistant sur le UNO) est utilisé pour contrôler le Shield DMX OUT.
Les différentes librairies qui permettent de gérer le DMX sur Arduino ne permettent pas de gérer deux bus série à la fois.
Pour éviter de réécrire une bibliothèque en profondeur, nous allons contourner le problème en en utilisant deux.
Conceptinetics, la plus robuste sera utilisée pour émettre les données en OUT vers nos 15 ParFect tandis que DMXSerial, plus légère, permettra d’écouter nous deux canaux en entrée.
Par défaut, Conceptinetics et DMXSerial utilisent UART0, ce qui pose problème.
Heureusement, une option cachée dans le fichier DMXSerial_avr.h de la librairie DMXSerial permet de basculer sur UART1.
Cette option permet à la base de monitorer le Shield via la console USB qui utilise UART0.
Les développeurs ont donc permis cette fonction sur les Arduino MEGA.
Il suffit de décommenter la ligne 33 :
#define DMX_USE_PORT1
Cela redirige DMXSerial vers UART1 (Serial1), libère Serial0 pour la programmation USB ou, dans notre cas, le DMX OUT.
L’ordre des #include est crucial pour éviter les collisions :
#include <Conceptinetics.h>
#include <DMXSerial.h>
Conceptinetics configure son propre port en premier, suivi par DMXSerial sur Serial1 sans interférence.
→ Résultat : Shield OUT sur Serial0, Shield IN sur Serial1.
Voici les deux librairies :
J’ai trouvé quelques librairies incomplètes ou non fonctionnelles. Celles-ci fonctionnent avec le code ci-dessous.
#include <Conceptinetics.h>
#include <DMXSerial.h>
#define DMX_MASTER_CHANNELS 165 // 15 ParFect x 11 canaux
#define DMX_TX_ENABLE_PIN 2 // DE du Shield OUT (empilé)
#define DMX_RX_ENABLE_PIN 3 // DE du Shield IN (déporté)
#define DMX_IN_FIRST_ADRESS 1 // Première adresse DMX IN
#define DMX_OUT_FIRST_ADRESS 1 // Première adresse DMX OUT
DMX_Master dmx_master(DMX_MASTER_CHANNELS, DMX_TX_ENABLE_PIN);
// Tableau des zooms personnalisés
uint8_t zoomValues[15] = {
110, 120, 130, 140, 150, 160,
170, 180, 190, 200, 210, 220, 230, 240, 250};
void setup() {
pinMode(DMX_RX_ENABLE_PIN, OUTPUT);
digitalWrite(DMX_RX_ENABLE_PIN, HIGH); // Activation du Shield IN
DMXSerial.init(DMXReceiver); // Initialisation DMX IN (RX1 via DMX_USE_PORT1)
dmx_master.enable();
dmx_master.setChannelRange(1, DMX_MASTER_CHANNELS, 0); // Reset des canaux OUT
}
void loop() {
if (DMXSerial.noDataSince() < 1000) {
uint8_t intensityGroup1 = DMXSerial.read(DMX_OUT_FIRST_ADRESS);
uint8_t intensityGroup2 = DMXSerial.read(DMX_OUT_FIRST_ADRESS + 1);
for (uint8_t i = 0; i < 15; i++) {
uint16_t startChannel = i * 11 + DMX_OUT_FIRST_ADRESS; // Adresse DMX de départ (1-based)
dmx_master.setChannelValue(startChannel + 0, 0); // CH1 Power
dmx_master.setChannelValue(startChannel + 1, 0); // CH2 Virtual Colour Wheel
dmx_master.setChannelValue(startChannel + 2, 0); // CH3 Rouge
dmx_master.setChannelValue(startChannel + 3, 0); // CH4 Vert
dmx_master.setChannelValue(startChannel + 4, 0); // CH5 Bleu
dmx_master.setChannelValue(startChannel + 5, 255); // CH6 Blanc
dmx_master.setChannelValue(startChannel + 6, 0); // CH7 CTC
dmx_master.setChannelValue(startChannel + 7, 45); // CH8 Color MIX Control
dmx_master.setChannelValue(startChannel + 8, zoomValues[i]); // CH9 Zoom
dmx_master.setChannelValue(startChannel + 9, 32); // CH10 Shutter ouvert
// CH11 Dimmer selon le groupe
if (i < 6) {
dmx_master.setChannelValue(startChannel + 10, intensityGroup1);
} else {
dmx_master.setChannelValue(startChannel + 10, intensityGroup2);
}
}
}
}




