RS485 teploměr

01.09.2014

Intro

Uvažuji o stavbě domu a pokud by k tomu někdy došlo, chtěl bych si do něj nabastlit nějakou tu automatizaci. Chci se vyhnout kupování hotových věcí a jelikož je bastlení, i přes současný nedostatek času, stále mým největším koníčkem, je domek to správné "pískoviště" :-)

V první fázi by mělo jít o měření teplot v místnostech a ovládání okruhů podlahového topení dle požadovaných teplot. Když jsem se koukal okolo, jak to řeší jiní, tak mnoho lidí vezme nějaký PC (dnes nejčastěji Raspberry PI), připojí k němu 1-wire sběrnici a tu si roztahá po domě. Ono to funguje a pokud se respektují app-note od Maximu (délky vedení, odbočky, buzení, aktivní pullup apod.), tak poměrně spolehlivě. Jenže otázkou je, co dělat v případě, že bych nechtěl jen měřit teplotu? Že bych chtěl například indikovat stav topení, umožnit změnu požadované teploty z každého pokoje a třeba za 5-10 let udělat ještě něco úplně jiného? Z těchto důvodů jsem samotnou 1-wire zavrhnul a zvolil raději klasiku v podobě RS485. Oproti 1-wire je potřeba jeden drát navíc, ale univerzálnost budoucího použití předčila i větší složitost jednotlivých koncových prvků - na prosté měření teploty nestačí jen čidlo, ale MCU s RS485 řadičem.

Jak to funguje?

Pricip je jednoduchý - existuje sběrnice RS485 (dva dráty A a B) a napájení (+12V a zem). K této sběrnici jsou připojeny prvky jako je např. tento teploměr (SLAVE) a prvek, který realizuje řídící člen (MASTER) - tím může být bežné PC, Raspberry a nebo v mém případě Atmel ATMega328. Master prvek poté komunikuje se slave prevky, úkoluje je a dotazuje se. Slave prvek nikdy sám nevysílá, vždy pouze na vyžádání mastera. Tím je zajištěno, že na sběrnici nemůže dojít ke kolizi - bohužel však za cenu, že slave prvek nemůže masterovi ohlásit nějakou událost ihned, ale master se musí zeptat. Ostatně toto je věc protokolu, samotná RS485 zajišťuje pouze fyzický přenos dat a to ještě bez specifikace low-level rámců.

Komunikace probíhá pomocí UART rámců rychlostí 1200bps s jedním stopbitem. Je to sice dosti malá rychlost, ale má jisté výhody:

O RS485 je toho na webech popsáno moc, ale pro úplnost je nutné připomenout, že pro správný provoz je důležité, aby byl na sběrnici definován klidový stav - tedy aby byl B(+) proti A(-) napěťově kladnější. Jelikož je v označování A a B je trochu zmatek, platí proto, že vývod 6 MAX485 musí být připojen na vývody 6 ostatních a analogicky u vývodu 7. Vývod 6 je pak kladnější než 7. Pokud se vývody prohodí, nic se nestane, pouze nebude fungovat komunikace. Bez definování klidového stavu by pak do přijímače chodil chaos, což by mohlo v určitém případě zapříčinit doručení chybných dat.

Konstrukce

Základem je IC1 MCU ATtiny85. Výhoda tohoto kousku je v tom, že obsahuje 8kB FLASH paměti (dostatek prostoru pro firmware), dá se snadno koupit jako kusovka v GME (levněji pak z Číny) a vyrábí se v pouzdře DIP8. Nevýhoda pak, že neobsahuje HW UART, čili příjem a vysílání rámců je nutné řešit softwarově - to zabre místo ve flash a ostatní HW zdroje. Je taktován na 1MHz interním RC oscilátorem.

K MCU je připojen převodník TTL UART na RS485 MAX485, IC2. Je možné použít i levnější alternativu v podobě SN75176, ale vzhledem k tomu, že se dá MAX485 objednat z číny za témeř stejnou cenu, tak asi není co řešit. Rozdíl mezi MAX485 a SN75176 je ten, ze MAX má výrazně nižší klidovou spotřebu. Sběrnice je k MAX485 připojena přes ochranné odpory R1 a R2, které tam samozřejmě být nemusí, ale už se mi párkrát podařilo místo komunikace docílit ohňostroje :-) Ochraný odpor R3 mezi výstupem MAX485 a vstupem MCU je zde umístěn proto, že datový výstup MAX485 je napěťově docela tvrdý a znemožňoval by tak naprogramování zapájeného MCU.

