Lekce 35 – Arduino – komunikace přes RS485 až na vzdálenost 1200m

Dneska si ukážeme jak pomocí technologie seriové komunikace RS485 můžeme z jednoho zařízení odesílat data do dalších a to až do vzdálenosti 1200m. Nejprve si ale řekneme něco o RS485.

     Tato technologie je standard sériové komunikace definovaný v roce 1983 sdružením EIA. Používá se především v průmyslovém prostředí. Standard RS485 je navržen tak, aby umožňoval vytvoření dvouvodičového poloduplexního vícebodového sériového spoje. Má stejný základ jako standard RS232, od kterého se liší především jinou definicí napěťových úrovní, nepřítomností modemových signálů, možností vytváření sítí (též sběrnice) sestávající z až 32 zařízení a možností komunikace na vzdálenost až 1200m (proti 20m u RS232). Výhodou rovněž je, že linku RS485 je možné vytvořit z široce rozšířeného standardu RS232 pomocí jednoduchých převodníků úrovně.

RS485 (stejně tak RS422) se vyznačuje dvouvodičovým propojením jednotek. Tyto vodiče se označují písmeny A a B, někdy se používá označení „-“ a „+“. V klidovém stavu by na vodiči A (neboli „-“) mělo být menší napětí než na vodiči B (neboli „+“). Maximální délka sběrnice je až 1200 m, maximální počet uzlů (tj. zařízení vysílajících a přijímajících po lince data) je 32. Při použití opakovačů může být počet uzlů vyšší. Maximální přenosová rychlost je nepřímo úměrná délce vedení. Přenosová rychlost u krátkých spojů (do 10 m) může být až 10 Mb/s. Při komunikaci na vyšší vzdálenosti musí být vedení na obou stranách zakončeno zakončovacími odpory, neboli terminátory. Smyslem „terminátorů“ je zabránit odrazům signálu od konců vedení, rovněž pomáhají zvýšit odolnost linky proti rušivým signálům. Terminátor by měl mít v ideálním případě hodnotu 110 Ω (tzv. obrazová impedance), výsledná impedance linky je pak 55 Ω (110 Ω || 110 Ω).

Logické úrovně (nebo stavy) jsou reprezentovány rozdílným napětím mezi oběma vodiči. Je to rozdíl oproti RS-232, kde se úrovně stavů vztahují k referenční zemi (značené GND nebo G). Detekce logického stavu založená na rozdílovém napětí mezi oběma vodiči je výhodná zejména kvůli eliminaci indukovaného rušivého signálu, který se většinou přičítá k oběma vodičům stejně. Přijímač rozlišuje logický stav „1“ (také označovaný jako „Mark“) při rozdílu napětí A – B < -200 mV. Logický stav „0“ označovaný jako „Space“ při rozdílu napětí A – B > +200 mV. Vysílač by měl na výstupu při logické 1 (klidový stav linky) generovat na vodiči A napětí -2 V, na vodiči B +2 V, při logické 0 by měl na vodiči A generovat +2 V, na vodiči B -2V.

I když se pracuje s rozdílovým napětím, při spojení na delší vzdálenosti se musí kromě signálových vodičů (RxTx+ a RxTx-) propojit i země (GND, G) komunikujících zařízení (viz např. specifikace Modbusu). Příčinou je, že ve vzdálených místech mohou existovat značné rozdíly v potenciálu „země“. Proto je často „dvouvodičová“ RS-485 ve skutečnosti spíše třívodičová a „čtyřvodičová“ RS-422 spíše pětivodičová.

My si k vyzkoušení pořídíme moduly převodní RS485, který se nám hodí výborně k Arduinu. Vypadá takto:

    A zapojíme si ho k Arduinu jednoduchým způsobem.  Nejprve si zapojíme napájení modulu (GND na GND a Vcc na 5V do Arduina). Já jsem použil 2 mini nepájivé kontaktní pole, protože do velkého kontaktního pole má dost blbé rozměry.

V dalším kroku kroku spojíme na modulu RS485 pin RE a DE jednoduše propojovacím kabílkem. DE dále propojíme s Arduinem na pin 3. DI připojme na pin 11 a RO na pin 10.

Tím máme jedno Arduino s modulem zapojeno, ale k pokusu s komunikací přes RS485 budeme potřebovat ještě jedno Arduino stejně s tímto modulem propojené. Po zapojení i druhého zařízení propojíme oba moduly libovolně dlouhým vodičem. Ja pro testovací účely použil asi 1m 3-linky. Měla by stačit i 2-linka a propojíte A s A, poté B s B. Propojení GND není povinné a důvody jsou vysvětleny výše.

    V našem případě si nejprve rozhodneme, které Arduino bude data přijímat a které vysílat. Rozdíl bude pouze v programu. Do Arduina zvoleného jako vysílač nahrajeme následující program:

