česky english Vítejte, dnes je pátek 19. duben 2024

Mechatronika, část 4 Komunikace s okolím

DPS 4/2022 | Články
Autor: RNDr. David Obdržálek, Ph.D. | MFF UK, Jiří Rotta | JeDe Robot s. r. o.
01.jpg

Jen výjimečně se dnes najde robotický projekt nebo obecněji projekt s mikrokontrolérem, kde řídicí jednotka nepotřebuje komunikovat s okolím. Už i nejzákladnější úlohy s Arduinem nebo micro:bitem zahrnují připojení například vstupních tlačítek a teplotního a vlhkostního senzoru nebo malého displeje a se všemi je třeba nějak komunikovat. Ve zmíněných Arduino projektech programátor obvykle využije nějakou už existující knihovnu a ve svém programu komunikuje pomocí jejích objektů, metod a funkcí, například na Arduinu příkazem Serial.println("Ahoj"); pro výpis pomocí sériové linky nebo t=dht.readTemperature(); pro čtení teploty ze senzoru DHT12, na micro:bitu pak například použitím bloku „zobraz text“. Ale i v takovém případě je velmi užitečné vědět, co je v pozadí, například proto, že v mnoha případech může při použití různých knihoven dojít ke konfliktům, nebo proto, že na řídicím modulu jsou některé funkčnosti pinů sdílené mezi více periferiemi a není možné je použít zároveň. A hlavně, pro úspěšné připojení je nutné respektovat požadavky obou propojovaných prvků. Tehdy se velmi hodí znalost, jak je vlastně komunikace navržena a jak probíhá, aby bylo projekt možné zprovoznit. V mnoha projektech se také různé typy komunikace kombinují a jako programátor potřebujete vědět, jak vše dohromady správně obsloužit. V dnešním článku se podíváme na několik možností komunikace a naznačíme možné potíže i jejich řešení.

Principiálně rozdílné jsou mezi nejpoužívanějšími komunikačními systémy tyto:

1. Přímé připojení

V takovém systému řídicí mikrokontrolér přímo ovládá danou periferii, např. vypíná/zapíná napájení, čte pomocí analogovědigitálního převodníku napětí na vstupu nebo v programu měří dobu mezi pulzy na digitálním vstupu. Typickým příkladem jsou nejjednodušší vstupní a výstupní periferie, jako je tlačítko, termistor nebo ultrazvukový dálkoměr a LED, elektromotorek nebo modelářské servo (viz například obrázky zapojení motorů a senzorů v předchozích dílech našeho seriálu). Pin mikrokontroléru použitý pro takovou komunikaci tady není možné zároveň využít jinak.

2. Point-to-point systémy

V těchto systémech jsou mezi sebou přímo propojeny vždy pouze dvě jednotky a mohou spolu komunikovat také pouze takto jedna s jednou (proto se také tento systém jmenuje point-to-point). Na rozdíl od přímého připojení se v této kategorii obvykle využívá datový přenos a nějaký jeho protokol, kdy údaje jsou reprezentovány číselnými (nebo i textovými) hodnotami a komunikace probíhá na úrovni přenosu jedniček a nul. Typickým příkladem jsou již zmíněný přenos po sériové lince nebo komunikace se senzorem teploty a vlhkosti DHT12 či s LCD displejem. I v tomto případě je pin (nebo piny) použitý pro komunikaci vyhrazen pouze pro tento účel a nejde na něj přímo připojit jinou periferii. V případě nutnosti je to však někdy možné obejít, a to tak, že na daný pin (piny) připojíme vhodným způsobem periferií více a zároveň dalším vhodným způsobem omezíme či určíme, se kterou periferií bude mikrokontrolér doopravdy komunikovat. Některé periferie totiž mají tzv. „enable“ nebo „select“ signál, jehož aktivace povoluje periferii komunikovat, a pokud není tento pin aktivován, periferie nekomunikuje (a může se chovat, jako by tam ani nebyla). Pokud periferie tento signál nemá k dispozici, ještě může být možné periferii odpojovat napájení pomocí digitálních výstupů mikrokontroléru (musejí být obvykle posíleny, např. spínacím tranzistorem nebo relé). V obou případech je samozřejmě nutné věnovat pozornost fyzickému zapojení vodičů, aby periferie, která nemá komunikovat, elektricky neovlivňovala skutečný požadovaný přenos.

