Na počátek krátký popis asi nejužívanějšího protokolu pro dálkové ovládání infračerveným zářením a tím je
protokol RC5 (pro "vniknutí do problému"), i když tato rutina dekódování RC5 nepoužívá.
Pro dálkové ovladače byl vytvořen kód RC5. Ten používá bi-phase kódování a
pracuje na 36 kHz. Bi-phase znamená, že v definovaném čase se úroveň změní
sestupně, nebo vzestupně. Tím je definována log. 1 nebo log. 0. Každý stisk
klávesy je přenášen bitovým rámcem o délce 114 ms. To znamená že za sekundu je možné
teoreticky přenést necelých 9 příkazů z dálkového ovládání. Vlastní informace o
stisknutém tlačítku je však přenášena v rámci RC5 pouze 24,9 ms. Tato informace se
skládá z 2 startbitů, toggle bitu, 5. bitové adresy a 6. datových bitů. Každý bit je
přenášen jako 32 pulsů kdy f0=36 kHz. Z toho plyne 14 bitů x 32 pulsů na 36 kHz = 448
x (1/36 kHz) = 24,8888 ms. Časová délka jednoho bitu (tedy 1/0 nebo 0/1) je 1778us. Více je vidět na obrázku.
V zásadě existují dva principy pro rozeznání jednotlivých příkazů vysílaných dálkovými ovladači.
Rozpoznání kódu ovladače - pokud existuje definované kódování, lze toto detekovat a dále přenášet tyto informace – v případě RC5 tedy 14 bitů = 2 byte |
Paměťový záznam kódu -
výstup z infračidla je v tomto případě zaznamenán od příchodu startovacího impulsu v nějakém časovém rozsahu okamžik po okamžiku. To je samozřejmě náročné na paměť a výkon procesoru, ale je to nejuniverzálnější cesta. Vyskytuje se zde však problém s ukončením platnosti příkazu,
protože každý dálkový ovladač může mít až řádově rozdílné doby.
Prodloužení doby detekce příkazu nic neřeší, protože naopak kratší
příkazy mohou být nastaveny a doplněny šumem pozadí, který se
příště samozřejmě nebude opakovat a sekvence tak nebude rozpoznána.
Spolehlivé softwarové ošetření tohoto problému je dosti složité. |
Vyzkoušel jsem oba způsoby, a druhý, ač náročnější se ukázal jako spolehlivější. V prvním případě docházelo k tomu,
že se mi dařilo správně dekódovat jen některé ovladače. U ostatních se stávalo, že po naučení na jedno konkrétní
tlačítko přijímač reagoval i na různá jiná téhož ovladače (ne všechny). Jak jsem se nakonec přesvědčil na
osciloskopu, normu protokolu přesně dodržuje jen málo kdo. U některých RC5 chyběl start
bit, jinde byly dva, o dodržení časování ani nemluvim . Co firma to prostě originál. Nakonec jsem přistoupil
k druhému způsobu "dekódování". V podstatě nejde o dekódování, protože se přijímač "naučí" jen jedno tlačítko z DO a na to
jediné reaguje. To mi pro implementaci tohoto přijímače do konstrukce stmívače stačilo. Pokud by byl požadavek ukládat více kódů,
bylo by nutno omezit jejich velikost, resp. kompresovat. Šlo by použít např. CRC, ale já jsem to nepotřeboval, takže jsem
to ani nezkoušel. Musím poznamenat, že druhý, mnou použitý princip kupodivu fungoval asi s 7 ovladači DO a byl schopen se "naučit"
libovolné tlačítko. Chybné vyhodnocení (při stisku jiného tlačítka) jsem nezaznamenal.
A nyní již následuje samotný popis rutiny.
Tato rutina je psána pro PIC 16F628 (16F628A). Je plně funkční, výsledkem její činnosti je (pro test) rozsvícení LED diody
připojené na pin 1 portu A procesoru při příjmu správného infra kódu a bliknutí LED diody na pin 0 portu A při zápisu do interní EEPROM. Testovací zapojení najdete na konci stránky.
Kód vyslaný při stisknutí tlačítka na DO je
zaznamenán v paměti EEPROM procesoru, a pro správnou činnost rutiny je třeba, jej tam nejprve uložit. Opět pro test je zvoleno připojení tlačítka pro uložení na pin 1 portu B. Tato rutina využívá celou paměť EEPROM procesoru, samozřejmě záleží na délce kódu infračerveného ovladače. Uznávám, že to není moc hospodárné,
jak jsem psal výše, bylo by možno využít komprese, ale v tomto případě mi velikost záznamu nevadila, naopak jsem potřeboval co nejrychlejší
a nejjednodušší algoritmus kvůli prvotnímu určení této rutiny (stmívač). Rutina je rozdělena na dvě hlavní části. Dekódování dat, záznam a na dekódování dat, porovnání.
Princip je jednoduchý. Měří se doba impulsů pomocí časovače TMR0 a softwarového čítače.
To je dohromady v podstatě 16 bitový čítač. Dosažená doba impulsu (vyšší byte, tedy
softwarový čítač) je postupně ukládaná nejprve do paměti RAM mikrokontroléru, po
příjmu celého telegramu je překopírovaná do paměti EEPROM. Protože kódy ovladačů obsahují tzv. toggle bit, kterým se identifikuje držení tlačítka na ovladači (při stisku a držení se nemění, při uvolnění a novém stisknutí je bit invertován a při podržení se vysílá jeho nová hodnota) je nutné v této rutině zaznamenat a kontrolovat dva kódy.
Nejprve tedy stiskneme a držíme tlačítko pro uložení. Poté stiskneme tlačítko na dálkovém
ovladači do doby, než se rozsvítí LED, indikující správné uložení telegramu do RAM (cca 1 sec., zhasne po uvolnění tlačítka na DO). Po uvolnění tlačítka na DO jsou data z RAM přenesena do paměti EEPROM, to trvá několik milisekund, v závislosti na počtu uložených dat. Tento počet se liší podle výrobce a druhu dálkového ovládání. Uvolníme tlačítko pro záznam. Pokud nyní stiskneme tlačítko na DO, jehož kód jsme
přijímač "naučili", po dobu jeho stisknutí svítí indikační LED dioda. Po uvolnění tlačítka dioda zhasne. Jestliže rutina rozsvicuje LED jen na každé druhé stisknutí tlačítka, je to proto, že námi použitý ovladač vysílá výše zmíněný toggle bit. Budeme tedy celý postup uložení dat opakovat s tím, že po uvolnění tlačítka na DO neuvolníme tlačítko záznamu, ale stiskneme tlačítko na DO znovu a až teprve potom tlačítko záznamu uvolníme. Tímto postupem máme nyní zaznamenány dva totožné kódy, v nichž jediná změna je právě v toggle bitu. Nyní již musí LED dioda reagovat na každé stlačení uloženého tlačítka dálkového ovladače. Pokud náš ovladač nevysílá toggle bit, můžeme touto rutinou přijímat dva různé kódy pro spuštění jedné akce. (Např. ze dvou ovladačů - nedoporučuji)
Ale jak to tedy vlastně pracuje?
Budu se vše snažit vysvětlit do detailu, z pochopení z komentářů zdrojového souboru to může být poněkud náročnější . Pokud Vám bude něco nejasné, sledujte zároveň s
popisem
zvětšený vývojový diagram, nebo lépe máte-li možnost (a chcete-li, samozřejmě), vytiskněte si jej.
V klidu, kdy se nic neděje vykonává procesor nějakou činnost v hlavní smyčce programu.
Přerušení od časovače TMR0 není povoleno, externí přerušení povoleno je. Při příchodu
prvního impulsu (resp. hrany z log. H do log. L) nastane přerušení. Načte se hodnota
softwarového časovače. Protože před prvním vyvolání přerušení ještě "neběžel"
(resp. nebylo povoleno přerušení) TMR0, nebyl obsah softwarového čítače inkrementován.
Proto první hodnota není platná, my ji zdetekujeme odečtením předvolby soft. čítače, pokud je výsledek záporný, jde právě o první impuls. Tuto hodnotu nepoužijeme, ale povolíme přerušení od TMR0 a načteme předvolbu do soft. čítače a vystoupíme z obsluhy přerušení.
TMR0 nyní běží a při každém svém přetečení vyvolá přerušení. Tímto přerušením od
časovače se detekuje několik událostí, které popíšu postupně. Nejprve je tedy
inkrementován softwarový čítač.
Při příchodu dalšího impulsu od infra přijímače se sejme stav soft. čítače, ve
kterém nyní máme platnou hodnotu trvání impulsu. Následně se otestuje, zda je
požadavek na uložení dat. Pokud ano, uloží se hodnota do paměti RAM na adresu, jejíž
indirect adresa je v registru FSR. Následuje opět načtení předvolby soft. čítače a
vynulování TMR0. Pokud není požadavek ukládání dat, porovnává se okamžitě hodnota soft. čítače s daty v EEPROM. Vše je samozřejmě synchronizováno, první byte od soft. čítače musí být porovnáván s prvním byte záznamu v EEPROM. Proto je v rutině několik výpočtů, neboť volná RAM mikrokontroléru v bance 0 začíná na adrese 20H, několik byte je využito pro rutinu, záznam infra kódu tedy začíná na adrese 26H. Pro druhý kód je využita druhá banka mikrokontroléru, začínající na adrese 0A0H. Pro přepsání do EEPROM je tedy třeba přepočítat adresování (záznam v EEPROM pro kód DO č.1 používám od adresy 01H a pro kód DO č.2 od adresy 41H).
S příchodem dalšího pulsu (přerušení) se provede opět uložení s tím, že je nejprve
inkrementována hodnota resp. adresa v FSR.
Takto se postupně ukládají všechy doby impulsů.
Po dokončení telegramu (po vyslání bloku dat viz obrázek) nedojde k dalšímu přerušení od
externího vstupu, a softwarový čítač přeteče. Po tomto přetečení se otestuje, zda jde
o přetečení softwarového čítače poprvé. Jestliže je to poprvé, otestuje se flag ERR,
který je nastaven / nulován při porovnávání kódů. Pokud je vynulovaný, byl přijat správný kód,
a je rozsvícena signalizační LED. Při neplatném kódu (ERR nastaven) je LED zhasnuta.
Po tomto přetečení software čítače je nastaven příznak prvního přetečení a čítač je dále
inkrementován. Pokud dojde k novému přetečení, je díky tomuto bitu zjištěno, že šlo o
druhé přetečení a tím zjistíme, že tlačítko na DO bylo uvolněno. Pokud by totiž uvolněno
nebylo, došlo by ještě před přetečením tohoto soft. čítače k vyvolání přerušení z externího
vstupu díky nové sérii impulsů, které nuluje příznak prvního přetečení. Tím se pak celý děj
opakuje a my jsme schopni zjistit stisknutí i uvolnění tlačítka na DO.
Za zmínku ještě stojí záznam do EEPROM. Po ukončení přijímání prvního kódu (uvolnění tlačítka
na DO) dojde jak jsem již předeslal dříve k uložení do EEPROM. Navíc se nastaví příznak pro
příští záznam do druhé banky RAM. Podle tohoto příznaku se řídí ukládání do RAM a následně do
EEPROM tak, aby vždy první banka RAM byla zrcadlena v nižší části adresního prostoru EEPROM a
druhá banka RAM ve vyšší části.
Toto zapojení je jen testovací pro uvedenou rutinu. Ve vlastním zdrojovém souboru si můžete upravit obsazení
bitů portu podle sebe, a také využití výstupu rutiny určitě nebude sloužit jen k blikání s LEDkou . Tento
algoritmus by fungoval samozřejmě i na jednapadesátce (8051), ale ta bohužel nemá integrovanou interní EEPROM.
| | Zdrojový kód rutiny, přeložený *.hex a schéma ke stažení |
|
|
© DH servis 2002 - |