Modbus a analogové hodnoty
Při integraci zařízení protokolem Modbus se nevyhneme čtení a zápisu analogových hodnot. Modbus ovšem, na rozdíl od některých jiných protokolů, ve svém standardu formáty analogových hodnot nedefinuje. Jeho registry přenášejí šestnáctibitová čísla, která lze interpretovat více způsoby.
Dodavatel integrovaného zařízení (Modbus serveru), resp. jeho modbusové tabulky, proto musí poskytnout dokumentaci, z níž bude jasné, jak se mají vyčtená data převést na číslo, které odpovídá příslušné veličině. Někdy tato dokumentace bohužel není úplná nebo srozumitelná a pak je nutno trochu experimentovat. V následujícím poněkud delším, ale věřím, že o to zajímavějším textu si ukážeme, jak postupovat v praxi při uvádění zařízení do provozu.
Předpokládejme, že samotnou komunikaci již máme oživenou a zařízení vrací nějaká data. Podstatné je, zda analogová hodnota je přenášena pomocí jednoho registru („vejde se“ do 16 bitů) nebo zda zabírá registrů více: dva či čtyři, tedy je dlouhá 32 nebo dokonce 64 bitů.
V modbusové tabulce to poznáme zejména podle čísel registrů. Pokud jdou za sebou bez mezer, jedná se o 16bitové hodnoty:
Modbusová tabulka Uniflair, čísla registrů pro příslušnou vnitřní jednotku jsou ve sloupcích „unit X“
HVAC integer
U 16bitových hodnot je dále potřeba zjistit, jak jsou reprezentována desetinná čísla. Šestnáctibitový word je obecně schopen nabývat hodnot 0…65535. Pro přenos fyzikálních veličin, jako je například teplota, je vhodnější zvolit formát umožňující reprezentaci i záporných hodnot – tedy integer (se znaménkem). Ten má pak rozsah −32768 až 32767. Abychom získali větší rozlišení, a sice na jedno až dvě desetinná místa, hodnota je na serveru před zápisem do modbusové tabulky násobena 10 nebo 100. Tomuto formátu se pak říká HVAC integer. Vyčteme-li tedy z registru s teplotou v místnosti např. hodnotu 2230, po vydělení konstantou 100 obdržíme teplotu 22.3 °C. Informace o konstantě a fyzikální jednotce musí být uvedena v modbusové tabulce.
Například frekvenční měniče Vacon mají konstantu pro každou proměnnou uvedenu zvlášť v pravém sloupci tabulky, Scale – viz obrázek. Vyčtenou hodnotu z registru (číslo registru je zde značeno ID) tedy násobíme příslušnou konstantou ideálně hned ve vstupní transformaci, pokud to programovací prostředí umožňuje.
Výřez z modbusové tabulky FM Vacon
Někdy konstanta závisí na typu zařízení. Typy se totiž liší například výkonem a škálování je pro každý typ zvoleno tak, aby se dosáhlo co největšího rozlišení a zároveň nedošlo k přetečení rozsahu. Pak musíme pátrat v katalogových listech či dalších dokumentech:
Výřez z modbusové tabulky FV střídačů Vacon
Pozor na typ proměnné v aplikačním programu. Je nutné zvolit typ bez znaménka nebo s ním, podle toho, jak vypadá formát v modbusovém serveru. Setkali jsme se s chybou, kdy se venkovní teplota přenášela po sběrnici a v klientském programu byla příslušná proměnná deklarována jako integer bez znaménka. Škálování (v tomto případě dělení 100) bylo v pořádku, vše fungovalo do okamžiku, kdy venkovní teplota klesla pod bod mrazu. V tu chvíli proměnná na straně klienta „podtekla“ a nabyla hodnoty přes 650 °C, což mělo za následek odstavení topného systému.
Další transformace
Konstanta nemusí být vždy jen „kulaté“ číslo:
Výřez z modbusové tabulky Buderus, rozhraní pro sběrnici Ecobus
V tomto případě bychom například pro nastavení požadované teploty 21.5 °C museli zapsat hodnotu 43 (dekadicky).
Transformace mohou někdy nabývat až absurdních podob, některé klimatizační jednotky vyžadují přepočet měřené nebo nastavené teploty podle nelineární tabulky s 20–30 body. Taková situace je již zralá na napsání zvláštní transformační funkce či úpravu klientského programu; běžnými prostředky, jako je lineární transformace y = kx + q bychom nedosáhli požadované přesnosti.
32bitové hodnoty
Někde rozsah šestnáctibitové proměnné nestačí, například chceme-li (s potřebným rozlišením) přenášet energii naměřenou elektroměrem. Obvykle jde o kumulované hodnoty – energie, ale kvůli standardizaci se zejména právě u elektroměrů často setkáváme s 32bitovými hodnotami i u veličin jako jsou napětí a proudy. Autoři modbusových serverů pak využívají pro přenos jedné proměnné dva za sebou jdoucí registry, čímž získají 32bitový prostor. V aplikačních programech podle IEC 61131 jsou pro 32bitové celočíselné hodnoty použity typy DINT (double integer) či UDINT (unsigned double integer).
Dvaatřicetibitové hodnoty poznáme hned podle tří znaků:
- uvedeného formátu (Data Format: INT32),
- délky (Length – words, tedy dvě slova po 16 bitech) a
- podle čísla registru, ty jsou „ob jeden“ – pouze lichá čísla.
Na obrázku níže vidíme, že např. modbusová tabulka elektroměru EM23-DIN obsahuje všechny tři údaje. Modicon address je číslování registrů od 1 s notací 3xxxx, Physical address je tatáž řada, ale v hexadecimálním formátu a začínající od nuly.
Modbusová tabulka elektroměru Carlo Gavazzi EM23-DIN
V modbusovém klientu ModComTool vypadají načtené hodnoty takto:
Hodnoty z EM23-DIN načtené programem ModComTool
Hodnoty napětí musíme vydělit 10, jak vysvětluje poslední sloupec v modbusové tabulce. Na první pohled vidíme, že napětí na fázích je přibližně 237 V.
Pokud náš aplikační software umožňuje z Modbusu zpracovávat jen šestnáctibitové hodnoty, nezbyde než vzít horní word (MSW), znásobit ho 65536 a přičíst k němu word spodní (LSW). Výsledkem je obvykle hodnota typu real, což ale pro výsledek může znamenat jednak
- nižší rozlišení (tedy malé změny se ve výsledné proměnné nemusí projevit), jednak
- hazard při přetečení nižšího wordu, pokud by se oba wordy nečetly jedním modbusovým dotazem: výsledná hodnota by pak mohla obsahovat dočasný skok, který by mohl být v aplikaci vyhodnocen jako nežádoucí a např. vést až k odstavení technologie.
Pořadí registrů
Pozor na pořadí wordů. Výrobce elektroměru Carlo Gavazzi EM23-DIN uvádí i v dokumentaci, že na sběrnici přichází registr (word) s nižší váhou (LSW) jako první:
Proto je nutné v definici proměnné určit správné pořadí příchozích dat:
Nastavení proměnné typu INT32 pro elektroměr EM23-DIN
Wordy jsou tedy po přijetí seřazeny tak, že první přijatý z nich (bajty 12) je brán jako LSW (least significant word, word s menší vahou), a druhý (bajty 34) jako MSW (most significant word, word s větší váhou). Klientské programy toto pořadí obvykle umí nastavit, ať už v podobě přepínačů s názvy „Hi-Lo“, „Reverse byte / word order“, „Word rotate“ atd., nebo přímým uvedením pořadí bajtů u definice proměnné. Tak je tomu např. u Merbon IDE, jak vidíme na obrázku výše.
Float podle IEEE 754
Standard IEEE 754 definuje mimo jiné reprezentaci hodnot s pohyblivou řádovou čárkou (float) pro 32bitový a 64bitový formát. U základní přesnosti, 32 bitů, je rozdělení bitového prostoru následující:
- 1 bit znaménko,
- 8 bitů exponent,
- 23 bitů mantisa.
Exponent a mantisa jsou ještě dále kódovány, ale to nás nemusí zajímat. Podstatné je, že do výpočtu musí načtená data vstupovat ve správném pořadí wordů a bajtů. Jak toho docílit na Modbusu, který pracuje s šestnáctibitovými registry?
Podobně jako u dlouhých integerů, pro 32bitové číslo zabere jedna hodnota dva 16bitové registry. Problém je v tom, že řazení registrů (a někdy i bajtů v registru) nemusí být v dokumentaci jednoznačně popsáno. Pokud se v klientském programu nepodaří dodržet stejné řazení bajtů a registrů jako na serveru, vyčtená hodnota je v lepším případě neplatná (nedodržuje předepsaný formát), což je vidět na první pohled, v horším nesmyslná. I když modbusová tabulka někdy správné pořadí popisuje, otázka je, zda klientský program používá stejnou terminologii. Obvykle je nejrychlejší řešení čtení prostě vyzkoušet.
V následující tabulce jsou přenášeny tři teploty jako 32bitové proměnné typu real. Každá tedy zabírá dva modbusové registry:
reg. 1 a 2: 21.7
reg. 3 a 4: 22.3
reg. 5 a 6: 20.1
Tři 32bitové hodnoty typu real
Komunikace přes Modbus TCP v hexadecimálním tvaru pro čtení registrů 1 a 2 vypadá takto:
dotaz: | 05 | 6D | 00 | 00 | 00 | 06 | 01 | 03 | 00 | 00 | 00 | 02 | |
odpověď: | 05 | 6D | 00 | 00 | 00 | 07 | 01 | 03 | 04 | 41 | AD | 99 | 9A |
Tučně je znázorněn obsah obou vyčtených registrů. Vidíme, že v telegramu přijde nižší registr (obsahující hodnotu 41 AD, v zelené tabulce s číslem 1) jako první a bajty jsou srovnány v pořadí vyšší – nižší. Tomu musí odpovídat i pořadí bajtů v Merbon IDE:
Zadávání pořadí bajtů u proměnné v Merbon IDE
Výše uvedenému standardnímu pořadí „po sběrnici přijde nejprve registr s nižším číslem, který obsahuje významnější word, v každém registru je nejprve jeho vyšší bajt“ odpovídá řetězec „1234“. Říká, že ve stejném pořadí, v jakém data přicházejí po sběrnici, jsou řazena do paměti proměnné datového typu float.
Dalším příkladem je vyčítání teploty z modulu Papago 2PT_ETH (v dotazu se čte 5 registrů najednou, nás zajímá 3. a 4. v pořadí):
dotaz: | 05 | 53 | 00 | 00 | 00 | 06 | 01 | 04 | 00 | 6E | 00 | 05 | |||||||
odpověď: | 05 | 53 | 00 | 00 | 00 | 0D | 01 | 04 | 0A | 00 | 00 | 00 | F6 | 41 | C5 | 21 | 52 | 00 | 00 |
Dva registry, reprezentující teplotu na vstupu 2, jsou vyznačeny tučně. Stejně jako v předchozím případě, v nižším registru (přijde jako první) je významnější word (41 C5), ve vyšším registru je méně významný word (21 52). Měřená hodnota je 24.641 °C. Můžeme ji pro kontrolu spočítat třeba některým z internetových kalkulátorů nebo programem pro konverzi hodnot podle IEEE 754. Pořadí je tedy standardní, není třeba nic prohazovat a Multibyte Order by byl opět „1234“.
Stejně tak má registry řazeny například měřič proudu PowerLogic BCPM, který v dokumentu s popisem modbusové tabulky uvádí:
PowerLogic BCPM – popis formátu hodnot Float
V samotné tabulce jsou pak uvedena čísla registrů pro MSW a LSW:
PowerLogic BCPM – výřez z modbusové tabulky
MSW je v nižším registru, přijde jako první, i zde by tedy Multibyte Order byl „1234“.
Někdy výrobce jen upřesní pořadí registrů (wordů) v poznámce:
Modbusová tabulka elektroměrné sondy QI-POWER-485, QEED / DEM
Tady ovšem přichází jako první v pořadí word s nižší váhou (LSW), Multibyte Order je tedy „3412“ – wordy musí být do paměti ukládány v opačném pořadí. Pořadí bajtů v rámci wordu zůstává zachováno.
Při zadávání počátečního registru proměnné musíme dát pozor na to, zda server používá číslování od 0 nebo od 1. Pokud by za sebou následovaly numericky podobné hodnoty, jako například několik teplot v místnostech nebo napětí u tří fází elektroměru, může dojít k omylu. Správné seskupování do 32bitových proměnných je na následujícím obrázku vlevo. Jestliže bychom při experimentování proměnnou typu real omylem četli z registrů 2 a 3, jako je tomu na obrázku vpravo, a zároveň se prohodilo pořadí wordů (tedy MultiByte order by byl 3412), vyčtené číslo bude 22.325, což může působit dojmem, že se jedná o platnou hodnotu. Jde ale o chybnou úvahu, celá komunikace by pak nefungovala správně.
Vlevo: správné řazení, vpravo: chybné řazení
U 64bitových registrů je problematika obdobná, výchozí pořadí multibyte je „12345678“, tedy nejdřív přijdou nižší registry, v každém registru jde významnější bajt jako první. Hodnoty zpracováváme proměnnou typu lreal (long real), který představuje 64bitové číslo v pohyblivé řádové čárce.
Vlastní Float
Někteří výrobci, jako např. Gossen-Metrawatt, zvolili pro své přístroje vlastní – nestandardní – formát hodnoty s pohyblivou řádovou čárkou. U elektroměru U228X najdeme v dokumentaci následující popis:
Gossen-Metrawatt U228X, popis formátu okamžitých hodnot
V jednom 16bitovém registru je základ (mantisa) jako celé číslo se znaménkem a v druhém je v tomtéž formátu exponent. V tomto případě nejspíš modbusový klient (SCADA nebo programovací prostředí pro PLC) nebude mít takovou transformaci předdefinovanou a k výsledku se musíme dobrat vyčtením každé hodnoty zvlášť a jejich následným zpracováním v aplikačním programu podle výše uvedeného příkladu z dokumentace.
Zpracování hodnoty ze dvou registrů v Gossen-Metrawatt „formátu typu 1“.
Nelze spoléhat na to, že se exponent nemění, a zjednodušit si práci prostým vydělením hodnoty z prvního registru deseti. Tento postup by představoval hazard, který by se mohl projevit chybou i po několika letech bezproblémového provozu, v situaci, kdy to očekáváme nejméně.
Pokud bychom podobných hodnot četli několik desítek, určitě se vyplatí napsat si vlastní transformaci v podobě funkčního bloku nebo lépe ST funkce, pokud to vývojové prostředí dovolí. Hodnotu by pak bylo možné číst jako jednu 32bitovou proměnnou, obsaženou ve dvou registrech. Tato proměnná by sama o sobě nedávala smysl a musela by projít transformací:
- rozložit na dvě 16bitové proměnné, mantisu a exponent,
- umocnit konstantu 10 na hodnotu exponentu,
- výsledek znásobit mantisou.
Ještě komplikovaněji to vyřešila Toshiba u svého staršího komunikačního rozhraní TCB-IFMB640TLE. Používá 16bitový float formát, který v transformacích u vývojových prostředí nejspíše opravdu nenajdeme. Na rozdíl od standardu IEEE 754 half-precision binary floating-point format, který má pro exponent vyhrazeno 5 bitů, jsou zde pro exponent určeny bity čtyři:
Toshiba, implementace 16bit Float v TCB-IFMB640TLE
V tomto případě by bylo nutné buď napsat vlastní funkci ve strukturovaném textu nebo jiném skriptovacím jazyku, případně rozebrat obsah registru na jednotlivé bity a z nich pak počítat mantisu a exponent a komplikovaně skládat výslednou teplotu.
Právě tento příklad ukazuje, jak je důležité už v projekční fázi prozkoumat i formáty analogových hodnot a nespokojit se s ujištěním, že zařízení „komunikuje po Modbusu“, protože tento problém může znamenat přinejmenším více práce pro aplikačního programátora, v horším případě pak nepřekonatelnou překážku při uvádění zařízení do provozu.
Domat Control System s.r.o. patří k evropské špičce dodavatelů řídicích systémů a regulací pro inteligentní budovy, průmysl a energetiku. Cílem této ryze české společnosti je vyvíjet, vyrábět a dodávat řídící systémy v mezinárodním měřítku.