3. Sběrnicové systémy

Ve sběrnicových systémech jsou jednotky propojeny pomocí společného datového nosiče (ať už „po drátě“, nebo „vzduchem“) a to, která jednotka se kterou komunikuje, je určeno protokolem dané sběrnice. Obvykle pomocí adresování, kdy každá jednotka má přiřazenu svou identifikaci − adresu, a pokud jiná jednotka s touto potřebuje komunikovat, musí ji znát. Typickým příkladem jsou například sběrnice i2c nebo SPI, o kterých píšeme dále; čtenář jistě bude znát ethernet nebo Wi-Fi, což jsou příklady dalších sběrnic, ale jejich popis by jednak byl silně nad rámec tohoto článku a navíc se s nimi obvykle v projektech s mikrokontroléry nesetkáme. Svým návrhem jsou sběrnicové systémy přímo určeny k zapojení více jednotek najednou.

Nejčastěji používaná propojení

Pro připojení mikrokontroléru k okolí se používají samozřejmě všechny výše uvedené možnosti. Podívejme se nyní na tři příklady konkrétních možností pro komunikaci, se kterými se u nejběžnějších malých mikrokontrolérů (jako je Arduino, micro:bit apod.) asi setkáte nejčastěji:

1. Sériová linka

Pro komunikaci mikrokontroléru s osobním počítačem je nejběžnější sériová linka. Data se přenáší postupně jako potrubím, co na jedné straně do potrubí nasypete, to na druhé ve stejném pořadí vypadne. Počítač i mikrokontrolér umožní svým programům otevřít spojení po zvolené lince a programy pouze posílají svá data. Požádají o otevření linky, zadají rychlost komunikace a už jen posílají data. Na úrovni elektrických signálů však mohou být u sériové linky využity dva zcela rozdílné systémy, které nelze míchat: telekomunikační standard RS-232 (případně RS-423), kdy logická 0 je představována napětím +3 až +15 V a logická 1 napětím –3 až –15 V, a tzv. TTL sériová linka, kdy logická 0 je představována napětím 0 až 0,8 V a logická 1 napětím 2 až 5 V nebo při použití prvků s menším napájecím napětím třeba jen 2 až 3,3 V. Někdy je navíc logika obrácená, tj. logická nula je vyšší napětí a logická jednička nižší. Je tedy zřejmé, že pro zapojování obvodů je nezbytné vědět, která přesně varianta je použita.

Dnes se často používá sériový přenos do počítače za použití USB, Wi-Fi nebo Bluetooth. Z hlediska programové obsluhy se jedná stále o sériovou linku, která má výhradně dva konce, ale na fyzické úrovni přenášeného signálu je tomu jinak. V takovém případě ale obvykle v malých projektech nepotřebujete vědět, jak to je přesně zařízeno, protože výrobce modulu (třeba právě Arduina a micro:bitu) už zařídil vše za vás – na modulu je kromě vašeho mikrokontroléru ještě další prvek, který to zařídí, a vám jako programátorům stačí data vysílat a přijímat. Ovšem pokud k modulu chcete připojit něco dalšího, co komunikuje sériovou linkou, už se o tyto napěťové úrovně zajímat musíte.

Pro vlastní přenos dat musíte také správně a na obou stranách stejně nastavit parametry přenosu, zejména přenosovou rychlost (anglicky Baudrate) a někdy i další parametry (např. paritu nebo počet bitů v jednom přenášeném rámci, ale to je v drtivé většině případů přednastaveno a nepotřebuje změnu).


Obr. 1 Základní propojení pomocí sériové linky

Na úrovni spojů (drátů) se využívají vždy dvě komunikační linky, jedna pro přenos „tam“ a druhá „zpět“, a to z pohledu každého zařízení. Jsou obvykle označeny jako Tx (Transmit, vysílání) a Rx (Receive, příjem), a to na obou zařízeních tak, jak je to použito právě na něm. Je tedy logické, že je třeba propojit linku Tx prvního s Rx druhého a linku Rx prvního s Tx druhého.

2. SPI

