• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Arduino + ledy ws2812b
#51
Obsługa seriala działa bardzo dobrze, testowałem 9600. CPU jest faktycznie zajęty, ale i tak nic innego nie ma do roboty, więc to żadna wada.
 
#52
Edit: faktycznie obsługa seriala nie jest idealna - przy Adafruit_Neolib czasem gubią się bajty, ale ogólnie jest całkiem nieźle i bez problemu dałoby się odpowiednim protokołem nadrobić braki. Natomiast FastLED zupełnie zabija seriala - dwa bajty w buforze i tyle.
 
#53
(16-12-2019, 22:35)elvis napisał(a): Obsługa seriala działa bardzo dobrze, testowałem 9600. CPU jest faktycznie zajęty, ale i tak nic innego nie ma do roboty, więc to żadna wada.
Może zadziałać i 921600 jak się uda "wstrzelić". Gdy dane wysyłane są do LED przez AVR, który "macha pinem" to muszą być zablokowane przerwania. Jak masz szczęście to akurat podczas transmisji nie do LED nie ma transmisji po UART. Spróbuj jednak wysyłać dane po UART bez przerwy z prędkością 9600 ni na 100% będziesz miał gubienie znaków. matematyki nie da się oszukać. 500 LED to transmisja trwająca 1/(800e3/24/500) = 15ms. nie chce być inaczej. transmisja 1 znaku przy 9600 8N1 to 1/(9600/10) = ok 1ms. Matematyka nie kłamie. W 15ms może zostać przesłane 15 znaków, zgadza się? FIFO w AVR ma 2 znaki, więc 13 zgubisz. Tak czy nie?
Prędkość, która gwarantuje, ze znaki nie będą zgubione to 1200 co wynika z 1/(1200/10)= ok 8,3ms. W 15 ms mogą być przesłane co najwyżej 2 znaki a tyle ma sprzętowe FIFO.
Dlatego do obsługi WS281x najlepiej wykorzystać UART lub SPI. Nie trzeba zawieszać przerwań a samą transmisję można zrealizować w przerwaniach właściwie to trzeba, bo pomiędzy kolejnymi zapisami do UART lub SPI nie można przekroczyć czasu ok 20us a AVR to nie ARM.


Co do hobby, kobiety są najkosztowniejsze.
 
#54
Jak zwykle masz trochę racji, ale nie całkiem. Po pierwsze w tym temacie nie dyskutujemy o działaniu portu szeregowego, ale o sterowaniu ledami ws281x. Program ma robić to co zakłada projekt, nie musi robić kawy, ani podawać kapci - i pomimo tych braków będzie nadal wystarczająco dobry.
Po drugie, gdyby ktoś chciał mieć obsługę seriala to wystarczy chwilę pomyśleć i zmienić sposób komunikacji. Skoro 2 bajty mogą być przechowywane w buforze sprzętowym, to równie dobrze można z PC wysłać jeden, a później zrobić przerwę w nadawaniu, dając Arduino czas na zakończenie serowania ledami. Po takim opóźnieniu będzie już można spokojnie przesyłać całą resztę danych - oczywiście podczas transmisji danych nie będzie sterowania ledami - ale zawsze to lepsze niż powiedzieć "nie da się".
A wreszcie po trzecie... chyba da się sterować ledami i nie wyłączać przerwań. Napisałem chyba, bo muszę to więcej potestować. Jednak jak na razie 3 paski led + przerwania działają całkiem ładnie. Jak będzie działało poprawnie to coś więcej o tym napiszę - chociaż raczej na forbocie.
 
#55
Update: steruję 3 paski po 144 diody ws2812b, czyli 432 sztuki - to mniej więcej 2 razy więcej niż potrzebuje autor tego tematu.
Przerwania są wyłączane tylko kiedy to konieczne, więc zarówno millis jak i serial działa. Przykład działania seriala:
   
Dla porównanai - używając Adafruit_Nexpixel ten sam komunikat testowy gubił niektóre znaki, co w sumie było oczekiwanym efektem. Bez wyłączania przerwań widoczne były za to błędy w sterowaniu ledami.
Teraz zarówno ledy, jak i serial działają bardzo dobrze Smile
 
#56
(17-12-2019, 11:28)elvis napisał(a): A wreszcie po trzecie... chyba da się sterować ledami i nie wyłączać przerwań. Napisałem chyba, bo muszę to więcej potestować.
Widzę, ze niewiele wiesz o WS281x i nie zaglądałeś do danych katalogowych. Dziwi więc dlaczego zabierasz głos? Cięzko było przeczytać 3 strony noty katalogowej? Nie pisałbyś wtedy głupot!

