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 ATTiny25 - Lampka RGB, pierwsze zderzenie z Tiny25

hary94 12 Maj 2013 19:11 2295 14
  • #1 12 Maj 2013 19:11
    hary94
    Poziom 9  

    Witam

    Jestem początkującym w dziedzinie programowania AVR w C, jednak postanowiłem zrobić lampke RGB. Zasada działania prosta, a jednak...

    Od początku: Wciskamy przycisk PB4 zapala się kolejny kolor, wciskamy PB5, zapala się poprzedni kolor. TAkie jest założenie... Obecnie gdy wciskam PB4 nie dzieje sie nic a gdy PB5 to dioda gaśnie na moment.
    Nie wiem już gdzie mam tym razem spojrzeć, czy to Tiny, czy timery, czy może coś sprzętowo, a może blahostka w programie.

    Proszę o podpowiedzi, zamieszczam program poniżej.

    Kod: c
    Zaloguj się, aby zobaczyć kod


    PS. Korzystałem z różnych zasobów sieci jednak po którymś dniu już wymiękam. Zdaję sobie sprawę, że wiele rzeczy robie niepoprawnie i własnie oczekuję cierpliwych, tematycznych wypowiedzi.

    Z góry dziękuje i pozdrawiam

    EDIT: Poprawiłem zmienną kolor. Bardzo dziękuję jednak sytuacja identyczna.

    0 14
  • #2 12 Maj 2013 19:44
    Krauser
    Poziom 26  

    Jak kolor jest typu uint8_t - liczba 8 bitowa bez znaku to nie zadziała sprawdzenie warunku if (kolor<0)
    albo kolor zmień na int8_t albo warunek na if(kolor==255)

    0
  • #3 12 Maj 2013 21:00
    ZbeeGin
    Poziom 38  

    Układ Tiny ma na tyle wyjść sprzętowych PWM z liczników by sterować diodą RGB, zatem czym prędzej zrezygnuj z programowej generacji tego przebiegu.

    Pętla czytania klawiszy nie ma żadnego opóźnienia byś mógł reagować na zmiany kolorów. Obecnie efekt jest taki, że naciskasz klawisz i kolor wychodzi losowo bo tak szybko się zmienia.

    0
  • #4 15 Maj 2013 10:48
    hary94
    Poziom 9  

    Dobrze. Dziękuję za odpowiedzi. Korzystam z PWM, na razie dwóch, ale już mam pewien problem...
    Mianowicie przy tym kodzie:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Zupełnie nie odczytuje styanu przycisków. Wciskam przycisk i nic sie nie dzieje!
    Gdzie robie błąd?

    0
  • #5 15 Maj 2013 12:25
    BlueDraco
    Specjalista - Mikrokontrolery

    if (PINB &= ~(1<<PB4))
    - to podstawienie na rejstr PINB

    Chodziło Ci zapewne o
    if (PINB & (1<<PB4))

    albo o

    if (!(PINB & (1<<PB4)))


    Niezależnie jednak od tego - przyciski należy testować w przerwaniu timera. W tym programie zresztą wszystko powinno się dziać w przerwaniu timera, a pętla główna powinna tylko usypiać procesor.

    0
  • #6 15 Maj 2013 12:39
    hary94
    Poziom 9  

    Mógłbys trochę rozwinąć myśl co do tego usypiania procesora w pętli głównej?

    EDIT:
    Idąc za powyższą sugestią poczyniłem coś takiego:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Mogę prosić o podpowiedź w jaki sposób to przekształcić by działało? Gdy całe switch wrzucam do przerwania to świeci jedna dioda, a trzymając przycisk da się zauważyć, że przechodzi przez każde z... case'ów, nazwijmy to... W powyższym kodzie nic się nie dzieje.

    Proszę o cierpliwość :)

    0
  • #7 15 Maj 2013 13:46
    BlueDraco
    Specjalista - Mikrokontrolery

    Jedynym przerwaniem, jakiego potrzebujesz, jest przerwanie timera, tego samego, który generuje PWM.
    W obsłudze przerwania sprawdzasz stan przycisku, pamiętając przynajmniej jeden poprzedni stan w jakiejś zmiennej. Jeśli nastąpiła zmiana stanu - zmieniasz tryb pracy i ładujesz nowe wartości PWM.

    Coś z lekka podobnego masz tutaj:
    http://mikrokontrolery.blogspot.com/2011/02/o-drganiach-stykow-bez-bajek-przykad.html

    W Twoim obecnym kodzie są dwa duże problemy - brak atrybutu volatile w deklaracji zmiennej sterującej trybem pracy oraz użycie przerwania od przycisku, a w nim jeszcze opóźnienie.

    0
  • #8 16 Maj 2013 15:39
    hary94
    Poziom 9  

    OK. Po dniu walki wymyśliłem cos takiego. Zastanawia mnie tylko czy w poprawny sposób wywołuje przerwanie. Pomyślałem, że skoro mój PWM jest 8 bitowy to jego czestotliwość wynosi ok. 3906Hz. Dzieląc ją przez 39 otrzymamy 100 Hz. Tak też postanowiłem zrobić sprawdzając przycisk co 100 Hz. Wiem, że to jeszcze słabo wykończony pomysł, ale brak mi pomysłów. Proszę o podpowiedzi i dziękuje za powyższe.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #9 16 Maj 2013 16:40
    BlueDraco
    Specjalista - Mikrokontrolery

    Wykrywaj zmianę stanu przycisku (np. poprzednio zwolniony, teraz wciśnięty, a nie sam stan wciśnięcia.
    Przerzuć kod modyfikacji współczynników z pętli głównej do przerwania timera, w miejsce, gdzie wykryłeś naciśnięcie, zaraz po zmianie wartości j.

    0
  • #10 20 Maj 2013 23:07
    hary94
    Poziom 9  

    Dokonałem czegoś takiego. Widać, że coś się dzieje ale brak w dalszym ciągu widocznego przełączenia stanów.

    Proszę o podpowiedzi- nakierowanie mnie

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • Pomocny post
    #11 21 Maj 2013 15:33
    BlueDraco
    Specjalista - Mikrokontrolery

    1. Masz niepotrzebnie włączone nieobsługiwane przerwanie INT0 - procesor idzie w maliny.

    2. Z grubsza sensowny kod testowania przycisku wygląda tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #12 22 Maj 2013 10:05
    hary94
    Poziom 9  

    Dobrze. Działa wszystko tak jak powinno. Dziękuję pięknie, tylko proszę wyjaśnij mi dlaczego stosujesz tutaj %3? Z tego powodu, że mam 3 tryby i każdą liczbę dzieląc przez 3 otrzymam resztę odpowiadającą moim trybom czy jakiś inny?

    0
  • Pomocny post
    #13 22 Maj 2013 10:18
    BlueDraco
    Specjalista - Mikrokontrolery

    % 4 (ogólnie: % L_TRYBOW) służy do zawijania zakresu 0..3 bez instrukcji if(), czyli dla CZTERECH trybów o numerach 0..3. Tak jest łatwiej, pod warunkiem, że liczba trybów jest potęgą dwójki. Jeśli nie jest - lepiej zrobić if (tryb = L_TRYBOW) tryb = 0;

    Poprawka - miało być % 4 a nie % 3. Zamiast % 3 lepiej użyć if().

    0
  • #14 23 Maj 2013 10:22
    hary94
    Poziom 9  

    Właśnie poprawiłem na if bo pomijało mi jeden tryb. Fantastycznie! Bardzo dziękuję za wyjaśnienie! Jeszcze tylko pomęcę timer 0 i jego PWM, więc na wszelki wypadek jeszcze nie będę zamykać :)

    EDIT:

    Gdy załączam drugi timer to mi się wysypuje cały program... Nie reaguje na przyciski... Co robie źle?

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #15 25 Maj 2013 17:41
    BlueDraco
    Specjalista - Mikrokontrolery

    Zapewne to, czego nie pokazałeś - bez kompletnego kodu trudno zgadywać.

    0