Raspberry Pi
45) Infračervený přijímač - dálkový ovladač
V tomto článku popíšu, jak je možné ovládat RasPi pomocí
běžného infračerveného dálkového ovladače (například ovladače od
televize).
Jako přijímač jsem použil obvod TSOP31236.
Existuje sice už hotový projekt s názvem LIRC,
který se zabývá IR ovládáním RasPi, ale já jsem nechtěl jen jednoduše
opisovat.
Chtěl jsem sám pochopit princip tohoto řízení, a proto jsem si vytvořil
vlastní program pro IR ovládání.
1) Schéma
LED diody jsou použity jen pro signalizaci. Pro funkci přijímače nejsou důležité.
2) Popis vysílaného kódu Hlavním
problémem bylo to, že každý dálkový ovladač vysílá jiný kód.
Proto není možné vytvořit univerzální program pro všechny ovladače. Při
pokusech jsem vycházel z tohoto článku: http://www.ostan.cz/IR_protocol_analyzer/analyza_protokolu_dalkoveho_ovladace_Ondrej_Stanek.pdf Osciloskopem
jsem však naměřil úplně jiné průběhy.
Pro příklad zde uvádím průběhy z univerzálního dálkového ovladače
"CHUNGHOP RM88E", na kterém
jsem zvolil náhodný kód TV114 (pro
televizor MANTIANXING).
Jak je vidět na prvním průběhu, v klidu (když není stisknuto žádné
tlačítko na ovladači) je signál z výstupu čidla v "1".
Po stisknutí tlačítka se vyšle jeho kód. Pokud je tlačítko na
ovladači drženo trvale, odešle se po 110ms další krátký kód, který
je však už jen opakovací (nenese informaci o tom, které tlačítko
bylo stisknuto). Písmeno "K" je vysvětleno níže.
Na tomto průběhu je zvětšená ta část signálu, která nese
informaci o stisknutém tlačítku. Okamžitě po stisku
tlačítka se stav na čidle překlopí do poměrně dlouhé
"0". Tato "0" trvá asi 5ms.
Po ní následuje také celkem dlouhá "1" (4,5ms). Poměr šířek
těchto signálů může být u každého ovladače jiný.
Zatím u všech ovladačů, které jsem vyzkoušel, ale platilo, že šířky
těchto dvou stavů jsou výrazně delší, než šířky ostatních impulzů. Po
této "hlavičce", která se skládá z dlouhé "0" a dlouhé
"1" následují vlastní data.
U všech testovaných ovladačů platilo, že šířka nulového signálu byla v rámci jednoho kódu vždycky stejná (u univerzálního ovladače
asi 0,6ms).
Měnila se ale šířka
jedničkového signálu (někdy byla ta šířka asi 0,6ms, jindy
byla zhruba
3x delší = 1,7ms). Pro zjednodušení jsem tedy celkový signál
rozložil na 5 různých stavů:
Zvětšená úvodní část předchozího obrázku. 1) Dlouhá "0" znamená začátek kódu - (stav
Z).
2) Dlouhá "1" - (stav H)
3) Krátká "0", následovaná krátkou "1" - (stav 0)
4) Krátká "0", následovaná delší "1" - (stav 1)
5) Velice dlouhý jedničkový signál = konec sekvence (stav K)
- je vidět na prvním obrázku.
Když jsem pak takto převedený kód nechal zobrazit,
dostal jsem pro různé ovladače takovéto řetězce: Univerzální
TV ovladač:
ZH01110000011100000000000011111111K = Tlacitko 1 (pro toto tlačítko jsou
výše zobrazené průběhy
z osciloskopu)
ZH01110000011100001000000001111111K = Tlacitko 2
ZH01110000011100000100000010111111K = Tlacitko 3
ZH01110000011100001100000000111111K = Tlacitko 4
ZH01110000011100000010000011011111K = Tlacitko 5
STB Evolve:
ZH00000000111111010100101010110101K = Tlacitko 1
ZH00000000111111010000101011110101K = Tlacitko 2
ZH00000000111111010000100011110111K = Tlacitko 3
ZH00000000111111010110101010010101K = Tlacitko 4
ZH00000000111111010010101011010101K = Tlacitko 5
VCR Toshiba:
ZH00100010110111011000000001111111K = Tlacitko 1
ZH00100010110111010100000010111111K = Tlacitko 2
ZH00100010110111011100000000111111K = Tlacitko 3
ZH00100010110111010010000011011111K = Tlacitko 4
ZH00100010110111011010000001011111K = Tlacitko 5
Podle těchto kódů pak stačí vykonat příslušnou akci v
RasPi.
3) Software Vzhledem k tomu, že se úrovně na výstupu
čidla střídají strašně rychle, nebylo možné pro vyhodnocení použít
můj oblíbený programovací jazyk Python, ale musel jsem se naučit
alespoň základy o hodně
rychlejšího jazyka C. Aby bylo možné v tomto jazyce číst stav
GPIO pinu případně něco ovládat, bylo třeba doinstalovat ovladač
(knihovnu) pro práci s procesorem BCM2835.
Postupoval jsem podle této stránky:
http://www.airspayce.com/mikem/bcm2835/index.html
Do terminálu jsem postupně zadal tyto příkazy:
wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.36.tar.gz
tar zxvf bcm2835-1.36.tar.gz
cd bcm2835-1.36
./configure
make
sudo make check
sudo make install |
(verzi 1.36 si případně opravte
na aktuální, která je uvedena na té výše zmíněné stránce)
Můj zdrojový kód programu pro čtení a vyhodnocování infra ovladače
je zde: infra.c
(Je to můj první projekt v C, tak než mě začnete kritizovat,
zkuste třeba proradit, jak to udělat líp.)
Program se skládá z několika základních částí:
1) Načtení knihoven, nastavení typů proměnných, nastavení GPIO
portů ...
2) Pomalá smyčka, která čeká na začátek příjmu signálu (čekání
na úvodní dlouhou "0").
3) Rychlá smyčka, která načte 1500 vzorků z GPIO portu do paměti.
4) Smyčka pro zobrazení celého průběhu nasnímaného signálu.
5) Analýza a převedení 1500 vzorků na zjednodušený kód stisknutého
tlačítka (asi 35 znaků).
6) Vyhodnocení tohoto zjednodušeného kódu tlačítka a případné
vykonání nějaké akce (rozsvícení / zhasnutí LED).
Zdrojový kód programu můžete stáhnout přímo do RasPi příkazem:
wget http://www.astromik.org/raspi/infra.c |
Tento kód je třeba převést do spustitelného souboru.
K tomu se používá překladač GCC, který je základní součástí
instalace Raspbian.
Příkaz pro přeložení zdrojového kódu "infra.c" do
spustitelného programu "infra" s připojením ovladače pro BCM2835 vypadá
takto:
sudo gcc -o infra infra.c -l bcm2835 |
Spuštění přeloženého programu se pak provede klasicky:
Ještě před spuštěním je však nutné, abyste si ten program přizpůsobili
přímo pro váš dálkový ovladač.
4) Přizpůsobení programu pro konkrétní dálkový ovladač
Ve zdrojovém kódu programu si můžete všimnout části programu,
který slouží pro zobrazení naskenovaných dat z GPIO portu.
Tato data obsahují pouze "1" a "0" - je to takový
"textový logický osciloskop".
V první fázi si tedy musíte tato data prohlédnout:
0000000000000000000000000000011111111111111111111111111111111111111111111111111111
000000011111100000011111111111111111111000000111111111111111111100000001111111111111111111
000000011111100000001111110000001111111000000111111000000011111110000011111111111111111111
0000000111111111111111111100000001111111111111111111000000011111100000011111110000011111111
00000011111100000001111111000001111111000000011111100000011111100000001111110000001111111
0000001111110000000111111100000011111111111111111110000000111111111111111111100000011111111111111111111
000000011111111111111111100000001111111111111111111100000001111111111111111111
0000001111111111111111111110000000111111111111111111000000111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
000000000000000000000000000000000000000000000000000001111111111111111111111111111111111111111111111111111
00000000000000111111111111111111100000001111111111111111111111111111111111111111111
1111111111111111111111111111111 |
Měli byste rozpoznat hned na začátku delší řadu
"0" (v příkladu označená modře), která je následovaná
delší řadou jedniček (v příkladu zeleně).
Další nápadná část je velice dlouhá nepřerušená řada
"1", která signalizuje konec přenášených dat (fialová
barva).
Mezi těmito částmi se nachází dva druhy signálů:
1) krátká řada nul a krátká řada jedniček (jedna z těchto částí
je v příkladu označena světle modře)
2) krátká řada nul a delší řada jedniček (jedna z těchto částí
je v příkladu označena červeně)
Je třeba alespoň zhruba spočítat následující údaje:
Počet tmavě modrých nul - v příkladu je jich 29.
Počet zelených jedniček - v příkladu je jich 53.
Počet světle modrých jedniček - v příkladu se jejich počet pohybuje
mezi 6 a 8.
Počet červených jedniček - v příkladu je to mezi 18 a 20.
V programu, v části "Analýza naskenovaných
dat", naleznete několik podmínek, které upravíte tak, aby s
rezervou bezpečně rozpoznaly jednotlivé části datové sekvence.
Pak je také třeba pamatovat na to, že se v kódech občas
mohou vyskytovat chyby. Tyto chyby mohou být způsobené špatným zamířením
ovladače na čidlo, různými odrazy, a nebo i programem, který nestačí
při rychlém skenování zachytit všechny stavy na GPIO portu.
Proto je možné, že při opakovaném stisku jednoho tlačítka
můžete dostávat různé kódy.
V tom případě je vhodné provést několik pokusných načtení tlačítek
a pak ručně vyhodnotit, který z kódů je správný a který je chybný.
Správný kód se bude opakovat nejčastěji. Chybné kódy budou pokaždé
jiné a pravděpodobně i kratší. Správný kód bude také na začátku
obsahovat znaky "ZH" a na konci znak "K".
Zjistil jsem, že pokud je spuštěný VNC Viewer, dochází
k chybám častěji, než když je program spuštěn přes terminál PuTTy.
Pravděpodobně VNC Viewer zabírá hodně systémových prostředků a
program pak nestíhá skenovat GPIO port.
Jako příklad takového ručního vyhodnocení jsem použil data
dvou tlačítek, která byla nasnímaná z dálkového ovladače AverMedia:
Červeně jsou označeny chybné kódy a vysvětlení chyb.
Z toho se dá usuzovat, že správný kód pro tlačítko "1" je "ZH01000000101111111010000001011111K"
a správný kód pro tlačítko "3" je "ZH01000000101111111110000000011111K"
V poslední fázi se musí vyhodnotit kód stisknutého
tlačítka.
V programu jsem pro vyhodnocení tlačítek 1 až 5 (na univerzálním
ovladači) testoval 3 znaky v kódu na pozicích 18,19 a 20.
Vycházel jsem z těchto kódů:
Každý ovladač má ale ty kódy různé, tak si správné
části musíte určit sami, nebo můžete testovat úplně celé kódy.
5) Ukázkové video
|