Da się jak użyjesz UART lub SPI, gdy "machasz" pinem na AVR MUSISZ wyłaczyc przerwania. Powód jest banalny, impulsy dla WS2812 mają czasy ok 400 i 800us ns. Przesłanie bajtu ok 1200us bitu ok 1.2us. Sygnał RESET (powinien nazywać się raczej LATCH) 50us. 
Poza danymi z katalogu mogę dodać, że:
- Ledy zatrzaskują dane w 15..25us a 50 jest gwarantowane.
- Czas trwania "H" jest krytyczny, "L", można przeciągnąć bezpiecznie do 10us.

Mając garść informacji widać, że krytyczny jest stan "H", który nie może przekraczać ok 400ns +/- 15% jak pamiętam.
Napisz ob sługę przerwania na AVR, która wykona się w max 460ns! Cykl zegarowy AVR popędzanego 20MHz to 50ns. Masz do dyspozycji max 10 rozkazów min 5. Stan GPIO zmienisz ale jak zrobisz wstawkię ASM bo nam prolog przerwania (piszę z pamięci)
Kod:
SEI - 1 cykl
PUSH r0 - 2 cykle
MOV r0,PSW - 1 cykl
PUSH r1 - 2 cykle
EOR r1,r1 - 1 cykjl
to 7 cykli, epilog
Kod:
POP r1 - 1 cykl
POP r0 - 1 cykl
MOV PWS,r0 - 1 cykl
POP r0 - 1 cykl
RETI - nie pamiętam, nich będzie 1 cykl
kolejne 5 cykli, razem 12 cykli co daje 600ns. A gdzie reszta przerwania? przykładowo odczyt danej z UART i zapis do FIFO? Przerwania w AVR, zależnie od stopnia skomplikowania, trwają 2..20us.

Nawet jak obsłużysz WS281x na przerwaniach od UART czy SPI możesz napotkać problemy w postaci przerwań odbiorczych UART lub od linii INT wyzwalanych poziomem niskim. AVRmega/tiny nie ma (poza najnowszymi) wielopoziomowego sytemu przerwań. Nie można użyć nieblokującego (INTERRUPT czy ISR_NOBLOCK) przerwania od UART czy INT dla poziomu. W przypadku UART dopóki nie odczytasz danej, nie możesz odblokować przerwań. Dlatego przerwania odbiorce UART są ISR_BLOCK. Jest na to obejście ale wymaga wstawki ASM. W Elektronice dla Wszystkich będzie artykuł na ten temat.


(17-12-2019, 11:28)elvis napisał(a): Po drugie, gdyby ktoś chciał mieć obsługę seriala to wystarczy chwilę pomyśleć i zmienić sposób komunikacji. Skoro 2 bajty mogą być przechowywane w buforze sprzętowym, to równie dobrze można z PC wysłać jeden, a później zrobić przerwę w nadawaniu,
Nie rozśmieszaj mnie. Zmuś jakiegoś slave nadającego w MODBUS do przerwy. przypomnę, że pomiędzy bajtami w MODBUS nie może być przerwy dłuższej niż 3,5 znaku. Dla 115200 8N1 to czas ok 303us. W takim czasie wyślesz dane do 5 led, dla 92600, która często używam do ani jednej, dopiero, dla żółwia 9600 jest lepiej bo przez ponad 3,6ms można nakarmić ok 70 led.
Rozwiązanie, które zaproponowałeś to amatorka aż się patrzy. przy nadawaniu nie można skorzystać z DMA. Gdyby taką propozycję dał jakiś arduinowiec to bym zrozumiał ale taki ekspert jak Ty? Wstyd!
Temat zamknięty, więc pewnie pan Semi nie będzie mógł poprawić nawet jak już ochłonie, a szkoda by ktoś patrzył na takie dane.   Kaczakat
 
#57
A wracając do ws2812 - znalazłem ciekawy wpis https://wp.josh.com/2014/05/13/ws2812-ne...know-them/
I wygląda na to, że to faktycznie działa. Można więc włączać przerwania podczas transmisji i chociaż to niezgodne z dokumentacją, diody działają bardzo ładnie. Taka ciekawostka - może się komuś przyda, bo mi gównoburza z @semi zupełnie odebrała ochotę na zabawę Arduino i diodami ws2812.
 
#58
Posprzątałem i zamykam.
Jeśli autor wątku ma ochotę to ciągnąć, proszę o PW.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
  


Skocz do:


Przeglądający: 1 gości