Ich bin gerade in der Versuchsphase. Möchte mir eine Tischlampe bauen.
Dabei sollen 3 RGB-LEDs einen Bergkristall von unten beleuchten. Es sind
also insgesamt neun LEDs.
Bis jetzt habe ich erfolgreich eine dreifache nicht-lineare PWM in
Software verwirklicht. Das läuft auf einem ATMega8. Wegen der Auflösung
von 10 Bit ist der uC mit anderen Aufgaben überfordert. Er packt es
gerade noch ein paar Taster auszulesen. Einige Verzweigungen mehr und
die LESs beginnen zu flackern. Deshalb wird sich um jede RGB-LED ein
eigener ATMega8 kümmern. Eine kleinere Auflösung ist nicht erwünscht.
Der Master-uC soll ein ATMega32 sein. Er wird die Farbspiele abarbeiten
und die nötigen Daten an die drei ATMega8 schicken. Zusätzlich wird es
vier Taster und einen Drehimpulsencoder geben, die ebenfalls an dem
ATMega32 angeschlossen sein werden.
Mein Problem ist jetzt die Kommunikation zwischen dem Master-uC und den
ATMega8. Zunächst habe ich an eine parallele "Datenübertragung" gedacht.
Dabei sollten einfach 6 Pins eines Ports des ATMega8 und des 32er
zusammengeschaltet werden. Somit könnte ich 64 Helligkeitsstufen
übertragen. Das hat auch gut funktioniert, zumindest provisorisch mit
drei Tastern und 8 möglichen Kombinationen. Der Rechenaufwand
unterscheidet sich aber nicht von 6 Eingängen ... Dann ist mir
einfefallen, dass ich ja jede Farbe getrennt ansteuern können muss. Was
soll ich jetzt machen?
Eine serielle Datenübertragung wird wohl kaum realisierbar sein, da zu
wenig Ressorucen bereitstehen, zumindest denke ich das. Habe keine
Erfahrung mit serieller Übertragung und muss deshalb hier nachfragen, ob
das gehen könnte. Zusätzlich werde ich die Taktfrequenz von 8 auf 16Mhz
erhöhen. Aber das ist auch kein großer Sprung.
Mir kommt bis jetzt eine einzige Lösung in den Kopf:
Die restlichen 2 Pins des Ports an dem die Helligkeitsstuffen anliegen,
könnte ich nutzen, um die Farbe einzustellen, die verändert werden soll.
Aber ob das funktioniert? Angenommen ich stelle Rot auf 15 ein und
möchte nun Blau auf 3 haben. Ich schalte also auf Blau um, aber die
Helligkeit ist immernoch auf 15. Somit wird Blau kurzzeitig mit der
Helligkeit 15 leuchten. Vielleicht könnte man neben den drei Zuständen
R,G und B noch einen vierten einplanen, der ebenfalls über die
zusätzlichen zwei Leitungen realisiert wird. Er wäre sozusagen der
Leerlauf, in ihm wird keine der Farben von der aktuell anliegenden
Heligkeitstuffe beeinflusst. So könnte man zuerst die Helligkeitsstuffen
einstellen und dann die Farbe wählen und gleich wieder zurück in den
Leerlauf schalten. Die Frage ist nur, wie sich das bei schnellen
Farbwechseln aller drei LEDs schlagen wird. Ob da nicht Ruckler entshene
oder der Master-uC ins Schwitzen kommt?
Ich befürchte leider, dass selbst diese Methode zu viel Rechenzeit des
ATMega8 verbrauchen könnte.
Raus mit Ideen und Vorschlägen! Bitte :-)
Ohne auf das Problem mit dem Dimmen von 3 RGB-LEDs einzugehen: Für
serielle Kommunikation braucht's fast gar keine Ressourcen, denn das
läuft interruptgesteuert. Die paar Takte, die du zum Abarbeiten eines
empfangenen Bytes brauchst, fallen gar nicht auf..
Nein nein, zerbrich Dir lieber den Kopf, wie Du das mit einem Controller
lösen kannst!
Vorschlag: Statemachine im Timerinterrupt, wobei die Zeiten dynamisch
berechnet werden. Beispiel:
Folgende (bereits linearen) Helligkeiten
R1: 0
G1: 200
B1: 112
R2: 756
G2: 34
B2: 820
R3: 1000
G3: 345
B3: 345
Beim ersten Interrupt sortierst Du Dir die Liste der Zeiten so, dass Sie
der Reihe nach abgearbeitet werden können. Es entsteht eine
Ereignisliste:
R1: 0 -> fliegt aus der todo-Liste ganz raus
G2: 34
B1: 112
G1: 200
G3: 345
B3: 345
R2: 756
B2: 820
R3: 1000
Der Ablauf ist dann:
Interrupt 1: Relevante LEDs einschalten, 34 Zyklen bis zum nächsten Int
Interrupt 2: G2 aus, 78 Zyklen bis zum nächsten Int
Interrupt 3: B1 aus, 88 Zyklen bis zum nächsten Int
Interrupt 4: G1 aus, 145 Zyklen bis zum nächsten Int
Interrupt 5: G3, B3 aus, 411 Zyklen bis zum nächsten Int
Interrupt 6: R2 aus, 64 Zyklen bis zum nächsten Int
Interrupt 7: B2 aus, 180 Zyklen bis zum nächsten Int
Interrupt 8: R3 aus, 24 Zyklen, damit 1024 Zyklen durchlaufen wurden
Interrupt 9: Wie Interrupt 1
Es werden also immer die Differenzen zum nächsten Ereignis berechnet.
Alles läuft im Hintergrund bei minimaler Prozessorbelastung.
@Jens P.: Wie sieht die einfachste serielle Verbindung zwischen zwei uCs
aus und kann man an einen uC gleich drei andere anbinden?
@Chrisi Das original: Ich kann mir nicht vorstellen, wie das
funktionieren soll. Ersetzt das die "normale" PWM-Methode? Könnte man
stattdessen nicht einfach eine Tabelle aus dem ROM abarbeiten? Durch
einen Interrupt werden die Werte nacheinander ausgelesen und an die
PWM-Methode übergeben. Jeder dritte Wert entspricht jeweils einer LED.
ps: Gerade habe ich eine neunfache PWM ausprobiert. Das Licht flackert
mit etwa 40Hz, ist also alles andere als Optimal für eine Tischlampe.
Maxim wrote:
> ps: Gerade habe ich eine neunfache PWM ausprobiert. Das Licht flackert> mit etwa 40Hz, ist also alles andere als Optimal für eine Tischlampe.
Ich betreibe eine 64-fach PWM an einem Mega8. Ohne Flackern.
OK. Ich hab nur 64 Stufen aber für mich langt das Dicke.
> Einige Verzweigungen mehr und die LESs beginnen zu flackern.
Nicht wenn du die PWM in einen Timer Interrupt legst. Ich
denke da zb. an Timer1 im CTC Modus. Damit kannst du dann Taktgenau
festlegen, wieviel Zeit die PWM dem restlichen Programm noch übrig
lässt. Der Interrupt unterbricht dann ganz einfach kurzfristig die
'Verzweigungen mehr'. Der restliche Programmablauf geht zwar etwas
in die Knie, wenn der Timer nur noch wenig übrig lässt, aber um
ein paar Taster abzufragen und einen Lichtwechsel zu berechnen langt
es allemal.
Die Idee mit den 3 Prozessoren finde ich nicht gut. Zuviel Aufwand,
zu komplex. Da würde ich den Prozessor noch lieber übertakten.
>Ich betreibe eine 64-fach PWM an einem Mega8. Ohne Flackern.>OK. Ich hab nur 64 Stufen aber für mich langt das Dicke.
Was verstehst du unter 64-fach PWM? Der ATMega8 hat doch nichtmal
soviele Pins?!
Maxim wrote:
>>Ich betreibe eine 64-fach PWM an einem Mega8. Ohne Flackern.>>OK. Ich hab nur 64 Stufen aber für mich langt das Dicke.>> Der ATMega8 hat doch nichtmal> soviele Pins?!
Das Stichwort lautet: Schieberegister.
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Schieberegister> Was verstehst du unter 64-fach PWM?
64 PWM Einheiten, die 64 LED unabhängig voneinander dimmen.
Allerdings, wie gesagt, nicht mit 10 Bit-PWM sondern weniger.
@Maxim
Naja, sollte nur ein Denkanstoss sein. Bei meinem Vorschlag hast Du eine
lächerliche mittlere Interruptfrequenz von 1kHz.
Die Timerzeiten müssen bei jeder Änderung einer Helligkeit neu berechnet
werden, das hat nix mit einer ROM-Tabelle zu tun.
>Das Stichwort lautet: Schieberegister.
Das kenne ich sogar noch aus dem Unterricht ... :-)
>Naja, sollte nur ein Denkanstoss sein. Bei meinem Vorschlag hast Du eine>lächerliche mittlere Interruptfrequenz von 1kHz.
Das hört sich vielversprechend an aber leider auch zu komplex.
Hoffentlich werden wir das in der Schule durchnehmen.
Zurück zur Sache.
Mit 8-Bit-PWM hätte ich auch keine Schwierigkeiten neun LEDs
anzusteuern. Aber eine vierfache Auflösung zieht nunmal eine vierfache
Rechenlast nach sich. Die ganze Lampe wird mir insgesamt mehr als 100€
kosten, weshalb das Ergebnis nicht befriedigend, sondern mindestens gut
sein soll. Da ist mir der größere Aufwand wegen mehreren uCs recht.
Deshalb lese ich mich in die SPI-Schnittstelle ein. So kompliziert kann
es nun auch nicht sein ... ;-) Schlimmstenfalls werde ich zumindest
wissen, wie SPI funktioniet.