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:

sudo ./infra

 

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
0000000111111
00000001111110000001111111000000111111000000011111110000011111111111111111111
0000000111111111111111111100000001111111111111111111000000011111100000011111110000011111111
00000011111100000001111111000001111111000000011111100000011111100000001111110000001111111
00000011111100000001111111
00000011111111111111111110000000111111111111111111100000011111111111111111111
000000011111111111111111100000001111111111111111111100000001111111111111111111
0000001111111111111111111110000000111111111111111111000000
111111111111111111111111111111
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


Odkaz na YouTube

 



úvodní strana webu AstroMiK.org

poslední úprava stránky 1.2.2014