DMX - Controller | Programmcode+Schaltung

Videos des Zusammenbaus und des fertigen Controllers sind hier zu finden.


Verwendung der Schaltung und des Programmcodes auf eigene Gefahr. 


Schaltung

Ich habe die Schaltung jetzt mal in der "Fritzing"-Software erstellt. 4 Potis, der Drehimpulsschalter, das Display, ein paar passive Bauteile und der MAX485 IC für die Signalaufbereitung.

 

Der Pluspol der 9V Batterie muss nach den beiden Schaltern direkt an den + Pol der Stromversorgungsbuchse angelötet werden. Die Buchse soll ja trotzdem noch nutzbar sein. Der On/Off Schalter funktioniert nur im Batteriebetrieb. Darauf achten das BATT nicht aktiviert ist wenn die externe Stromversorgung genutzt wird. Also vorher umschalten. Lässt sich natürlich  schaltungstechnisch eleganter gestalten, aber ist jetzt erst mal so. Bei der Beschaltung des LCD-Displays einfach an VCC und GND orientieren. Was noch fehlt ist die galvanische Trennung vor der XLR-Buchse. Aber das lässt sich ja mit Optokopplern leicht nachrüsten. Man könnte sich in Fritzing auch gleich eine Leiterplatte designen, was aber m.M. nach bei der Schaltung keinen Sinn macht. Die Potis landen im Gehäuse und werden dort verschraubt, und nur für den IC und die paar passiven Teile reicht auch eine Lochrasterplatine.

 

Programmcode

Hier der Arduino Code. Es erscheint das Menü, man kann den Cursor bewegen, und mit dem OK Button auswählen. Derzeit ist egal welchen Menüpunkt man wählt, man landet immer im gleichen Programmteil für die Einstellung des RGB-Wertes über die Potis. Diese werden dann auch direkt über die Kanäle 1-3 per DMX ausgegeben. Aber einfach mal den Code durchgehen, dort habe ich ein paar Kommentare etc. eingefügt. 

// DMX-Master MG 5000 Software - schöner Name
#include <DmxSimple.h> // DmxSimple library - das hier ist die Library für die
DMX Ansteuerung

#include <TFT.h> // Arduino LCD library - Library für das Display
#include <SPI.h> // SPI library - Library für die SPI Ansteuerung des Displays
// pin definition for the Uno - Display - Pins für das Display
#define cs 10
#define dc 9
#define rst 8
// create an instance of the library
TFT TFTscreen = TFT(cs, dc, rst);
// Definition der genutzten Variablen
char sensorPrintout[4];
char rotary[4];
char red[4];
char green[4];
char blue[4];
int val; int encoder0PinA = 4; // Pin 4
int encoder0PinB = 5; // Pin 5
int encoder0Pos = 0;
int encoder0ButtonPin= 6; // und PIN 6 werden für die Eingaben
des Drehimpulsschalters genutzt

