Forum: Mikrocontroller und Digitale Elektronik STM32Fxx und WS2812 LEDs ohne DMA


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von MichaelS (Gast)


Lesenswert?

Hi,

ich versuche mit der lightweight WS2812 Library von Tim 
(https://github.com/cpldcpu/light_ws2812) meine WS2812 LED Strips auf 
einem STM32F4xx respektive STM32F1xx zum laufen zu bringen, leider 
bisher ohne erfolg da die Library für LPC's ausgelegt ist.

#include "stm32f4xx.h"

Ich habe schon versucht es anzupassen, aber da meine Assemblerkenntnisse 
leider nicht so ausgeprägt sind, vorallem in Inline Assembler, ist es 
leider nichts geworden ;(

Nunmal zum wesentlichen. Ich habe mein STM32F4xx soeit konfiguriert das 
ich eine System Clock von 32 MHz habe. Dementsprechend habe ich auch die 
Library angepasst.

#define ws2812_cpuclk 32000000

Allerdings ist mir dort direkt, da ich die Output line am DSO haengen 
habe, das die Frequenz keine 800kHz sind. Also habe ich die 
ws2812_cpuclk nochmal versucht anzupassen. Bei 28000000 Hz habe ich 
optimale 800kHz, was aber ja nicht so sein soll denke ich, da die 
anderen Timings für High und Low dementsprechend "verzogen" sind.

Ich habe als Port Set und Clear Register folgende Aenderungen 
vorgenommen:

#define ws2812_port_set ((uint32_t*)&GPIOA->BSRRH)  // Address of the 
data port register to set the pin
#define ws2812_port_clr  ((uint32_t*)&GPIOA->BSRRL)  // Address of the 
data port register to clear the pin

#define ws2812_mask_set  GPIO_Pin_6    // Bitmask to set the data out 
pin
#define ws2812_mask_clr  GPIO_Pin_6    // Bitmask to clear the data out 
pin

So bekomme ich wie schon geschrieben auch ein Datensignal heraus, 
allerdings nicht im geforderten WS2812 Muster, desweiteren wird die
ws2812_sendarray Funktion nicht beendet und wird unendlich ausgeführt.

Vielleicht hat ja jemand schon eine erfolgreiche Umsetzung mit der 
lightweight ws2812 Library auf einem STM32 gemacht und kann mir 
eventuell helfen.

Gruß Michael

: Verschoben durch Moderator
von Uwe B. (derexponent)


Lesenswert?

Hi Michael,

bei der "lightweight" Library kann ich dir leider nicht helfen
aber nur mal zum Verständnis

du schraubst den CPU Clock vom STM32F4 von 168MHz runter
auf 32MHz nur damit du den WS2812 Clock von 800kHz hinbekommst ?

ist das nicht etwas am Ziel vorbei ?

falls du eine fertige Library für den STM32F4 suchst :

http://mikrocontroller.bplaced.net/wordpress/?page_id=3665

allerdings ist die "mit" DMA also event. nicht das was du suchst

Gruss Uwe

: Bearbeitet durch User
von MichaelS (Gast)


Lesenswert?

Hi Uwe,

ja deine Library nutz ich ja schon. Das runtertakten war jetzt nur 
lightweight ws2812 bedingt. Letzlich soll es ja auf einem F1 laufen. 
Also mein eigentliches Problem ist das ich versuche mit dem ARM die 
Länge der Strips dynamisch zu erkennen. Ich habe das auf einem ATmega 
bereits umgesetzt mit der lightweight library weil die mir die Daten ja 
direkt auf einen Port gibt und ich mitzaehlen kann wieviele LEDs bediemt 
wurden und so mit einem Interrupt auf der letzten DOUT die Anzahl der 
LEDs habe. Mit deiner DMA Library war ich etwas unsicher so das ich dort 
keine wirklichen Ergebnisse erzielen konnte so das ich die lightweight 
library noch mal probiert habe.

Eventuell hast du ja eine Idee zu meinem Problem :)

Gruß Michael

von Uwe B. (derexponent)


Lesenswert?

hmm ok,

mit "dynamisch" meinst du aber nicht ständig während der Laufzeit
sondern z.B. nur nach einem "PowerOn" oder bei einem besondern Ereignis
wie "Button_OnClick" usw.

in meiner Library müsste man aber vom schlimmsten Fall ausgehen
und im RAM die maximale Länge der Stripes reservieren

mit einer "TestFunktion" die z.B. nach "PowerOn" aufgerufen werden 
müsste, könnte man dann die tatsächliche Länge bestimmen.

Falls das in deinem Sinne wäre, lass es mich wissen und ich
schau mal was ich machen kann.

Gruss Uwe

von MichaelS (Gast)


Lesenswert?

ja, genau.

Momentan auf dem ATMega wird die Längenerkennung einmal beim starten 
ausgeführt und evtl in späteren Versionen noch per wie du sagst onClick. 
Das ganze soll bzw wird mit einer Android App gesteuert daher passe dein 
Beispiel sogar recht gut ;)

