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.
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.