Strony

poniedziałek, 20 stycznia 2014

WS2812 - MAGIC RGB LED - PART 03

Witam,

Chciałbym rzec .... "no to lecimy dalej Panie i panowie" .... Zapraszam na kolejny odcinek poradnika z cyklu Magic LED. Zaczynamy pisać kod źródłowy. Uprzedzam - trochę tego będzie - nie uda mi się zamknąć całości w 2 lub 3 kolejnych odcinkach ... dlaczego ? ... dlatego że w książce już nie będę tego opisywał a chciałbym aby każdy mógł zrozumieć to OD PODSTAW i cieszyć się diodami RGB tak jak ja - czyli tak jak dziecko ;) ...

W związku z moim apelem na youtube - mam również prośbę o klikanie Google PLUS (tej jedyneczki na dole postu) na blogu pod poradnikiem jeśli się wam podoba ...
 tak samo jak łapki na youtube. A jeśli ktoś z was posiada konto plus google to również o udostępnianie moich poradników ... POMOŻECIE ??? ;) ... z góry serdecznie dziękuję.

to dzięki temu - postanowiłem tworzyć dalej poradniki zupełnie bez żadnych opłat ... w zamian za taką małą pomoc - o ile oczywiście Wam spodoba się dany poradnik.



poniżej film


;)

