How to / Sterowanie i akwizycja danych

Protokół Modbus/RTU, czyli komunikacja na łączu szeregowym RS-485 w modułach ADAM - część 1/2

10.09.2015 Producent: Advantech Zastosowanie: Zakłady przemysłowe, Gaz i Paliwa
Wizerunek autora
Jarosław Molenda Inne artykuły tego autora
Protokół Modbus/RTU, czyli komunikacja na łączu szeregowym RS-485

    Zastosowanie w danym sprzęcie pomiarowym specjalizowanego protokołu, dedykowanego (opracowanego) tylko dla danej grupy produktów (np. własny protokół opracowany przez producenta i stosowany tylko w przypadku jego produktów), wiąże się często z ograniczonymi możliwościami zastosowania tegoż sprzętu. Budując/projektując nasz system automatyki i/lub pomiarów od samego początku możemy oczywiście wstępnie założyć konieczność zaimplementowania takiego protokołu komunikacyjnego w naszej aplikacji, lecz niestety nie zawsze istnieje taka możliwość. W zależności od rodzaju i stopnia elastyczności (całości czy nawet tylko pewnej części) naszego układu automatyki możemy bowiem napotkać ograniczenia w postaci zamkniętej listy możliwych do wykorzystania protokołów komunikacyjnych (np. w przypadku oprogramowania SCADA, wybranej przez nas rodziny sterowników programowalnych, osprzętu komunikacyjnego itp.), bez jakiejkolwiek możliwości jej rozszerzenia!

W przypadku większości oprogramowania klasy SCADA/HMI bardzo często pomocnym staje się tu standard wymiany danych OPC. Oczywiście tylko w przypadku, gdy także producent sprzętu przewidział wykorzystanie tegoż standardu do wymiany danych z urządzeniem i wraz ze sprzętem dostarcza dedykowany serwer OPC. Nie zawsze jest to jednak rozwiązanie optymalne. Natomiast w przypadku samego sprzętu (np. sterowników programowalnych, osprzętu komunikacyjnego itp., który chcemy "połączyć" z naszym sprzętem pomiarowym) uniwersalnego rozwiązania często po prostu nie ma. Przy projektowaniu naszego układu od podstaw jesteśmy oczywiście w stanie wystrzec się tego typu problemów poprzez odpowiedni dobór kompatybilnych ze sobą wszystkich podzespołów - bez tego oczywiście nie ruszymy. Jednakże przy projektowaniu takiego układu zobowiązani jesteśmy zazwyczaj (i jest to często warunek konieczny) także do zapewnienia możliwości rozbudowy czy pewnej jego rekonfiguracji. Zatem, by uniknąć w przyszłości tego typu problemów, już na samym początku powinniśmy iść w kierunku standardów - będzie to na pewno najbezpieczniejsze rozwiązanie.

Zgodnie z tym założeniem protokół Modbus zaimplementowano także w modułach pomiarowych (i sterujących) serii ADAM-4k/5k/6k, co oczywiście znacznie poszerza spektrum ich zastosowań. W zależności od wykorzystywanego medium transmisyjnego (komunikacja szeregowa / ethernetowa) skorzystać więc możemy z:

Typ Seria Grupa Przykłady
Modbus/RTU Seria ADAM-4000 Wybrane moduły I/O ADAM-4017+/4055/4068 ...
Seria ADAM-5000 Kasety komunikacyjne ADAM-5000E ...
Kasety programowalne ADAM-5550, APAX-5580 ...
Modbus/TCP
 
Seria ADAM-5000 Kasety komunikacyjne ADAM-5000/TCP ...
Kasety programowalne ADAM-5550, APAX-5580....
Seria ADAM-6000 Wszystkie moduły I/O ADAM-6017/6050/6060 ...
Seria ADAM-6200 Wszystkie moduły I/O ADAM-6217/6250/6260 ...
WISE-4000 Wszystkie moduły I/O WISE-4010/4050/4060/LAN

 

Dodatkowo: zaprojektowano także kilka urządzeń pracujących w trybie "Modbus Data Gateway", czyli - najprościej ujmując - pozwalających na współpracę między poszczególnymi odmianami protokołu Modbus (np. ADAM-4572, moduły serii EKI-122X).

