Forum: Projekte & Code [STM32] Binäruhr bzw 12x4 RGB LED Display mit WS2812


von Michael F. (startrekmichi)


Angehängte Dateien:

Lesenswert?

Moin,

hier über's Forum ist letzens eine Sammelbestellung von speziellen RGB 
LEDs zusammengekommen: Beitrag "[Mitbestellung] SMD5050 RGB-LED mit integriertem 8-bit PWM Controller"

Diese LEDs haben bereits einen 8bit PWM controller integriert und werden 
über ein serielles Protokoll angesprochen (siehe genannter Thread). Ich 
habe mir als erste Anwendung folgendes ausgedacht:
a) Ein allgemeines 12x4 RGB Display, das über diverse Schnittstellen 
(UART, I2C, o.ä.) angesteuert werden kann und ev schon etwas Intelligenz 
bezüglich Farben/Formen/Verläufen mitbringt.
b) Eine Binäruhr. Es gibt ja mitlerweile einige Pseudo-Binäruhren zu 
kaufen, bei denen man einfach nur die LEDs zählen muss. Ich will aber 
eine richtige mit "echter" Binärdarstellung. Klar ist das nix neues, 
aber es ist 1. auf dem STM schnell gemacht und 2. muss jeder Bastler in 
seinem Leben einmal eine Uhr gebaut haben ;-)

Zum Testen habe ich jetzt mal mit b) abgefangen. In der endgültigen 
Version wollte ich einen STM32F1 verwenden, vorläufig teste ich es aber 
mit meinem STM32F4DISCOVERY. Den Code muss man dann noch entsprechend 
abändern, insbesondere die RTC ist bei den beiden Reihen 
unterschiedlich. Insgesamt ist es eher als "work in progress" anzusehen, 
v.a. den Code zur Ansteuerung der LEDs wollte ich aber schon mal 
hochladen.

Aktueller Stand:
- Ansteuerung der LEDs funktioniert (per Timer PWM+DMA)
- "Umrechnen" der Uhrzeit in Pixel geht
- Die RTC läuft mit dem internen 32kHz Takt (zu ungenau für eine Uhr, 
aber der Uhrenquarz des Discovery ist nicht bestückt und für's debuggen 
reicht's)
- Die Uhrzeit ist noch hartcodiert und kann nicht zur Laufzeit geändert 
werden. Dafür muss ich mir noch ein Bedienkonzept überlegen.

Zum Code:
Ich benutze einen Timer (21MHz) im PWM-Modus, um das Datensignal für die 
LEDs zu erzeugen. Wenn neue Daten auf's Display sollen, muss man nur 
"ws2812_update_leds()" aufrufen. Diese Funktion rechnet die 24bit 
RGB-Daten in Timer-Werte um und erstellt daraus ein Array, das dem DMA 
übergeben wird. Diese Umrechnung dauert 260/103/50µs (O0/Os/O3), der 
Rest (sprich das eigentliche Senden der Daten) läuft dann im Hintergrund 
per DMA ab.


Anhang:
- der aktuelle CoIDE-Workspace
- eagle layout der Display-Platine
- qick&dirty "Frontplatten" für die Binäruhr
- den Ansteuercode habe ich noch mal separat angehängt, dann kann man 
direkt mal reinschauen.

von Tobi B. (tobib)


Lesenswert?

Hallo Michael,

habe den Thread vor ein paar Tagen gefunden und interessiert mich auch 
gerade, da ich was ähnliches vor habe.

Daher würde mich der aktuelle Stand interessieren, ist ja schon eine 
Weile her. Bei mir soll es später auch auf einem F103 oder auf dem F0 
Discovery-Board laufen.

Kannst du den aktuellen Stand vielleicht nochmal posten?

von Fabian L. (fabls)


Lesenswert?

Mich würde es auch sehr interessierien!

von Lothar L. (lole)


Lesenswert?

Hallo Michael,

interessanter Ansatz mit PWM+DMA und super umgesetzt. Der RAM Bedarf ist 
natürlich enorm, was beim F4 zwar keine Rolle spielt, wenn aber ein 
kleineres Teil zum Einsatz kommen soll und dann vielleicht noch mehr 
LEDs angesteuert werden sollen?? Wenn ich meine Versuche richtig deute, 
nimmt sich der Compiler für ein uint8_t ein ganzes Wort, also 4Byte. Ich 
habe mit einem halben Meter (30 LEDs) auf einem STM32VLDisco 
experimentiert, an DMA habe ich mich aber nicht ran getraut, also Bits 
in einer Schleife geschoben.
Wenn mal Zeit ist will ich das auf 8 Streifen (240 LEDs, 30x8) 
erweitern. Auf dem Alublech kleben sie schon. Die 8kB RAM sind da nicht 
so üppig und 24MHz... na ja, reichen. Für die LEDs habe ich eine Tabelle 
drin, exp. Kennlinie. Im Test dimmen die 30 LEDs gleitend zwischen 
Zufallswerten, jede für sich.
Wenn's interessiert kann ich die Zip mal reinstellen (CooCox Projekt).

Grüße Lothar

von tobi (Gast)


Lesenswert?

Hallo,
Wäre an dem ZIP interessiert, zwar find ich DMA interessant, aber bisher 
läufts bei mir leider noch nicht...

von Lothar L. (lole)


Angehängte Dateien:

Lesenswert?

Hallo Tobi,

DMA ist schon interessant, wenn nur sporadisch ein Stream rausgeschoben 
wird und dabei jedes Bit als PWM-Wert berechnet und gespeichert werden 
muss?? Es gibt immer viele Ansätze, ein Problem anzugehen. Das ist ja 
auch der Sinn des Forums, mal sehen, wie das ein anderer macht. 
Einfacher ist es erst mal Bits zu schieben um mit den Ressourcen eines 
STM32VL auszukommen. Mein Ziel war es, die Teile erst mal zum Leuchten 
zu bringen. Mit 8x30 ist auch Lauftext mit scrollen in alle Richtungen 
möglich. Schau es Dir an. Ich hoffe, die Quellen sind ausreichend 
kommentiert. Wie Du am Datum siehst, die Spielerei ist schon etwas 
angestaubt und .... liegen geblieben.

Grüße Lothar

von Michael F. (startrekmichi)


Lesenswert?

Ich habe da leider fast nichts mehr dran gemacht (zu viel anderes zu 
tun) und werde in den nächsten Wochen auch nicht dazu kommen.

Der Hauptgrund den Code hier hochzuladen war eigentlich die Ansteuerung 
der LEDs per TIM+DMA, weil ich das bisher so noch nicht gesehen hatte. 
Dass es nicht der ressourcenschonendste Weg ist, ist mir durchaus 
bewusst.

Der Nachteil an DMA ist eben, dass die Daten schon komplett fertig im 
RAM liegen müssen. Bei größeren Displays könnte man ev. segmentweise 
arbeiten und in obigem Beispiel die 8 Streifen nacheinander berechnen 
und rausschieben. Es ist eben wie immer ein Trade-off zwischen 
Prozessorlast und Speicherverbrauch.

Ev. gibt es noch eine klevere Methode den SPI zu missbrauchen und 
dadurch nur noch Bytes (und keine Bits wie jetzt) abspeichern zu müssen. 
Das würde den Speicherverbrauch des DMA-Puffers immerhin um Faktor 8 
reduzieren.

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.