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.

[BASCOM][ATmega8]Sterowanie diodą RGB przez PWM

KD93 13 Gru 2008 21:06 7209 15
  • #1 13 Gru 2008 21:06
    KD93
    Poziom 12  

    Witam

    Chciałem zrobić prostą lampkę RGB, według zasady, że każdy następny kolor pulsuje świeci zapala się i gaśnie dłużej, co powoduje ich mieszanie.

    Code:

    $regfile = "m8def.dat"
    $crystal = 1000000

    Config Pinb.1 = Output
    Config Pinb.2 = Output
    Config Pinb.3 = Output


    Dim R As Byte
    Dim G As Byte
    Dim B As Byte



    Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1
    Config Timer2 = Pwm , Async = Off , Pwm = On , Compare Pwm = Clear Up , Prescale = 1

    Do

    For R = 0 To 255
       Pwm1a = R
    Waitms 4
    Next R

    For R = 255 To 0 Step -1
       Pwm1a = R
    Waitms 4
    Next R

    For G = 0 To 255
       Pwm1b = G
    Waitms 7
    Next G

    For G = 255 To 0 Step -1
       Pwm1b = G
    Waitms 10
    Next G

    For B = 0 To 255
       Ocr2 = B
    Waitms 7
    Next B

    For B = 255 To 0 Step -1
       Ocr2 = B
    Waitms 13
    Next B


    Loop

    End



    Program jednak nie działa do końca tak jak chciałem. Kolorki się ładnie zmieniają, płynnie przechodzą, ale są ciągle takie same: ciemnoróżowy, żółty, seledynowy, ciemnoróżowy, żółty, seledynowy itd itd. (zmienne R, G i B są umowne, nie podłączam diody czerwonej pod R, zielonej pod G a niebieskiej pod B). Jak przerobić kod, żeby kolory się mieszały i było więcej barw?

    Domyślnie chciałem robić układ na ATtiny2313,a le jak na razie ATMegę8 lepiej rozumiem.

    Jestem również otwarty na PROSTE programy, żeby tylko nie było niepotrzebnej regulacji szybkości, barw i innych dupereli, bo mnie na tym w ogóle nie zależy, jestem "bardzo początkujący" w temacie µC.

    Pozdrawiam.

    Przeniosłem z "Programowanie początkujący"
    [Dr.Vee]

    Poprawiłem tytuł - regulamin p.11
    [zumek]

    0 15
  • #2 13 Gru 2008 22:37
    prokopcio
    Poziom 29  

    nie wnikam bardzo szczegółowo bo piszę w assemblerze ale na pierwszy rzut oka widzę taki algorytm który na pisałeś:

    1.rozjaśnij czerwony
    2.ściemnij czerwony
    3.rozjaśnij zielony
    4.ściemnij zielony
    5.rozjaśnij niebieski
    6.ściemnij niebieski
    7. zapętl od pkt 1

    nie widzę Tutaj żadnego mieszania kolorów - i Ty chyba też nie ujrzysz. zrób np tak (zakładam, że Twój program rzeczywiście działa tak jak opisałeś bo nie znam dokładnie składni bascoma):

    sama pętla:

    Do



    For R = 0 To 255
    Pwm1a = R
    G=255-R
    Pwm1b = G
    Waitms 4
    Next R

    For R = 255 To 0 Step -1
    Pwm1a = R
    B=255-R
    Ocr2 = B
    Waitms 4
    Next R

    For G = 255 To 0 Step-1
    Pwm1b = G
    Waitms 7
    Next G
    ....
    ......
    ....
    ....
    Loop



    oczwiście, żeby mieć zamierzony efekt wszystkich kolorów to trzeba napisać algorytm wykonujący przejście przez wszystkie 256*256*256 kolory wraz z odcieniami ;) ja tylko chciałem Ci pokazać o co chodzi a Ty kombinuj dalej :)

    0
  • #3 14 Gru 2008 07:10
    KD93
    Poziom 12  

    Właśnie problem ma taki, że kolory się mieszają, nie ma tak:
    1.rozjaśnij czerwony
    2.ściemnij czerwony
    3.rozjaśnij zielony
    4.ściemnij zielony
    5.rozjaśnij niebieski
    6.ściemnij niebieski

    Jak by się tak działo, to przynajmniej wiedziałbym w czym jest problem.

    Dzięki za podpowiedź, będę kombinował :D

    0
  • #4 14 Gru 2008 14:10
    atom1477
    Poziom 43  

    Jak nie jak tak.
    Właśnie tak jest. Zaraz po całkowitym zapaleniu diody R (umownej diody R) dioda ta jest gaszona. Dopietro potem nastęuje zapalanie i gaszenie G, a potem B.
    To jeszcze zależy czy diody podłączyłeś jedną końcówką do masy czy do VCC.
    Wtedy masz efekt zmieniania się innych barw, ale także niedokładnie taki jak byś chciał.
    Np. w jednym z momentów dioda G musi się rozjaśniać gdy R świeci pełnym światłem a u Ciebie tak nie jest.
    Zmień to na takie coś:
    1.rozjaśnij czerwony
    2.ściemnij niebieski
    3.rozjaśnij zielony
    4.ciemnij czerwony
    5.rozjaśnij niebieski
    6.ściemnij zielony

    0
  • Pomocny post
    #5 14 Gru 2008 20:33
    prokopcio
    Poziom 29  

    dobra atom1477 - chyba wiem, w czym chłopak ma problem... Wszystko zależy od tego jak ma podłączone te diody a schematu nie widzimy - bo inaczej będzie to działać jeśli będą pomiedzy +ucc a wyjściami a inaczej jeśli ma podpięte pomiędzy masą a wyjściami - zależy od tego czy maksymalna jasność jest dla PWM = 255 czy dla PWM=0 !!!
    Sprawdź dla jednej diody z programem który na nią wystawi stałą wartość PWM=0 lub 255 to będziesz wtedy wiedział a później dojdziesz do wniosku że to o czym pisaliśmy z atom1477 ma rację bytu.

    0
  • #6 15 Gru 2008 13:59
    atom1477
    Poziom 43  

    No tak. Dopiero teraz to sobie uświadomiłem.

    MłodyZielony napisał:

    ... są ciągle takie same: ciemnoróżowy, żółty, seledynowy, ciemnoróżowy, żółty, seledynowy ...


    Zmyliły mnie nazwy kolorów. Ja używam innych nazw.
    To są barwy dopełniające (CMY). Pewnie pomiędzy nimi masz kolor biały. Ale go nie zauważyłeś bo pewnie jasności diod RGB nie są identyczne i kolor odbiegał od prawidłowego koloru białego.


    A tak wogóle to kolory nie są ciągle takie same ;p Raz jest seledynowy, raz żółty.... Nawet jak zrobisz całą tęczę to według Twojej teorii kolory ciągle były by takie same? Ciągle tęcza i tęcza... ;p


    Ale do rzeczy:
    Na bank masz diody podłączone do VCC. Może nawet używasz diody RGB a w takim wypadku nawet nie możesz połączyć diod do GND.
    Zmień więc konfigurację PWMów. Zamiast "Clear Down" wpisz "Clear Up". A tak wogle to dlaczego w Timerze1 masz Clear Down a w Timerze2 Clear Up?


    Wtedy powinieneś uzyskać efekt zmian składowych RGB taki o jaki Ci chodziło.
    Ale zaznaczam: efekt zmian składowych RGB, a nie efekt końcowej zmiany kolorów. Końcowy efekt będzie inny niż byś chciał bo widzę że nie rozumiesz jak należy mieszać barwy.



    MłodyZielony napisał:
    Witam

    Chciałem zrobić prostą lampkę RGB, według zasady, że każdy następny kolor pulsuje świeci zapala się i gaśnie dłużej, co powoduje ich mieszanie.



    Samo dłuższe zapalanie i gaszenie nie spowoduje mieszania się barw.
    Musisz zmienić kolejność zapalania i gaszenia poszczególnych składowych tak jak Ci wcześniej napisałem.


    PS. Co do "Clear Down" i "Clear Up". Być może masz dobrze. Już nie pamiętam jak to trzeba ustawić żeby dla wartości PWM = 0 przy diodach podłączonych do VCC uzyskać jasność równą 0. Najlepiej ustaw wszystkie składowe na 0 i zobacz czy faktycznie są wygaszone. Jeżeli nie to zmieniaj "Clear Down" na "Clear Up".
    Jak to uzyskasz to dopiero przejdź do dalszych prób.

    0
  • #7 15 Gru 2008 16:40
    KD93
    Poziom 12  

    dzięki za podpowiedzi,mam dużo czasu przez święta to będę próbował.

    Mam diodę RGB ze wspólną anodą.

    Dodano po 1 [godziny] 34 [minuty]:

    Ok, więc tak:


    Code:
    $regfile = "m8def.dat"
    
    $crystal = 1000000

    Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up , Prescale = 1
    Config Timer2 = Pwm , Async = Off , Pwm = On , Compare Pwm = Clear Down , Prescale = 1

    Pwm1a = 0
    Pwm1b = 0
    Ocr2 = 0





    Teraz nie świeci żadna dioda.


    atom1477, jeżeli będzie dużo kolorów, to nie przeszkadza mi, że będą się powtarzać, ale czy by cie nie wkurzały 3 kolory w kółko ( i do tego jeszcze 1 różowy)?

    0
  • Pomocny post
    #8 15 Gru 2008 17:00
    atom1477
    Poziom 43  

    No to teraz tak:

    Code:

    Do

    For R = 0 To 255
       Pwm1a = R
    Waitms 4
    Next R

    For B = 255 To 0 Step -1
       Ocr2 = B
    Waitms 13
    Next B

    For G = 0 To 255
       Pwm1b = G
    Waitms 7
    Next G

    For R = 255 To 0 Step -1
       Pwm1a = R
    Waitms 4
    Next R

    For B = 0 To 255
       Ocr2 = B
    Waitms 7
    Next B

    For G = 255 To 0 Step -1
       Pwm1b = G
    Waitms 10
    Next G

    Loop


    A z tymi kolorami to przecież żartowałem.

    0
  • #9 15 Gru 2008 17:16
    KD93
    Poziom 12  

    Super, działa tak jak chciałem!

    Code:
    $regfile = "m8def.dat"
    
    $crystal = 1000000

    Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up , Prescale = 1
    Config Timer2 = Pwm , Async = Off , Pwm = On , Compare Pwm = Clear Down , Prescale = 1

    Pwm1a = 0
    Pwm1b = 0
    Ocr2 = 255

    Dim R As Byte
    Dim G As Byte
    Dim B As Byte


    Do



    Wait 3

    For R = 0 To 255
    Pwm1a = R
    Waitms 20
    Next R

    Wait 3

    For B = 255 To 0 Step -1
    Ocr2 = B
    Waitms 20
    Next B

    Wait 3

    For G = 0 To 255
    Pwm1b = G
    Waitms 20
    Next G

    Wait 3

    For R = 255 To 0 Step -1
    Pwm1a = R
    Waitms 20
    Next R

    Wait 3

    For B = 0 To 255
    Ocr2 = B
    Waitms 20
    Next B

    Wait 3

    For G = 255 To 0 Step -1
    Pwm1b = G
    Waitms 20
    Next G

    Loop
    End



    Teraz tylko przerobić na attiny2313 i git :D

    Chociaż dibelska myśl mi przez łeb przechodzi... Attiny 2313 ma dwa timery, każdy z nich 2 kanały PWM, czyli razem 4, może by tak jeszcze dorzucić gdzieś diodę białą? Trzeba popróbować :twisted:

    Wielkie dzięki wam! Bez was bym sobie nie poradził.

    0
  • #10 15 Gru 2008 19:05
    atom1477
    Poziom 43  

    Cieszę się że się podoba.
    Zamiast białej dożuć inną. Jak dorzucisz białą to będziesz miał mniej więcej taki efekt jak na początku. No chyba że ta biała dioda będzie zapalana dość rzadko.
    Niestety nie ma dobrego sposobu na dorzucenie czwartej diody. Człowiek widzi mniej więcej w RGB więc nie bardzo jest co dorzucać.
    Jak juz to fioletową, ultrafioletową albo bursztynową.
    Ale tą dodatkową czwartą diodę to daj gdzieś obok to uzyskasz gradient kolorów.

    0
  • #11 21 Gru 2008 15:04
    KD93
    Poziom 12  

    Hym....

    Ma ktoś pomysł jak ustawić Timer0 na Attiny2313? Tam są dwa kanały Pwm, ja bym potrzebował tylko jednego, wiem, że to trzeba ustawić "ręcznie" i że trzeba wpisać odpowiednie wartości:
    Tccr0a=?
    Tccr0b=?

    Tylko nie wiem jakie. Szukałem i próbowałem dwa dni ale nic z tego nie wyszło.

    I jeszcze jedna sprawa. Na ATmega8 przy wew. oscylatorze 1mH działa ładnie, a na ATtiny2313 przy takim samym wew. oscylatorze diodki migają. Taka już architektura? Bo jeśli tak, to zrobię tę lampkę na ATmega8, chociaż to jak wożenie jednej paczki tirem...

    0
  • #12 21 Gru 2008 17:11
    atom1477
    Poziom 43  

    Może jest włączony sprzetowy podział sygnału zegarowego przez 8 i dlatego diody (zauważalnie) migają.

    0
  • #13 21 Gru 2008 18:26
    dawid512
    Poziom 32  

    Jest włączony podział tzw. CKDIV8 i masz wew. oscylator na 1MHz jeżeli to wyłączysz to masz 8MHz.

    0
  • #14 21 Gru 2008 19:24
    KD93
    Poziom 12  

    To chyba znaczy, że muszę grzebać w fusach...

    Macie jakiś pomysł na uruchomienie tego 3 kanału PWM?

    0
  • #15 21 Gru 2008 20:01
    atom1477
    Poziom 43  

    ldi R16, &B10100011
    !Out Tccr0a, R16
    ldi r16, &B00000001
    !Out Tccr0b, R16

    To uruchomi obywa kanały PWM (Chyba uruchomi ;p)

    0
  • #16 21 Gru 2008 20:51
    KD93
    Poziom 12  

    Uruchomiło :D Szkoda tylko, że nic z tego nie rozumiem.
    Co prawda jest na odwrót niż w ATmega8 (tam 0-dioda nie świeci, tutaj 0 - dioda świeci), pozmieniałem trochę kod i jest tak samo jak wcześniej na ATmega.

    Kod:

    Code:
    $regfile = "attiny2313.dat"
    
    $crystal = 1000000

    Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Disconnect , Prescale = 1
    ldi R16, &B10100011
    !Out Tccr0a, R16
    ldi r16, &B00000001
    !Out Tccr0b, R16


    Config Pind.5 = Output
    Config Pinb.2 = Output
    Config Pinb.3 = Output
    Config Pinb.4 = Output

    Dim R As Byte
    Dim G As Byte
    Dim B As Byte

    Pwm1a = 0                                                   'niebieski
    Pwm1b = 255                                                 'nie używam
    Pwm0a = 255                                                 'zielony
    Pwm0b = 255                                                 'czerwony

    Do

    Wait 3

    For R = 255 To 0 Step -1                                    'rozjaśnianie czerwonej
    Pwm0b = R
    Waitms 20
    Next R

    Wait 3

    For B = 0 To 255                                            'ściemnianie niebieskiej
    Pwm1a = B
    Waitms 20
    Next B

    Wait 3

    For G = 255 To 0 Step -1                                    'rozjaśnianie zielonej
    Pwm0a = G
    Waitms 20
    Next G

    Wait 3

    For R = 0 To 255                                            'ściemianie czerwonej
    Pwm0b = R
    Waitms 20
    Next R

    Wait 3

    For B = 255 To 0 Step -1                                    'rozjaśnianie niebieskiej
    Pwm1a = B
    Waitms 20
    Next B

    Wait 3

    For G = 0 To 255                                            'ściemianie zielonej
    Pwm0a = G
    Waitms 20
    Next G

    Loop
    End


    Dziękuję wam bardzo za pomoc :D Wesołych Świąt.

    0