1-wire sběrnice je k MCU připojena opět přes ochranný odpor R6 a ochrannou diodu D2. Obě součástky také nejsou nutné, ale jedná se o korunovou položku, která může zachránit buď MCU nebo čidla. Firmware umožňuje vyčítat teplotu až z 5-ti čidel DS1820 nebo DS18B20. Poslední volná noha MCU je využita pro indikační LED přes odpor R5. Jeho hodnotu lze volit dle použé LED a požadovaného jasu. Místo LED lze připojit cokoliv jiného (např. tranzistor a relé), proto je napájena z vývodu MCU - tak aby zapnutá LED reprezentovala log.1 na výstupu z MCU.

Schémata a desky

Spotřeba

V předchozím textu jsem se zmínil, že MCU je taktováno na 1MHz a že jsem raději použil MAX485 místo SN75176. V obou případech byla důvodem nižší spotřeba. Jde hlavně o to, že v napájecí části je použit lineární stabilizátor 78L05. Jeho problémem je napěťový úbytek a z toho plynoucí teplo :-)Kombinace ATtiny85 na základním taktu 8MHz a SN75176 totiž žere v klidu 25mA a při tomto proudu už 78L05 nezůstává chladný - není horký, ale vlažný. Jinde by to asi nevadilo, ale jelikož v této konstrukci jde hlavně o měření teploty, představa "vytápěné" elektroinstalační krabice s čidlem na jejím povrchu je těžce snesitelná :-) Pro představu naměřené proudy:

Ještě by šel nahradit 78L05 nějakým jiným stabilizátorem (např. LE50), ale tam už to zbytečně cenově povyskočilo a výsledek by nebyl tak výrazný.

Firmware

Program pro Atmela je ke stažení dole. Jedná se o balík, který obsahuje:

USBasp je potřeba přepnout do lowspeed režimu, neboť po zápisu fuses na snížení taktu z 8 na 1MHz přestane MCU rychlý režim programátoru stíhat. Nejsnáze je použitelná dávka avrdude_renew.cmd, která vše smaže, zapíše fuses, flash, eeprom a provede verifikaci.

Software UART

Jelikož použitý MCU Atmel ATtiny85 nemá hardwarový UART, bylo zapotřebí přelouskat application note "AVR274: Single-wire Software UART" a zjednodušenou variantu implementovat. Obrázek je nad tisíc slov....

Předpoklady:

Funkce:

Vysílání je ještě jednodušší:

1-wire

Maxim na svém webu umístil dokument "APPLICATION NOTE 187, 1-Wire Search Algorithm", kde prakticky popisuje jak realizovat algoritmus na vyhledání ROM kódu zařízení připojených na 1-wire sběrnici. Kód je ale příliš komplexní, takže ho trochu pokrátil a implementoval do dvou funkcí:

Tyto funkce jsou použity pro možnost nastavení ROM připojených čidel, tak, aby jeden tento teploměr mohl měřit více teplot.

Ovládání

Teploměr komunikuje rychlostí 1200bps, 1 stopbit, žádná parita.

Formát paketu (vše ASCII znaky): * d s [fc] #

Příklad:

Vrácení teplot čidel a nastavení LED

Jedná se o základní fukci, která vrací teploty z čidel. Teploty jsou průměrovány za poslední 4 měření, resp. za 4 poslední volání této funkce. Součástí funkce o vrácení teploty je i možnost nastavení stavu LED a to proto, aby se nemusely posílat dva příkazy - jeden na zaslání teploty a druhý na nastavení stavu LED.

Příkaz:

*ds# Vrátí průměrovanou teplotu teploměrů.
*dsZ# Vrátí průměrovanou teplotu teploměrů a zapne LED.
*dsV# Vrátí průměrovanou teplotu teploměrů a vypne LED.
*dsR# Vrátí průměrovanou teplotu teploměrů a zapne rychlé blikání LED.
*dsP# Vrátí průměrovanou teplotu teploměrů a zapne pomalé blikání LED.
*ds?# Vrátí průměrovanou teplotu teploměrů. ? je libovolný znak mimo ZVRP.

Příklad:

*XM# *XMZ# *XMR# apod.

Odpověď:

*dsl[ttt]#

Příklad odpovědi:

*MXV4F13EA# vrací dvě teploty 4F1 (1265=26.5°C) a 3EA (1002=0.2°C) a info, že LED je vypnutá.

Změna adresy

