Uživatelské nástroje

Nástroje pro tento web


Rozdíly

Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.

Odkaz na výstup diff

cs:howto:gpio [2017/04/05 15:47] (aktuální)
patrick vytvořeno
Řádek 1: Řádek 1:
 +====== GPIO (vstupně-výstupní porty pro všeobecné účely) ======
 +
 +GPIO jsou porty, které může ovládat uživatelský program. Jejich umístění a
 +očíslování na desce je možné nalézt pro [[cs:​howto:​turris_versions#​omnia|Turris
 +Omnia]] {{:​omnia-pinout.png?​linkonly|zde}} a pro
 +[[cs:​howto:​turris_versions#​turris_11|Turris 1.x]]
 +{{:​turris_pinout-v1_2.pdf?​linkonly|zde}}.
 +
 +Maximální elektrické vlastnosti GPIO portů jsou:
 +|          ^ [[cs:​howto:​turris_versions#​turris_11|Turris 1.x]] ^ [[cs:​howto:​turris_versions#​omnia|Turris Omnia]] ^
 +^ Napětí ​  | 3,3 V       | 3,3 V         |
 +^ Proud    | ±1 mA       | ±5 mA         |
 +
 +<WRAP important>​
 +Při překročení elektrických parametrů není zaručena správná funkčnost portů a může
 +dojít k trvalému poškození routeru!
 +</​WRAP>​
 +
 +===== Shell =====
 +
 +GPIO porty mohou být exportovány do souborového systému a řídit je tak může i
 +jednoduchý shell skript.
 +
 +Prvním krokem je exportování GPIO portu, se kterým budeme pracovat. To lze učinit
 +zapsáním čísla portu do souboru ''/​sys/​class/​gpio/​export''​. Například pro
 +//GPIO18// takto:
 +
 +<code bash>
 +echo 18 > /​sys/​class/​gpio/​export
 +</​code>​
 +
 +Po exportu vybraného portu se automaticky vytvoří složka
 +''/​sys/​class/​gpio/​gpio**'',​ kde namísto hvězdiček je číslo GPIO portu. Pro port 18
 +je to tak ''/​sys/​class/​gpio/​gpio18''​. V této složce naleznete především soubory
 +''​direction''​ a ''​value''​. První ze souborů určuje, jestli je port nastavený jako
 +vstupní, nebo jako výstupní. Odpovídající hodnoty v souboru jsou ''​in''​ a ''​out''​.
 +Funkce druhého ze souborů, ''​value'',​ závisí na nastavení v souboru ''​direction''​.
 +Pokud je port nastavený jako vstupní, soubor ''​value''​ obsahuje aktuální stav
 +portu (''​0''​ pro nízkou a ''​1''​ pro vysokou napěťovou úroveň) a není do něho možné
 +zapisovat. Pokud je port nastavený jako výstup, do souboru ''​value''​ je možné
 +zapsat nulovou hodnotu pro nízkou napěťovou úroveň a nenulovou pro vysokou, také
 +je možné nastavenou hodnotu přečíst zpět stejně, jako když je port nastavený jako
 +vstup.
 +
 +Nastavení portu jako vstupu a přečtení stavu je tak možné tímto způsobem:
 +
 +<code bash>
 +echo in > direction
 +cat value
 +</​code>​
 +
 +Nastavení portu jako výstupu a nastavení vysoké napěťové úrovně je tak možné tímto způsobem:
 +
 +<code bash>
 +echo out > direction
 +echo 1 > value
 +</​code>​
 +
 +
 +===== Python2 =====
 +
 +V případě jednodušších operací je dostatečný shell, ale pro složitější programy je
 +lepší použít plnohodnotný programovací jazyk jako například Python. Na Turris
 +byla přeportována GPIO Python knihovna, originálně vytvořená pro Raspberry
 +Pi. Pro její použití nejprve musíte nainstalovat balíček ''​python-turris-gpio''​.
 +
 +Tento návod pokrývá pouze základní použití knihovny. Nepopisuje všechny vlastnosti,
 +které knihovna poskytuje. Další a podrobnější informace můžete nalézt v
 +[[https://​sourceforge.net/​p/​raspberry-gpio-python/​wiki/​Home/​|dokumentaci
 +k originální verzi knihovny]].
 +
 +==== Inicializace ====
 +
 +Prvním krokem k použití této knihovny je její naimportování a inicializace.
 +Knihovnu inicializujeme v módu ''​BCM'',​ kde čísla portů odpovídají tomu, jak jsou
 +označeny na čipu, tedy stejně jako na {{:​omnia-pinout.png?​linkonly|obrázku
 +pinoutu}}.
 +
 +<code python>
 +import turris_gpio as gpio
 +gpio.setmode(gpio.BCM)
 +</​code>​
 +
 +Dále nastavíme porty, které budeme řídit.
 +
 +<code python>
 +gpio.setup(18,​ gpio.OUT)
 +gpio.setup(33,​ gpio.IN)
 +</​code>​
 +
 +Prvním argumentem funkce ''​setup''​ je číslo portu a druhým argumentem je buďto
 +''​OUT''​ pro výstupní port, nebo ''​IN''​ pro vstupní port.
 +
 +==== Výstup ====
 +
 +Porty, které jsou nastavené jako výstupní, je následně možné ovládat pomocí funkce
 +''​output''​. Tato funkce přijímá jako první argument číslo portu a jako druhý
 +argument napěťovou úroveň. To může být ''​True''​ pro vysokou nebo ''​False''​ pro
 +nízkou úroveň (alternativně také ''​0''​ nebo ''​gpio.LOW'',​ respektive ''​1''​ nebo
 +''​gpio.HIGH''​).
 +
 +Příkladem může být tento kód, který nastaví port //GPIO18// do vysoké napěťové
 +úrovně po dobu deseti sekund:
 +<code python>
 +gpio.output(18,​ True)
 +time.sleep(10)
 +gpio.output(18,​ False)
 +</​code>​
 +
 +==== Vstup ====
 +
 +Napěťovou úroveň portu nastaveného jako vstup je možné číst pomocí funkce
 +''​input''​. Ta očekává jediný argument, a to číslo portu. Její návratová hodnota je
 +''​True''​ pro vysokou napěťovou hodnotu a ''​False''​ pro nízkou.
 +
 +Pro příklad kód, který přečte a vypíše stav portu //GPIO33//:
 +<code python>
 +if gpio.input(33):​
 + print("​Port 33 je HIGH")
 +else:
 + print("​Port 33 je LOW")
 +</​code>​
 +
 +
 +<WRAP info>
 +Programově nastavitelné pull up/down rezistory nejsou podporovány a doporučuje se
 +namísto nich použití hardwarových.
 +</​WRAP>​
 +
 +==== Vyčkávání na změnu signálu ====
 +
 +V případě, že váš program pouze čeká na změnu vstupu, je výhodnější místo opakovaného
 +kontrolování vstupu (tzv. busy loop) přenechat tuto kontrolu
 +operačnímu systému a program uspat. Toto je možné s touto knihovnou voláním jediné
 +funkce, a to ''​wait_for_edge''​. Tato funkce očekává minimálně dva argumenty. Prvním
 +je číslo portu a druhým je buďto ''​RISING'',​ nebo ''​FALLING'',​ nebo ''​BOTH''​.
 +Funkce pozastaví běh programu, dokud nedojde ke změně signálu z nízké napěťové
 +úrovně do vysoké v případě ''​RISING'',​ nebo ke změně z vysoké napěťové
 +úrovně na nízkou v případě ''​FALLING'',​ případně k oběma změnám v případě ''​BOTH''​.
 +Návratová hodnota funkce je číslo portu, na kterém se změna projevila.
 +
 +Pro vyčkání na náběznou hranu na //GPIO18// je tak možné použít následující kód:
 +<code python>
 +port = gpio.wait_for_edge(18,​ gpio.RISING)
 +if port == 18:
 + print("​Náběžná hrana na portu 18")
 +else:
 + print("​Tohle by se nikdy nemělo stát, nemáme timeout a čekáme pouze na port 18")
 +</​code>​
 +
 +Je také možné uvést volitelně jako argument funkce ''​wait_for_edge''​ maximální
 +dobu čekání na změnu (tzv. timeout). Jedná se o čas v milisekundách. Pokud zvolený
 +čas uplyne a změna na portu nebyla zaznamenána,​ funkce vrátí ''​None''​ namísto
 +čísla portu. Příklad pro port //GPIO18// by byl:
 +<code python>
 +port = gpio.wait_for_edge(18,​ gpio.FALLING)
 +if port:
 + print("​Sestupná hrana na portu " + str(port))
 +else:
 + print("​Došel čas")
 +</​code>​
 +
 +==== Úklid ====
 +
 +Před ukončením programu, nebo pokud již nadále nebude s portem pracováno, je
 +nutné stav portu resetovat, a nechat tak knihovnu po sobě uklidit. To je možné
 +zajistit funkcí ''​cleanup''​. Ta volitelně přijímá jako argument číslo portu, se
 +kterým ukončujete práci. Pokud není funkci argument předán, tak dojde k uklizení
 +všech portů, které program nastavil.
 +
 +Pro uklizení všech portů (//GPIO18// a //GPIO33//) nastavených na začátku toho
 +návodu tak použijeme jedno z následujících volání:
 +<code python>
 +gpio.cleanup([18,​ 33])
 +gpio.cleanup()
 +</​code>​