Protokół ten (we wszystkich stosowanych obecnie implementacjach ASCII/RTU/TCP) wykorzystywany jest powszechnie do komunikacji pomiędzy poszczególnymi urządzeniami systemów automatyki oraz aplikacjami nadzoru i/lub sterowania pracującymi na komputerach PC z urządzeniami pomiarowymi i wykonawczymi. Opracowany pierwotnie przez firmę Modicon stał się standardem przyjętym przez większość znanych producentów sterowników przemysłowych i sprzętu pomiarowego. Należy on do rodziny protokołów typu master-slave, w których tylko jedno urządzenie (jednostka nadrzędna - master) może inicjować transakcje, a pozostałe (jednostki podrzędne - slave) odpowiadają jedynie na zdalne zapytania mastera. Transakcja składa się z polecenia (query) wysyłanego z jednostki master do slave oraz odpowiedzi (response) przesyłanej zwrotnie, zawierającej żądane dane lub potwierdzenie realizacji polecenia (wyjątkiem są wiadomości rozgłoszeniowe broadcast przeznaczone dla wszystkich jednostek podrzędnych w sieci, na które jednostki slave nie przesyłają żadnej odpowiedzi).


W przypadku protokołu Modbus/RTU przesyłane w obydwie strony wiadomości zorganizowane są w postaci ramek o czterech ściśle określonych polach:

ADDRESS FUNCTION CODE DATA CHECKSUM


W implementacji RTU dla zapytania mamy:

• ADDRESS [1 bajt] - określa do którego urządzenia wpiętego w sieć (tu RS-485) adresowane jest zapytanie
• FUNCTION CODE [1 bajt] - określa kod funkcji/zapytania
• DATA [różnej długości] - przekazuje parametry wejściowe wywoływanej funkcji
• CHECKSUM [2 bajty] - stanowi sumę kontrolną

Dla odpowiedzi:

• ADDRESS [1 bajt] - określa adres urządzenia slave odpowiadającego na zapytanie
• FUNCTION CODE [1 bajt] - określa kod funkcji/zapytania z zapytania
• DATA [różnej długości] - przekazuje parametry wynikowe funkcji
• CHECKSUM [2 bajty] - stanowi sumę kontrolną

Najczęściej wykorzystywane funkcje (spośród wielu dostępnych ściśle zdefiniowanych w standardzie) przedstawiono w poniższej tabeli:

Function code Function description
0x01 Read Coils
0x02 Read Discrete Inputs
0x03 Read Holding Registers
0x04 Read Input Registers
0x05 Write Single Coil
0x06 Write Single Register
0x08 Loopback Diagnostic
0x0F Write Multiple Coils
0x10 Write Multiple Registers

 

Oprócz znajomości kodów i struktury poszczególnych funkcji Modbus potrzebne są nam jeszcze adresy rejestrów. W przypadku modułów pomiarowych serii ADAM możemy je znaleźć w dokumentacji lub odczytać za pomocą ADAM.NET Utility. Dla najpopularniejszych modułów serii ADAM-4000 - czyli modułu wejść analogowych ADAM-4017+ i modułu we/wy cyfrowych ADAM-4055 będą to następujące wartości:

ADAM-4017+   ADAM-4055
Analog Inputs   Digital Inputs
40001 AI-0 R   00001 DI-0 R
40002 AI-1 R   00003 DI-1 R
... ... ...   ... ? ...
40008 AI-7 R   00008 DI-7 R
Analog Inputs Types   Digital Outputs
40201 AI-0 typ R/W   00017 DO-0 R/W
40202 AI-1 typ R/W   00018 DO-1 R/W
... ... ...   ... ? ...
40208 AI-7 typ R/W   00024 DO-7 R/W
Module Info   Module Info
40211 Name-1 R   40211 Name-1 R
40212 Name-2 R   40212 Name-2 R
40213 Firmware-1 R   40213 Firmware-1 R
40214 Firmware-2 R   40214 Firmware-2 R

 


Korzystając z tych informacji możemy już budować strukturę naszych zapytań Modbus/RTU. Na początek skorzystamy z funkcji 0x04 - Read input Registers. Struktura jej zapytań i stosownych odpowiedzi, zgodnie ze standardem Modbus wygląda następująco:

Read input Registers - struktura zapytania
FUNCTION CODE 1 bajt 0x04
DATA Starting Address 2 bajty 0x0000-0xFFFF
Quantity of Input Registers (N) 2 bajty 0x0001-0x007D

 

Read input Registers - struktura odpowiedzi
FUNCTION CODE 1 bajt 0x04
DATA Byte Count 1 bajt 2xN
Input Registers Nx2 bajtów -


Przykładowe transakcje będą więc wyglądały następująco:

• Odczyt nazwy urządzenia i wersji firmware dla modułu ADAM-4017+:

01 04 00-D2 00-04 E4-30 odp. 01 04 08 40-17-50-00-A2-02-00-00 C9-14


• Odczyt wartości wejścia analogowego AI-0 dla modułu ADAM-4017+:

01 04 00-00 00-01 31-CA odp. 01 04 02 E5-F9 33-E2

 


Do ustawienia pojedynczego wyjścia cyfrowego skorzystamy z funkcji 0x05 - Write Single Coil:

