Guten Morgen, ich möchte LED-Strips und einen Fernbedienungsempfänger gleichzeitig an einem AVR-Controller betreiben. Das Rausschreiben der Daten an die LED-Strips ist zeitkritisch und muss deshalb unter Interrupt-Sperre passieren. Je länger der Strip, desto länger die Sperre. Wenn man jetzt einen flüssigen Helligkeitsübergang möchte (Update alle 20ms) und 300 LEDs hat, ist man schon einen beträchtlichen Anteil der Rechenzeit in Interrupt-Sperre unterwegs. Das beeinträchtigt natürlich die Auswertung einer IR-Fernbedienung, die ja auch auf Interrupts und Zeitmessung basiert. Kennt jemand dieses Problem und eine elegante Lösung dafür ? Mein bisheriger Ansatz: Die IR-Auswertung erkennt immer noch dass etwas gesendet wurde. Nur nicht mehr was das genau war. Daraufhin würde ich die Ausgabe der LED-Strips verzögern bis ich einen gültigen Befehl von der Fernbedienung empfange (Fernbedienung wiederholt alle ca. 100ms solange eine Taste gedrückt ist) oder ein Timeout abgelaufen ist. Aktuelles Problem ist, dass die Interruptsperre meist mitten in einer IR-Message vorbei ist und die Auswertung dann nicht das erste Byte als erstes sieht und mit der Bytezählung durcheinander kommt. Die Synchronisation findet sie dann auch nicht mehr, bis die Taste losgelassen wurde. Dann müsste man also immer 2x drücken und den LED-Strip entsprechend lange pausieren. Das ist nicht mehr komfortabel. Ich müsste also die IR-Auswertung entsprechend anpassen, dass sie bei der Byte-Zählung flexibler ist. Bevor ich mir die Arbeit mache wie gesagt: Kennt jemand eine einfachere Lösung ? Vielen Dank im Voraus !
Sven G. schrieb: > Kennt jemand eine einfachere Lösung ? Multitasking, Multicore/Mulutiprozessor ... Verrate bloß keine Detais zum Timing der LED Ansteuerung und des IR-Signals.
Sven G. schrieb: > Anteil der Rechenzeit in > Interrupt-Sperre unterwegs. Dann lass den Interrupt nicht sperren ... Wenn du deiner ISR-Funktion als zweiten Parameter ISR_NOBLOCK mitgibst, ist der erste Befehl in deiner ISR ein "sei", der die Interrupts wieder aktiviert. Du musst nur auf deinen Stack aufpassen, dass der nicht überläuft, soll heißen, die ISRs dürfen nicht zu lange brauchen. Ich vermute, du verwendest IRMP? Dann richte dir einen Timer-Interrupt mit sowas 15kHz ein, in dem die IRMP-Interrupt-Funktion aufgerufen wird. Der Rest mit den RGB-LEDs dürfte dann per Timer in einer anderen Interrupt-Funktion passieren. So hatte ich es gemacht und bei mir gab es dann keine Probleme :)
Hallo Mampf, vielen Dank für die Antwort. Ich habe es noch nicht ganz verstanden. Ich weiß auch nicht, ob ich mich klar ausgedrückt habe: Die LED-Strip-Ausgabe verwendet selbst keine ISR, sie sperrt nur die Interrupts, weil sie aufgrund der Timing-Anforderung nicht unterbrochen werden darf. Ich habe schon ausprobiert die Interruptsperre einfach wegzulassen, dann zeigt der LED-Strip aber Blödsinn an. Geht also nicht. IRMP verwende ich nicht. Ich verwende eine sehr kleine Library, die aus einem Lernroboter-Projekt stammt (Ringo Robot). Die benutzt Timer/Counter1 zur Zeitmessung. Da ich sehr viele LEDs ansteuern möchte brauche ich einen großen Teil des RAMs für das Muster. Daher möchte ich mit Code so sparsam wie möglich sein. Hallo Wolfgang, vielen Dank. ;-) Gruß Sven
:
Bearbeitet durch User
Sven G. schrieb: > Die LED-Strip-Ausgabe verwendet selbst keine ISR, sie sperrt nur die > Interrupts, weil sie aufgrund der Timing-Anforderung nicht unterbrochen > werden darf. Ich habe schon ausprobiert die Interruptsperre einfach > wegzulassen, dann zeigt der LED-Strip aber Blödsinn an. Geht also nicht. Hmm, in diesem Fall wäre es sinnvoll den Code zu posten, da es einige Möglichkeiten gibt, wie du das implementiert haben könntest. Die Alternative ist, wir ziehen dir das Stück für Stück aus der Nase ;-) Glaub, Code posten ist einfacher.
Man könnte sich das Leben leichter machen indem man einen uC nimmt der die Ansteuerung besser in Hardware unterstützt, LPC824/845 oder ATiny817 oder STM32, https://www.mikrocontroller.net/articles/WS2812_Ansteuerung
Manche Leute verstehe ich nicht: Reißen hier den große Thread auf mit der Feststellung, dass es nicht anders geht, so aber nicht funktioniert und dann kommen keine Fakten (Programm, Typenbezeichnungen, IR-Protokoll), damit sich ja kein anderer ein Bild oder gar konkrete Vorschläge zur Lösung machen kann.
Ich erwarte nicht, dass sich jemand ein Bein für mich ausreißt. Ich habe lediglich gefragt, ob jemand schon mal ein LED-Strip+AVR+IR-Empfänger betrieben und damit Erfahrung hat. Ganz einfach. Von dir, Wolfgang, erwarte ich gar nichts, soviel Erfahrung habe ich mit diesem Forum. Ich verwende Adafruit NeoPixel RGBW-LEDs mit 800kHz Datentakt. Das Protokoll ist ein 1-Drahl-Protokoll ähnlich dem im Datenblatt zu WS2812, WS2811 oder SK6812 beschrieben. Nur mit 32Bit statt 24Bit pro Modul. Der Code, der die Daten rausschickt sieht so aus... https://github.com/adafruit/Adafruit_NeoPixel/blob/master/Adafruit_NeoPixel.cpp Das IR-Protokoll weiß ich gerade nicht und kann ich auch vor Übermorgen nicht in Erfahrung bringen. Die sind doch aber alle ähnlich und werden alle das gleiche Problem haben, dass man zeitliche Abstände zwischen Signalflanken bestimmen muss und daher der Interrupt nicht längere Zeit gesperrt sein darf. Bevor jemand für Wolfgang nochmal antwortet probiere ich es lieber selbst nochmal. Vielen Dank schon mal an die anderen für die konstruktiven Hinweise. Gruß Sven
Sowohl IRMP als auch die WS2812- bzw. SK6812-LED-Ansteuerung im RGBW-Mode (nichts anderes sind Deine "Neopixel") laufen hervorragend zusammen auf z.B. einem STM32F103. Siehe auch WordClock mit WS2812, wo beides zusammen eingesetzt wird - neben vielem mehr. Dabei werden die LEDs per DMA beschickt und der STM32 langweilt sich zu Tode.
:
Bearbeitet durch Moderator
Sven G. schrieb: > Bevor jemand für Wolfgang nochmal antwortet ... Ich frage mich ernsthaft, warum solche Infos nicht im ersten Posting auftauchen, sondern erst einmal sechs Postings mit Rätselraten und Nebelstochern kommen müssen ...
Sven G. schrieb: > Ich verwende Adafruit NeoPixel RGBW-LEDs mit 800kHz Datentakt. Das > Protokoll ist ein 1-Drahl-Protokoll ähnlich dem im Datenblatt zu WS2812, > WS2811 oder SK6812 beschrieben. Nur mit 32Bit statt 24Bit pro Modul. > Der Code, der die Daten rausschickt sieht so aus... > https://github.com/adafruit/Adafruit_NeoPixel/blob/master/Adafruit_NeoPixel.cpp Ach du schei*e ... Ich hab mir gerade das Protokoll angeschaut ... Das ist ein asynchrones Protokoll mit harten Echtzeitanforderungen (Timing +/-150ns) ... Und der Code dazu ... Völliger Wahnsinn. Ich würde sagen IR und LEDs beschreiben gleichzeitig kannst du vergessen ... *edit*: Gerade gesehen, bei einem Low-Pegel von 80µs machen die LEDs einen Reset. Wer hat sich denn den kranken Mist ausgedacht ? Frank M. schrieb: > Dabei werden die LEDs per DMA beschickt und der STM32 langweilt sich zu > Tode. Ja, das ist auch die einzige Lösung, die mir einfällt.
:
Bearbeitet durch User
Ich würde bei zeitkritischen Sachen einen APA102 LED Strip verwenden. Der versteht SPI und das auch noch deutlich fixer als ein WS2812. Zumal SPI Übertragung vom AVR von der Hardware aus unterstützt wird...
Mampf F. schrieb: > Frank M. schrieb: >> Dabei werden die LEDs per DMA beschickt und der STM32 langweilt sich zu >> Tode. > > Ja, das ist auch die einzige Lösung, die mir einfällt. Wenn man noch berücksichtigt, dass man die STM32F103 bei eBay als kleines aber feines Board für unter 2 EUR bekommt - mit 64 KB Flash und 20 KB RAM, dann will man keinen AVR mehr anpacken, jedenfalls nicht für so eine Aufgabe. https://www.ebay.de/itm/1-2-5-10Stks-STM32F103C8T6-ARM-STM32-Minimum-System-Development-Board-Module-New/272425764978 EDIT: Der TO könnte noch APA102-LEDs verwenden. Die werden über SPI gesteuert und man kann selbst das Übertragungstempo bestimmen. Man wird jedenfalls bzgl. Timing nicht fremdbestimmt. Aber ob es die auch in RGBW statt lediglich RGB gibt, weiß ich nicht.
:
Bearbeitet durch Moderator
Mampf F. schrieb: > *edit*: Gerade gesehen, bei einem Low-Pegel von 80µs machen die LEDs > einen Reset. Die machen keinen Reset, sondern stellen nach 80µs Ruhe den Ihnen zugewiesenen RGB(W)-Wert dar, damit dann alle LEDs gleichzeitig die übertragenen Werte darstellen. Die Länge des Ruhepegels ist übrigens verschieden und kann von 50µs bis 120µs variieren - je nach Ausführung.
@ Sven G. (captainalbern) >ich möchte LED-Strips und einen Fernbedienungsempfänger gleichzeitig an >einem AVR-Controller betreiben. Machbar. > Das Rausschreiben der Daten an die >LED-Strips ist zeitkritisch und muss deshalb unter Interrupt-Sperre >passieren. Kann sein, muß nicht, man kann es ggf. auch clever mit SPI machen. > Je länger der Strip, desto länger die Sperre. Nö. Man kann auch zwischen den einzelnen Bytes mal KURZ was anderes machen. >Wenn man jetzt >einen flüssigen Helligkeitsübergang möchte (Update alle 20ms) und 300 >LEDs hat, ist man schon einen beträchtlichen Anteil der Rechenzeit in >Interrupt-Sperre unterwegs. Nö, du bist in einer konzeptionellen Sackgasse. > Das beeinträchtigt natürlich die Auswertung >einer IR-Fernbedienung, die ja auch auf Interrupts und Zeitmessung >basiert. Das kann man ggf. clever verschachteln, was so oder so der Grundgedanke von kooperativem Multitasking ist. >Mein bisheriger Ansatz: Die IR-Auswertung erkennt immer noch dass etwas >gesendet wurde. Nur nicht mehr was das genau war. Daraufhin würde ich >die Ausgabe der LED-Strips verzögern bis ich einen gültigen Befehl von >der Fernbedienung empfange (Fernbedienung wiederholt alle ca. 100ms >solange eine Taste gedrückt ist) oder ein Timeout abgelaufen ist. Ziemlicher Murks. IR-Dekodierung ist doch eher langsam, so im Bereich von 1kBit/s. Das kann man relativ einfach mit der LED-Ansteuerung muxen. >LED-Strip entsprechend lange pausieren. Das ist nicht mehr komfortabel. In der Tat. >Ich müsste also die IR-Auswertung entsprechend anpassen, dass sie bei >der Byte-Zählung flexibler ist. Scheint so. >Bevor ich mir die Arbeit mache wie gesagt: Kennt jemand eine einfachere >Lösung ? Vielen Dank im Voraus ! Kauf dir was fertiges bei Conrad, Pollin oder Perl. ;-) Wenn du aber kein Konsumerweichei bist, klemmst du dich dahinter und löst das Problem ELEGANT! Und JA, das geht auch mit einem "kleinen" AVR nicht allzuschwer. Fette 32 Bitter mit DMA und anderen Geschützen braucht man da nicht wirklich. Brain 2.0 ist immer noch up to date!
@Sven G. (captainalbern) >wegzulassen, dann zeigt der LED-Strip aber Blödsinn an. Geht also nicht. SO einfach geht es nicht. Aber es geht. Siehe mein vorheriger Beitrag. >IRMP verwende ich nicht. Ich verwende eine sehr kleine Library, die aus >einem Lernroboter-Projekt stammt (Ringo Robot). Die benutzt >Timer/Counter1 zur Zeitmessung. Auch das kann man anpassen. >Da ich sehr viele LEDs ansteuern möchte >brauche ich einen großen Teil des RAMs für das Muster. Daher möchte ich >mit Code so sparsam wie möglich sein. Jaja, spare jederzeit, dann hast du immer Not. Mein Gott, hat der Bastler von heute nicht mal drei Euro für einen ausreichend großen uC mit ausreichend RAM?
@Frank M. (ukw) (Moderator) >Dabei werden die LEDs per DMA beschickt und der STM32 langweilt sich zu >Tode. Weiß Amnesty International schon davon?
Mampf F. schrieb: > Ach du schei*e ... Ich hab mir gerade das Protokoll angeschaut ... Das > ist ein asynchrones Protokoll mit harten Echtzeitanforderungen (Timing > +/-150ns) ... 2 Bit der LED-Daten dauern 2.4µs (8 Bit á 0.3µs), d.h. wenn man die als 8Bit mit SPI bei 3.33MHz Clk raustackert, hat man zum Bereitlegen der Daten, Gucken nach dem IR-Empfängerpin und Warten auf fertige SPI-Übertragung 2,4µs Zeit. Nicht die Welt, aber mit Assembler bei einem µC, der nicht gerade mit 1MHz dahinschleicht, sind das schon ein paar Takte. Die IR-Auswertung muss dann nach dem LED-Telegramm erfolgen.
@ Mampf F. (mampf) >Ach du schei*e ... Ich hab mir gerade das Protokoll angeschaut ... Das >ist ein asynchrones Protokoll mit harten Echtzeitanforderungen (Timing >+/-150ns) ... So what! >Und der Code dazu ... Völliger Wahnsinn. Keine Ahung. >Ich würde sagen IR und LEDs beschreiben gleichzeitig kannst du vergessen >... *edit*: Gerade gesehen, bei einem Low-Pegel von 80µs machen die LEDs >einen Reset. Ja und? Dann lass halt nen High-Pegel stehen. >> Dabei werden die LEDs per DMA beschickt und der STM32 langweilt sich zu >> Tode. >Ja, das ist auch die einzige Lösung, die mir einfällt. Es gibt so gut wie IMMER mehrere Lösungen, ganz egal wie gut oder schlecht die auch sein mögen.
Falk B. schrieb: >> Das Rausschreiben der Daten an die >>LED-Strips ist zeitkritisch und muss deshalb unter Interrupt-Sperre >>passieren. > > Kann sein, muß nicht, man kann es ggf. auch clever mit SPI machen. Hatte ich vorher mal durchgerechnet ... SPI müsste auf 20MHz laufen und um die Toleranz von +/-150ns einzuhalten, hätte man 3 Taktzyklen Zeit eine neue SPI-Übertragung zu starten - bei einem AVR mit 20MHz. DMA hat der AVR ja leider nicht. Falk B. schrieb: >>Ich würde sagen IR und LEDs beschreiben gleichzeitig kannst du vergessen >>... *edit*: Gerade gesehen, bei einem Low-Pegel von 80µs machen die LEDs >>einen Reset. > > Ja und? Dann lass halt nen High-Pegel stehen. Lies bitte das Datenblatt, damit du weißt, was dann passiert ;-) Falk B. schrieb: >>Ja, das ist auch die einzige Lösung, die mir einfällt. > > Es gibt so gut wie IMMER mehrere Lösungen, ganz egal wie gut oder > schlecht die auch sein mögen. Wenn dir andere Lösungen einfallen, immer her damit - der TE wäre sicherlich hoch erfreut.
:
Bearbeitet durch User
Wolfgang schrieb: > 2 Bit der LED-Daten dauern 2.4µs (8 Bit á 0.3µs) Wie kommst du darauf? Hatte für Low- und High-Data 0,3µs und 0,95µs gelesen ... Die Daten werden wohl in der Länge der High-Low-Pegel kodiert und anscheinend auch noch abwechseln mal High mal Low ... Der kleinste gemeinsame Teiler wären 0,05µs und der Clock damit 20MHz. Kann sein, dass ich mir irre, aber so hatte ich es im Datenblatt verstanden.
:
Bearbeitet durch User
Mampf F. schrieb: > Kann sein, dass ich mir irre, aber so hatte ich es im Datenblatt > verstanden. Nein, du irrst nicht. Und die anderen beiden sollten die Dinger erstmal selbst programmieren. Falk B. schrieb: > Keine Ahung. Ich denke mal, da fehlt ein 'n' in der Mitte. Leider ist das die einzige richtige Aussage in deinen Beiträgen. Wenn ich deine sonstigen Beiträge auch durchaus zu schätzen weiß, aber bei den Neopixel-Leds liegt du nicht zum ersten Mal völlig daneben.
@Thomas Eckmann (Firma: Thomas Eckmann Informationst.) (thomase) >Nein, du irrst nicht. Und die anderen beiden sollten die Dinger erstmal >selbst programmieren. Ja, aber. >> Keine Ahung. >Ich denke mal, da fehlt ein 'n' in der Mitte. Hier hast du dein 'n' für 300 Euro. Maren, dreh mal um (also das n meine ich) >Leider ist das die einzige >richtige Aussage in deinen Beiträgen. Wenn ich deine sonstigen Beiträge >auch durchaus zu schätzen weiß, aber bei den Neopixel-Leds liegt du >nicht zum ersten Mal völlig daneben. Kann sein, muß nicht. Ich sehe das eher sportlich. Der OP geht mit einem "OMG, geht alles gar nicht" ins Rennen. Ich sage, wo ein Wille, Know How und Sportsgeist vorhanden ist, findet man auch dafür eine Lösung. Ob man die wilden Stunts mit Inline-Assembler wie in der oben genannten Bibliothek machen muss, nur damit es Arduino-Style nach außen ist, sei dahingestellt.
Reden wir hiervon? https://www.adafruit.com/product/1376 Gähn Die Daten werden pulsbreitenmoduliert mit 800kHz / 1,25us rausgetaktet, zwischen den LEDs darf nicht mehr als 50us Pause sein, damit es keinen Reset bzw. Latch-Befehl gibt. 50us sind eine EWIGKEIT! Man muss ja nicht das gesamte IR-Protokoll in 50us dekodieren, es reicht wenn man ein Sample des IR-Empfängers speichert. Gehen wir mal sportlich von 100 LEDs aus, so dauert deren Ansteuerung 1250 us, ein Witz. Wenn wir also alle 10 LEDs (=12,5us / 80kHz) ein Sample nehmen, ist das mehr als ausreichend. Da wir ja nicht dauerhaft nur LEDs ansteuern, sondern mal sportlich von 100 Hz Updaterate ausgehen, bleiben noch ca. 8,5ms übrig, um dann die Dekodierung der IR-Daten vorzunehmen. In wie weit die Software des IR-Dekoders dafür schon ausgelegt ist, weiß ich nicht. Das Ganze macht man spielend in reinem C ohne eine Zeile Inline Assembler, sinnvollerweise natürlich mit dem SPI oder UART im SPI-Mode oder USI, je nach Verfügbarkeit. Will jemand dagegen wetten? Die minimale Pulsbreite von 0,35us entspricht 2,8 MHz. Da das SPI vom AVR mindestens mit Teilerfaktor 2 arbeitet, braucht man halt ~5,7 MHz. Bei den Arduino-üblichen 16 MHz wird es etwas krumm mit dem Teilerfaktor, sollte laut Datenblatt aber auch noch gehen! 16 MHz / 4 = 4 MHz / 250ns (liegt in den +/-150ns drin) Ok, ist nicht optimal in bezug auf die verbleibenden Toleranzen. Also den Quarz auf 12 MHz umlöten.
Mampf F. schrieb: > Wolfgang schrieb: >> 2 Bit der LED-Daten dauern 2.4µs (8 Bit á 0.3µs) > > Wie kommst du darauf? Ich war von Timing der SK6812 RGBW Chips[1] ausgegangen, i.e. 0-Bit als 0.3µs High + 0.9µs Low und 1-Bit als 0.6µs High + 0.6µs Low. Dann könnte man das Bitmuster über SPI mit 0.3µs-Takt und 4 SPI-Bits pro LED-Bit generieren. Ob das auf einem AVR mit 16MHz in Assembler genug Freiraum schafft, müsste man probieren. [1] https://cdn-shop.adafruit.com/product-files/2757/p2757_SK6812RGBW_REV01.pdf Der TO bekommt es ja irgendwie nicht fertig, zu seinen Chips mal das Datenblatt rüberwachsen zu lassen. Wenn er was anderes braucht - nur her damit.
Vielen vielen Dank soweit. Ich bitte es zu entschuldigen, wenn ich mich erst mal nicht mehr melde. Ich muss erst ausprobieren. IRMP kannte ich nicht. Ich habe mir inzwischen den Artikel dazu durchgelesen und daraufhin Mampf's 1. Kommentar mit der 15kHz-Routine jetzt verstanden. Wenn es tatsächlich möglich ist, zwischen den einzelnen LEDs kurze Pausen zu machen und die Timing-Anforderungen nur innerhalb der 32Bit für ein LED-Modul gelten, könnte man da evtl. was multiplexen. Ich bedanke mich und gucke, wie ich damit weiterkomme. PS: Nach dem Code der IR-Auswertung und der Beschreibung im IRMP-Artikel könnte es ein NEC-Code sein. Auf jeden Fall 38kHz, 1-Start-Bit, 32Bit Daten (Adresse, invertierte Adresse, Datenbyte, invertiertes Datenbyte). Falls es ein Stopp-Bit gibt ignoriert es der Code.
:
Bearbeitet durch User
Falk B. schrieb: > Ich sage, wo ein Wille, Know How > und Sportsgeist vorhanden ist, findet man auch dafür eine Lösung. Vollkommen richtig. Falk B. schrieb: > Ob man die wilden Stunts mit Inline-Assembler wie in der oben genannten > Bibliothek machen muss, nur damit es Arduino-Style nach außen ist, sei > dahingestellt. Natürlich nicht.
1 | #define WsOut() do\
|
2 | {\
|
3 | unsigned int ledind = 0;\
|
4 | unsigned char colorind = 1;\
|
5 | unsigned char data = 0;\
|
6 | \
|
7 | unsigned char* wsled = (unsigned char*)WsLed;\
|
8 | \
|
9 | while(ledind < (WS_N * 3))\
|
10 | {\
|
11 | data = wsled[ledind + colorind--];\
|
12 | for(unsigned char nInd = 0; nInd < 8; nInd++)\
|
13 | {\
|
14 | if(data & (1 << 7))\
|
15 | {\
|
16 | WS_TOGGLE;\
|
17 | HighDelay();\
|
18 | WS_TOGGLE;\
|
19 | }\
|
20 | else\
|
21 | {\
|
22 | WS_TOGGLE;\
|
23 | LowDelay();\
|
24 | WS_TOGGLE;\
|
25 | }\
|
26 | data <<= 1;\
|
27 | LoopDelay();\
|
28 | }\
|
29 | if(colorind == 1) ledind += 3;\
|
30 | else if(colorind == 255) colorind = 2;\
|
31 | \
|
32 | }\
|
33 | \
|
34 | }while(0)
|
Die Delays sind je nach Controllertakt(>=6MHz) 0 - 7 NOPs. Das ist die Zeit, die für anderes zur Verfügung steht. WS_TOGGLE ist mit dem Schreibzugriff aufs PIN-Register realisiert. Das Gewürge mit colorind ist dem Umstand geschuldet, daß ich die Farbwerte in der Reihenfolge RGB eingeben will und die Leds sie anders haben wollen. Beim besten Willen: Wo willst du da noch was einbauen? Denn das Tolle ist, daß auch nur kleine Abweichungen, also ein NOP zuviel oder zu wenig, die Dinger zum wilden oder auch nur gelegentlichen Blinken bringen. Schon das WS_TOGGLE, welches man normalerweise jeweils vor oder hinter die if/else stellen würde, verhagelt dir bei manchen Taktraten das Timing.
:
Bearbeitet durch User
Sven G. schrieb: > PS: Nach dem Code der IR-Auswertung und der Beschreibung im IRMP-Artikel > könnte es ein NEC-Code sein. Ja, sieht so aus. Über 90% aller herumschwirrenden Fernbedienungen nutzen heutzutage den NEC-Code. Es gäbe vielleicht noch folgende Alternative: IRMP auf ATTiny45 und Rausschreiben der empfangenen Codes per Software-Uart an Deinen verwendeten µC. Wenn Du auf die Übertragung der Geräteadresse verzichtest und das schon im ATTiny prüfst, ob sie zu Deiner Fernbedinung passt, reicht ein Byte zur Übertragung des IR-Kommandos. Dieses kannst Du dann bequem zwischen den LED-Frames, die Du verschickst, auf Deinem UART einlesen und entsprechend verarbeiten.
Falk B. schrieb: > Ob man die wilden Stunts mit Inline-Assembler wie in der oben genannten > Bibliothek machen muss, nur damit es Arduino-Style nach außen ist, sei > dahingestellt. Bei dem Protokol muss man wohl zumindest Assembler verwenden und die Zyklen abzählen, wenn man keine Hardware-Unterstützung hat. Also hier die Problemlösung: 300 LEDs mit je 32Bit @ 1,25µs pro Bit (1,25µs LO, 1,3µs HI) bräuchten dann in etwa 12ms insgesamt. Pro LED - das wäre dann quasi eine Atomare Einheit, die man nicht unterbrechen kann - wären das 40µs - Timer einrichten mit zB 10kHz (IRMP zB verwendet mindestens 10kHz für den IR-Sampler) = 100µs - In jedem Timeraufruf die Daten für 2 LEDs senden (80µs) - Nach dem Daten schreiben den IR-Sampler aufrufen (maximal 20µs oder ca 400 Taktzyklen bei 20MHz AVR). - etwas Overhead kommt vlt noch hinzu, aber die gehen halt dann von den 400 Taktzyklen weg. Die 20µs für den IR-Sampler sind noch unterhalb der 80µs Reset-Time der LEDs, passt also. Und der IR-Sampler wird mit ziemlich konstanten 10kHz aufgerufen. Die Refresh-Zeit ist damit dann ziemlich genau 15ms und innerhalb der 20ms, die der TE anstrepte. Voila, Problem gelöst :)
:
Bearbeitet durch User
@ Thomas Eckmann (Firma: Thomas Eckmann Informationst.) (thomase) >Natürlich nicht. > #define WsOut() do\ Auch herje, ein Monster-Makro. Auch das braucht man hier nicht wirklich. >Die Delays sind je nach Controllertakt(>=6MHz) 0 - 7 NOPs. Das ist die >Zeit, die für anderes zur Verfügung steht. WS_TOGGLE ist mit dem >Schreibzugriff aufs PIN-Register realisiert. Schon klar. >Beim besten Willen: Wo willst du da noch was einbauen? Zwischen den einzelnen LED-Paketen, dort hat man bis zu 50us Zeit. Schrieb ich bereits mehrfach. >Denn das Tolle >ist, daß auch nur kleine Abweichungen, also ein NOP zuviel oder zu >wenig, die Dinger zum wilden oder auch nur gelegentlichen Blinken >bringen. Dann haben sie entweder ihr Datenblatt nicht gelesen oder du einen Fehler gemacht. Was ist wohl wahrscheinlicher? > Schon das WS_TOGGLE, welches man normalerweise jeweils vor oder >hinter die if/else stellen würde, verhagelt dir bei manchen Taktraten >das Timing. Wer das mit einem beliebigen Takt per Bitbanging machen will, bitte schön. Kriegt man hin, ist aber auch eher ein Makro-Krampf. Aber das ist doch gar nicht zwingend nötig. SPI/UART, fertig.
@ Frank M. (ukw) (Moderator) >IRMP auf ATTiny45 und Rausschreiben der empfangenen Codes per >Software-Uart Kann man machen, ist aber nicht nötig. Auch wenn der AVR nur ein guter, alter 8-Bitter ist, kriegt der das hin.
Falk B. schrieb: > SPI/UART, fertig. Kauf dir einen Streifen, programmier die Dinger und dann zeig, was du hast. In der Zwischenzeit unterhalte ich mich mit dem Papst über, na du weißt schon was.
@Thomas Eckmann (Firma: Thomas Eckmann Informationst.) (thomase) >> SPI/UART, fertig. >Kauf dir einen Streifen, programmier die Dinger und dann zeig, was du >hast. Deal. Wo gibt's die zu kaufen, außer in den USA?
Falk B. schrieb: > Deal. Wo gibt's die zu kaufen, außer in den USA? https://www.ebay.de/sch/i.html?_from=R40&_trksid=p2380057.m570.l1311.R1.TR12.TRC2.A0.H0.Xws2812.TRS0&_nkw=ws2812b&_sacat=0 Das sind die WS2812b mit RGB. Die vom TO sind die verschärfte Variante mit RGBW.
Falk B. schrieb: > Zwischen den einzelnen LED-Paketen, dort hat man bis zu 50us Zeit. Mit einem LED-Paket meinst Du die Daten für eine LED, richtig? Um 24 Bit (1 Bit = 1.25µs) für eine LED zu übertragen, bist Du dann ca. 30 µs taub auf dem IR-Receiver. Bei 32 Bit für eine RGBW-SK6812-LED, wie sie der TO verwendet, sind es ca. 38µs (hier: 1 Bit = 1.2µs). Das heisst, Du hast bei empfangenen IR-Daten einen Fehler beim Messen der IR-Flanken von 38µs. Wenn man sich das NEC-Protokoll anschaut: 0-Bit 560µs Puls, 560µs Pause 1-Bit 560µs Puls, 1690µs Pause kann das hier konkret, wo sich die Pausen für 1-Bit und 0-Bit erheblich unterscheiden, tatsächlich funktionieren. Denn 560µs sind von den 1690µs noch meilenweit entfernt, so dass man einen großen Toleranzbereich (von ca. 50%) für die gemessenen Zeiten ansetzen kann. Allerdings schätze ich, dass sich die Übertragungszeit für den ganzen LED-Frame von 400 LEDs ungefähr verdoppelt. Aus 400 * 36µs = 14,4ms werden dann so ca. 28 ms. Naja, damit kann man wahrscheinlich leben. EDIT: Könnte tatsächlich auch mit IRMP noch funktionieren, man muss lediglich den Timer-Interrupt, der für IRMP zuständig ist, während der Übertragung der Daten für eine LED abschalten. IRMP arbeitet beim NEC-Protokoll mit einer Toleranz von 40%, wenn ich das richtig in Erinnerung habe.
:
Bearbeitet durch Moderator
... eine Lösung mit einem zusätzlichem µc der auf die IR Kommandos lauscht wurde glaube ich schon vorgetragen, wenn man es wirklich nicht anders hinbekommen sollte ist das wohl die einfachste und angenehmste Lösung. Wenn man möchte könnte man dem IR µc einen Puffer verpassen für die empfangenen Kommandos und der LED steuernde µc gibt dann entsprechend die Übertragung zwischen den beiden µc frei, wenn genug Zeit dafür ist. Oder der IR µc "fragt" halt periodisch den LED µc ob er ein neues Kommando an ihn senden darf, schon recht simpel.
Frank M. schrieb: > Falk B. schrieb: >> Zwischen den einzelnen LED-Paketen, dort hat man bis zu 50us Zeit. > > Mit einem LED-Paket meinst Du die Daten für eine LED, richtig? Wenn er das wirklich so meint, leuchtet nur die erste. Frank M. schrieb: > Um 24 Bit (1 Bit = 1.25µs) für eine LED zu übertragen, bist Du dann ca. > 30 µs taub auf dem IR-Receiver. Bei 32 Bit für eine RGBW-SK6812-LED, wie > sie der TO verwendet, sind es ca. 38µs (hier: 1 Bit = 1.2µs). > > Das heisst, Du hast bei empfangenen IR-Daten einen Fehler beim Messen > der IR-Flanken von 38µs. Die Daten für alle Leds müssen in einem Rutsch gesendet werden. Die Dinger warten nicht, bis die 50µs zuende sind. Das ist die Mindestzeit, die eingehalten werden muß, bevor der nächste Frame kommt, damit die letzte, also in diesem Fall die dreihundertste, das auch noch mitkriegt. Diese LED-Streifen sind keine synchronen Schieberegister, sondern digitale Eimerketten.
:
Bearbeitet durch User
Thomas E. schrieb: > Die Daten für alle Leds müssen in einem Rutsch gesendet werden. Die > Dinger warten nicht, bis die 50µs zuende sind. Doch, warten sie. Solange die 50µs nicht überschritten werden, geben sie die Daten an die nächste LED weiter.
@Thomas Eckmann (Firma: Thomas Eckmann Informationst.) (thomase) >>> Zwischen den einzelnen LED-Paketen, dort hat man bis zu 50us Zeit. >> >> Mit einem LED-Paket meinst Du die Daten für eine LED, richtig? >Wenn er das wirklich so meint, leuchtet nur die erste. Nö. >> Das heisst, Du hast bei empfangenen IR-Daten einen Fehler beim Messen >> der IR-Flanken von 38µs. >Die Daten für alle Leds müssen in einem Rutsch gesendet werden. Die >Dinger warten nicht, bis die 50µs zuende sind. Das sollten sie aber. Oder das Datenblatt stimmt nicht. > Das ist die Mindestzeit, >die eingehalten werden muß, bevor der nächste Frame kommt, damit die >letzte, also in diesem Fall die dreihundertste, das auch noch mitkriegt. >Diese LED-Streifen sind keine synchronen Schieberegister, sondern >digitale Eimerketten. Naja, es ist schon ein wenig ein Hack ala OneWire, nur deutlich schneller.
Falk B. schrieb: > Das sollten sie aber. Oder das Datenblatt stimmt nicht. Das Ding kommt aus China. Da kann das mal passieren. Irgendwer muss den LED-Controllerchen doch sagen, dass ein neues Datenbit kommt und das kann eigentlich nur die steigende Flanke sein. Sonst wäre keine Synchronisation möglich und bei vielen LEDs liefe einem das Timing weg.
Ihr Lieben ! Ich bin sowas von begeistert ! Ich habe leider zwei Tage warten müssen, bevor ich es ausprobieren konnte, aber es funktioniert auf Anhieb. Vielen Dank für die Inspiration ! Folgendermaßen: Ich habe in die Assemblerschleife, die die Daten an die LEDs rausschickt einfach vor dem Rücksprung an den Anfang ein sei; eingefügt und am Anfang ein cli;. Damit sind für einen kurzen Augenblock die Interrupts freigegeben. Wenn jetzt zwischendurch ein Interrupt ausgelöst wird, wartet der in der Hardware bis er dran ist und nutzt dann diese kurze Zeit direkt aus. Die dadurch entstehende Verzögerung ist so gering, dass das IR-Signal noch gut ausgewertet werden kann. Die von mir verwendete IR-Auswertung verwendet allerdings keinen regelmäßigen Interrupt wie IRMP das tut, sondern lässt den Interrupt vom Flankenwechsel am Empfänger auslösen. Nochmal vielen Dank an Mampf für die Idee mit dem Multiplexing. Ich habe gezweifelt, dass ich das hinkriege und nie gedacht, dass das SO einfach ist. Auszug aus dem Veränderten Code (Quelle: Adafruit)
1 | "head20:" "\n\t" // Clk Pseudocode (T = 0) |
2 | "cli;" "\n\t" // Änderung 1 |
3 | "st %a[port], %[hi]" "\n\t" // 2 PORT = hi (T = 2) |
4 | "sbrc %[byte], 7" "\n\t" // 1-2 if(b & 128) |
5 | "mov %[next], %[hi]" "\n\t" // 0-1 next = hi (T = 4) |
6 | "dec %[bit]" "\n\t" // 1 bit-- (T = 5) |
7 | "st %a[port], %[next]" "\n\t" // 2 PORT = next (T = 7) |
8 | "mov %[next] , %[lo]" "\n\t" // 1 next = lo (T = 8) |
9 | "breq nextbyte20" "\n\t" // 1-2 if(bit == 0) (from dec above) |
10 | "rol %[byte]" "\n\t" // 1 b <<= 1 (T = 10) |
11 | "rjmp .+0" "\n\t" // 2 nop nop (T = 12) |
12 | "nop" "\n\t" // 1 nop (T = 13) |
13 | "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 15) |
14 | "nop" "\n\t" // 1 nop (T = 16) |
15 | "rjmp .+0" "\n\t" // 2 nop nop (T = 18) |
16 | "rjmp head20" "\n\t" // 2 -> head20 (next bit out) |
17 | "nextbyte20:" "\n\t" // (T = 10) |
18 | "ldi %[bit] , 8" "\n\t" // 1 bit = 8 (T = 11) |
19 | "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 13) |
20 | "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 15) |
21 | "nop" "\n\t" // 1 nop (T = 16) |
22 | "sbiw %[count], 1" "\n\t" // 2 i-- (T = 18) |
23 | "sei;" "\n\t" // Änderung 2 |
24 | "brne head20" "\n" // 2 if(i != 0) -> (next byte) |
:
Bearbeitet durch User
Sven G. schrieb: > Ich bin sowas von begeistert ! Prima > Die dadurch entstehende Verzögerung ist so gering, dass > das IR-Signal noch gut ausgewertet werden kann. Interessant wäre jetzt noch zu wissen, wie lange bei einem Interrupt die Ausgabe an die LEDs maximal verzögert wird.
Wolfgang schrieb: >> Die dadurch entstehende Verzögerung ist so gering, dass >> das IR-Signal noch gut ausgewertet werden kann. > > Interessant wäre jetzt noch zu wissen, wie lange bei einem Interrupt die > Ausgabe an die LEDs maximal verzögert wird. Soweit ich das verstanden habe, ist das egal ... Die LEDs dürfen nur nicht länger als 80µs ein LOW-Signal erhalten. 80µs ist eine lange Zeit, in der viel gemacht werden kann - der IR-Interrupt wird diese bestimmt nicht aufbrauchen. Die Lösung vom TE finde ich gut! Daran hatte ich nicht gedacht, dass der Interrupt gespeicher und dann ausgeführt wird, sobald die Interrupts wieder aktiviert werden. Die maximal 40µs Verzögerung dürften dem IR-Dekoder dann kaum stören.
:
Bearbeitet durch User
Mampf F. schrieb: > Soweit ich das verstanden habe, ist das egal ... Die LEDs dürfen nur > nicht länger als 80µs ein LOW-Signal erhalten. Ich bin auch dieser Meinung, obwohl das den Angaben im Datenblatt widerspricht. Deshalb wäre es IMHO gut zu wissen wie weit die IR-Interruptroutine von Sven diesen 0-Pegel ungestraft verlängert. Ich habe leider keine von den LEDs hier, um mal das Streching der 0-Phase auszureizen.
Ich werde bei Gelegenheit mal die Zeit in der IR-Routine messen. Den kompletten Code der IR-Routine wollte ich hier nicht her kopieren und ich habe auch gerade keinen konkreten Link dahin gefunden. Er stammt auf jeden Fall von http://www.plumgeek.com/ und gehört zu einem Lernroboter Ringo2. Der Originalcode ist nur für 8MHz und braucht für 16MHz µC eine kleine Änderung in der Zeitmessung (>>1). Dass der Interrupt in der Hardware wartet, hatte ich glaube ich mal irgendwo gelesen, war mir aber nicht mehr sicher. Aber dass es jetzt reibungslos funktioniert spricht dafür, dass das stimmt.
Sven G. schrieb: > Damit sind für einen kurzen Augenblock die Interrupts > freigegeben. Besser fährt man i.d.R. mit der umgekehrten Logik: Die IRQ für die nötige Zeit sperren, sonst freigeben. Nicht alle IR-Protokolle verkraften 80µs Framing-Error.
@batman: Das ist schon klar. Aber es ging doch jetzt gerade darum, aus einem leistungsschwachen µC ein Protokoll mit harten Timinganforderungen rauszuquetschen und dafür braucht man eine lange Interruptsperre. Jetzt haben wir offenbar eine Stelle im Protokoll gefunden, wo die Timinganforderung lockerer ist und nutzen die für den Interrupt. Das von mir verwendete IR-Protokoll kann die kurze Verzögerung gut verkraften. Wenn es für andere nicht reicht muss man da wohl trickreicher sein oder aber gleich einen anderen µC verwenden, wie oben andere schon vorgeschlagen haben. Da ich sehr gern so lange wie möglich bei Bekanntem bleibe, bin ich froh dass das nochmal funktioniert. Es sollte natürlich Augenblick heißen. ;-)
:
Bearbeitet durch User
@Mampf unterwegs (Gast)
>Pragmatische Einstellung, finde ich gut :)
Jain. Der OP hat auch eine gute Portion Glück, daß es hier so einfach
funktioniert. Wenn man sicher sein will, muss man zumindest mal
durchmessen, wie lange die ISR braucht und wieviel Reserve noch zu den
offiziellen 50us Maximalpause vorhanden ist.
Sven G. schrieb: > Jetzt haben wir offenbar eine Stelle im Protokoll gefunden, wo die > Timinganforderung lockerer ist und nutzen die für den Interrupt. Man kann es auch ganz klar so formulieren: Das Datenblatt der LEDs ist bzgl. der Dauer des Zeitfensters für die Low-Phase falsch. Meine Vermutung: Die angegebenen Werte z.B. beim SK6812 für T0L und T1L sind Minimalwerte und die Toleranzangaben ("±0.15μs") sind in dieser Form Unfug. Die maximale Dauer der Low-Phase ist durch die Schwelle von 80µs für Trst (Reset/Latch?) begrenzt.
@Wolfgang (Gast) >Man kann es auch ganz klar so formulieren: Das Datenblatt der LEDs ist >bzgl. der Dauer des Zeitfensters für die Low-Phase falsch. >Meine Vermutung: Die angegebenen Werte z.B. beim SK6812 für T0L und T1L >sind Minimalwerte und die Toleranzangaben ("±0.15μs") sind in dieser >Form Unfug. Die maximale Dauer der Low-Phase ist durch die Schwelle >von 80µs für Trst (Reset/Latch?) begrenzt. Das würde ich auch vermuten. Die Dekodierung erfolgt einfach über 2 retriggerbare Monoflops. Das erste mißt die Pulsdauer von 350/700ns, das 2. die Resetdauer von 50us.
Die 50µs Zeit hat man ja nicht nur nach einem bestimmten sondern nach jedem LED-Bit. Bei einem 20MHz µC entspricht das 1000 Takten Zeit. Da sehe ich die "harten Timinganforderungen" nicht wirklich.
Wolfgang schrieb: > Man kann es auch ganz klar so formulieren: Das Datenblatt der LEDs ist > bzgl. der Dauer des Zeitfensters für die Low-Phase falsch. Im mc.net Artikel steht für die WS2812 das gleiche ... Allerdings wird dort geschrieben, dass meistens schon 5us ausreichen für einen Reset anstatt 50us ... :)
Falk B. schrieb: > @Mampf unterwegs (Gast) > >>Pragmatische Einstellung, finde ich gut :) > > Jain. Der OP hat auch eine gute Portion Glück, daß es hier so einfach > funktioniert. Wenn man sicher sein will, muss man zumindest mal > durchmessen, wie lange die ISR braucht und wieviel Reserve noch zu den > offiziellen 50us Maximalpause vorhanden ist. Aus Interesse habe ich mir vor einiger Zeit mal den vom AVR-GCC erstellten Assembler Code (zu finden in der *.LSS Datei im Kopilerordner) für eine ISR angesehen... Je nach Optimierung des Compilers kann man für das Pushen / Pullen der uC Register auf den Stack etwas 50 Takte als Overhead rechnen, d.h. bei 16Mhz macht das gut 3,1us zusätzlich zum eigentlichen Code in der ISR.... Sollte also noch satt im Toleranzbereich der WS2812 Chips liegen
@Reiner_Gast (Gast) >> durchmessen, wie lange die ISR braucht und wieviel Reserve noch zu den >> offiziellen 50us Maximalpause vorhanden ist. >Aus Interesse habe ich mir vor einiger Zeit mal den vom AVR-GCC >erstellten Assembler Code (zu finden in der *.LSS Datei im >Kopilerordner) für eine ISR angesehen... Und was hast du gesehen? Wieviele Takte wurden benötigt? >Je nach Optimierung des Compilers kann man für das Pushen / Pullen der >uC Register auf den Stack etwas 50 Takte als Overhead rechnen, d.h. bei >16Mhz macht das gut 3,1us zusätzlich zum eigentlichen Code in der >ISR.... Sollte also noch satt im Toleranzbereich der WS2812 Chips liegen ??? Ich sehe keine Angabe zur ISR-Laufzeit. Die besteht ja nicht nur aus deinen ca. 50 Takten für push/pop.
Falk B. schrieb: > @Reiner_Gast (Gast) > >>> durchmessen, wie lange die ISR braucht und wieviel Reserve noch zu den >>> offiziellen 50us Maximalpause vorhanden ist. > >>Aus Interesse habe ich mir vor einiger Zeit mal den vom AVR-GCC >>erstellten Assembler Code (zu finden in der *.LSS Datei im >>Kopilerordner) für eine ISR angesehen... > > Und was hast du gesehen? Wieviele Takte wurden benötigt? > >>Je nach Optimierung des Compilers kann man für das Pushen / Pullen der >>uC Register auf den Stack etwas 50 Takte als Overhead rechnen, d.h. bei >>16Mhz macht das gut 3,1us zusätzlich zum eigentlichen Code in der >>ISR.... Sollte also noch satt im Toleranzbereich der WS2812 Chips liegen > > ??? > > Ich sehe keine Angabe zur ISR-Laufzeit. Die besteht ja nicht nur aus > deinen ca. 50 Takten für push/pop. Ja, was weiß denn ich, ich kenne auch nicht den Code jeder ISR auf dieser Welt... Das kann nur der Programmierer sagen, wenn er schaut, was der Compiler daraus macht (siehe LSS Datei) Wie ich geschrieben kann mal als zusätzlichen der Overhead ca 50 Takte zum eigentlichen Code innherhalb der ISR rechnen
Man kann auch gleich Assembler schreiben. Für eine ISR müssen nicht zwingend 50 Register gepusht werden, wenn überhaupt welche.
@batman (Gast) >Man kann auch gleich Assembler schreiben. Kann man, will man meistens aber nicht. >Für eine ISR müssen nicht zwingend 50 Register gepusht werden, wenn >überhaupt welche. Niemand redet von 50 Registern, sondern bestenfalls von 50 TAKTEN! Aber naja, wir wissen ja vom wem dieser Beitrag kommt.
batman schrieb: > Man kann auch gleich Assembler schreiben. > Für eine ISR müssen nicht zwingend 50 Register gepusht werden, wenn > überhaupt welche. 50 Take != 50 Register.... Schau mal ins Datenblatt von z.B. dem ATMega328 (Kapitel 37)... Da "kostet" ein PUSH oder ein PULL eines Registers jeweils 2 Takte Bei 50 Takte macht das 25 Takte für den Eintritt in die ISR... Und 25 Takte für das Wiederherstellen der uC Umgebung... das ganze nochmal geteilt durch die 2 Takte pro Befehl... Einfluss hat darauf auch, welche Compiler Optimierung eingeschaltet ist bzw. wie viele der Register in der ISR tatsächlich benutzt werden (weil nur die vorher gesichert werden)
Mampf unterwegs schrieb: > Im mc.net Artikel steht für die WS2812 das gleiche ... Allerdings wird > dort geschrieben, dass meistens schon 5us ausreichen für einen Reset > anstatt 50us ... :) Das halte ich für ein Gerücht. Neuerdings bekommt man bei eBay eher WS2812-LEDs, die eine Mindestzeit von 250µs(!) brauchen, bevor die Daten ausgegeben werden ("Latch"). Wahrscheinlich liegt das an den neu eingeführten WS2813-LEDs, welche auch bei Defekt noch das Signal über einen "Bypass" an die nächste LED weitergeben. Diese brauchen "ganz offiziell" (s. Datenblatt) diese 250µs. Aber man muss nicht meinen, dass die Chinesen diese "neuen" WS28212 als solche deklarieren. Ich habe das vor ca. einem halben Jahr nur durch Trial- and Error herausgefunden, wo ich von den neuen WS2813 noch nichts wusste. EDIT: Siehe auch https://www.elecrow.com/blog/ws2813-vs-ws2812/
:
Bearbeitet durch Moderator
Frank M. schrieb: > Das halte ich für ein Gerücht. Ich nicht. Ich habe gerade nagelneue SK6812 mit RGBW auf dem Tisch. Die benehmen sich zwar deutlich manierlicher als WS2812b, resetten aber dennoch nicht erst nach den im Datenblatt angegebenen 80µs, sondern nach 40µs. Aber vielleicht bin ich ja nur wieder zu blöd, das Datenblatt zu lesen oder mein Monstermakro ist schuld.
Thomas E. schrieb: > Frank M. schrieb: > Das halte ich für ein Gerücht. > > Ich nicht. > > Ich habe gerade nagelneue SK6812 mit RGBW auf dem Tisch. SK6812 != WS2812
Mampf unterwegs schrieb: > Im mc.net Artikel steht für die WS2812 das gleiche ... Allerdings wird > dort geschrieben, dass meistens schon 5us ausreichen für einen Reset > anstatt 50us ... :) Immerhin ist im Datenblatt der WS2813 jetzt angegeben, dass die Low-Phase vom Signal bis zu 100 Mikrosekunden lang sein darf. Reset ist dort mit >300µs angegeben. Das hört sich schon anders an als 0.9µs/0.6μs ±0.15μs bei den SK6812 bzw. 0.8us/0.6µs ±150ns bei den WS2812. http://www.normandled.com/upload/201605/WS2813%20LED%20Datasheet.pdf
Frank M. schrieb: > Das halte ich für ein Gerücht ich habe ja deine IRMP in "meine" wordclock mit 114 ws2812b LEDs eingebaut und keine Probleme, sind aber nur um 3ms für die LEDs das rauszutakten. Meine wordclock24 mit 296 LEDs ist leider auf dem Rückweg kaputt gegangen sonst hätte ich da weiter messen und probieren können. Dort braucht das raustakten ca. 9ms. Du bist ja zum STM gewechselt ich vom ATmega328p zum ATmega1284p und immer noch optimistisch das ich es schaffe. Wie regelst du das beim STM OK per DMA für die LEDs, aber läuft der DMA unabhängig vom IRQ?
Frank M. schrieb: > SK6812 != WS2812 Ach, sag nicht sowas. Ist aber das gleiche Prinzip, inklusive dem RG-Dreher und ein weiteres Indiz dafür, daß diese Neopixels sich einen Scheiß an die Angaben im Datenblatt halten.
Thomas E. schrieb: > daß diese Neopixels sich einen Scheiß an die Angaben im Datenblatt > halten. Da gebe ich Dir recht. Allerdings muss man da auch fragen: Welches Datenblatt kann man da als verbindlich betrachten, wenn man irgendwelche WS2812 oder SK6812 in China bestellt. Von den Datenblättern schwirren zig Varianten im Internet rum.
Joachim B. schrieb: > Wie regelst du das beim STM OK per DMA für die LEDs, aber läuft der DMA > unabhängig vom IRQ? Ja, der DMA läuft komplett unabhängig vom Rest. Da kannst Du den STM32 mit IRQs malträtieren, wie Du willst: Die Übertragung auf die LEDs läuft einfach stoisch durch. Für den DMA-Transfer übergibst Du einfach einen Pointer auf einen Buffer und die Länge. Danach hast Du nichts mehr damit zu tun. Das ist die einfache, aber relativ RAM-intensive Lösung. Seit über einem Jahr benutzt die WordClock mit WS2812 jedoch eine etwas raffiniertere Kombination von DMA und DMA-Interrupt. Damit reduziert sich der nötige RAM-Bedarf auf einen Bruchteil. Im DMA-Interrupt werden die nötigen Daten on-the-fly aus den noch zu übertragenen RGB-Werten berechnet und dann laufend nachgeliefert. Der DMA-Buffer hat hier keinen Anfang und kein Ende, sondern ist ein Ringbuffer. Mit dieser Optimierung konnte ich die Pausen zwischen zwei Animationsframes für knapp 400 LEDs derart minimieren, dass das "Fehlverhalten" neuerer WS2812, die nun mehr als 250µs statt 50µs Pause für den Reset brauchen, erst aufgefallen ist. Statt dann vorne am Anfang der Stripes weiterzumachen, wurden die Daten des zweiten Frames plötzlich am Ende des Stripes bitweise rausgekippt. Das bemerkte ich auf der Suche nach den verlorenen LED-Daten erst, als ich nach den 400 LEDs noch ein paar weitere LED an den Streifen hing. Die fingen dann plötzlich an zu leuchten. Dieser Effekt war erst weg, als ich die 50µs Pause schrittweise bis auf 250µs erhöhte. Mittlerweile arbeitet die WordClock mit einer Pause von sogar 280µs, um auf der sicheren Seite zu sein. P.S. Die Wordclock24h hat nicht exakt 400 LEDs, sondern inkl. Ambilight zwischen 349 und 409 LEDs - je nach Ausführung.
:
Bearbeitet durch Moderator
Frank M. schrieb: > Für den DMA-Transfer übergibst Du einfach einen Pointer auf einen Buffer > und die Länge. Danach hast Du nichts mehr damit zu tun. Das ist die > einfache, aber relativ RAM-intensive Lösung. Und der serialisiert und transferiert die Daten über den Port zu den LEDs?
batman schrieb: > Und der serialisiert und transferiert die Daten über den Port zu den > LEDs? Jepp. Du musst die rohen RGB-Daten natürlich vorher noch ein wenig "aufarbeiten". Normalerweise lässt Du den DMA-Transfer per HW-Timer steuern, dann hast Du einen definierten DMA-Takt, der rein durch HW gesteuert wird und um den Du Dich nicht kümmern musst. Dafür musst Du die 0en und 1en vorher so im DMA-Buffer platzieren, dass sie den Zeiten T0H, T0L, T1H und T1L entsprechen. Du blähst Deine Daten dadurch von 24Bit pro LED Rohdaten mal schnell auf einen satten 8K-DMA-Buffer auf - je nach Anzahl der LEDs. Das war die simple Methode. Jetzt zu der eleganten: Wenn Du den DMA-Buffer so dimensionierst, dass er gerade die Daten für 2 LEDs halten kann, Du diesen dann als "Circular buffer" für DMA definierst, kommst Du mit weniger als 100 Bytes fürs RAM aus, *egal wieviele* LEDs Du am Streifen hast. Immer, wenn eine Hälfte des DMA-Buffers (also für eine LED) bereits übertragen ist, lieferst Du die Daten für die übernächste LED nach, während der DMA-Transfer gerade die Daten für die nächste LED raustaktet. Zusammen mit einem Double-Buffer für den nächsten 400er Frame kannst Du bereits die Daten für den nächsten Animationsframe berechnen, während die DMA immer noch am ersten Frame knabbert. Du bist also insgesamt viel schneller als die LEDs überhaupt verkraften könnten. Mit DMA macht das so richtig Spaß :-)
:
Bearbeitet durch Moderator
Hmm mit ISR kommt mir das einfacher vor aber ich habs noch nicht probiert.
Ich wollte noch nachreichen: Die IR-Routine braucht 12-16µs mit micros() gemessen (also unter 20µs).
Circular-DMA-Transfer für WS2812: https://www.mikrocontroller.net/svnbrowser/wordclock24h/src/ws2812/ws2812.c?view=markup Circular-DMA-Transfer für SK6812: https://www.mikrocontroller.net/svnbrowser/wordclock24h/src/sk6812/sk6812.c?view=markup DMA-Transfer für APA102: https://www.mikrocontroller.net/svnbrowser/wordclock24h/src/apa102/apa102.c?view=markup Bei den APA102 wird auf den kleinen Circular Buffer und den DMA-IRQ verzichtet, da sich das wegen SPI nicht mehr lohnt. Das geht hier sowieso um ein Vielfaches schneller als bei den WS2812 und SK6812 und braucht auch keinen so großen DMA-Buffer. Hier ist der DMA-Buffer genau so groß wie die RGB-Rohdaten, also pro LED 24Bit. Trotzdem: Auch hier gibt einem der DMA-Transfer (SPI über DMA) viel Luft für andere zu erledigende Dinge.
Frank M. schrieb: > P.S. > Die Wordclock24h hat nicht exakt 400 LEDs mein Prototyp hat ohne Ambilight 18 x 16 + 5 Status LEDs = 293
So, da bin ich mal wieder. Ich hab mir mal 5m LED-Streifen mit 60Stück/m = 300 Stück bestellt. Wenn man dafür nicht mal 40 Euro bezahlt, ist das irgendwie spottbillig 8-0. Es sind WS2812B, die haben 4 Pins und leider auch nicht ihr Datenblatt gelesen 8-(. Denn die dort genannte Resetzeit von >50us sind real nur 5us, wie es auch schon im Artikel WS2812 Ansteuerung geschrieben steht. Hat da der Chinese einen Dezimalpunkt vergessen? Das penible Einhalten der HIGH/LOW Zeiten ist nicht nötig? Dachte ich am Anfang! Nach ersten, schnellen Erfolgen an der LED-Front kam irgendwann die Ernüchterung! Man kann die LEDs zwar ansteuern, aber die Farben stimmen keine Sekunde! Hää? Sind die High/LOW Zeiten wirklich SOOO eng? Scheint so. Also mal fix nen Crashkurs "Wie binde ich Assemblerfunktionen in C ein" und ein paar Stunden später dann die taktgenaue Ansteuerung in Software. Jetzt passen die Farben exakt. Hmmm. Damit ist SPI zumindest raus! Warum? Bei diesem Test musste ich feststellen, daß das SPI vom ATmega 2560 nicht so ganz schnell ist. D.h. man kann nicht lückenlos hintereinander Daten senden, auch wenn man die Schleife zur Datenausgabe mit nop() taktgenau optimiert. Es bleibt immer eine minimale Lücke von ca. 300ns (5 CPU-Takte), welche nicht unterschritten werden kann. Eine weitere Merkwürdigkeit ist, daß man das Bit CPHA im Register SPCR setzen muss, damit MOSI am Ende der Datenausgabe auf LOW bleibt! Setzt man es nicht, geht es immer auf HIGH! Das hab ich bisher bei keinem SPI gesehen, auch nicht auf anderen AVRs. Bug oder Feature? Also doch Assembler und Bitbanging. Naja, wenns halt nicht anders geht. Der Vorteil dieser Funktion ist zumindest, daß man sie auf jeden beliebigen Portpin anwenden kann. Mit den passenden Arduino-Wrappern geht das sogar im Arduini-Style. Hab ich jetzt aber nicht gemacht. Die Low Pulse sind 6 CPU-Takte lang, macht bei 16 MHz = 375ns, die langen Pulse exakt doppelt so lang. Passt. Doch was machen wir jetzt mit den doch arg knappen 5us, welche maximal als Pause zulässig sind? 5us sind nicht wirklich viel Zeit, auch nicht bei 16 MHz CPU-Takt. Wir nehmen die sportliche Herausforderung an! Der IRMP basiert darauf, daß das Signal vom IR-Empfänger mit 10-20kHz abgetastet und dann dekodiert wird. Sagen wir 16 kHz, das sind 62,5us Periodendauer. Wenn gleich die Auswertung schnell ist, so sind 5us recht knapp. Wir wollen also nicht die Dekodierung in Echtzeit im Timer-Interrupt machen, wie es IRMP standardmäßig macht. Anstelle dessen werden nur die Informationen der Abtastung gespeichert und später zur günstigen Zeit ausgewertet. D.h. der Timerinterrupt liest nur das IR-Data Signal und speichert es in einem Array. Sozusagen ein Logikanalysator mit 1 Bit. So weit, so gut. Aber trotzdem ist das so eine Sache. 5us sind für eine echt kurze ISR incl. Hin- und Rücksprung zwar machbar, auch in C, aber es bleibt ein relativ großer Overhead an CPU-Last, welcher eher ungünstig ist. Mit den hier verwendeten FIFO-Funktionen wird die Zeit zu lang, wie man im Screenshots Timing_ISR_short und Timing_ISR_long.png sieht. Selbst der kurze Durchlauf ohne FIFO-Zugriff reißt eine 6.4us Lücke, der lange mit FIFO-Zugriff ca. 8,7us. Man sieht auch, daß der Testpuls SYNC, welcher im C ganz am Anfang und Ende der ISR steht, deutlich kürzer ist. Die restliche Zeit ist nicht meßbar und wird zum An/Abspringen der ISR sowie Register sichern/wiederherstellen benötigt! Das sieht man auch recht gut im *.lss File im Unterordner default.
1 | ISR(COMPA_VECT) { |
2 | 328: 1f 92 push r1 |
3 | 32a: 0f 92 push r0 |
4 | 32c: 0f b6 in r0, 0x3f ; 63 |
5 | 32e: 0f 92 push r0 |
6 | 330: 0b b6 in r0, 0x3b ; 59 |
7 | 332: 0f 92 push r0 |
8 | 334: 11 24 eor r1, r1 |
9 | 336: 2f 93 push r18 |
10 | 338: 8f 93 push r24 |
11 | 33a: 9f 93 push r25 |
12 | 33c: ef 93 push r30 |
13 | 33e: ff 93 push r31 |
Satte 9xpush + 3 einfache Befehle + 4 Takte zum ISR-EinSsprung macht mal locker 25 Takte! Das Gleiche beim Beenden! Darum wählen wir einen etwas unorthodoxen Ansatz. Während der Übertragung der LED-Daten werden die Interrupts global gesperrt (I-Bit der CPU = 0). Nach jedem Byte wird allerdings geprüft, ob das Interruptflag des Timers, welcher ja weiter läuft, schon gesetzt ist. Denn das passiert immer, egal ob der Interrupt freigegeben ist oder nicht! Man kann den Timer somit auch im Abfragebetrieb, neudeutsch "Polling" betreiben. Und genau das tun wir hier. Ist das Timerflag gesetzt, führen wir die Aktion der Timer-ISR direkt vor Ort aus. Das spart das Hin- und Rückspringen sowie Register sichern. Das verschafft uns wertvolle CPU-Zeit, die man im Falle einer komplexeren Operation gut gebrauchen kann. Das Ganze packen wir in eine 2. Assemblerfunktion, die neben der LED-Datenausgabe auch noch die IR-Daten abtastet und im FIFO speichert. Weil während der Interruptsperre auch der Softwarezähler in der ISR nicht weiter läuft, wird das auch in der Assemblerfunktion mit erledigt, damit stimmt das Gesamttiming wieder. Die übertragung der LED-Daten dauert 1,2us/Bit * 24Bit/LED * 300LED = 8640us. Bei 16 kHz Abtastfrequenz sind das ca. 138 Samples. Runden wir das mal großzügig auf 256 Samples = 32 Bytes auf. Dieser werden als FIFO benutzt. D.h. während die Timer-ISR mit 16 kHz neue Daten aufnimmt, werden die bereit vorhandenen Daten in den IRMP gefüttert und verarbeitet. Das FIFO ist ein wenig vereinfacht, es gibt keine Echtzeitprüfung auf Überlauf. Es wird nur am Anfang der LED-Übertragung geprüft, ob genügend Platz im FIFO ist. Wenn nicht, war die Dekodierung zu langsam und es kann ein Fehler signalisiert werden. Im Beispiel ist de FIFO sogar 64 Bytes groß. Warum? Weil die UART-Ausgabe mit 9600 Baud ziemlich langsam ist, ein Zeichen dauert mehr als 1ms! So lang ist auch ca. ein Bit der IR-Übertragung! Wenn gleich der Interrupt während der UART-Ausgabe weiter läuft und Daten sammelt, werden diese nicht ausgewertet! Wenn also zu lange Strings per UART ausgegeben werden, wird irgendwann mal der FIFO überlaufen. Abhilfte schaffen hier eine deutlich höhere Baudrate, ein größeres FIFO oder eine UART-Ausgabe mit Interrupts. Das Update der LED-Kette erfolgt im 20ms Raster, d.h. es bleiben ca. 11,5ms für die IR-Dekodierung und andere Dinge übrig. Das ist mehr als genug. Die Steuerung der 3 Testprogramme sowie deren Geschwindigkeit erfolgt über die empfangenen IR-Codes meiner Fernseherfernbedienung, die entgegen den Aussagen im Artikel IRMP noch mit RC5 Code arbeitet ;-) Mittels der Lautstärketasten (+/-) kann man die Geschwindigkeit einstellen, mittels der Programmwahltasten (+/-) das Testprogramm. Mit der POWER Taste kann man die LEDs dunkel schalten. Es werden nur die Codes der ersten Betätigung ausgewertet, die nachfolgenden bei gehaltener Taste werden ignoriert. Das kann man ggf. auch ändern. Parallel dazu erfolgt die Ausgabe per UART mit 9600 Baud, dann sieht man, welche Tastencodes empfangen wurden. OK, das ganz große Luxusziel der Ansteuerung nur mit C und SPI wurde verfehlt. Aber bei DEN engen Timinganforderungen ist das auch illusorisch. Aber dennoch wurde gezeigt, wie man zwei zeitlich anspruchsvolle Aufgaben multiplexen kann, und damit problemlos mit nur einem eher kleinen Mikrocontroller auskommt, auch wenn man zur Assembler-Schrotflinte greifen muss ;-) In Zukunft ist es jedoch SEHR zu empfehlen, LEDs mit DEUTLICH längerer Reset-Zeit und entspannterem Timing zu nutzen, wie sie hier im Thread genannt wurden. Dann kann man auch auf Assembler verzichten. Das Grundkonzept bleibt aber gleich! Im Anhang ein paar Screenshots vom Timing und Versuchsaufbau. Timing_WS2812B_bit.png Bitabstand innerhalb eines Bytes Timing_WS2812B_byte.png Bitabstand zwischen Bytes Timing_WS2812B_sample.png Bitabstand zwischen Bytes beim Sampling und Speicherung im FIFO Hinweis! In meinem Test wird der LED-Streifen direkt vom Arduino mit 5V versorgt. Das geht natürlich nur, wenn man nur sehr wenige LEDs mit voller Stromstärke einschaltet! Will man mehr LEDs gleichzeitig leuchten lassen, muss man ein externes Netzteil anschließen und die 5V vom Arduino abklemmen! Wenn man alle 300 LEDs gleichzeitg mit voller Stromstärke einschalten WÜRDE, würde der LED-Streifen 18A ziehen! Das klappt praktisch natürlich nicht, weil dann der Spannungsabfall auf den dünnen Leitungen viel zu groß wird. Wer dennoch mögichst viele LEDs leuchten lassen, will, muss mit dicken Leitungen vom Netzteil an Zwischenpunkten einspeisen. Ich würde mal 2,5mm^2 Querschnitt und eine Einspeisung pro Meter empfehlen.
Hier noch ein Video des Aufbaus, sowas liegt ja im Trend ;-) https://youtu.be/R85U29fj_Rw Uiii, mein allererstes Youtube-Video!!!
Falk B. schrieb: > So, da bin ich mal wieder. Danke für die ausführliche Erklärung, so hat man auch als nur "Mitleser" was davon
:
Bearbeitet durch User
Nachtrag zur Unmöglichkeit des vollen LED-Stroms. Beitrag "Re: Led- Lichterkette der besonderen Art." Ich kann im Moment nicht messen, wie hoch der Widerstand der +5V/GND Leitungen dieser Streifen ist. Es sind ca. 4mm breite Bahnen. Sind wir mal optimistisch und gehen von 35um Dicke aus, macht das 0,14mm^2 Querschnitt. 8-0 Wenn wir von N = 300 LEDs (RGB) I-LED = 60mA/LED (RGB zusammen) 17mm Abstand 0,14mm^2 Querschnitt 18mOhm mm^2/m (Kupfer) ausgehen, kommen wir auf 300*60mA=18A Gesamtstrom
1 | Rk = rho * l / A |
2 | = 18 mohm mm^2/m * 0,017m / 0,14mm^2 |
3 | = 2,2mOhm |
zwischen den LEDs (jeweils auf GND und +5V) Macht in Summe
1 | U = N/2 * (N+1)*I-LED * 2 * Rk |
2 | ~ N^2 * I-LED * Rk |
3 | = 90000 * 60mA * 2,2mOhm |
4 | = 11,9V |
Bissel viel für ein 5V System ;-) Ok, rechnen wir mal realistischer mit 0,5m LED-Streifen, einseitig gespeist, das ist gleichbedeutend mit 1m LED-Streifen und beidseitiger Speisung.
1 | U ~ N^2 * I-LED * Rk |
2 | = 900 * 60mA * 2,2mOhm |
3 | = 0,122V |
Das passt! Und jetzt mit 1m LED-Streifen einseitig (=2m LED zweiseitig)
1 | U ~ N^2 * I-LED * Rk |
2 | = 3600 * 60mA * 2,2mOhm |
3 | = 0,483V |
Das geht gerade noch so, d.h. man muss einen 5m LED-Streifen an den Enden sowie je 1,5m nach innen versetzt speisen. Zum Gegensteuern kann man ja mit 5,5V speisen, das ist noch OK.
Falk B. schrieb: > Wer dennoch mögichst viele LEDs > leuchten lassen, will, muss mit dicken Leitungen vom Netzteil an > Zwischenpunkten einspeisen. Ich würde mal 2,5mm^2 Querschnitt und eine > Einspeisung pro Meter empfehlen. ich hatte alle 36 LEDs einen eigenen stepdown aus 24V gewählt um die Ströme beherschbar zu machen.
Falk B. schrieb: > Damit ist SPI zumindest raus! Warum? > > Bei diesem Test musste ich feststellen, daß das SPI vom ATmega 2560 > nicht so ganz schnell ist. D.h. man kann nicht lückenlos hintereinander > Daten senden, auch wenn man die Schleife zur Datenausgabe mit nop() > taktgenau optimiert. Danke für's ausprobieren. Ich hatte das weiter oben im Thread schon mal nachgerechnet und kam auf das gleiche Ergebnis :)
Falk B. schrieb: > Denn die dort genannte Resetzeit von >50us sind real nur 5us, wie es > auch schon im Artikel WS2812 Ansteuerung geschrieben steht. Das ist natürlich böse. Offenbar gibt es da alles mögliche zwischen 5us und 280ms. Und alle nennen sich WS2812. > Bei diesem Test musste ich feststellen, daß das SPI vom ATmega 2560 > nicht so ganz schnell ist. Meinst Du, dass dieses nur speziell beim ATmega 2560 so ist oder bei allen AVRs? Alles in allem danke für den ausführlichen Test und Bericht, war eine Freude zu lesen :-)
Falk B. schrieb: > So, da bin ich mal wieder. Chapeau! Wirklich tolle Zusammenfassung! Da lag ich mit dem Overhead durch die ISR gar nicht schlecht ;-)
@ Frank M. (ukw) (Moderator) Benutzerseite >> Bei diesem Test musste ich feststellen, daß das SPI vom ATmega 2560 >> nicht so ganz schnell ist. >Meinst Du, dass dieses nur speziell beim ATmega 2560 so ist oder bei >allen AVRs? Das hab ich so noch nicht gesehen, wobei ich die Lücke vor Ewigkeiten mal als 1 CPU-Takt identifiziert habe. Das war aber auf einem ATtiny2313 oder so. Beitrag "Re: Atmega SPI Geschwindigkeit (Arduino schneller als C?)" Beitrag "Re: SPI Codetuning" http://www.matuschek.net/atmega-spi/ (Mein Gott, das Netz vergißt nichts) >Alles in allem danke für den ausführlichen Test und Bericht, war eine >Freude zu lesen :-) Gern geschehen.
Man kann sich das Leben auch schwer machen. Die gängigen IR-Protokolle lassen sich mit einer handvoll Codezeilen decodieren. Man braucht nicht immer ein fettes IRMP reinzuquetschen.
batman schrieb: > Man kann sich das Leben auch schwer machen. Die gängigen > IR-Protokolle > lassen sich mit einer handvoll Codezeilen decodieren. Man braucht nicht > immer ein fettes IRMP reinzuquetschen. Ja kann man ... Aber weshalb sollte man? Klar, der Quellcode ist sehr lang, aber wenn IRMP entsprechend konfiguriert ist, wird nur das nötigste mit kompiliert und dann ist es nicht mehr fett. Und ich finde IRMPs Sample-Ansatz sehr gut ... Der Sampler wird vom Timer aufgerufen und macht selbst nur sehr wenig. Und ganz ehrlich, man kann sich das Leben auch schwer machen und das Rad immer wieder neu (und schlechter) erfinden ;-)
:
Bearbeitet durch User
Mampf F. schrieb: > Klar, der Quellcode ist sehr lang, und sprengt die Arduino IDE, als ich meine wordclock 2015 baute klappte es noch, als ich es mit neuester IRMP versuchen wollte leider nicht mehr.
Joachim B. schrieb: > Mampf F. schrieb: >> Klar, der Quellcode ist sehr lang, > > und sprengt die Arduino IDE, als ich meine wordclock 2015 baute klappte > es noch, als ich es mit neuester IRMP versuchen wollte leider nicht > mehr. Hmm, hattest du alle Protokolle aktiviert? Hatte mit IRMP bisher keine Probleme - auch nicht letztens auf einem ATMega8 (mit vUSB).
Mampf F. schrieb: > Hmm, hattest du alle Protokolle aktiviert? ja, daran wirds gelegen haben, wollte einen Uni Dekoder machen nur welche lässt man dann weg für einen Code Erkenner?
@Joachim B. (jar) >> Hmm, hattest du alle Protokolle aktiviert? >ja, daran wirds gelegen haben, wollte einen Uni Dekoder machen Das sollte kein Problem sein. >nur welche lässt man dann weg für einen Code Erkenner? Gar keinen. Warum auch? Die paar kB Flash hat doch jeder. Was ging denn nicht?
Falk B. schrieb: > Gar keinen. Warum auch? Die paar kB Flash hat doch jeder. Was ging denn > nicht? Die Arduino IDE stotterte konnte den gesammten Code nicht verarbeiten, file zu groß wenn ich mich recht erinnere, ist schon etwas her, habe dann abgebrochen.
Ich hab mal den IRMP im Normalzustand vermessen. Die ISR dauert dort 3,5-9,2us, dazu kommen die nicht meßbare An- und Absprungzeit der ISR von ca. 3us bei 16 MHz CPU-Takt. Incl. Reserve sind vielleicht 15us im Maximum. Wenn man also LEDs hat bzw. kauft, welche 20us oder mehr als Pause vertragen, braucht man weder Assembler noch eine IRMP-Modifikation!
Falk B. schrieb: > Wenn man also LEDs hat bzw. kauft, welche 20us oder mehr als > Pause vertragen, braucht man weder Assembler noch eine > IRMP-Modifikation! meine wordclock von 2015 mit IRMP und 114 LEDs läuft ordentlich ohne Probleme. Timer alle 10ms updatet die LEDs, IRMP ist mit IRQ alle 1/15000s dran
Joachim B. schrieb: > Die Arduino IDE stotterte konnte den gesammten Code nicht verarbeiten, das hab' ich noch nie erlebt; dass ein Compilat mal grösser als die Zielflashgrösse wurde, ok, das gibt aber ja bloss entsprechende Meldungen... @Falk: total OT, aber ich glaube, der Nachfolger deiner 0.6.5 uralt-Software ist diese hier: http://www.qdkingst.com/en/download :-)
Falk B. schrieb: > Bei diesem Test musste ich feststellen, daß das SPI vom ATmega 2560 > nicht so ganz schnell ist. D.h. man kann nicht lückenlos hintereinander > Daten senden, auch wenn man die Schleife zur Datenausgabe mit nop() > taktgenau optimiert. Es bleibt immer eine minimale Lücke von ca. 300ns > (5 CPU-Takte), welche nicht unterschritten werden kann. Was haste genommen, ein normales SPI? Probier mal einen USART im Master-SPI-Mode, da ist das Tx-Register doppelt gepuffert.
@ Horst Meier (horst) >Was haste genommen, ein normales SPI? Ja. >Probier mal einen USART im Master-SPI-Mode, da ist das Tx-Register >doppelt gepuffert. Kann sein, ist aber jetzt mit der Softwarelösung überflüssig.
@ Jan L. (ranzcopter) >@Falk: total OT, aber ich glaube, der Nachfolger deiner 0.6.5 >uralt-Software ist diese hier: http://www.qdkingst.com/en/download :-) Hab ich probiert, die Software findet meinen LA nicht. Scheint die falsche Firmware zu haben. Außerdem meldet Windows beim Anstecken ein Problem, obwhl der alte Treiber mit der alten Software läuft. Ein Deinstallieren und neu Installieren des Treibers brachte keinen Erfolg. 8-0 Ich glaub meine Hardware ist nicht kompatibel, denn von dem LA1016 gibt es diverse (Billig)Nachbauten.
Das Bessere ist immer Feind des Guten. Ich hab mal meine Funktionen mit ein paar Macros aufgepeppt. Jetzt können sie mit 6,3-10MHz arbeiten, und das mit recht geringen Abweichungen vom optimalen Timing.
Sooo, da ich gerade mal wieder ein WS2811 Problem beheben musste, habe ich mal meine ASM-Funktion ein wenig aufgefrischt und optimiert. Man kann jetzt die Bitzeiten direkt in den Quelltext schreiben, die Berechnung der Delays erfolgt im Quelltext. Ebenso kann man zwischen LOW und HIGH Speed Modus wählen.
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.