24 komentarze:

  1. Panie Mirku,super.Dzięki wielkie za trzecią część,pozdrawiam,Piotr.

    OdpowiedzUsuń
  2. Mam pytanko, czy muszę założyć konto na google+ żeby to działało bo klikam i klikam i tylko stronas logowania mi się wyświetla :(

    OdpowiedzUsuń
    Odpowiedzi
    1. A możliwe, że tak .... ale jeśli kolega nie chce zakładać konta na plus google to nie ma sprawy, rozumiem to ... Bo rzeczywiście chyba założenia konta nie uda się kliknąć.

      Usuń
    2. Niestety ale trzeba być zalogowanym na google+ by móc dawać komentarze , łapki w górę etc...
      Założenie konta w google nie wiąże się z jakąś tam utratą prywatności.
      Przecież nie musi się wyświetlać nazwisko i imię a sam login itp
      Sam jest by chronić prywatność. Choć w dobie internetu to raczej trudne :)

      Pozdrawiam

      Usuń
  3. Cieszę się Mirku iż odzyskałeś pozytywne nastawienie. Ze swojej strony mogę obiecać iż będę klikał ikonkę "g +1" przy każdym nowym filmiku. Mnie osobiście się ten poradnik nie przydał ale oglądałem go z wielkim zaciekawieniem. Osobiście jestem najbardziej zainteresowany zagadnieniem transmisji CAN BUS. Mam nadzieję iż znajdziesz kiedyś czas na i taką serią. Tak czy siak, czy ta seria powstanie czy nie, zawsze będę Twoim wielkim fanem i klientem Twojego sklepu.

    OdpowiedzUsuń
  4. A ja tam założyłem konto i klikam ... by mirek wiedział że warto robić takie super poradniki

    OdpowiedzUsuń
    Odpowiedzi
    1. eeeeh powiem tak .... dzisiaj zasiadłem do kompa i włączyłem widok statystyk ... i przysięgam aż mi się łza w oku pojawiła - bo teraz widzę że zareagowaliście ... Np na YT wzrost kliknięć od was o 600% !!! to pokazuje - że wcześniej Was tak jakby nie było :( ... więc nie ma co się dziwić, że Was nie widziałem ... W końcu pokazała się np wyraźna różnica między negatywami (łapka w dół - czyli głosowaniami malkontentów a zadowolonymi)

      Uwierzcie mi - ten wzrost - chociaż nie wiem czy się utrzyma - ale bardzo mi pomoże ... tzn mam taką nadzieję ... już teraz odnotowałem kilka telefonów do firmy z zapytaniem o książkę bo ktoś się właśnie z YT dowiedział o moich książkach ...

      to że piszecie, to że klikacie w łapki czy plusiki na google plus, na facebooku, to że udostępniacie ... to na prawdę działa i teraz widać przynajmniej zaczątki tego ....

      teraz zaczynam lepiej czuć że jesteście ze mną, widzę też że zaczyna działać reklama tego co robię - i to dzięki TYLKO WAM ...

      dziękuję uprzejmie

      Usuń
    2. Nie masz Mirku za co dziękować to my dziękujemy

      Usuń
  5. Świetny poradniczek . Mirku dziękuję że się nie poddajesz ,no i czekam na kolejne poradniki . Pozdrawiam.

    OdpowiedzUsuń
  6. Mój Nick Piotr. Po oglądnięciu trzeciej części i nie tylko. Stwierdzam że Mirek posiada wielką wiedze i potrafi to przekazać.

    OdpowiedzUsuń
  7. Dziękuję za ten poradnik i za wszystkie inne na tym wspaniałym Blogu .

    OdpowiedzUsuń
  8. Super, coś zaczyna się dziać w kodzie, jak na razie ogarniam co robimy. Świetny poradnik Panie Mirku!

    OdpowiedzUsuń
  9. to ja podejmę "próbę" "napisania" funkcji wysyłającej bajty. Zabawę z mikrokontrolerami i programowaniem zacząłem miesiąc temu więc proszę o skrajną wyrozumiałość. nie napiszę striktę kodu tylko opiszę słowami co probował bym osiągnąc.

    1) po pierwsze powinna być static żeby jej kod był wpisywany w miejsce wywołania. i powinna nazywać się narazie send_byte() -- (jednak upartuję tutaj błąd o czym powiem poniżej w punkcie 2)
    2) ponieważ oglądając wcześniejsze poradniki dosłuchałem się że istnieje też komenda "reset" czyli nieaktywność na lini przez określony czas więc nie dość że mamy kaganiec na szyi związany z wywołaniem funkcji send_zero() lub send_one() ale mamy kaganiec taki że przerwy w wywołaniu funkcji send_bye() powinny być poniżej czasu "reset" ws2812 dlatego optował bym dla ułatwienia sobie sprawy napisać funkcję ktora odrazu wyśle WSZYSTKIE potrzebne nam bajty.
    3) powinniśmy przekazywać wskażniki do zmiennych a nie same zmienne żeby nie tracić cennych tików procesora na tworzenie kopi zmiennej w pamięci lub inne znią problemy\
    4) powiniśmy stworzć sobie tablicę dwu wymiarową [ilość _diod][8 znaków same 0 lub 1]i po przygotowaniu wysłać wskaźnik do niej.

    czyli funkcja powinna wyglądać.(tak jak mówilem to nie kod w C tylko opis:P)

    static void send_bytes (*int ilosc_diod, *char bajty[])
    int counter=0; // zabierze nam jeden tik zegara wiec uwzględniamy to w asm"nop" w funkcjach send_zero() i send_one();

    while (counter<ilosc diod) // sprawdzenie warunku też nam zabiera czas procesora więc znowu -1x asm"nop";
    {
    if ( bajty[counter][0]=="0") send_zero(); \\kolejny warunek wiec -1x asm"nop" :(
    else send_one();
    //aby nie marnować tików na pentle i warunki to to robimy ręcznie kolejnych 7 bitów
    if ( bajty[counter][1]=="0") send_zero();
    else send_one();
    if ( bajty[counter][2]=="0") send_zero();
    else send_one();
    if ( bajty[counter][3]=="0") send_zero();
    else send_one();
    if ( bajty[counter][4]=="0") send_zero();
    else send_one();
    if ( bajty[counter][5]=="0") send_zero();
    else send_one();
    if ( bajty[counter][6]=="0") send_zero();
    else send_one();
    if ( bajty[counter][7]=="0") send_zero();
    else send_one();
    // i wysłaliśmy 1 byte. czyli obsłużyliśmy tylko 1 diodę. teraz zwiększamy counter o 1 powtarzemy to dla wszystkich diod;
    counter++
    {


    w ten sposób wysłaliśmy informację do wszystkich diod więc powinnyśmy wykonać komendę reset polegającą na "nie narawaniu" porze jakiś czas. ale prawdopodobnie zanim przygotujemy kolejny komplet bitów do tablicy bajtów to reset wykona się mimo woli. wiec olewamy i zajmujemy się planowaniem kolorków do następnego wywołania funkcji send_bytes( .. ).

    tyle. tak jak powiedziałem jest to opis dzalania a nie kod wiec proszę nie probować tego kompilowac :P

    OdpowiedzUsuń
    Odpowiedzi
    1. i SUPER!, że kolega próbuje tworzyć takie kody ... bo na prawdę później będzie łatwiej. Ja tylko SPROSTUJĘ / PODPOWIEM,. że

      ... ten RESET = 50us dotyczy czasu po przesłaniu CAŁEGO POCIĄGU WAGONIKÓW ja z poprzedniego poradnika a nie po przesłaniu każdego bajtu. Czyli dla przykładu jak mamy dwie diody w łańcuchu to RESET przyjdzie po 6 bajtach ale gdy mamy 3 diody w łańcuchu to RESET przyjdzie po? ...

      .... po 9 bajtach - to istotna rzecz. Od razu trzeba się z tym oswajać ;)

      Usuń
    2. ok w takim razie popełniłem błąd. bo umaniło mi się w głowie że na 1 diodę przypada 1 bajt. i to w sumie jest prawda ale w 1 diodzie są 3 (GRB) i każda powinna dostać po 1 bicie. krótko mówiąc albo zmienną ilość_diod trzeba po mnorzyć przez 3 albo tablicę utworzyć w taki sposób byte[ilosc_diod][ciągem 3 bajty dla 1 punktu świetlnego]. i dodać kolejne wpisy
      if ( bajty[counter][8 do 23 ]=="0") send_zero();
      else send_one();

      tak na marginesie ciekaw jestem czy blisko byłem poprawnej funkcji? wiem że nie chodzi tu o same wywołania bo to można załatwić na wiele sposobów tylko o to czy zmieściłem się w czasie 1200 ns i czy dobrze myślę? Na razie nie przetestuję swojego bazgrołu bo czekam na kwarc. Mam atmegę8 a odradzał Pan kwarce 8MHz wewnętrzne wiec kupię taki jak w poradniku.

      Pytanie dodatkowe. jeżeli wyślę dane do wszystkich diod i w ogóle przestanę na dawać to co się stanie? diody pozostaną w ostatnim nadanym im stanie czy pogasną? jest to o tyle istotne bo jeżeli pozostaną w ostatnim nadanym im stanie to przy wysyłaniu jednocześnie nie po bajcie tylko całość danych dla wszystkich diod możemy olać reset (co starałem się osiągnąć). i wysyłać całe dane co dowolny czas.

      Usuń
    3. Sama idea tak do przynajmniej teoretycznego rozważania i podejścia jest jak najbardziej słuszna, niestety takie działanie z tablicą która miałaby przechowywać bity spowodowałoby już bardzo duże rozjechanie się czasówki i byłby zonk ... ale już w kolejnym odcinku zobaczymy jak do tego podejść i super, że ktoś pokusił się o takie podejście ... Bo np na forum.atnel.pl koledzy na razie próbują ot po prostu "z ręki" w sposób bardzo liniowy wysyłać jakieś sekwencje bitów ... ale nikt się tam jeszcze nie pokusił o ubieranie tego w jakieś nadrzędne funkcje do wysyłania paczek (wagoników) ... więc ten przykład będzie dobrym wstępem do treningu i lepszego zrozumienia ...

      Jeśli wyślesz do wszystkich diod a będzie ich nawet 50 - to oczywiście, że każda będzie wciąż świecić i nie zgaśnie ... będzie świecić z takim PWM jaki został jej ostatnio zadany. Natomiast przestać świecić może tylko w dwóch przypadkach:

      1. wyłączenie zasilania
      2. ponowna zmiana PWM na ZERO

      Usuń
    4. to mam jeszcze 2 pytania.
      1) Jeżeli stworzymy nadrzędną funkcję i z jakiś powodów przekroczymy czas "reset" pomiędzy wysyłaniem kolejnych "wagonów" to wtedy stanie się tak że będziemy sterować tylko pierwszą diodą bo potem cała reszta uzna że nastąpił reset i zaczynamy zabawę od początku?
      2) skoro reset=50us czy to oznacza ze jeżeli wyrobimy się np. w 30us z podaniem kolejnego bajtu to nie zresetujemy magistrali(mieli byśmy wtedy 30.000/90 rozkazów do wykożystania co daje nam drobne pole do działania w inny sposób)? czy taka tolerancja jest do zaakceptowania przez ws2812? ja rozumiałem że transmisja kolejnego bitu musi następować prawie natychmiast po poprzednim. Z drugiej strony to jak szybko działa funkcja send_byte() określa nam maksymalną długość paska led oraz płynność animacji. wiec optymalizacja jest wskazana. przy 20 metrach paska (średni pokoik bądź ekran 34x34cm czyli mały ) i częstotliwości pracy ok 30us wychodzi mi że mamy odświeżanie obrazu na poziomie 108 ms czyli 9,25 Hz. więc kiszka taki obraz będzie mało płynny dla naszego oka. trzeba optymalizować.

      ps. kiedy następna część bo nie będę mógł spać??

      Usuń
    5. Ale poczekaj - przeczytaj dobrze to co piszę wyżej, jeszcze raz obejrzyj animacje .,..... bo

      ad.1) .... RESET nie wysyłamy po 3 wagonikach do diody .... rozumiesz ? RESET wysyłamy na magistralę po wysłaniu WSZYSTKICH WAGONIKÓW, WSZYSTKICH ;) .... czyli do WSZYSTKICH DIOD halo halo ;) wszystkich diod ... ok?

      ad 2. .... jak widzisz z uwagi na to co napisałem wyżej to pytanie jest bezzasadne

      Usuń
  10. a może by tak w przyszłości LED-CUBE ;) ?

    OdpowiedzUsuń
  11. Witam
    Odnośnie czasów 400ns i 800ns - taki pomysł wpadł mi do głowy.
    Napisać taki programek żeby policzył faktyczny czas stanu wysokiego i stanu niskiego dla zadanych parametrów np 100 cykli. Jak poda czas 100 cykli to można wyliczć "współczynnik wydłużenia".

    OdpowiedzUsuń
  12. Witam. Podpowiedzcie proszę, czy i gdzie znajdę gotowy kod w C (tak coby samemu nie przepisywać na podstawie video). Ma to swoje zalety, ale mimo wszystko fajnie byłoby mieć pod ręką oryginalne źródła, czy to w postaci finalnej, czy to na etapie np. z odcinka 3.

    OdpowiedzUsuń
    Odpowiedzi
    1. Za kilka dni pojawi się link do pobrania kodu

      Usuń