Forum: Mikrocontroller und Digitale Elektronik LED PWM mit 10 RGBs


von Horst (Gast)


Lesenswert?

Hey

Ich bin hier langsam echt am verzweifeln. Kann mir mal wer unter die 
arme greifen bzw. eine Gedankenstütze geben?

Fakten:
- 10 RGB LEDs
- ATmega644 mit 16 MHz

Die Frage ist erstmal ob sich das überhaupt ausgeht mit 30 SoftPWMs?
Wenn ja, wie sollte ich es am besten lösen? (Hab dazu schon den Soft-PWM 
Artikel gelsen, aber ich vermute der Code hat ein paar lücken?)

Ich hab bereits einen test gemacht, aber größtenteils flackert da alles 
nur anstatt die helligkeit zu verändern =D

Vielen dank
horst

von Falk B. (falk)


Lesenswert?

@Horst (Gast)

>Ich bin hier langsam echt am verzweifeln.

Baby don't worry, bout a thang, every little thing s'go be alright . . .

>- 10 RGB LEDs
>- ATmega644 mit 16 MHz

Yup.

>Die Frage ist erstmal ob sich das überhaupt ausgeht mit 30 SoftPWMs?

>Wenn ja, wie sollte ich es am besten lösen? (Hab dazu schon den Soft-PWM
>Artikel gelsen, aber ich vermute der Code hat ein paar lücken?)

Nö, der passt.

>Ich hab bereits einen test gemacht, aber größtenteils flackert da alles
>nur anstatt die helligkeit zu verändern =D

Tja, was hast du denn gemacht? Nimm den Code erstmal ohne Änderungen für 
8 Kanäle. Wenn das läuft kannst du ihn auf 32 Kanäle aufbohren. Ist 
alles vorbereitet.

MFG
Falk

von Horst (Gast)


Lesenswert?

Hey

Habs mittlerweile rausgefunden, waren einige andere Fehler noch drinnen 
:) Also die Helligkeit steuern geht nun
1
 Baby don't worry, bout a thang, every little thing s'go be alright . . .

haha, thanks
1
Tja, was hast du denn gemacht? Nimm den Code erstmal ohne Änderungen für
2
8 Kanäle. Wenn das läuft kannst du ihn auf 32 Kanäle aufbohren. Ist
3
alles vorbereitet.


Was ich gemacht habe ist eigentlich ganz simple ohne Timer.
Im Hauptprogramm inkrementiere ich einen Zähler und schaue anschließend 
ob eine von den drei Farben der aktuellen LED ausgeschaltet werden muss. 
Wenn alle drei aus sind gehts zur nächsten LED etc.

Das ganze muss noch gemultiplext werden in einer 2x5 Matrix.

Bis zu einer LED anzahl von 5 gleichzeitig gehts noch ok (flickert ein 
wenig bei niedrigen Werten). Bei 4 Gleichzeitig ist Perfekt, nur da 
fehlen halt ein paar. :D

Ich vermute das ich einfach zu langsam bin....  hat da jemand 
Vorschläge?

von Horst (Gast)


Lesenswert?

Problem gelöst:

Maximalen Wert des Counters von 255 auf 100 reduziert, damit hab ich 
genügend Zeit.

Falls wer noch mehr verbesserungsvorschläge hat, bitte darum :)

danke
Horst

von Simon B. (nomis)


Lesenswert?

Horst schrieb:
> Im Hauptprogramm inkrementiere ich einen Zähler und schaue anschließend
> ob eine von den drei Farben der aktuellen LED ausgeschaltet werden muss.
> Wenn alle drei aus sind gehts zur nächsten LED etc.
>
> Das ganze muss noch gemultiplext werden in einer 2x5 Matrix.
>
> Bis zu einer LED anzahl von 5 gleichzeitig gehts noch ok (flickert ein
> wenig bei niedrigen Werten). Bei 4 Gleichzeitig ist Perfekt, nur da
> fehlen halt ein paar. :D
>
> Ich vermute das ich einfach zu langsam bin....  hat da jemand
> Vorschläge?

Äh, ja.  :)

Also vorab: Du hast 32 I/O-Pins, von denen (vermutlich) 2 für eine 
Kommunikationsschnittstelle (Seriell, I2C) benötigst. Bleiben noch 3x10 
übrig.

Brauchst Du von denen noch welche für was anderes? Oder könntest Du da 
direkt alle RGB-LEDs anschließen? Dann könntest Du Dir die multiplexerei 
nämlich sparen...

Wenn das ginge, dann wäre ein sehr einfacher Ansatz folgender:

