====== Připojení skrze protokol Modbus ====== Jedním z nejčastějších úkonů ve vývoji průmyslové automatizace je nastavení komunikace za pomoci komunikačního protokolu Modbus. ;;# Patron \\ Neuron \\ Gate \\ Unipi 1.1 \\ Axon ;;# ===== Připojení se k Modbus RTU slave zařízení ===== Pro účely tohoto tutoriálu předpokládejme, že jste v **Plném módu** vytvořili jednoduchý projekt. K projektu máte připojený kontrolér, vytvořili jste **spustitelný projekt** s jedním **FBD** programem a daný program je nastavený jako **task**. Rovněž předpokládejme, že jste na kontroléru provedli **nastavení Autogenu** a jak **kompilace**, tak i **nahrání** sestavy proběhlo bez problémů. Pokud jste provedli vše výše uvedené, vaše pracovní plocha by měla vypadat zhruba takto: {{ :en:sw:01-mervis:connecting-to-modbus-slave-01-workspace.png?direct |}} K nastavení komunikace přes protokol Modbus RTU je zapotřebí nejprve vytvořit odpovídající kanál. Klikněte pravým tlačítkem na **PLC** a v kontextovém menu klikněte na **Přidat kanál**. {{ :en:sw:01-mervis:connecting-to-modbus-slave-02-add-channel.png?direct |}} V levém panelu se pod PLC objeví nový kanál nazvaný **channel**. Vyberte jej a v panelu **Vlastnosti** změňte jeho název na něco lépe vyjadřující účel kanálu. Jelikož bude kanál použit ke komunikaci přes Modbus RTU, nejlepší volbou bude nazvat jej **ModbusRTU**. {{ :en:sw:01-mervis:connecting-to-modbus-slave-03-channel-name.png?direct |}} Ve stejném panelu vyberte z rozbalovacího menu protokol Modbus. {{ :en:sw:01-mervis:connecting-to-modbus-slave-04-channel-protocol.png?direct |}} **Linkový protokol** je ve výchozím stavu nastaven na **Serial**, zde je proto třeba pouze nastavit správné **Parametry sériové linky**. Z rozbalovacího menu **Číslo portu** vyberte správný port. {{ :en:sw:01-mervis:connecting-to-modbus-slave-05-serial-line-parameters.png?direct |}} Zbytek **parametrů sériové linky** pak musí být nastaven zcela identicky jako u všech zařízení, která jsou k sériové sběrnici připojena. {{ :en:sw:01-mervis:connecting-to-modbus-slave-06-serial-line-parameters.png?direct |}} Kanál ModbusRTU je tím nastaven. Nyní můžeme přidat zařízení, se kterými budeme chtít komunikovat. V **levém panelu** na kanál klikněte a v kontextovém menu vyberte **Přidat zařízení**. {{ :en:sw:01-mervis:connecting-to-modbus-slave-07-add-modbusrtu-device.png?direct |}} Pod kanálem se objeví nové zařízení. Vyberte jej a v panelu **Vlastnosti** jej přejmenujte na více popisný název. Ve stejném panelu je rovněž třeba zadat správnou Modbus adresu zařízení. {{ :en:sw:01-mervis:connecting-to-modbus-slave-08-modbusrtu-device-name.png?direct |}} Název by měl odrážet účel či umístění zařízení, nikoliv pouze tovární označení. Pokud chcete odečítat údaje z rozvaděče vybaveného více elektroměry, doporučujeme každý z nich pojmenovat podle okruhu, na kterém provádí měření, tj. například **energyMeterL1**. ===== Konfigurace ===== Na předchozích řádcích jsme provedli základní konfiguraci Modbus RTU zařízení a nyní se můžeme pustit do složitějšího úkolu - mapy registrů. Dvojitě klikněte na název nově přidaného zařízení. Na **hlavním panelu** se objeví prázdný seznam Modbusových registrů. {{ :en:sw:01-mervis:connecting-to-modbus-slave-09-modbus-register-map.png?direct |}} Hodnoty Modbusových slave zařízení jsou "sdíleny" skrze registry (vyjádřené v 16-bitových hodnotách) či coily (pouze jednobitové stavy). Abychom ze slave zařízení mohli tyto hodnoty vyčítat, musíme nejprve nadefinovat, jaké registry chceme vyčítat a jak je budeme převádět na proměnné použitelné později. Nyní je na čase představit si Modbus RTU zařízení, ze kterého budeme data odečítat: chytrý elektroměr Inepro PRO1-Mod. {{ :en:sw:01-mervis:inepro-pro1-mod.jpg?direct&500 |}} Jako první krok doporučujeme pročíst si {{ :en:sw:01-mervis:pro1-user-manual-v2.18.pdf|manuál}}. Informace z něj jsme již využily - rychlost a nastavení sériové linky má být 9600 bps s 8 datovými bity, sudou paritou a jedním stop bitem. Výchozí Modbus adresa je dle manuálu **1**, náš elektroměr je ale nastavený na **31**. V manuálu se dozvíte i to, jak toto číslo získat přímo z elektroměru. Na straně 25 naleznete kompletní seznam registrů Modbus, jejich adresy, hodnoty a velikosti. Jako první budeme vyčítat proudové napětí. {{ :en:sw:01-mervis:connecting-to-modbus-slave-11-registers-map.png?direct |}} Zde se věci naneštěstí rapidně komplikují, především kvůli široké škále způsobů implementace protokolu Modbus, které se mezi jednotlivými výrobci mohou výrazně lišit. Jak můžete vidět, adresy registrů jsou v šestnáctkové soustavě. Hodnota registru **Voltage** (tj. napětí) nám nepomůže, neboť adresa 5000 může být v šestnáctkovém i desítkovém formátu. Pokud se ale podíváte na registr **Current** (tj. proud), u zde přítomné hodnoty 500A poměrně snadno poznáte, že jde o šestnáctkový formát. Pro Modbusové registry Mervis IDE podporuje pouze desítkové hodnoty, hodnoty z manuálu proto budeme muset manuálně převést, a to za pomoci kalkulačky či programu MS Excel Dalším zrádným krokem je rozdíl mezi číslem registru a adresou registru. Čísla registrů začínají od jedničky, ale adresy registrů začínají od nuly. Mervis IDE dokáže čísla registrů využít, v manuálu k elektroměru ale používají adresy registrů. Sečteno a podtrženo, **adresa registru Voltage je 5000 v šestnáctkové soustavě**, což v desítkové soustavě činí 20480 a **číslo registru je tak 20481** (adresa + 1) V mnoha případech je těžké tyto hodnoty rozpoznat a manuál je příliš obecný. Budete se proto muset uchýlit k metodě pokus-omyl. Podívejme se nyní na to, jak můžeme registr **Voltage** přidat do Mervisu. Na **Hlavním panelu** by měl být vidět prázdný seznam registrů. Pokud ne, v **levém panelu** dvojitě klikněte na název zařízení. Pro zjištění hodnoty kteréhokoliv z registrů nejprve musíme přidat **skupinu**. Skupina obsahuje alespoň jeden registr, který může být přečten naráz a následně parsován do **datových bodů**. Tento způsob odpovídá tomu, jak Modbus pracuje, zvláště [[https://en.wikipedia.org/wiki/Modbus#Function_code_4_(read_input_registers)_and_function_code_3_(read_holding_registers)|funkčního kódu 4]]. Klikněte pravým tlačítkem na **Hlavní panel** a v kontextovém menu vyberte **Přidat skupinu** {{ :en:sw:01-mervis:connecting-to-modbus-slave-10-add-group.png?direct |}} Objeví se nová skupina s názvem **Skupina**, společně s ní také vznikly tři **datové body**. Klikněte na řádek se jménem **Skupina** a v panelu **Vlastnosti** název změňte na něco více popisného. Rozsah adres zvolíme dle manuálu k elektroměru (tj. 5000-5000B). V sekci **Vlastnosti skupiny** je třeba specifikovat číslo prvního registru neboli **počátečního prvku**. Jak jsme zjistili výpočtem výše, **počátečním prvkem** pro registr **Voltage** je 20481. Funkce je nastavena na **F03 Read Holding Register**. **Počet prvků** udává počet registrů, které chceme ze slave zařízení do skupiny vyčítat, abychom je mohli později převést na datové body. Vyberte číslo 12, neboť budeme později chtít zároveň odečítat **napětí**, **frekvenci** a **proud**. {{ :en:sw:01-mervis:connecting-to-modbus-slave-12-group-for-voltage.png?direct |}} Pro převod skupiny registrů na proměnné je třeba definovat **datový bod**. Klikněte pravým tlačítkem na prázdný prostor na **hlavním panelu** a v kontextovém menu klikněte na **Přidejte datový bod**. {{ :en:sw:01-mervis:connecting-to-modbus-slave-13-add-datapoint.png?direct |}} Na seznamu se objeví nový datový bod s názvem **IO**. Vyberte jej a v panelu **Vlastnosti** změňte jeho jméno na **Napětí**. {{ :en:sw:01-mervis:connecting-to-modbus-slave-14-datapoint-name.png?direct |}} Dalším krokem je určit **skupinu**, do které bude datový bod náležet. Vyberte skupinu **5000-5000B** z rozbalovacího menu sekce **Skupina**. {{ :en:sw:01-mervis:connecting-to-modbus-slave-15-datapoint-group.png?direct |}} Datový bod je reprezentovaný proměnnou, které musíme přiřadit nějaký typ. Jelikož napětí je obvykle vyjádřeno v reálných číslech, vyberte možnost **Builtin** z menu **Typ mapované kom. hodnoty**. {{ :en:sw:01-mervis:connecting-to-modbus-slave-16-mapped-variable-type.png?direct |}} Z rozbalovací nabídky **Typ ST** pak vyberte možnost **real**. {{ :en:sw:01-mervis:connecting-to-modbus-slave-17-st-type.png?direct |}} Abychom se nemuseli zabývat složitým vysvětlováním, do políčka **Délka MultiByte (Parser)** zadejte číslo 4. K tomuto políčku se vrátíme později. {{ :en:sw:01-mervis:connecting-to-modbus-slave-18-multibyte-length.png?direct |}} Po dokončení definice datového bodu je nyní na řadě vygenerování proměnných skrze funkci **Nastavit Autogen**. Klikněte pravým tlačítkem na zařízení v **levém panelu** a v kontextovém menu vyberte **Nastavit Autogen**. {{ :en:sw:01-mervis:connecting-to-modbus-slave-19-set-autogen.png?direct |}} Zobrazí se dialogové okno **Nastavit Autogen**, který potvrdťe kliknutím na **OK**. {{ :en:sw:01-mervis:connecting-to-modbus-slave-20-set-autogen-dialog.png?direct |}} Nyní můžete sestavu **zkompilovat** a **nahrát** do kontroléru. Pokud je vše v pořádku a program je spuštěn, klikněte na **Start ladění**, v **hlavním panelu** přepněte na **Prohlížeč proměnných** a vyhledejte **napětí**. Jedinou zobrazenou proměnnou by nyní měl být datový bod s aktuální výší napětí na lince. {{ :en:sw:01-mervis:connecting-to-modbus-slave-21-variable-browser.png?direct |}} Pro další část tutoriálu je nyní nutné zcela pochopit způsob, kterým jsme s **napětím** pracovali a jak v Modbusu vyjádřit různé datové typy. Modbus pracuje pouze se 16-bitovými registry (nyní na chvíli zapomeneme, že existují i "coily"). V jednom registru tak lze uložit pouze 65536 hodnot, které představují různé typy čísel. Může jít o neznačený integer v rozmezí 0-65535. Může jít o značený integer v rozsahu -32768-32767. Případně vůbec nemusíme používat všechny možné hodnoty a převedeme je na "char" číslo s hodnotou 0-255. Co když ale potřebujeme vyčítat údaje ze slave zařízení, které vyžaduje více než 16 bitů? K tomu bude zapotřebí více než jeden Modbusový registr a následně bude třeba v Mervisu provést transformaci dat. Přesně to jsme provedli s **napětím**. **Napětí** je zde reálné číslo vyžadující 32 bitů. V manuálu elektroměru se dozvíme, že jako datový typ je užit "float" a délka registru je 2. Neznamená to, že registr má jinou velikost než 16 bitů, nýbrž poukazuje na fakt, že **napětí** je uloženo ve dvou registrech - na adresách 5000H a 5001H. Abychom mohli hodnotu vyjádřit v Mervisu, bylo zapotřebí vyčítat dva registry a spojit je do jedné proměnné. Toto parsování více registrů do jednoho datového bodu (proměnné) probíhá na dvou úrovních. Nejprve je třeba Mervisu sdělit, aby četl více registrů naráz; to lze provést na úrovni **skupin**. Určili jsme **číslo prvního registru**, který chceme číst (**Počáteční prvek**) a počet registrů, ze kterých chceme od tohoto čísla vyčítat (úroveň **Skupiny**). Jak můžete vidět výše, začali jsme vyčítat od registru č. 20481 a čteme z dvanácti následujících 16 bitových registrů = 24 bytů. Dalším krokem je specifikování datového bodu **Napětí**. Tento datový bod navážeme na skupinu, aby z ní vyčítal údaje a převáděl je na určenou proměnnou. Abychom Mervis IDE sdělili, jaká data chceme použít, nastavíme **Parametry datového bodu Modbus**. Pro čtení dat ze skupiny do datového bodu je třeba nastavit **Offset dat (Parser)** a **Délka MultiByte (Parser)**. **Offset dat (Parser)** označuje první **byte** (nikoliv registr!) skupiny, zatímco **Délka MultiByte (Parser)** vyjadřuje počet **bytů**, které budou do dané proměnné parsovány. Jak můžete vidět, vybrali jsme první čtveřici bytů (Offset dat = 0, Délka MultiByte = 4), což odpovídá dvěma registrům (4×8 bit = 2×16 bit). Nastavením **typu ST** pak nastavíme transformaci tohoto 32 bitového datového prostoru na reálné číslo. Zní to poněkud komplikovaně, u dalšího datového bodu už Vám to ale bude o něco jasnější. Přidejme si nyní další datový bod - **Frekvence mřížky**. Jak můžete vidět v mapě Modbus registrů, **Frekvence mřížky** je na adrese 5008 a délka registru (či spíše délka hodnoty) je 2. To už víme, neboť námi nakonfigurovaná skupina **5000-500B** pokrývá i tyto registry. Díky tomů můžeme datový bod definovat přímo. Klikněte pravým tlačítkem do prázdného prostoru v záložce **energyMeterL1** a z kontextového menu vyberte **Přidat datový bod**. Objeví se nový datový bod, u kterého můžete nastavit jeho vlastnosti. Výsledek by měl vypadat zhruba takto: {{ :en:sw:01-mervis:connecting-to-modbus-slave-22-grid-frequency.png?direct |}} * Datový bod jsme nazvali **GridFrequency** * Určili jsme, že data budou vyčítána ze skupiny **5000-5000B** * **Typ mapované kom. hodnoty** je nastaven na **Builtin** a **Typ ST** je **real**. * **Offset dat (Parser)** = (adresa registru - adresa prvního registru ve skupině) × 2 = (5008H-5000H) × 2 = 16 * **Délka MultiByte (Parser)** je 4 (4 byty = 2 16 bitové registry) Jelikož jsme přidali nový datový bod, je třeba na zařízení **nastavit Autogen**. Následně **nahrajte sestavu**, zapněte **mód ladění** a na **hlavním panelu** se přepněte do **Prohlížeče proměnných**. Zde vyhledejte **energyMeterL1**. Výsledek by měl vypadat následovně: {{ :en:sw:01-mervis:connecting-to-modbus-slave-23-variable-browser.png?direct |}}