A do Arduina jako přijímače kód:

Nyní si spustíme v na Arduinu jako přijímač serial monitor. Ve výsledku vidíme a dokážeme to odvodit i z kódu pro vysílač, že serial monitor bude zobrazovat každé 2 sekundy text arduino8.webnode.cz.

Je to sice pěkné, ale ne moc účelné. V praxi budeme potřebovat, aby jedno Arduino odesílalo data a druhé Arduino je nějak zpracovalo a zobrazilo. A aby to nebylo úplně zas tak snadné, připojíme si ještě jedno Arduino a ze 2 zařízení budeme odesílat do jednoho. Já jsem program pro odesílání trošku upravil a vytvořil pro odesílání takový jednoduchý protokol:

Z kódu vyplývá, že je nejdříve odeslán startovací byte (0x02 nebo 2), poté je adresát (může to být adresa zařízení na které data odesíláme – já mám zapojeno pouze jedno zařízení, které přijímá tak je to jedno, číslo může být jaké chce), následuje adresa Arduina, které data odeslalo. Vyberte si libovolné číslo v rozsahu 0 – 255 (protože budu odesílat ze dvou zařízení, je dobré tuto informaci mít – já použil 8 a 11. Další bude číslo hodnoty, které jednotlivé Arduino odesílá (můžete z Arduina odeslat až 256 různých hodnot (v mém případě pouze jednu na ukázku z analogového pinu, kde jsem použil u jednoho Arduina světelný senzor a u druhého obyčejný odporový trimr.

Na straně přijímače dojde také ke drobným úpravám:

Zatím si tedy necháme posílat hodnoty na Serial monitor v trosku upravené formě jako na obrázku:

   Takže jsme v bodě, kdy dostáváme údaje ze dvou Arduin a je jen na nás jak tyto údaje využijeme. Zvolíme si nějakou formu pro náš případ a zobrazíme si je na displeji. Upravíme tedy náš program např. pro zobrazení na klasickém LCD 4×20 znaků přes I2C řadič. Výsledek už vypadá zase lépe pro praktické využití:

Aby jsme poznali, že jsou data přijímána i když se hodnoty nemění u hodnoty na posledním znaku krátce blikne znak *. Zádná složitá data jsem pro tento návod neposílal, jak jsem již uvedl, oba jsou z analogového pinu a na Arduino 8 je zapojen senzor světla a na Arduino 11 obyčejný odporový trimr. Interval odesílání jsem u vysílačů nastavil na 1 sekundu.

Na závěr chci uvést, že jsem poznal, že RS485 je velmi citlivé na kvalitu vedení. Sám jsem zkoušel zařízení propojit na vzdálenost 1m. Se 2 zařízeními vše fungovalo v pohodě s přidáním 3 to bylo velice náchylné, ale bylo to dané spíše meně kvalitním nepájivým polem nebo spojovacími drátky. Dale chci uvést, že protokol nemá checksum takže přijatá data se nějak neověřují zda jsou v pořádku. Vám nic nebrání si dopsat tuto kontrolu pomoci funkce XOR a přidat jí do protokolu. Také není ošetřen stav, když obě zařízení, která vysílají data, vyšlou tyto současně. Mužete toto ošetřit, nebo můžete naopak připsat kód, kdy se bude přijímač ptát na hodnoty, které chce dostat.

Zkuste si nechat poslat dat kolik jen chcete třeba jen z jednoho zařízení. V kodu nemám ošetřeno jaká hodnota se odesílá pouze z jakého Arduina přichází, protože odesílám jen jednu hodnotu z každého zařízení. Dále vyzkoušejte delší vzdálenosti a své zkušenosti můžete napsat do diskuze.

6 Komentářů

  1. Radek

    Ahoj. Počítam že ten printscreen com10 k příkladu nepatří…
    Jinak díky za tutorial.

    1. Administrátor (Autor)
  2. Radek

    Ahoj, u lekce 33 je taky zatoulanej jinej obrazek z Monitoru, prave z teto lekce 35…

  3. paja

    Příklad jsem vyzkoušel, funguje. Co je potřeba s textem arduino8.webnode.cz udělat, když bych jej na příjmacím arduinu chtěl zobrazit namísto na serial monitoru, na LCD?

    1. Administrátor (Autor)

      Odpověď najdeme v dalším tutoriálu.

  4. acat

    Zapojil jsem 3 Arduina podle popisu a nefugují dohromady, vždy mi vypisuje pouze hodnoty jednoho Arduina. V čem je problém?

Napsat komentář

Translate »