int encoder0Button = 0;
int encoder0PinALast = LOW;
int n = LOW;
int count=0;
int brightness;
int bright_r;
int bright_r_old; int bright_g;
int bright_g_old; int bright_b;
int bright_b_old; int bright_w;
int bright_w_old;
void setup() {
// Pin für DmxSimple - also der Pin an dem das Signal dann raus geht zum MAX485,
in der Schaltung der grüne Draht

DmxSimple.usePin(3);
// Anzahl der verwendeten DMX-Kanäle - hier die max. Anzahl der Kanäle eintragen
DmxSimple.maxChannel(3);
// PinModes für den Drehimpulsgeber - Pin 4,5 und 6 werden genutzt - siehe
Schaltung

pinMode (encoder0PinA,INPUT);
pinMode (encoder0PinB,INPUT);
pinMode (encoder0ButtonPin,INPUT);
// Ausgabe der Anzeige auf dem LCD Screen
TFTscreen.begin();
// clear the screen with a black background
TFTscreen.background(0, 0, 0);
// Textfarbe Weiß
TFTscreen.stroke(255, 255, 255);
// Textgröße 1
TFTscreen.setTextSize(1);
// Überschrift
TFTscreen.stroke(255,255,0);
TFTscreen.text("DMX-MASTER MG 5000", 27, 3);
TFTscreen.text("by Mike Gross | 2017", 22, 12);

}
void loop() {

TFTscreen.setTextSize(1);
TFTscreen.stroke(255, 255, 255);
TFTscreen.text("Foyer",65,40); // Menüpunkt 01
TFTscreen.text("Kleine Arena",45, 50); // Menüpunkt 02
TFTscreen.text(" ???",65,60); // Menüpunkt 03
TFTscreen.text(" ???",65,70); // Menüpunkt 04
TFTscreen.text("Manuell",61,80); // Menüpunkt 05
TFTscreen.stroke(255,0,0); // hier kommen jetzt ein paar bunte Linien - bischen
Deko Schnickschnack

TFTscreen.line(0,30,160,30);
TFTscreen.stroke(100,0,0);
TFTscreen.line(0,31,160,31);
TFTscreen.stroke(50,0,0);
TFTscreen.line(0,32,160,32);
TFTscreen.stroke(50,0,0);
TFTscreen.line(0,95,160,95);
TFTscreen.stroke(100,0,0);
TFTscreen.line(0,96,160,96);
TFTscreen.stroke(255,0,0);
TFTscreen.line(0,97,160,97);
TFTscreen.stroke(0,255,0);
TFTscreen.text("Auswahl per OK-Button",20,106);
do { // Schleife für Menüauswahl beginnt
do { // hier folgt jetzt die Abfrage des Drehimpulsgebers
n = digitalRead(encoder0PinA);
if ((encoder0PinALast == LOW) && (n == HIGH)) {
if (digitalRead(encoder0PinB) == LOW) {
encoder0Pos--;
} else {
encoder0Pos++;
}
}
encoder0Button=digitalRead(encoder0ButtonPin);
} while ((n==encoder0PinALast) ^ (encoder0Button==HIGH));
encoder0PinALast = n;
if (encoder0Pos>5) {
encoder0Pos=5;
}
if (encoder0Pos<1) {
encoder0Pos=1;
}
// entsprechend der resultierenden Position wird im folgenden der Cursor an die
neue Position gezeichnet, und in der alten gelöscht

if (encoder0Pos==1) {
TFTscreen.stroke(0,255,0);
TFTscreen.text(">> <<",20,40);
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,50);
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,60);
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,70);
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,80);
}
if (encoder0Pos==2) {
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,40);
TFTscreen.stroke(0,255,0);
TFTscreen.text(">> <<",20,50);
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,60);
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,70);
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,80);
}
if (encoder0Pos==3) {
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,40);
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,50);
TFTscreen.stroke(0,255,0);
TFTscreen.text(">> <<",20,60);
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,70);
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,80);
}
if (encoder0Pos==4) {
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,40);
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,50);
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,60);
TFTscreen.stroke(0,255,0);
TFTscreen.text(">> <<",20,70);
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,80);
}
if (encoder0Pos==5) {
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,40);
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,50);
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,60);
TFTscreen.stroke(0,0,0);
TFTscreen.text(">> <<",20,70);
TFTscreen.stroke(0,255,0);
TFTscreen.text(">> <<",20,80);
}
// hier folgt die Abfrage des Buttons im Drehimpulsgeber

encoder0Button=0;
encoder0Button=digitalRead(encoder0ButtonPin);
} while (encoder0Button==LOW); // die Schleife der Menüauswahl wird solange
wiederholt bis der Button des Drehimpulsgebers gedrückt wird

encoder0Button=HIGH; // warum ????
TFTscreen.stroke(0,0,0);
TFTscreen.background(0,0,0);
delay (1000); // kleine Verzögerung, falls einer den Button nicht los lässt
// Beschriftung 1-3 der Buttons
TFTscreen.stroke(0, 255, 0); TFTscreen.text("1 2 3",15,95);

