Hallo,
eigentlich ja ein schon häufig besprochenes Thema. Ich möchte einen
Kleinen DMX-Empfänger aufbauen der mir dann PWM-Kanäle macht.
Mir stellen sich da einige Fragen, da ich noch nicht so lange im Thema
drin stecke.
Es sollen insgesamt 5 RGB Kanäle angesteuert werden, das wären also 15
PWM Signale. Macht es Sinn, für jede Tube (5 Tubes sind es) einen
eigenen uC zu nehmen um die PWM zu generieren, oder kann man da noch
alles aus einem Controller machen?
Programmiertechnisch hätte ich noch die Frage, wie man eigentlich das
DMX512 Signal in ein PWM-Signal bring?
Und dann noch eine Programmierfrage, es sollte eine "Masterhelligkeit"
geben. D.h. es kann trotzdem RGB angesteuert werden, aber der Master
gibt vor wie hell das ganze insgesamt max. sein darf.
Vielen Dank schonmal für Antworten
@ Marian (Gast)
>PWM Signale. Macht es Sinn, für jede Tube (5 Tubes sind es) einen>eigenen uC zu nehmen um die PWM zu generieren,
Kann man machen, wenn es unbedingt eine relativ hochfrequente PWM in
Hardware sein soll.
> oder kann man da noch>alles aus einem Controller machen?
Geht auch, mit Soft-PWM.
>Programmiertechnisch hätte ich noch die Frage, wie man eigentlich das>DMX512 Signal in ein PWM-Signal bring?
Mit einem DMX2PWM Converter ;-)
Hier mal ein Ansatz.
http://www.mikrocontroller.net/forum/codesammlung?filter=dmx>Und dann noch eine Programmierfrage, es sollte eine "Masterhelligkeit">geben. D.h. es kann trotzdem RGB angesteuert werden, aber der Master>gibt vor wie hell das ganze insgesamt max. sein darf.
Dazu nimmt man einen extra DMX-Kanal und multipliziert einfach die
einzelnen RGB-Kanäle mit dem Master. Fettig.
MFG
Falk
Ich würde für jede Tube einen eigene Controller benutzen weil man die
dann auch einzel nutzen kann.
Also auf der Bühne schön verteilen und nur DMX und Strom bringen muss
und nicht zu von ner Master Tube nochmal jede andere Tube anfahren muss.
Außerdem kosten die Bauteile für einen Empfänger so zwischen 10 und 15€
würd ich mal schätzen, also durchaus vertretbar ;)
Geplant sind ca. 35cm lange Tubes, davon sollen immer 5 Stück
untereinander an ein AluRohr. Wenn ich jede einzeln ansteuere ist das
"Problem", dass ich auch bei jeder die DMX Adresse neu vergeben muss,
was dann bei einer größeren Menge auch kein Spaß mehr macht. Einzeln
werden sie eigentlich nicht benutzt.
Was die PWM angeht: Es sollte schon etwas besser werden als diverse
China-LED-Geräte bei denen das flackern schon mit dem "normalen Auge"
erkennbar ist.
Deshalb ist die erste Sache für das Projekt immer noch die
Hardware-Sache, das Programmiertechnische guck ich mir nach und nach an.
Der Aufbau wird ca. so aussehen wie im Anhang.
Bestückt wird eine Tube mit 15 Superflux RGB LED's (4-Pin).
Was ist da jetzt Sinnvoller, die 15PWM Kanäle auf mehrere uC's auslagern
oder mit Software-PWM arbeiten?
Achso, dann ist das ntürlich was anderes, ich dachte das sollen so
mannshohe Tubes werden die einzeln verteilt werden.
Das dürfte eigentlich problemlos mit Soft-PWM zu machen sein, informier
dich doch mal bischen drüber.
DMX kommt mit 250Kbad über die Leitung. Wenn du die Tubes mit LED
ausstatten willst, rat ich dir für jede Tube einen Slavecontroller zu
nehmen. Dieser stellt dir die 3 PWM für RGB zur Verfühgung. Und ich
würde eine HSV zu RGB Wandlung vorher machen. Damit kannst du wunderbar
die Helligkeit regeln, ohne dass dir der Farbwert verloren geht. Der
Mastercontroller kümmert sich nur um die DMX-Auswertung und stellt die
HSV-Werte den Slaves zur Verfühgung. Eventuell mittels SPI..
Hier mal ein HSV zu RGB Wandler mit 10bit PWM für LED in ASM. Da musst
du dich eigentlich nur noch um den Empfang der HSV-Werte vom DMX-Master
per SPI kümmern und diese 3x 8bit in den SRAM schreiben.
Bytes dazu im SRAM:
HSV_H: [0..255] (Hue) Farbwinkel
HSV_S: [0..255] (Saturation) Sättigung
HSV_V: [0..255] (Brightness) Helligkeit
Alles gut kommentiert..
Danke Steffen, ich werde mir deinen Code mal abspeichern. Allerdings ist
das ganze wirklich erstmal noch zu komplex für mich, da ich noch recht
weit am Anfang von uC's stehe.
Habe bis jetzt (siehe Uhrzeit, oh mann...) echt viel über PWM, Soft-PWM
und auch DMX-Empfang gelesen. Vieles ist mir jetzt schon deutlich klarer
geworden.
Allerdings wäre da noch eine Sache. Und zwar das DMX-Signal für einen
Kanal auf die PWM zu bringen. Die hier verlinkten Code-Beispiele aus der
Sammlung habe ich mir angeschaut.
Könnte dass evtl. nochmal jemand in Worte fassen, damit ich das
Grundlegende Prinzip erstmal verstehe, wie diese "Wandlung" vorgeht?
Ich empfange z.B. den DMX-Wert 70 auf Kanal 1.
Legt man jetzt eine "Tabelle" an, in der drin steht "Bei Wert 70 -> x
Ein- und x Ausschaltzeit"?
Sorry für die evtl. doch sehr trivialen Fragen.
Die Tabelle (LookupTabel) habe ich aus 2Gründen angelegt.
1. Die Wandlung der Werte von 8bit auf 10bit (z.B. 0=0 ; 255=1023)
2. Die linearisierung der empfunden Helligkeit
zu2:
Die vom menschlichen Auge wahrgenommene Helligkeit einer LED ist nicht
proportional zum Tastverhältnis der PWM. Bei einem geringem
Tastverhältnis (1:1023) leuchtet die LED schon gut sichtbar. Und bei
einem Tastverhältnis von 200:1023 empfindet man die Helligkeit der LED
schon fast als Maximum. Deshalb wird oft eine expotentielle Kennline zur
PWM in einer Tabelle (LookupTabel) hinterlegt.
Wie eine PWM erzeugt wird weißt du?
Ja, wie eine PWM erzeugt wird weiß ich. Die Sache der exponentiellen
Kennlinie hatte ich in der Nacht auch schon aus dem Beitrag "LED_Fading"
gelesen.
Hier wird die PWM ja über einen Timer mit Vorteiler und dann in einer
Forschleife realisiert. Das ganze also als Hardware-PWM. Klar bei den
15PWM Kanälen die ich brauche dann evtl. über die Software PWM oder eben
doch mehrere Controller.
Ich frag mich nur immer noch so halbwissen, wie man nun die Empfangenen
DMX Bytes auf die PWM bzw. eine erstellte exponentielle Kennlinie
"bringt"
Eine Hardware PWM läuft autark im Hintergrund ab. Dafür stehen dann ja
die Compare Register OCR0A und/oder OCR0B ; OCR1A und/oder OCR1B zur
Verfühgung. (je nach Controller)
Mal angenommen du hast deine PWM 8bit groß gewählt:
Das heißt, dein Zähler läuft von 0 bis 254. Beim nächsten hochzählen
wird dein Zähler wieder genullt! 254 -> 255 = 0
Bei einer Übereinstimmung von Zählerstand und Compare Register
OCR(0A;0B;1A;1B) kann eine Aktion der Ausgangspins ausgelöst werden. Zum
Beispiel Aktion:
Bei Zählerstand=0 > Ausgangspin=1
Zählerstand=Compare Register > Ausgangspin=0
Je nachdem wie du den jeweiligen Ausgangspin auf eine Aktion des Compare
Match eingestellt hast wird diese ebenfalls autark ausgeführt.
Dass heißt also ich müsste für die verschiedenen DMX-Werte die ich auf
einem Kanal empfange unterschiedliche Vergleiche zwischen dem
Zählerstand und dem Compareregister machen?
Danke nochmals für deine Antworten. So langsam wird doch alles etwas
deutlicher :)
Ein LookupTable funktioniert folgendermaßen:
Lookuptable im Flash Speicher:
Der Table hat ein Label, zum Beispiel Kennlinie. Das ist ja nichts
anderes als eine Adresse. Unter dieser Adresse stehen jetzt die
einzelnen Werte. Beim Flash Speicher 16bit breit, beim SRAM 8bit breit.
Kennlinie:
.dw 0x0000, 0x0003, 0x0009, ..u.s.w (Werte)
0 , 1 , 2 , 3 (Adresse wo der Wert gespeichert
ist)
Mal angenommen dein DMX Wert ist 3.
1.
Nun musst du nur die Ardresse des LookupTable (Kennlinie) in den
Z-Pointer laden.
ldi zl, low (Kennlinie*2)
ldi zh, high (Kennlinie*2)
Die *2 brauchst du zur Adressierung im Flash Speicher. Das will ich hier
jetzt aber nicht weiter erklären warum das so ist.
2.
Du addierst zu der Adresse deinen DMX Wert. Kennlinie + 3
Damit bekommst du nun auch den 3. Wert in deinem LookupTable.
clr Null (Null ist ein oberes Register; z.B. r20)
add zl, DMX_Wert
adc zh, Null
3.
Du ladest den 3. Wert aus deinem LookupTable in das Register r0 und
kopierst es in ein OCR Compare Register.
lpm
mov OCR0A, r0
fertig!
>Dass heißt also ich müsste für die verschiedenen DMX-Werte die ich auf>einem Kanal empfange unterschiedliche Vergleiche zwischen dem>Zählerstand und dem Compareregister machen?
Ja. Aber bedenke, in Hardware hast du nur 2 Vergleichsregister pro
Zähler. Und max. 2 Zähler.
Das ergibt eine max. 4 PWM Kanäle.
Allerdings ist die Hardware PWM vollkommen autark. Du musst sozusagen
nur das OCR (Compare Register) neu beschreiben und schon hast du die
neue PWM.
Stell dir das ganze doch mal etwas vereinfacht vor, z.B. mit einer PWM
die nur 10 Stufen kenn.
Du hast nun einen Timer, der ständig von 0 bis 10 hochzählt. Außerdem
gibt es ein Steuerregister, in dem steht bei welchem Timer-Wert der
Prozessor seinen Ausgangspin umschalten soll.
Steht in dem Register also "5", schaltet er beim 5. Timer-Schritt um.
Sieht dann so aus:
Timer Ausgang
1 1
2 1
3 1
4 1
5 1
6 0
7 0
8 0
9 0
10 0
Steht in dem Register eine andere Zahl, schaltet der Pin automatisch
z.B. erst bei "7" um.
Mit der Umschalterei hast du im Programm nichts zu tun. Du startest
einmalig den Timer und speicherst den gewünschten PWM-Wert im
Steuerregister. Der Timer läuft im Hintergrund und schaltet die
Ausgänge.
Während der Timer läuft, kannst du natürlich den Wert im Steuerregister
ändern. Beim nächsten Durchlauf schaltet der Pin dann mit dem geänderten
Wert.
Der Timer im Atmega hat z.B. 8 Bit, läuft also von 0 bis 255.
Ein Byte vom DMX-Bus kannst du direkt in das Steuerregister schreiben,
wobei 0=0% PWM und 255=100% PWM entsprechen.
Also ich denke die "normale" Hardware-PWM + DMX habe ich jetzt
verstanden. Der Ablauf im Programm wäre dann:
Nach dem hochfahren Standart-mäßig alle PWM's auf 0%, dann warten auf
neue DMX-Bytes -> Wenn Kanal stimmt, dann neuen Wert ins Register für
die PWM übernehmen?
Die Sache von Steffen, LookUpTable, schau ich mir jetzt nochmal intensiv
an.