Du legst die Anzahl der Helligkeitsstufen fest, in denen Du die 
Einzelkanäle steuern können möchtest, z.B. 64.

Du legst ein Array von 4x64 Bytes an. Je 4 Bytes beschreiben den 
Portstatus PORTA bis PORTD.

Du merkst Dir in einer Variable in welcher Zeitscheibe Du gerade bist.

Im Timerinterrupt (ja, mach es mit dem Timer, sonst flackert es bei z.B. 
beim Verarbeiten serieller Kommunikation) setzt Du die vier Ports aus 
der akt. Position im Array und aktualisierst anschließend die aktuelle 
Position.

Damit kannst Du auch hervorragend "double-buffering" machen:
Im Hauptprogramm hast Du alle Zeit der Welt, ein zweites Array nach 
Userdaten zu füllen. Wenn das fertig vorbereitet ist, setzt Du ein Flag, 
das der Timer-ISR signalisiert, dass es doch bitte beim nächsten 
vollständigen Zyklus auf das andere Array umschwenken soll. Wenn das 
geschehen ist (was die Timer-ISR z.B. durch rücksetzen des Flags 
signalisieren kann), dann kann das Hauptprogramm das erste Array mit 
neuen Userdaten vorbereiten.

Vorteil: Schnelle Timer-ISR, die fast nix tun muss, kein Multiplexing
Nachteil: Pinwucher, Speicherwucher

Man kann in dieses Schema natürlich problemlos ein Multiplexing 
integrieren, falls man z.B. mehr LEDs verwenden will oder Pins für noch 
was anderes braucht.

Wenn man dem Speicherwucher zu Leibe rücken möchte, kann man das Schema 
auch dahingehend umbauen, dass man die Zeitscheiben nicht gleich breit 
macht und in dem "Framebuffer" die Bits des Helligkeitswerts direkt 
speichert. Man hat dann nur noch (bei 64 Helligkeitsstufen) 6x4 Bytes 
für den Framebuffer, muss dann aber etwas mehr Hirnschmalz in die ISR 
investieren.

In einem Bastelprojekt von mir multiplexe ich 8x18 = 144 (monochrome) 
LEDs mit 32 Helligkeitsstufen nach diesem Schema. Funktioniert gut, man 
muss das Ding schon schnell hin- und herschütteln um das 
Multiplex-Flimmern zu sehen...

Viele Grüße,
        Simon

von Horst (Gast)


Lesenswert?

1
Also vorab: Du hast 32 I/O-Pins, von denen (vermutlich) 2 für eine
2
Kommunikationsschnittstelle (Seriell, I2C) benötigst. Bleiben noch 3x10
3
übrig.

Nö, nicht ganz, Ich hab noch etliche Taster die eingänge brauchen usw... 
würd sich nicht aussgehen.

1
Im Timerinterrupt (ja, mach es mit dem Timer, sonst flackert es bei z.B.
2
beim Verarbeiten serieller Kommunikation) setzt Du die vier Ports aus
3
der akt. Position im Array und aktualisierst anschließend die aktuelle
4
Position.

Ja, das könnte man noch verbessern mit dem Timer, ne Idee wie oft der 
kommen müsste? alle 500us?
1
In einem Bastelprojekt von mir multiplexe ich 8x18 = 144 (monochrome)
2
LEDs mit 32 Helligkeitsstufen nach diesem Schema. Funktioniert gut, man
3
muss das Ding schon schnell hin- und herschütteln um das
4
Multiplex-Flimmern zu sehen...

cool, was mach ich mit 144 LEDs? :D
ne Spitzen Leistung, werd ich evt. nach den RGBs angehen, aber RGB ist 
einfach cooler =D



danke
Horst

von Simon B. (nomis)


Lesenswert?

Horst schrieb:
> Ja, das könnte man noch verbessern mit dem Timer, ne Idee wie oft der
> kommen müsste? alle 500us?

Generell: je schneller desto besser, desto weniger wird das PWM-Flimmern 
sichtbar. Konkrete Zahlen habe ich nicht, ich würde versuchen, daran zu 
tunen, wenn es prinzipiell funktioniert.

Erstaunlicherweise nehme ich bei modernen Auto-LED-Rücklichtern durchaus 
gelegentlich ein Flimmern wahr, wenn ich peripher ein Auto vorbeifahren 
sehe oder eine schnelle Augenbewegung mache. Mich erstaunt, dass die 
Hersteller da nicht auf Nummer Sicher gegangen sind und einfach mal eine 
absurd hohe PWM-Frequenz genommen haben...

Viele Grüße,
        Simon

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.