DMX Out

Raspberry Pi als DMX Master

DMX und die serielle Schnittstelle

Raspberry Pi stellt eine serielle Schnittstelle zur Verfügung. Diese ist in den meisten Linuxdistributionen bereits so konfiguriert, dass sie als Linuxkonsole verwendet werden kann. Somit wäre es möglich, den Raspberry Pi ohne zusäztliche Peripherie (Tastatur, Bildschirm, Netzwerk) zu verwalten. Diese serielle Schnittstelle wird vom Erweiterungsboard TT PI benötigt und muss daher einmalig konfiguriert werden. Falls auf die Kommunikation über die serielle Schnittstelle verzichtet werden möchte, so können die DMX Befehle auch per I2C übertragen werden. Dazu muss auch diese Schnittstelle zuerst konfiguriert werden. Siehe I2C.

TT PI Raspberry Pi Erweiterungsboard

Serielle Schnittstelle konfigurieren

Die Implementierung (Hardware und Software) der internen seriellen Schnittstelle ändert sich auf dem Raspberry Pi stetig. Darum geben wir hier keine Garantie auf Gelingen der folgenden Schritte.

Achtung:
Bei Verwendung von einem Raspberry Pi 3 oder Zero muss im Code weiter unten die Schnittstelle “ttyS0” anstelle von “ttyAMA0” verwendet werden.

Ab August 2017 (Raspbian Stretch):
sudo raspi-config
Dann unter “Interfacing Options” die serielle Schnittstelle einschalten (YES) und die Login Shell ausschalten (NO).
Programm verlassen und den RPi neu starten.

Ab 18. März 2016 (Raspbian Jessie):
sudo nano /boot/cmdline.txt
Dann “console=serial0, 115200” löschen.
Datei speichern und Editor verlassen (Ctrl-x, y).
Achtung: Im Code weiter unten muss die Schnittstelle “ttyAMA0” mit “serial0” ersetzt werden.

Hier unsere alte Dokumentation:

Als erster Schritt wird die Linuxkonsole über die serielle Schnittstelle deaktiviert. Dazu muss die Datei inittab angepasst werden.
sudo nano /etc/inittab
Danach die Zeile “ttyAMA0” mit # auskommentieren. Diese sieht dann wie folgt aus:
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
Datei speichern und Editor verlassen (Ctrl-x, y).

Falls die Datei nicht exisitert, haben Sie vermutlich schon eine aktuellere Linux Distribution installiert. Die serielle Schnittstelle lässt sich dann wie folgt deaktivieren.
sudo systemctl mask serial-getty@ttyAMA0.service

Um Fehlverhalten zu vermeiden, sollte die Bootup Info über die serielle Schnittstelle zusätzlich deaktivert werden.
Dazu folgende Datei bearbeiten
sudo nano /boot/cmdline.txt
und alle Referenzen zu “ttyAMA0” entfernen.
console=ttyAMA0,115200 kgdboc=ttyAMA0,115200
Datei speichern, Editor verlassen (Ctrl-x, y) und Raspberry Pi neu starten.

Anschluss DMX

DMX XLR    TT PI
Pin 1 GND (schwarz)
Pin 2 DMX2 (blau)
Pin 3 DMX3 (rot)

DMX Übertragungsprotokoll für die serielle Schnittstelle

DMX Befehle werden über die serielle Schnittstelle an TT PI übertragen. Ein Kanalwert wird in einem acht Byte grossen Paket gesendet. Checksummen verhindern Übertrangungsfehler. Die Baud Rate beträgt 115200bps.
Aufbau des benötigten Pakets für die Übertragung von DMX Befehlen
payload (ByteArray mit Grösse 8)
payload[0] = 0x06 (erstes Datenbyte per Definition fix 0x06)
payload[1] = 0x85 (zweites Datenbyte per Definition fix 0x85)
payload[2] = 0x04 (erste Checksumme -> Anzahl der folgenden Datenbytes)
payload[3] = 0x58 (entspricht dem ASCII Zeichen “X” und bedeuted für TT PI DM”X” Kommando)
payload[4] = DMX KANALNUMMER (max. 256 Kanäle)
payload[5] = DMX WERT (0 – 255)
payload[6] = 0 (reserviert für zukünftige Implementationen)
payload[7] = Berechnete Checksumme (siehe Beispiel weiter unten)

node.js Beispielprogramm (dmx.js)