Každý prvek na RS485 sběrnici má adresu z intervalu A-Z. Po naprogramování MCU je výchozí adresa nastavena na X. Je tedy nutné ji změnit a k tomu slouží následující funkce.

Příkaz:

*dsSAx#

Příklad:

*XMSAP# - změna adresy prvku X na P.

Odpověď:

*ds# odsílatelem s je už nová adresa

Příklad odpovědi:

*MP#

Přidání ROM čidla

Teploměr umožňuje vyčítat teploty z 5-ti čidel na 1-wire sběrnici. Aby veděl, jaké má které čidlo ROM a jakého je typu, je nutné toto pomocí této funkce nastavit. Funkce na vracení teplot vrací pouze nastavená čidla, ostatní ignoruje.

Příkaz:

*dsSCctssssssssssssssss#

Příklad:

*XMSC3110488B8A0208006F# - nastaví na pozici 3 čidlo DS18B20 s ROM 10488B8A0208006F

Odpověď:

*ds|c-t-ssssssssssssssss|#

Příklad odpovědi:

*MX|3-1-10488B8A0208006F|#

Odstranění nastavení čidla

Pokud se nějaké čidlo fyzicky odstraní, lze to touto funkcí deaktivovat. Chybná teplota z neexistujícího čidla pak není vracena funkcí na vrácení teplot.

Příkaz:

*dsSDc#

Příklad:

*XMSD3# - odstraní nastavení čidla z pozice 3

Odpověď:

*ds|c-0|#

Příklad odpovědi:

*MX|3-0|#

Prohledání 1-wire sběrnice

Funkce se pokusí prohledat všechny čidla na 1-wire sběrnici. Vráti jejich ROM, které lze použít ve funkci pro nastavení čidla. Výstup není omezen a funkce tak vrátí tolik ROM, kolik čidel na 1-wire najde.

Příkaz:

*dsSS#

Příklad:

*XMSS#

Odpověď:

*ds|ssssssssssssssss|ssssssssssssssss|# - počet dle nalezených prvků

Příklad odpovědi:

*MX|10488B8A0208006F|10488B65021824AA|#

Výpis nastavení teploměrů

Funkce vypíše nastavení všech 5-to pozic a to typ čidel a ROM kódy. Pokud je ve výpisu na místě typu čidla 0, znamená to, že čidlo není aktivní a funkce na vracení teplot ho nevrací.

Příkaz:

*dsSR#

Příklad:

*XMSR#

Odpověď:

*ds|0-t-ssssssssssssssss|...|4-t-ssssssssssssssss|# - zkráceno, výpis pro 0-4

Příklad odpovědi:

*MX|0-1-10488B8A0208006F|...|4-0-FFFFFFFFFFFFFFFF|#

Broadcast test dostupnosti

Jedná se o diagnostickou funkci, kterou poslechou všechny prvky na RS485 sběrnici. Po přijetí příkazu odešlou svoji identifikaci do cca 30-ti sekund dle adresy. Krokuje se od A do Z po sekundě, čili prvek s adresou A odpoví hned, prvek s adresou Z až za 26 (počet písmen v abecedě) sekund.

Příkaz:

*?s#

Příklad:

*?M#

Odpověď:

*ds# - odpověď příjde do 30 sekund dle adresy.

Příklad odpovědi:

*MX#

Příklad pro 10 teploměrů a následné rozsvícení LED u "I":

Test časování

Jedná se o diagnostickou funkci, která slouží k ověření přesnosti interního kalibrovaného RC oscilátoru. Po obdržení odpovědi se na cca. 8 sekund objeví na TXD obdélníkový signál, jehož půlperioda má délku bitu při 1200bps (tj. cca 833.34us) nebo 1.5 násobek delky bitu při 1200bps (tj. cca 1.25ms).

Příkaz:

*dsSTx#

Příklad:

*XMST0#

Odpověď:

*dsTx# - následuje obdélníkový signál

Příklad odpovědi:

*MXT0#

Korekce RC oscilátoru

Funkce pro korekci interního RC oscilátoru. Přičte nebo odečte jedničku z registru OSCCAL a diferenci uloží do EEPROM. Po provedení se spustí test časování bitrate - viz. výše.

Příkaz:

*dsSOx#

Příklad:

*XMSO1#

Odpověď:

*dsO+# - následuje obdélníkový signál

Příklad odpovědi:

*MXO+#

Fotky

Ukázka řídícího modulu:

Ke stažení

Zdrojáky a vše ostatní