Komunikační rozhraní SPI (Serial Peripheral Interconnection) je další velmi oblíbený způsob propojení. Na rozdíl od sériové linky, kde jsou obě strany komunikace rovnocenné, u SPI vždy jedno zařízení komunikaci řídí („master“) a druhé pracuje podle jeho pokynů („slave“). Pro spojení se využívají obvykle 3 nebo 4 datové linky. Datové linky jsou: SCLK (Serial clock) pro taktování komunikace: master generuje taktovací signál („hodiny“), přičemž při každém „tiku“ se přenese jeden bit. Spojení je jednosměrné, pro vlastní komunikaci se používají oddělené vodiče, označené MOSI (master out, slave in, tj. směr toku dat master ⇨ slave) a MISO (master in, slave out, tj. směr toku slave ⇨ master).


Obr. 2 SPI – propojení mastera k jednomu slave

Protože se jedná o sběrnici, je možné v případě potřeby připojit k jednomu masteru více podřízených zařízení. V takovém případě je ještě potřeba ke každému jednotlivému podřízenému zařízení přivést linku CS (Chip select, někdy též SS = Slave select), pomocí které master volí, se kterým podřízeným zařízením komunikuje. Tento signál je obvykle v inverzní logice, tj. signál je aktivní, pokud má hodnotu logické 0, a neaktivní v logické 1 (značí se pak s pruhem, tak jak je znázorněno na obrázku).


Obr. 3 SPI – propojení mastera k několika nezávislým slave

Občas se používá i varianta zapojení, kdy všechna zařízení jsou propojena za sebou tak, že master posílá data prvnímu zařízení, jeho výstup je přiveden na vstup následujícího atd., až výstup posledního je přiveden do vstupu mastera. Všechna zařízení tak v podstatě tvoří sérii posuvných registrů, které posouvají bity na základě impulsů hodin. V tomto způsobu zapojení je navíc obvykle použito propojení všech signálů SS dohromady a master dá všem zařízením pokyn, že mají data zpracovat tím, že SS uvede do neaktivního stavu.


Obr. 4 SPI – propojení mastera s několika zřetězenými slave

Pro správnou komunikaci je potřeba nastavit režim, v jakém SPI funguje. Tyto režimy jsou celkem 4 a určují jednak polaritu hodin (zda je sběrnice v klidu na úrovni 0 a takt je určen impulsem jedničky nebo naopak) a fázi hodin (zda se data mění při náběžné nebo sestupné hraně hodinového signálu). Pokud je nastavena nesprávná fáze, spojení buď nefunguje, nebo někdy ano, ale spíše s výpadky; nemusí být na první pohled zřejmé, že se vlastně nejedná o závadu na propojení vodičů, ale chybu v nastavení.

3. i2c

Směrnice i2c byla původně vytvořena pro komunikaci integrovaných obvodů na jedné desce plošných spojů (název je ostatně vytvořen jako zkratka „inter-integrated circuit“ čili spojení mezi integrovanými obvody; je možné se setkat se zkratkami IIC nebo častěji i2c, občas i TWI pro two-wire interface, tj. spojení pomocí dvou drátů). Nicméně brzy po vytvoření standardu i2c se ukázalo, že vlastně má dobré využití i pro spojení různých jednotek pomocí kabelu na krátkou vzdálenost. Ovšem je třeba v takovém případě mít na paměti, že takový kabel nesmí být dlouhý a je nutné dodržet parametry dané standardem i2c a ošetřit i možné rušení. Komunikace probíhá pomocí páru vodičů, kdy na jednom jsou přenášeny hodinové impulsy (SCK = serial clock) a na druhém vlastní data (SDA = serial data).


Obr. 5 Spojení pomocí sběrnice i2c