do {

// Abfrage des Drehimpulsgebers, wobei das hier gerade nicht notwendig ist, nur der
Button ist in dem Teil von Bedeutung

n = digitalRead(encoder0PinA);
if ((encoder0PinALast == LOW) && (n == HIGH)) {
if (digitalRead(encoder0PinB) == LOW) {
encoder0Pos--;
} else {
encoder0Pos++;
}
} encoder0PinALast = n;
// Abfrage der Drehpotis - Anpassung der eingelesenen Werte (0-1023) in einen Bereich
von 0-255 für RGB

bright_r=map(analogRead(A0),0,1023,0,255);
bright_g=map(analogRead(A1),0,1023,0,255);
bright_b=map(analogRead(A2),0,1023,0,255);
bright_w=map(analogRead(A3),0,1023,0,255);
// Abfrage des Buttons des Drehimpulsgebers
encoder0Button = 0;
encoder0Button=digitalRead(encoder0ButtonPin);
// von RGB wird jeweils der Wert des 4. Potis abgezogen, wenn kleiner 0 dann bleibt
der Wert bei 0

// also als Offset für alle Potis, maximal aber Abzug nur bis 0
bright_r=bright_r-bright_w; // Abzug des 4. Potis bei Rot
if (bright_r<0) { bright_r=0;
}
bright_g=bright_g-bright_w; // Abzug des 4. Potis bei Grün
if (bright_g<0) {
bright_g=0;
}
bright_b=bright_b-bright_w; // Abzug des 4. Potis bei Blau
if (bright_b<0) {
bright_b=0;
}
// Umwandeln der Zahlenwerte in Strings
String sensorVal = String(encoder0Pos);
String redVal = String(bright_r);
String greenVal = String(bright_g);
String blueVal = String(bright_b);
// Strings in Chararrays für die Anzeige
sensorVal.toCharArray(sensorPrintout, 4); redVal.toCharArray(red, 4);
greenVal.toCharArray(green, 4);
blueVal.toCharArray(blue, 4);
// die an den Potis eingestellten Werte werden an das DMX-Device gesendet
// bzw. bright_r an Kanal 1, bright_g an Kanal 2 etc.
// das passt natürlich in diesem Code nur weil der verwendete Scheinwerfer
// im 3 Kanalmode läuft, und der Scheinwerfer dabei für die ersten 3 Kanäle R,G
und B erwartet

// das müsste natürlich entsprechend des zu steuernden Gerätes angepasst werden
DmxSimple.write(1, bright_r);
DmxSimple.write(2, bright_g);
DmxSimple.write(3, bright_b);
DmxSimple.write(4, 90); // wird aktuell nicht verwendet - oben sind nur 3 Kanäle
eingestellt

// Counter für Bildschirmrefresh
count=count+1;
// Bildschirm wird alle 100 Zählerwerte erneuert
// count==200
//Änderung der Anzeige nur bei Änderung der Werte
if ((bright_r_old!=bright_r)||(bright_g_old!=bright_g)||(bright_b_old!=bright_b)){

TFTscreen.stroke(0, 0, 0); // Ausgabe der RGB Werte auf dem Display
TFTscreen.fill(0,0,0);
TFTscreen.rect(0,20,30,10);
TFTscreen.rect(15,80,135,10);
TFTscreen.rect(30,40,20,50);
TFTscreen.stroke(255, 255, 255);
TFTscreen.setTextSize(1);
TFTscreen.stroke(255, 0, 0);
TFTscreen.text("Rot",15,70);
TFTscreen.text(red,15,80);
TFTscreen.stroke(0, 255, 0);
TFTscreen.text("Gruen",70,70);
TFTscreen.text(green,80,80);
TFTscreen.stroke(0, 0, 255);
TFTscreen.text("Blau",120,70);
TFTscreen.text(blue,125,80);
if (encoder0Button == HIGH){
TFTscreen.rect(30,40,20,50);
encoder0Button = 0;
}

TFTscreen.noStroke(); TFTscreen.stroke(255,255,255);
TFTscreen.setTextSize(1);
// TFTscreen.text(sensorPrintout, 0, 20);
TFTscreen.fill(bright_r,bright_g, bright_b); // farbiges Rechteck
TFTscreen.rect(60,10,50,50); count=0;
bright_r_old=bright_r;
bright_g_old=bright_g;
bright_b_old=bright_b;
} } while (encoder0Button==LOW); // Das ändern der Lichtfarbe geht solange bis wieder
der Button gedrückt wird, dann wird die Schleife beendet und man springt wieder
ins Hauptmenü

encoder0Button=LOW;
TFTscreen.stroke(0,0,0);
TFTscreen.background(0,0,0);
delay (1000);
}

Kommentare: 0