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.

Dekodowanie RC5 bez użycia Timera?

robiw 06 Kwi 2009 22:26 2229 7
  • #1 06 Kwi 2009 22:26
    robiw
    Poziom 26  

    Witam,
    Zastanawiam się nad dekodowaniem kodu RC5 bez użycia Timera. Przyszło mi do głowy, iż można byłoby czekać na pierwsze zbocze opadające (pierwszy bit startowy) a następnie próbkować (w procedurze przerwania) co 3/4 z 1.76ms wejście wykorzystując puste pętle..aż do końca (do 14-bitu). Rozwiązanie takie wstrzymuje jednak główny program na ok. 25ms a ponadto nie jest odporne na błędy - np. gdy nagle pilot zgubi bit to procedura zawiesi program aż do następnej komendy. Zastanawiam się czy istnieje pewny algorytm dekodujący bez użycia Timera np. od dwóch zboczy sygnału - nic sensownego jednak nie przychodzi do głowy. Z resztą zastanawiam się czy procedura np. Atmelowska (z użyciem Timera) jest odporna np. na za krótkie ramki danych? Spotkaliście się z sensownym rozwiązaniem programowym? robiw

    0 7
  • #2 07 Kwi 2009 00:11
    mirekk36
    Poziom 42  

    Jedynie słuszne i sensowne procedury do dekodowania praktycznie każdego standardu IR zawsze powinny się opierać o co najmniej jeden Timer, żeby dokonywać dokładnych pomiarów, które w tych przypadkach są niewątpliwie bardzo istotne.

    Próba robienia tego na okrętkę - czyli bez użycia przerwań/timerów zawsze skończy się większym czy mniejszym (sorry za określenie) gniotem programistycznym, który co najwyżej jeśli już jakoś tam zadziała to będzie tylko sztuką-dla-sztuki i bez większej wartości takiego kodu.

    Dzięki optymalnemu wykorzystaniu przerwań i lub tylko 1 timera - możesz robić procedurki, całkowicie niezależne od pętli głównej a za to ładnie "podające" jak na talerzu kody nadlatująych klawiszy do obróbki. I to wszystko bez zawieszania na czas odbioru (a przynajmnie w ogóle nie zauważalnego, pomijalnego).

    Ja zwykle całą obróbkę dekodowania wrzucam w obsługę przerwania ICP od Timer1 i to w zupełności wystarczy o ile Timer1 (16bitowy) nie jest niezbędny akurat do czegoś innego.

    0
  • #3 07 Kwi 2009 08:51
    skynet_2
    Poziom 26  

    Ja zrobiłem dekodowanie oparte o timer, ale nie tak że czekam sobie (889*2)us i próbkuje kolejne bity :D tylko każda zmiana bitu na wejściu generuje przerwanie w którym sprawdzam czy in jest 1 lub 0 i na tej podstawie odtwarzam wszystkie półbity, na końcu mam 5 krotną kontrolę błędów[1 i 2 poziom jest już w przerwaniu i sprawdza warstwę fizyczną czyli półbity], co daje 100% pewność przesyłu danych żeby ściszyć wyjście audio w kompie :D
    Można to obejść dająć delay'a 600us ale tracimy 1 poziom kontroli błędów :( i zostają tylko 4 :( czyli mamy tylko 97% pewności transmisji.

    0
  • #4 07 Kwi 2009 09:11
    robiw
    Poziom 26  

    Witam,
    Przerwania oparte o Timer to standard jeśli chodzi o dekodowanie IR jednak wyobraź sobie sytuację, gdzie przy małym procku potrzebujesz kilka kanałów PWM (najlepiej sprzętowy, więc zajmujesz Timery) a do tego musisz obsłużyć IR - problem gotowy ;-). Gdzieś widziałem algorytm oparty o detekcję obu zboczy ale szczegółów nie pamiętam. Atmel w swojej nocie AVR410 wykorzystuje przerwanie od przepełnienia licznika Timer0 nie zaś ICP - czemu wybrałeś właśnie takie? Dodatkowo czy Twoje rozwiązanie (pytam tak z ciekawości) jest odporne na niepełne ramki, np. dostajesz tylko 12 bitów a po chwili nowe bity z nowej ramki? Musi istnieć pewne rozwiązanie bez użycia Timerów...robiw

    0
  • #5 07 Kwi 2009 09:49
    mirekk36
    Poziom 42  

    Witam,

    Wybrałem przerwanie wyzwalane wejściem ICP Timera1 ponieważ - załatwia mi to 2 rzeczy od razu. Po pierwsze obsługa IR działa ładnie na przerwaniach i nie zajmuję żadnego z wejść INTx, po drugie od razu zużywam ten sam timer. Jeśli chodzi o kod obsługi ramek IR - to pewnie, że obsługuje on tylko poprawne ramki i jest odporny na te "uszkodzone - jeśli takie nadlecą" Działa to u mnie jak brzytwa.

    Właśnie jestem powoli na ukończeniu takiego projekciku, gdzie hmm też potrzebowałem co najmniej 3 wyjść PWM i przy procku ATmega32 - już było po ptakach gdy zdecydowałem się użyć Timer1 do obsługi IR. Ale się wkurzyłem ;) i zrobiłem sobie programowy PWM i to 10 albo 12bitowy który ma wg uznania od 3 do 8 kanałów niezależnie sterownych, w oparciu o Timer2 - i też działa sobie jak brzytwa - wespół z obsługą IR na Timerze1.

    Został więc mi tylko Timer0 - hmm troszkę mało - niby ale wprowadziłem sobie taką jakby namiastkę obsługi zdarzeń dla wszystkich innych porocedur, które potrzebują jakichś tam odmierzanych odcinków czasu. Tak więc Timer0 generuje u mnie tylko "tyknięcia systemowe" co 20ms i tylko ustawia flagę - więc też w ogóle nie obciąża systemu - a już w pętli głównej wszystko opiera się o tyknięcia systemowe a nie żadne procedury opóźniające (poza może minimalnymi dla obsługi z kolei 1wire) itp.

    Dodam, że ten sam procek obsługuje jeszcze na przerwaniach wraz z buforowaniem sprzętowym RS232 z prędkością 115200 a do tego obsługę I2C.

    i wszystko jak narazie śmiga pięknie.

    A zrobienie prostego programowego wielokanałowego PWM'a w języku C to poprostu poezja, prostota i w niczym to nie ustępuje sprzętowemu PWMowi dla takich rzeczy jak sterowanie np diodą RGB, sterowanie jasnością świecenia LEDów , czy sterowaniem silniczków itp. Powiem nawet więcej - taki programowy PWM bywa nawet lepszy niż te 3 sprzętowe pod tym względem, że :

    - zużywa tylko 1 timer a nie 3
    - pozwala na więcej niż 8bitową rozdzielczość wszystkich kanałów (a w przypadku sprzętowego PWMa masz w większości przypadków dostępne 2 kanały tylko 8bitowe a tylko jeden kanał z możliwością nieco większą niż 8 bitów)

    Reasumując - jak widzisz, można spokojnie załatwić taki problem o jakim wspomniałeś - czyli kilku kanałów PWM i dodatkowo obsługę IR na przerwaniach i to z timerem ...... a nawet jak widzisz dużo więcej można zrobić i to nawet w małym procku.

    pozdrawiam

    0
  • #6 07 Kwi 2009 13:58
    Nawigator
    Poziom 33  

    Dekodowanie IR powinno być na jednym zboczu bo z odbiornika nie zawsze dostajemy czyste prostokąty o ostrych zboczach i pełnej amplitudzie i bez zakłóceń.
    Wtedy odstępy czasowe są przynajmniej zachowane.
    Protokoły IR biorą to pod uwagę.

    N.

    0
  • #7 08 Kwi 2009 22:37
    robiw
    Poziom 26  

    Witaj,

    mirekk36 napisał:
    ...Jeśli chodzi o kod obsługi ramek IR - to pewnie, że obsługuje on tylko poprawne ramki i jest odporny na te "uszkodzone - jeśli takie nadlecą" Działa to u mnie jak brzytwa...


    Ciekaw jestem jakim algorytmem uodporniłeś go na uszkodzone ramki ;-)?

    mirekk36 napisał:
    ... zrobiłem sobie programowy PWM i to 10 albo 12bitowy który ma wg uznania od 3 do 8 kanałów niezależnie sterownych, w oparciu o Timer2 - i też działa sobie jak brzytwa - wespół z obsługą IR na Timerze1...


    Jasne, że można lecz jeśli wykorzystałeś Timer i zwykłe przerwanie OVF (od przepełnienia) to po pierwsze, musisz wywoływać przerwanie dość często co nie służy programowi głównemu a po drugie ograniczasz częstotliwość generowanego przebiegu. Jak rozumiem, w procedurze OVF zmieniasz odpowiednie zmienne i decydujesz o momencie zbocza sygnału PWM. Oczywiście do RGB czy serwo jak najbardziej się nadaje.

    mirekk36 napisał:
    ...Tak więc Timer0 generuje u mnie tylko "tyknięcia systemowe" co 20ms i tylko ustawia flagę - więc też w ogóle nie obciąża systemu - a już w pętli głównej wszystko opiera się o tyknięcia systemowe a nie żadne procedury opóźniające (poza może minimalnymi dla obsługi z kolei 1wire) itp...


    Sprytnie, jak w Windows ;-). To kolejne zdarzenie obciążające procek.

    mirekk36 napisał:

    A zrobienie prostego programowego wielokanałowego PWM'a w języku C to poprostu poezja, prostota i w niczym to nie ustępuje sprzętowemu PWMowi dla takich rzeczy jak sterowanie np diodą RGB, sterowanie jasnością świecenia LEDów , czy sterowaniem silniczków itp. Powiem nawet więcej - taki programowy PWM bywa nawet lepszy niż te 3 sprzętowe pod tym względem, że ...


    Nie twierdziłem, że jest inaczej. To samo zrobisz w Bascom, no może poza tym, iż musisz odłożyć wszystkie rejestry.

    mirekk36 napisał:

    Reasumując - jak widzisz, można spokojnie załatwić taki problem o jakim wspomniałeś - czyli kilku kanałów PWM i dodatkowo obsługę IR na przerwaniach i to z timerem ...... a nawet jak widzisz dużo więcej można zrobić i to nawet w małym procku.


    Zgadza się. W sumie to jestem pod wrażeniem Twoich zmagań z C i tego co z nich wynika. Ja, nie ukrywam, nie lubię składni tego języka. Wolałbym coś w Basicu (Pascalu) ale bez gotowców jak w Bascomie. Serdecznie pozdrawiam... robiw

    0
  • #8 08 Kwi 2009 23:30
    mirekk36
    Poziom 42  

    jaki algorytm odnośnie sprawdzania uszkodzonych ramek? hmmm poza zliczaniem nadlatujących bitów, sprawdzam jeszcze szerokości impulsów i w zależności od tego kieruję procedurę na odpowiednie tory.

    Code:
    if ( PulseWidth < MIN_HALF_BIT ) frame_status = FRAME_RESTART;    // gdy zakłócenia (szpilki) - RESTART
    
    if ( PulseWidth > MAX_BIT ) frame_status = FRAME_RESTART;       // gdy błąd ramki danych (może inny standard niż RC5) RESTART


    Odnośnie Timera dla PWM'a - to używam go w trybie CTC z automatycznym ładowaniem OCR, więc nie muszę w przerwaniu ładować nowej wartości do TCNTx a to zawsze ciut mniej kodu w przerwaniu i krótszy czas wykonywania. Pozostaje więc tylko tak jak napisałeś kilka linijek kodu na obsługę 3 zmiennych i to wsio.

    Odnośnie tyknięć systemowych i jak piszesz kolejnego obciążania procesora - to chyba niestety troszeczkę przesadzasz albo może nie do końca zrozumiałeś moją ideę. Jak pisałem - cały kod tego przerwania to tylko i wyłącznie ustawianie odpowiedniej flagi na wartość = 1. Więc samo przerwanie - praktycznie nic a nic nie obciąża. Cała reszta dzieje się w pętli głównej - więc tym bardziej nie ma co mówić o obciążaniu procka - bo czym? programem ? w końcu lepiej większość czaso-żernych rzeczy przekładać do pętli głównej niż dawać to w przerwaniach - sam chyba przyznasz. A dzięki odpowiedniej konstrukcji tych tyknięć - i innego podejścia do odmierzania interwałów dla opóźnień czasowych - nie używam praktycznie w ogóle w pętli głównej takich rzeczy jak DELAY w C czy czegoś takiego jak WAIT, WAITMS w Bascomie. Więc to już coś. Pętla żyje własnym asynchronicznym życiem ;)

    Pewnie, że w Bascomie można podobne rzeczy zrobić - co także robiłem wcześniej, z tym, że po jakimś czasie dla bardziej rozbudowanych projektów zacząłem pisać kod obsługi przerwań w czystym asemblerze, żeby nie odkładać aż tylu niepotrzebnych rejestrów na stos itp. - więc można - czemu nie. Zawsze uważałem , że jak coś niedużego i szybko zrobic - to Bascom w rękę - heja ;) .... ale ostatnio - gdy mam pisać coś większego - to już widzę, że przynajmniej ja bez C się nie obejdę.

    Tak na zakończenie, ponieważ napisałeś, że nie lubisz składni tego języka .... to wyobraź sobie ile razy ja podchodziłem do C . Czały czas byłem nastawiony do niego jak do mega-jeża, i prawie dwa lata się co jakiś czas zabierałem i odrzucałem. Wolałem zwykle po odrzuceniu szukać jakiegoś Pascala do procków. Znalazłem nawet coś takiego jak MicroPascal - no ale to porażka się okazała. Potem jakiś niemiecki Pascal - wyglądał dobrze - ale cena za kompilator??? masakra - wyższa niż sam kupowałem pełne Delphi2006 na PCta - więc znowu odpuściłem. I po którymś kolejnym e-ntym starciu z C (zaczynałem od kursów z EdW) - w końcu - załapałem tą wtedy dla mnie też dziwną składnię C, wręcz straszną ;) ...... ale teraz? o kurczę - jaka ona elastyczna i ile można w tym zrobić cudeniek. Tak wiec jak nie teraz to za jakiś czas - ale polecam C - warto go też poznać. O ile oczywiście inne języki zaczynają mieć dla nas jakby ograniczenia.

    0