Samotná komunikace je v principu velmi jednoduchá. Přenos vždy zahájí master pomocí tzv. „start condition“, což je signalizace všem připojeným zařízením, že přenos začíná. Jako první je pak vyslána adresa zařízení, se kterým master chce komunikovat. Pokud je zařízení (slave) s danou adresou připojeno, potvrdí tuto adresu okamžitou odpovědí − zasláním potvrzení, které je realizováno jediným bitem ihned následujícím adresu. Pokud master tento bit obdrží, je možné pokračovat v komunikaci, naopak pokud žádné zařízení adresu nepotvrdí, master ví, že s ním nikdo komunikovat nebude, a přenos ukončí. Po úspěšném potvrzení adresy následuje vlastní přenos, ať už zápis (master ⇨ slave), nebo čtení (slave ⇨ master). O který směr komunikace se jedná, je v i2c určeno jednoduchým trikem: v základním režimu jsou přenosy dat vždy osmibitové, ale adresy jen sedmibitové, takže hned v prvním přenášeném bajtu jeden bit zbývá. A ten je využit právě pro určení směru: master zvolí, jestli chce data posílat nebo přijímat nastavením tohoto bitu na 0 pro zápis nebo 1 pro čtení. Samotný přenos pak probíhá tak, že s každým tikem hodinového signálu na lince pro hodiny je přenesen jeden bit na datové lince. Hodiny vždy generuje master, data posílá buď master (zápis), nebo slave (čtení) a každý bajt je potvrzen na datové lince přijímací stranou stejně jako v případě prvního bajtu, tj. adresy (při zápisu potvrzuje příjem dat slave, při čtení master). Jakmile toto potvrzení nepřijde, komunikace je ukončena.

U všech tří uvedených rozhraní je kromě přenosových datových linek (pro sériovou linku a i2c jsou dvě, pro SPI tři nebo častěji čtyři) také potřeba propojit země všech prvků, protože úroveň signálů je vztažena ke společnému zemnímu potenciálu. Proto obvykle spojení zahrnuje další vodič, zem (obvykle na modulech označeno GND = ground nebo elektrickým symbolem pro zem ⏚). Často je navíc k dispozici i napájení. Zde už je třeba dát pozor jednak na napěťové úrovně použitého napájení všech modulů a pak také věnovat pozornost elektrickému zapojení při propojování napájení dvou zařízení, která mají každé svůj vlastní zdroj, protože přivedení „cizího“ napětí na výstup zdroje by jej mohlo poškodit.

Napěťové úrovně

Jedním z hlavních, avšak skrytých a bohužel přehlížených problémů při propojování zařízení a modulů v hobby elektronice a robotice je nutnost dodržování správných napěťových úrovní. Správné propojení totiž nemusí být přímočaré „spojím konektory a je to“. U sériové linky jsme už jeden problém (+15/-15 V vs. 0/5 V) zmínili, ale tomu je poměrně snadné se vyhnout, protože „čistou“ sériovou linku podle standardu RS-232 stále častěji v počítačích nahrazuje virtuální sériové spojení přes USB, kde tento problém není (na obou stranách komunikačního kanálu jsou použity řadiče USB, které tomu kterému zařízení dávají, co je potřeba). Výrazně horším problémem ale je, že v dnešní době je k dispozici řada malých modulů, ať řídicích, nebo periferních, které používají různá napájecí napětí a různá napětí datových úrovní přenosu, avšak označení pinů je stejné (Tx, Rx, SCK apod.). Některé také používají napájecí napětí 5 V, jiné 3,3 V a jiné třeba i jen 1,8 V a další mají povolený i celý rozsah (např. 2,7–5,5 V), avšak s různou úrovní napájení se u nich mění výkonnostní parametry. Obdobně je také vždy nějak omezeno i maximální povolené napětí na jednotlivých vstupních pinech; někdy je omezeno toutéž úrovní, jako je pro napájení, jindy může být modul tolerantní i k napětí vyššímu: velmi časté například je, že řídicí modul je napájený 3,3 V, ale jeho vstupy jsou tolerantní k vyššímu napětí, třeba 5 V. Ovšem rozhodně tomu tak není vždy; velmi časté je, že modul napájený 3,3 V má povolené nejvyšší napětí na vstupu také 3,3 V a napětí vyšší než 3,6 V jej může snadno zničit. To je případ například micro:bitu − pokud k němu připojíte modul komunikující s pětivoltovými napěťovými úrovněmi, můžete jej velice rychle zničit. A totéž se týká i komunikace s jinými moduly.