Das untenstehende Script in einen Texteditor einfügen und und z.B. unter dem Dateinamen “dmx.js” abspeichern.
nano dmx.js
Programmcode:

var SerialPort = require("serialport");

//Serieller Port als Objekt erstellen
var serialPort = new SerialPort("/dev/ttyAMA0", {
  baudRate: 115200
});

//Serieller Port öffnen und DMX Signal senden
serialPort.on("open", function () {
  console.log("Serial port opened");
  //DMX Wert 255 an Kanal 7 senden
  sendDMX(7, 255);
});

//Methode zum Übertragen der DMX Anweisung
function sendDMX(channel, value) {
  var buffer = new Buffer(8);
  var checksum = 4;               //Checksumme = 4 Datenbytes folgen
  buffer[0] = 0x06;
  buffer[1] = 0x85;
  buffer[2] = checksum;
  buffer[3] = 0x58;               //ASCII Wert für X (TT PI Kommando DM"X")
  checksum ^= buffer[3];          //Checksumme neu berechnen 
  buffer[4] = channel;            //DMX Kanal
  checksum ^= buffer[4];          //Checksumme neu berechnen 
  buffer[5] = value;              //DMX Wert
  checksum ^= buffer[5];          //Checksumme neu berechnen 
  buffer[6] = 0x00;               //0 (reserviert für zukünftige Implementationen)
  checksum ^= buffer[6];          //Checksumme neu berechnen 
  buffer[7] = checksum;           //Checksumme speichern
  serialPort.write(buffer);       //Paket übermitteln
  //Status in Konsole ausgeben
  console.log("Sent DMX value " + value + " to channel " + channel);
}

Eventuell müssen vor dem Ausführen die benötigten node.js Module installiert werden.
npm install serialport

Das Script kann anschliessend mit diesem Befehl gestartet werden
node dmx.js

python Beispielprogramm (dmx.py)

import serial                   #benoetigte Module importieren
import time

delay = 0.5

serialport = serial.Serial('/dev/ttyAMA0', 115200)      #serialport Objekt erstellen
serialport.open()               #serielle Schnittstelle oeffnen

def send_dmx(channel, value):
    buffer = bytearray(8)
    checksum = 4
    buffer[0] = 0x06            #erstes Datenbyte per Definition fix 0x06
    buffer[1] = 0x85            #zweites Datenbyte per Definition fix 0x85
    buffer[2] = checksum
    buffer[3] = 0x58            #ASCII Wert fuer X (TT PI Kommando DM"X")
    checksum ^= buffer[3]       #Checksumme neu berechnen
    buffer[4] = channel         #DMX Kanal
    checksum ^= buffer[4]       #Checksumme neu berechnen
    buffer[5] = value           #DMX Wert
    checksum ^= buffer[5]       #Checksumme neu berechnen
    buffer[6] = 0x00            #0 (reserviert fuer zukuenftige Implementationen)
    checksum ^= buffer[6]       #Checksumme neu berechnen
    buffer[7] = checksum        #Checksumme speichern
    serialport.write(buffer)    #Paket uebermitteln

while True:
    send_dmx(7, 255)            #DMX Wert 255 an Kanal 7 senden
    time.sleep(delay)           #1/2 Sekunde warten
    send_dmx(7, 0)              #DMX Wert 0 an Kanal 7 senden
    time.sleep(delay)           #1/2 Sekunde warten

DMX Übertragung über die I2C Schnittstelle

Durch Schreiben von zwei Bytes kann der Wert eines DMX Kanals definiert werden. Das erste Byte beschreibt den DMX Kanal, das zweite den DMX Wert.

Über die Kommandozeile lassen sich DMX Signale leicht ausgeben. Im folgenden Beispiel wird auf Kanal 7 ein Wert von 100 übertragen:
i2cset -y 1 0x11 0x1B 0x07
i2cset -y 1 0x11 0x1C 0x64
0x11 ist die Adresse des TT PI Boards
0x1B ist das I2C Register für die DMX Kanäle
0x1C ist das I2C Register für die DMX Werte
0x07 = DMX Kanal 7
0x64 = DMX Wert 100

Für node.js und Python gibt es entsprechende Bibliotheken, mit denen sich ein DMX Programm leicht schreiben lässt. Da es im Internet unzählige Beispiele gibt, wird hier nicht weiter auf die Implementierung eingegangen.