Gruß Michael

von Uwe B. (derexponent)


Angehängte Dateien:

Lesenswert?

Hi Michael,

teste mal diese Version

die erkennt die Längen der Ketten automatisch
(per Exti-Interrupt an PD0)

falls du mehr als eine Kette anschließen willst,
verbinde einfach die Ausgänge aller letzten LEDs
über Dioden (z.B. BAT46) mit diesem Pin (Wired-Or)

die maximale Länge zum reservieren vom RAM
muss im H-File eingestellt werden
(auch welche Kanäle benutzt werden sollen)

Die Längenmessung wird bei der Initialisierung gemacht
(die liefert SUCCESS wenn alle Längen erkannt wurden)

die Anzahl der LEDs steht danach in :
1
WS2812_CHAIN_LEN.ch1
2
WS2812_CHAIN_LEN.ch2
3
WS2812_CHAIN_LEN.ch3
4
WS2812_CHAIN_LEN.ch4


hier ein Beispiel mit dem alle LEDs von CH1
abwechselnd auf grün, rot gesetzt werden :
1
  #include "stm32_ub_ws2812.h"
2
3
  if(UB_WS2812_Init()==SUCCESS) {
4
    UB_WS2812_SetChannel(1);
5
    for(n=0;n<WS2812_CHAIN_LEN.ch1;n+=2) {
6
      UB_WS2812_One_Led_RGB(n,WS2812_RGB_COL_GREEN,0);
7
      UB_WS2812_One_Led_RGB(n+1,WS2812_RGB_COL_RED,0);
8
    }
9
    UB_WS2812_Refresh();
10
  }
11
12
  while(1);

Gruss Uwe

: Bearbeitet durch User
von MichaelS (Gast)


Lesenswert?

Hi Uwe,

so ich hab deine Library mit der Längenerkennung nun einmal ausprobiert 
und muss sagen es funktioniert optimal :)
Vielen vielen Dank dafür... nun kann ich mich um die LED Programme 
kümmern :)

Gruß Michael

von MichaelS (Gast)


Lesenswert?

Was mir nun jetzt aufgefallen ist das die eigentlichen LED Funktionen 
nichtmehr funktionieren. Also ich bekomme nun wunderbar von allen 4 
Kanälen die Länge ausgegeben, aber selbst bei dem Beispiel was du oben 
geposted hast werden die LEDs nicht Farbig sondern nur weiß.

Gruß Michael

von MichaelS (Gast)


Lesenswert?

Vergiss meinen letzten Post. Ich hatte doch die Taktfrequenz 
runtergesetzt wegen der lightweight Library.... die sollte man dann auch 
wieder hochsetzen... %)

von Uwe B. (derexponent)


Lesenswert?

nur mal so aus Neugier :

wie viele LEDs haben deine LED-Ketten ?

und wie programmierst du deine "Licht-Effekte" ?

mir fällt da nämlich was ein :

wenn man einen zweiten Timer benutzt
sind 8 Kanäle möglich

wenn man die LEDS dieser 8 Ketten alle parallel legt,
könnte man auch Texte darstellen (mit einem 8Pixel Font)

man bräuchte natürlich LED-Ketten von entsprechender Länge
(und den Strom dafür :-)

aber rein von der Software wär das kein Problem
mit scrollendem, blinkendem Text usw.

einfach per Funktionen aus der CPU aufzurufen (ohne PC-Programm)

leider hab ich die Hardware dafür nicht...bräuchte also
jemand der das testen kann

hättest du Interesse an sowas ?

Gruss Uwe

: Bearbeitet durch User
von MichaelS (Gast)


Lesenswert?

Hi Uwe,

ja ansich reichen mir die 4 Kanäle noch :)
Programmiert werden die LED Programme bei mir auch direkt im Source 
(evtl wenn mir was einfällt auch dynamische LED Programme per Android 
App oder ähnlichem). Nimmt zwar momentan noch reichlich Speicher weg die 
Effektprogramme aber fürs erste ist das denke ich Okay.
Aber deine Idee mit dem 2ten Timer hatte ich auch schon und würde es 
auch testen, die Menge an LEDs (momentan so um die 500) und auch an 
Strom :) hätte ich da.



Gruß Michael

von MichaelS (Gast)


Lesenswert?

Hi nochmal,

sagmal Uwe ist es möglich für die Buffer der LEDs auch den SRAM zu 
benutzen?
Ich hab noch nichts mit dem SRAM gemacht (oder generell wenig mit ARM uC 
;)

Gruß Michael

von Uwe B. (derexponent)


Lesenswert?

ja, müsste gehen hab es aber selbst nicht ausprobiert
(meinst du den externen RAM vom STM32F429 ?)

dem DMA ist es egal ob er die Daten aus dem Flash, internen RAM
oder externen RAM kopiert.

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.