Hi zusammen, ich nutz einen Nano Pi Neo Air auf dem ich mit Python Sk6812 LEDs ansteuern möchte. Ich weiß dass es fertige Libs gibt, möchte es aber trotzdem selbst versuchen und verstehen was wie funktioniert. Mein erster Versuch den SPI Bus zu Zeckentfremden hat einigermaßen funktioniert. Das Timing war leider nicht stabil genug und ich konnte auch den Takt nicht exakt einstellen. Es waren immer mehr oder weniger 800kHz. Es funktioniert... aber nicht zuverlässig. Der nächste Gedanke war PWM zu nehmen. Hier müsste ich doch die 800kHz sauber einstellen können? Die LEDs unterscheiden eine 0 / 1 dann folglich am DutyCycle. Ich kann den DutyCycle auch sauber einstellen, nur muss ich das ja für eine exakte Anzahl an Takten ändern können. Hier hänge ich gerade. Wenn ich PWM aktiviere dann läuft PWM ja sofort mit dem festgelegten DutyCycle los. Ich muss aber Muster hinterlegen können. Wenn ich z.B. nur die 5. LED rot leuchten lassen möchte muss ich ja die Daten für die ersten 4 LEDs anders rausschicken als die für die 5. LED. Ist soetwas über PWM überhaupt möglich? Danke Gruß Borsty
:
Bearbeitet durch User
Borsty B. schrieb: > Wenn ich z.B. nur die 5. LED rot leuchten lassen möchte muss ich ja die > Daten für die ersten 4 LEDs anders rausschicken als die für die 5. LED. Bei Hardware PWM kann man den Pins üblicherweise jeweil einen eigenen Duty Cycle zuweisen. Ist das beim RPi anders? Für Beleuchtungs- und Anzeige Zwecke würde es reichen die Duty Cycle Werte jeweils so 30-60mal pro Sekunde zu ändern, um ein Muster flüssig zu erzeugen.
Die SK6812 LEDs erhalten über den DutyCycle ihre Daten. Es handelt sich nicht um klassisches PWM Dimming sondern um eine echte 8 Bit Datenübertragung. Deshalb muss ich taktgenau festlegen welchen DutyCyle der PWM Pin auf die Leitung wirft. Idealerweise brauch ich eine Liste in der ich die Daten hinterlege, der PWM Controller muss mir diese Liste dann "abfahren". Fraglich nur ob das mit Python auf dem Pi klappt.
A) Normalerweise macht man das mit DMA und SPI. Die SPI clock muss gar nicht mal 3*800kHz sein (damit du "110" als logische 1 oder "100" als logische 0 senden kannst) sondern kann auch deutlich schneller sein. Wichtig ist nur dass "Anzahl aufeinanderfolgender Einsen" (bzw. Nullen) multipliziert mit der SPI-Clockperiode gleich den Timings des WS2812B/SK6812 entspricht (350ns/900ns, siehe auch hier: https://www.mikrocontroller.net/articles/WS2812_Ansteuerung). Zum Beispiel, bei einer 20MHz SPI clock = 50ns Bit-Periode musst du 7 Einser (= 350ns lang "1") und 18 Nullen (= 900ns lang "0") ausgeben, damit am Schluss "110" mit 1.25µs Periodendauer raus kommt. Dann verbraucht ein Bit im WS2812B-Protokoll zwar 25 SPI-Bits, aber das ist bei 512MB DDR egal. Für 5 LEDS brauchst du also 5 Leds *8Bit/Farbe *3 Farben = 120 Bit im WS2812B-Protokoll, oder 3000 Bit (bei einer beispielhaften SPI clock von 20MHz) die du selber in Bytes aufteilen und über SPI rausschicken musst. Dann verwendest du DMA: du teilst dem DMA-Controller einmal mit, dass er deine 3000 Bit selbständig ans SPI übergeben soll. Der wickelt das dann selbständig im Hintergrund ab und füttert das SPI immer mit den nächsten Bits sobald es wieder Platz für neue Daten hat. Um deine LEDs anzusteuern musst du also 1: Deine WS2812B-Bits um einen Faktor SPI-clock/800kHz aufblasen und im Speicher ablegen 2: dein DMA konfigurieren dass es kontinuierlich alle aufgeblasenen Bits aus dem Speicher ans SPI sendet 3: herausfinden, wie du aus Python dein DMA ansteuerst 4: viel auf Einzelbitebene arbeiten, was in Python möglich aber umständlicher ist. B) Einfacher ist ein "Koprozessor", ein separater Mikrocontroller, dem du von Python über UART die PWM-Werte schickst und der kümmert sich dann ums Timing und ums raus schicken, ohne dass dir dein Betriebssystem dazwischen funkt. Wenn du den Selber-Lern-Effekt-ohne-Libs haben willst, kannst du es auch selber auf dem Mikrocontroller implementieren, aber da deutlich einfacher als auf deiner Pi-Alternative.
:
Bearbeitet durch User
Oder wenn man die Auswahl der LEDs noch im Griff hat auf APA102 gehen, die kann man ganz geschmeidig mit jeder SPI mit jedem beliebigen Takt füttern.
Philipp M. schrieb: > Zum > Beispiel, bei einer 20MHz SPI clock = 50ns Bit-Periode musst du 7 Einser > (= 350ns lang "1") und 18 Nullen (= 900ns lang "0") ausgeben, damit am > Schluss "110" mit 1.25µs Periodendauer raus kommt. Dann verbraucht ein > Bit im WS2812B-Protokoll zwar 25 SPI-Bits, aber das ist bei 512MB DDR > egal. Im Grunde hab ich das sogar so umgesetzt :) Nur bin ich nicht auf die Idee gekommen den Takt höher zu halten und die Anzahl der Bits zu erhöhen. Gar nicht doof :) Mein Problem war die 800kHz möglichst genau zu treffen. Philipp M. schrieb: > Dann verwendest du DMA: du teilst dem DMA-Controller einmal mit, dass er > deine 3000 Bit selbständig ans SPI übergeben soll. Der wickelt das dann > selbständig im Hintergrund ab und füttert das SPI immer mit den nächsten > Bits sobald es wieder Platz für neue Daten hat. Soweit hab ich das alles verstanden aber warum brauch ich DMA? Meine SPIDEV Lib kümmert sich doch bereits um den Versand der Daten nach "draußen"? Ob ich jetzt die Daten dem DMA oder meiner SPI Library übergebe ist doch prinzipell egal, oder? Welche Vorteile bringt die Nutzung von DMA in diesem Fall? H. schrieb: > Oder wenn man die Auswahl der LEDs noch im Griff hat auf APA102 gehen, > die kann man ganz geschmeidig mit jeder SPI mit jedem beliebigen Takt > füttern. Generell ja, brauch halt RGBW und möglichst günstig soll es auch sein. Mit einer fertigen Library funzt ja auch alles, dacht mir halt ich setz mich mal hin und schreib das von Grund auf selbst. So schwer kann es ja nicht sein ein paar LEDs anzusteuern :)
Borsty B. schrieb: > Ob ich jetzt die Daten dem DMA oder meiner SPI Library übergebe ist doch > prinzipell egal, oder? > Welche Vorteile bringt die Nutzung von DMA in diesem Fall? Ja, sofern deine SPI library das ohne Unterbrechung schafft. Sollte dein SPI-Peripheral mal leer laufen (keine Daten im TX FIFO) ist das für reguläres SPI ja kein Problem, da die Clock dann auch anhält. Da es beim WS2812B-Protokoll aber keine Clock gibt werden manche Symbole länger ausgegeben. "Nano Pi Neo Air" und "Python" klingt nach Linux und nicht nach Echtzeit oder bare metal. D.h. wenn dein SPI mal leer läuft, kann es einige Millisekunden dauern bis Python neue Daten nachliefert. Bis dahin haben sich deine LEDs aber längst resettet (50µs). Außer deine SPI-Bibliothek unterstützt DMA, was sie sicherlich tut (wie mir jetzt im Nachhinein bewusst wird). Borsty B. schrieb: > So schwer kann es ja > nicht sein ein paar LEDs anzusteuern :) Falsche LEDs ausgesucht ^^
:
Bearbeitet durch User
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.