Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[AVR] LED RGB - gradacja kolorów, jak to zrobić?

21 Sty 2012 18:46 4880 23
  • #1 21 Sty 2012 18:46
    30402
    Użytkownik usunął konto  
  • #2 21 Sty 2012 19:00
    tmf
    Moderator Mikrokontrolery Projektowanie

    Żeby zachować kolor, a tylko zmienić jego intensywność musisz przemnożyć wszystkie składowe koloru przez tą wartość. Czyli masz składowe RGB i mnożysz je przez współczynnik intensywności w zakresie 0-1 i uzyskane wartości składowych wpisujesz jako nowe. Oczywiście dla 8-bitowych wartości składników RGB cudów nie uzyskasz. ale możesz zawsze zwiększyć rozdzielczość PWM. Dla 16-bitowego PWM już całkiem ładne przejścia będą.
    BTW, po co sobie utrudniasz zadania pisząc w asm?

    0
  • #3 21 Sty 2012 19:19
    30402
    Użytkownik usunął konto  
  • #5 21 Sty 2012 19:54
    30402
    Użytkownik usunął konto  
  • #6 21 Sty 2012 20:02
    excray
    Poziom 39  

    Jeśli używasz kolorów podstawowych RGB lub CMY, to da się zrobić takie "zejście do zera". Jeśli chcesz to zrobić z bardziej "wysublimowanym" kolorem to niestety mój sposób nie nadaje się do tego.
    Proponuję Ci zrobić w tej sytuacji 4-ty PWM dla jasności ogólnej diody.

    0
  • #8 21 Sty 2012 20:40
    tmf
    Moderator Mikrokontrolery Projektowanie

    Saabotaz napisał:
    Z tym mnożeniem przez 0 i 1 dla 8 bitów to wyjdzie porażka bo albo świeci albo nie świeci.


    Nie chodzi o mnożenie razy 0 lub 1, bo wynik przecież jest oczywisty. Tylko o mnożenie razy liczbę z przedziału 0 do 1, żeby uniknąć typu float to robi się to wykorzystując arytmetykę stałopozycyjną lub tymczasowe promowanie do typu szerszego - np. liczbę z zakresu 0-1 traktujesz jako np. 8 bitową, w efekcie mnożenia uzyskujesz wartość 16-bitową, którą potem normalizujesz.

    0
  • #9 21 Sty 2012 20:56
    30402
    Użytkownik usunął konto  
  • #10 21 Sty 2012 21:19
    tmf
    Moderator Mikrokontrolery Projektowanie

    A w czym ci to przeszkadza? Przeciez procesor sprzętowo generuje PWM, więc się kompletnie nudzi, te pare obliczeń nie stanowi problemu. W C w dodatku miałbyś to za free bez gimnastyki.
    Zauważ, że 4 PWM wcale nie rozwiązuje problemu - zrobi się aliasing, ew. czętotliwość tego 4 PWM musiałaby być znacznie większa niż 3 podstawowych do regulacji kolorów, a to z kolei stanowi pewne wyzwanie dla drivera sterującego LED.

    0
  • #11 21 Sty 2012 21:39
    excray
    Poziom 39  

    Jest jeszcze jedna opcja ale ona mi osobiście się średnio podoba i wymaga znacznej wartości zegara aby led nie migał i zmiany nie trwały zbyt długo. Polega to na tym że w PWM (powiedzmy Fast) masz zliczanie 0-255 przez licznik i porównywanie tego z OCxn. na podstawie tego jest generowany pojedynczy impuls z wypełnieniem zależnym od OCxn. Taki cykl się powtarza wielokrotnie. Dodatkowo po przepełnieniu licznika jest generowane przerwanie TOV które tu się przyda. Więc można dodatkowo to w obsłudze przerwania podzielić na 256 CYKLI * 256 (0-255) cykli pełnego zliczenia timera i w tych CYKLACH robić przejście kolorów. Oczywiście taka procedura musi być wykonana dla 3-ch kolorów oddzielnie. Czyli dla jednego koloru wygląda to tak: robisz przejście z koloru A do koloru B w którym składowa zielona R w kolorze A wynosi AR=225 a w kolorze docelowym BR=32. Po każdym pełnym CYKLU robisz sprawdzanie. I tak na początku 256 na 256 pełnych cykli timera OCnx będzie zawierać wartość 225. Po 128 CYKLACH 128 cykli będzie z wartością OCnx=225 a kolejne 128 z wartością OCnx=32. Po 256 CYKLACH w OCnx będzie już tylko 32. Jak widać wymaga to 256*256*256cykli zegara przy założeniu że timer jest taktowany 1:1 co daje pełne przejście przy 16777216 cyklach czyli przy 8MHz przejście będzie się wykonywało 2sek. Oczywiście pętle można skrócić do mniejszej liczby cykli np: 128*128*256. Całość można wykonać w przerwaniu od przepełnienia i czasowo nie jest to długa procedura. Po prostu 2 liczniki (*3 dla RGB) które co przerwanie są zwiększane o 1 i sprawdzenie warunków.

    Dodano po 1 [minuty]:

    tmf napisał:
    Zauważ, że 4 PWM wcale nie rozwiązuje problemu - zrobi się aliasing, ew. czętotliwość tego 4 PWM musiałaby być znacznie większa niż 3 podstawowych do regulacji kolorów, a to z kolei stanowi pewne wyzwanie dla drivera sterującego LED.

    Zgadza się. Wiem o tym. Ale wcale nie musi być większa. Przy PWM 8 ma być o 256 razy mniejsza. I to na dodatek synchronicznie. Dlatego do 4 PWM dobrze wykorzystać TOV licznika generującego PWM dla 3-ch składowych kolorów - coś jak opisałem powyżej.

    0
  • #12 21 Sty 2012 21:54
    mirekk36
    Poziom 42  

    Też uważam, że wprowadzenie 4 PWM'a do tego to niestety troszkę jak piąte koło u wozu. A realizację równomiernego ściemnienia koloru: R: 230 G: 13 B: 47 spokojnie można uzyskać zmniejszając procentowo każdą składową, przy czym najlepiej wziąć tu pod uwagę nieliniowość o której wspomniał janbernat, żeby uzyskać dobry efekt. A dokonanie takich obliczeń to przecież pestka. Wystarczy na liczbach całkowitych.

    Tego się po prostu inaczej nie robi. Zajrzyj sobie zresztą choćby do Photoszopa i podejrzyj co dzieje się ze składowymi RGB w takim przypadku, twój kolor po ściemnieniu o 50% przyjmuje wartości: R: 107 G: 7 B: 24

    a jeśli ściemni się o 75% to masz kolejno: R: 53 G: 3 B: 12

    i musisz wziąć pod uwagę czy chcesz czy nie, że dla oka ludzkiego i tak już w takim przypadku zmieni się lekko barwa - nie ma że boli. A dodatkowo zależy jeszcze kto jakie ma oko. Najbardziej wrażliwe ma niewątpliwie Kobieta - ona szybko ci powie że np kolor cytrynowy przeszedł w musztardowy ;)

    a facet powie ci że żółty przeszedł w ciemnożółty.

    O daltoniście już nie wspomnę. A tak aprop'os skoro już mowa o kolorach to mały dowcip:

    Mąż po wielu latach z jedną żoną zebrał się na poważną rozmowę, powiedział żeby usiadła bo musi jej wyznać całą prawdę o sobie, którą skrywał przez wiele lat:

    - "posłuchaj kochanie, ukryłem przed tobą przed ślubem, że ..... że jestem daltonistą"

    a na to bardzo zaskoczona małżonka:

    - "Skoro tak szczerze mi to wyznałeś to i ja przyznam ci się do czegoś co skrywałam przed tobą od czasu gdy się poznaliśmy"

    mąż podenerwowany pyta - co ? co?

    - "skłamałam cię, że pochodzę z Kielc, tak na prawdę pochodzę z Mozambiku"

    ;)

    0
  • #14 21 Sty 2012 22:17
    30402
    Użytkownik usunął konto  
  • #15 21 Sty 2012 22:23
    tmf
    Moderator Mikrokontrolery Projektowanie

    mirekk36 napisał:

    a facet powie ci że żółty przeszedł w ciemnożółty.

    O daltoniście już nie wspomnę.


    Oj, tu bym uważał. Może się tak trafić, że akurat dane przejście będzie widział lepiej niż osoba prawidłowo widząca barwy.

    0
  • #16 21 Sty 2012 22:30
    mirekk36
    Poziom 42  

    Ale po cóż ci ułamki ;) .... ludzie jakie tam zaawansowane algorytmy, po co? proste obliczenie wartości procentowej na zwykłych liczbach całkowitych. Części ułamkowe same ci odpadną .... zero roboty.

    (213*50)/100 = 106

    czyli:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    no i masz, kolor będziesz miał równy 106. W czym problem z ułamkowością ? (oczywiście to bez uwzględnienia nieliniowej charakterystyki, ale z tym też można sobie poradzić bo wystarczy stablicować wartości PWM i potem na zasadzie "lookup" podobnie przy pomocy procentów "jeździć" po tej tablicy. I wtedy będą dużo ładniejsze przejścia tonów.

    Dodano po 47 [sekundy]:

    tmf napisał:

    Oj, tu bym uważał. Może się tak trafić, że akurat dane przejście będzie widział lepiej niż osoba prawidłowo widząca barwy.


    No tak - to już tak żartobliwie dodałem ;)

    0
  • #17 21 Sty 2012 23:03
    30402
    Użytkownik usunął konto  
  • #18 21 Sty 2012 23:17
    excray
    Poziom 39  

    Saabotaz napisał:
    excray - absolutnie nie pojmuję tego :) Zbyt dużo kombinacji.

    Wbrew pozorom jest to proste tylko ciężko wytłumaczyć
    Kod: asm
    Zaloguj się, aby zobaczyć kod

    Powyżej jest taki przykładowy programik który zmienia kolor dwukolorowej (ATiny13 ma tylko 2 wyjścia PWM) diody led z A na B. Kolor A to 0x10, 0xE0 a kolor B to 0xC0, 0x20. Program jest uproszczony do minimum.

    0
  • #19 21 Sty 2012 23:35
    30402
    Użytkownik usunął konto  
  • #20 22 Sty 2012 00:07
    mirekk36
    Poziom 42  

    Saabotaz napisał:

    Dobrze rozumuję to wszystko?


    Dobrze ;) I tak jak piszesz, bez uwzględnienia nieliniowości, przy zmianach jasności przy niskich wypełnieniach już do powiedzmy 20% w dół będą skokowe zmiany :( .... za to przy uwzględnieniu nieliniowości uzyskasz nieco zapasu i powiedzmy że skoki będą występowały dopiero do 10% PWM w dół. (to takie trochę przykładowe dane i porówanie).... Ale np przy 8-bitowym PWM nie dasz rady pięknie rozjaśniać diody od powiedzmy 0% do 5% tak, żeby przy 1% było widać ledwie żarzącą się strukturę półprzewodnika w diodzie LED patrząc przez szkło powiększające. No bo właśnie 8-bit PWM ma za małą rozdzielczość. Gdybyś zastosował już chociażby 9-bit PWM to już byłoby lepiej a przy 10-bit PWM - w zasadzie całkiem dobrze. Nawet nie trzeba byłoby 16-bitowego PWM'a zaprzęgać do roboty

    Saabotaz napisał:

    Ale teraz kolejne pytanie na które potrzebuję łopatologicznej odpowiedzi: jak wykorzystując gradację i procenty przejść z jednej barwy na inną?


    Niestety nie rozumiem do końca tego pytania - tzn? No odpowiedź powinna się nasunąć sama - zmniejszasz procentowo wartość jednej składowej a zwiększasz o tyleż samo wartość drugiej.... Potem przechodzisz na kolejny kolor. Ale podejrzewam, że chodziło ci tu może o coś innego.

    0
  • #21 22 Sty 2012 14:21
    30402
    Użytkownik usunął konto  
  • #22 22 Sty 2012 14:42
    236759
    Użytkownik usunął konto  
  • #23 22 Sty 2012 15:02
    mirekk36
    Poziom 42  

    Saabotaz napisał:
    mirekk - już wszystko jasne z przejściem do innego koloru, zamotałem się z tym. Wygaszanie też potraktuje jako przejście do innego koloru, z tym że wygaszenie będzie po prostu kolorem o wartości R:0 G:0 B:0

    No i o to chodziło, przecież czarny kolor to RGB = 000 ;)

    Saabotaz napisał:
    Ale Twój sposób jeszcze sobie uproszczę na:


    No to nie mój sposób, to podstawowe liczenie procentów.

    Saabotaz napisał:
    kolor= (R*procent)/64 'gdzie procent=0 do 64, ewentualnie przejdę na zakresy 0-128 z dzieleniem na 128

    Bo wiadomo jak upierdliwe są dzielenia. Dzielenie na 100 to jeszcze nie tak źle ale po co sobie komplikować sprawę. A tak tylko poprzesuwam rejestry w prawo. Wstępnie obliczyłem że to tez będzie się dobrze sprawowało. Więc zaczynam pisać.


    Tylko zastanów się albo określ, bo jeśli chodzi ci o przejścia kolorów w jakiejś pojedynczej diodzie LED czy taśmie LED - to nie wiem o jakich ty tu czasach krytycznych wciąż mówisz i chcesz upraszczać. A dzielenia na liczbach całkowitych kompilator sam sobie upraszcza do maximum, więc jeśli tylko dlatego schodzisz do 64 zamiast 100 - to hmm mija się to z celem. Podejrzyj sobie kod asemblera jednego i drugiego sposobu gdy go napiszesz. Wtedy będziesz miał najlepsze porównanie.

    No! chyba, że chodzi ci o operacje na pojedynczych pikselach jakiejś może nawet własnej matrycy diodowej RGB ;) i potrzebujesz robić operacje na grupach pikseli - to wtedy co innego....

    0
  • #24 22 Sty 2012 16:47
    30402
    Użytkownik usunął konto