bunex-industries

Logiciel et contrôleur DMX

Quelques recherches pour mettre en œuvre le protocole DMX512 sous Mac OS / Cocoa/Objective-C via un convertisseur USB-SÉRIE-RS485


capture de l'interface
Une capture de l'interface

Le standard DMX512 est utilisé pour piloter les lumières de spectacle.

Diverses améliorations ont été apportées avec le temps mais en théâtre, de ce que j'ai pu en voir, on utilise couramment le système "historique", c'est-à-dire :

XLR 3 Pins femelle
XLR 3 Pins femelle

Pour Human Brush et Méduse, j'ai commencé fabriquer mon système DIY il y a quelques temps, et je viens de l'utiliser pour la première fois hier !

J'ai trouvé un convertisseurs USB <> SERIAL <> RS-485 ici et, au moins pour expérimenter (car des sécurités additionnelles sont souhaitables), cela suffit et fonctionne bien.

Le logiciel Cocoa doit configurer et ouvrir une connexion USB-Serial avec convertisseur, créer les trames DMX selon le protocole (timings, etc) et les envoyer. On le fait via IOKit et ioctl comme pour communiquer avec un Arduino.

On configure la connexion série en 8 Bits avec 1 bit start, 2 bits stop


int success;
int serialFileDescriptor;
struct termios gOriginalTTYAttrs
struct termios options;
...
ouvrir le port
... 
success = tcgetattr(serialFileDescriptor, &gOriginalTTYAttrs
options =  gOriginalTTYAttrs;
options.c_cflag = (CS8 | CSTOPB | CLOCAL | CREAD); // CSTOPB est important pour avoir les 2 bits stop
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag &= ~OPOST;
options.c_cc[ VMIN ] = 1;
options.c_cc[ VTIME ] = 0;

tcsetattr(serialFileDescriptor, TCSANOW, &options);
ioctl(serialFileDescriptor, IOSSIOSPEED, &baudRate); // 250000
ioctl(serialFileDescriptor, IOSSDATALAT, &mics); // 3
tcflush(serialFileDescriptor, TCIOFLUSH);

//ce qui suit n'est peut-être pas nécessaire :-)       
int flag;
success = ioctl(serialFileDescriptor, TIOCMGET, &flag);
flag &= ~TIOCM_RTS;     // clear RTS flag
success = ioctl(serialFileDescriptor, TIOCMSET, &flag);


Ci-dessous, l'implémentation du protocole DMX à proprement parler. Une trame DMX est créée et envoyée à la volée (cette fonction tourne dans un thread séparé). actuellement, je ne parviens pas à envoyer plus de 20 trames par secondes. Cela s'avère suffisant en pratique, mais je constate à l'oscilloscope que la durée BRK ne descend pas en dessous d'environ 25 ms, valeur un peu trop grande pour pouvoir augmenter le débit sachant :

Qu'à 250 000 bauds, chaque bit dure 4µs,

Qu'une trame dure au minimum (la durée des BREAK et MAB peut varier un peu) : $$ BRK + MAB = 92 + 12 = 104 µs$$ $$ data = BRK + MAB + (512+1)*(1+8+2)*4 = 22676 µs $$


-(void)runDMXLoop {
    while (TRUE) {
        ioctl(serialFileDescriptor, TIOCSBRK, 0); //set break bit
        usleep(BRK); // 176 µs
        ioctl(serialFileDescriptor, TIOCCBRK, 0); //clear break bit
        usleep(MAB); // 12 µs
        write(serialFileDescriptor, "\0", 1); // adresse 0 en entête
        write(serialFileDescriptor, dmxData, COUNT); // uint8_t dmxData[512]
        usleep(pause);
    }
}

Je dois désormais finir l'interface et à l'évidence revoir certains partis-pris d'ergonomie, créer d'autres facilités pour un l'usage en répétition / live pratique.

Special thank pour Davy Deschepper qui a suivi le développement et m'a bien aidé ! Merci à Tom De Wit et Tarek Lamrabti pour tous leurs conseils et critiques avisées !

Merci également à Steven B., d'avoir précisé les chose quant à ce convertisseur, qui demande parfois un petit hack selon le N° de lot apparemment. Mettre la pin DE du circuit intégré 75176 (ou équivalent) à +5V, permet d'éviter un passage non-souhaité à 0V lors du BRK, constaté à l'oscillo (un bien bel appareil il faut le dire !).

À suivre...