Write Single Coil - struktura zapytania
FUNCTION CODE 1 bajt 0x05
DATA Output Address 2 bajty 0x0000-0xFFFF
Output Value 2 bajty 0x0000 / 0xFF00

 

Write Single Coil - struktura odpowiedzi
FUNCTION CODE 1 bajt 0x05
DATA Output Address 2 bajty 0x0000-0xFFFF
Output Value 2 bajty 0x0000 / 0xFF00


Przykładowe transakcje - włączenie i wyłączenie wyjścia cyfrowego DO-0 w module ADAM-4055 - będą więc wyglądały następująco:

02 05 00-10 FF-00 8D-CC odp. 02 05 00-00 FF-00 8C-09

 

02 05 00-10 00-00 CC-3C odp. 02 05 00-00 00-00 CD-F9

 


Do ustawienia kilku wyjść cyfrowych (jedną transakcją) skorzystamy funkcji 0x0F - Write Multiple Coils:

Write Multiple Coils - struktura zapytania
FUNCTION CODE 1 bajt 0x0F
DATA Starting Address 2 bajty 0x0000-0xFFFF
Quantity of Outputs 2 bajty 0x0001-0x07B0
Byte Count 1 bajt N
Outputs Value N bajtów -

 

Write Multiple Coils - struktura odpowiedzi
FUNCTION CODE 1 bajt 0x0F
DATA Starting Address 2 bajty 0x0000-0xFFFF
Quantity of Outputs 2 bajty 0x0001-0x07B0


Przykładowe transakcje - włączenie i wyłączenie wszystkich wyjść cyfrowych w module ADAM-4055 - będą więc wyglądały następująco:

02 0F 00-10 00-08 01 FF 3F-03 odp. 02 0F 00-00 00-08 54-3E

 

02 0F 00-10 00-08 01 00 7F-43 odp. 02 0F 00-00 00-08 54-3E

 


Do odczytu stanu wejść cyfrowych skorzystamy z funkcji 0x02 - Read Discrete Inputs:

Read Discrete Inputs - struktura zapytania
FUNCTION CODE 1 bajt 0x02
DATA Starting Address 2 bajty 0x0000-0xFFFF
Quantity of Inputs 2 bajty 0x0001-0x007D

 

Read Discrete Inputs - struktura odpowiedzi
FUNCTION CODE 1 bajt 0x02
DATA Byte Count 1 bajt N
Inputs Status N bajtów -


Przykładowa transakcja - odczyt stanu wszystkich wejść cyfrowych w module ADAM-4055 - będzie więc wyglądała następująco:

02 02 00-00 00-08 79-FF odp. 02 02 01 AA 21-B3

 


UWAGA: W przedtawionych wyżej przykładach, w każdej z komend (zgodnie ze standardem Modbus) występują dwa kończące bajty reprezentujące sumę kontrolną CRC. Do jej wygenerowania (algorytm jest bardziej złożony niż np. w przypadku protokołu ADAM-ASCII) skorzystać możemy np. z poniższej funkcji (Pascal/Delph):

procedure GenerateModbusCRC(var modbus_command:string);
var CRC:word;
bajt,bit:byte;
LSB:byte;
begin
  CRC:=$FFFF;
  for bajt:=1 to length(modbus_command) do
    begin
    CRC:=CRC xor ord(modbus_command[bajt]);
    for bit:=1 to 8 do
      begin
      LSB:=CRC and $0001;
      if LSB=1 then CRC:=CRC-1;
      CRC:=CRC shr 1;
      if LSB=1 then CRC:=CRC xor $A001;
      end;
    end;
  modbus_command:=modbus_command+chr(CRC and $00FF)+chr((CRC and $FF00) shr 8);
end;

Na podstawie przedstawionych powyżej danych i przykładów (oraz oczywiście po sięgnięciu do dokumentacji protokołu Modbus) możemy jak widać we własnym zakresie - od podstaw - zorganizować komunikację naszej aplikacji z modułami pomiarowymi ADAM - w oparciu o bezpośrednią obsługę łącza szeregowego. Nie jest to sprawa trywialna - trzeba pamiętać o pewnych dodatkowych, nie opisanych wyżej właściwościach protokołu Modbus, oraz - co bardzo ważne - odpowiednio zaimplementować obsługę błędów. Na szczęście nie zawsze jesteśmy do tego zmuszeni - z pomocą przychodzi nam zazwyczaj implementacja protokołu w systemach SCADA/HMI, plus szeroka dostępność serwerów OPC (pozycja taka występuje także w ofercie Advantech). Jednakże znajomość struktury tegoż protokołu będzię zapewne pomocna także i w takim przypadku...


Ciąg dalszy w drugiej części artykułu "Protokół Modbus/TCP, czyli komunikacja w sieci Ethernet z modułami ADAM i nie tylko".