Protokół Modbus (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.
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).
Struktura ramki w protokole Modbus/RTU
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 |
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".
Skontaktuj się ze specjalistą Elmark
Masz pytania? Potrzebujesz porady? Zadzwoń lub napisz do nas!