Velmi často se v praxi setkáváme s tím, že stavitelé robotů tento problém přehlížejí (resp. spíše nevědí o něm, a proto jej neřeší). Uvedeme jeden typický příklad za všechny: obrátil se na nás jeden z hobbystů s problémem, kdy k micro:bitu připojil několik maticových displejů 8 x 8 LED řízených obvodem MAX 7219. A ono to nějak úplně nefungovalo nebo fungovalo, jen když těch modulů bylo jen pár nebo když svítilo jen pár LED, text neskroloval, i když program byl v pořádku atd. Jak to, když tentýž modul s Arduinem funguje zcela v pořádku? V čem je problém? Vysvětlení je jednoduché: Arduino běžně používá napájení (a tedy i datové vstupy a výstupy) 5 V. Naopak micro:bit, i když je také možné jej připojit k USB, má napájení i vstupy a výstupy 3,3 V. Jenže zmíněný řídicí obvod maticového displeje MAX 7219 má v dokumentaci uvedené pracovní napájení 4,5−5,5 V a stejně tak při komunikaci vyžaduje, aby signál rozlišoval jedničky a nuly napětím 0 resp. 5 V. Pokud tedy modul budeme napájet z micro:bitu, a tedy napětím 3,3 V, anebo budeme na této napěťové úrovni chtít komunikovat, nemusí to fungovat správně a může to nenávratně poškodit jeden nebo druhý propojovaný modul. Nemusí, ale může – jakmile jsme mimo rozsah uvedený výrobcem ve specifikaci, nelze o fungování říct vůbec nic. Někdy se nic nestane, jindy to modul poškodí nebo i zničí.

Stejně tak je při napájení periferií, zejména elektrických motorků a serv nebo většího počtu LED, třeba brát ohled na proudovou zatížitelnost. Připojit topnou spirálu kávovaru přímo k mikrokontroléru snad nikoho nenapadne, ale velmi často se setkáváme s připojením několika motorků, řetízku senzorů a dalších modulů nebo LED pásků k jednomu malému Arduinu napájenému z USB počítače. Jenže pokud k modulu, který napájíme „tkaničkou od bot“ z USB, připojíme elektrický motorek „větší než malinký“, může při pokusu o jeho roztočení být potřeba natolik velký proud, že přesáhne povolený limit pro USB, aktivuje se automatická ochrana USB a dojde k odpojení příslušného USB portu. Nebo poklesne napájecí napětí pod úroveň, kterou k životu potřebuje řídicí mikrokontrolér a dojde k jeho resetu. V horším případě může dojít k poškození až zničení modulů, mikrokontroléru, nebo dokonce USB portu počítače. Úplně nejhorší ale je, že internet je plný návodů, kdy to autorovi nějak funguje (nebo to aspoň tvrdí) a vy to nedokážete zopakovat nebo vám to chvíli nějak funguje a chvíli ne, případně zpočátku funguje a pak bez zjevné vnější příčiny něco fungovat přestane.

Důležitá rada na závěr

V běžné amatérské praxi výše zmíněné potíže obvykle skončí povzdechem „to mi prodali šmejd!“ či nepublikovatelnou kletbou, ale spíše to je neznalost, kterou je velmi snadné překonat: dávejte pozor na to, jaké napájení propojované moduly potřebují a jaké jsou napěťové úrovně potřebné pro jejich komunikaci. Pokud nejsou stejné, zapojte mezi zařízení patřičný obvod nebo modul, pomocí kterého požadavky zařízení sladíte. Takové moduly jsou přitom velmi snadno dostupné a pro běžné případy i velmi levné. Například pro správnou komunikaci mezi 3,3 a 5 V i2c zařízeními stačí přidat dva FET tranzistory v haléřové ceně anebo mezi taková dvě zařízení s různým napájením zapojíte už hotový modul za pár korun. Také přizpůsobení TTL sériové linky mezi zařízeními s různou datovou napěťovou úrovní se dá pro jednosměrný provoz vyřešit i třeba jen pomocí dvou rezistorů nebo obousměrně pomocí dvou rezistorů a jednoho tranzistoru. A samozřejmě existují i hotové obvody nebo moduly, které snadno do svého obvodu zapojíte, a tím zcela odstraníte jednu možnou příčinu potíží.

david.obdrzalek@mff.cuni.cz | rotta@jederobot.cz
www.robodoupe.cz | www.dps-az.cz/zajimavosti/mechatronika