Protokół Modbus RTU ADAM

background image

Protokół Modbus/RTU

Czyli komunikacja na łączu szeregowym RS-485


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

background image

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

-> 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

-> 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

-> 02

05

00-00

FF-00

8C-09


02

05

00-10

00-00

CC-3C

-> 02

05

00-00

00-00

CD-F9

background image

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

-> 02

0F

00-00

00-08

54-3E


02

0F

00-10

00-08

01

00

7F-43

-> 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

-> 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;

background image

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ędzie zapewne
pomocna także i w takim przypadku...

background image

Protokół Modbus/TCP

Czyli komunikacja w sieci Ethernet

W implementacji TCP/IP zrezygnowano z pola adresowego (w odwołaniach Modbus/TCP adres
urządzeń, do których kierowane jest zapytanie jednoznacznie określa już przy samym nawiązywaniu
połączenia docelowy adres IP) i sumy kontrolnej. Wprowadzono natomiast rozszerzony nagłówek MBAP
(Modbus Application Protocol Header) zawierający cztery pola:

identyfikator transakcji (2 bajty) - wykorzystywany przez urządzenie master do prawidłowego
kojarzenia odpowiedzi uzyskiwanych na jego kolejne zapytania (wartość ta zostaje ustalona i umieszczona
w ramce zapytania przez jednostkę master, a następnie skopiowana i umieszczona w ramce odpowiedzi
przez jednostkę slave)
identyfikator protokołu (2 bajty) - pole to ma zawsze wartość 0 odpowiadającą oznaczeniu protokołu
Modbus
rozmiar wiadomości (2 bajty) - liczba pozostałych bajtów wiadomości (poczynając od pola identyfikatora
urządzenia; pole to zostało wprowadzone ze względu na możliwość dzielenia pojedynczej wiadomości na
oddzielne pakiety TCP/IP)
identyfikator urządzenia (1 bajt) - odgrywający znaczenie np. w przypadku komunikacji z urządzeniami
Modbus wyposażonymi w interfejs szeregowy za pomocą bram (Modbus Data Gateway)

Odnośnie wykorzystywanych funkcji i ich parametrów: obowiązują oczywiście te przedstawione
wcześniej - jak w przypadku implementacji RTU (np. dla modułów serii ADAM-4000). Podobnie jak w
przypadku Modbus/RTU musimy oczywiście także posiadać informacje na temat listy adresów rejestrów
naszego urządzenia. Dla dwóch najpopularniejszych reprezentantów serii ADAM-6000 i wybranych ich
rejestrów będą to:

ADAM-6017
40001-40008 AI0-AI7 Current Value

R

40011-40018 AI0-AI7 Max Value

R

40021-40028 AI0-AI7 Min Value

R

00101-00108 AI0-AI7 Max Value Reset R/W
00111-00118 AI0-AI7 Min Value Reset R/W
00131-00138 AI0-AI7 HI Alarm Flag

R

00141-00148 AI0-AI7 LO Alarm Flag

R


ADAM-6060
00001-00006 DI0-DI5

R

00017-00022 DO0-DO5

R/W

40001

CNT0

R (32bit)

00033

CNT0 Start[1]/Stop[0]

W

00034

CNT0 Clear[1]

W


background image

W przypadku kasety komunikacyjnej ADAM-5000/TCP adresy przypisane są natomiast do poszczególnych
jej slotów:

Slot number Analog I/O

Digital I/O

0

40001÷40008 00001÷00016

1

40009÷40016 00017÷00032

2

40017÷40024 00033÷00048

3

40025÷40032 00049÷00064

4

40033÷40040 00065÷00080

5

40041÷40048 00081÷00096

6

40049÷40056 00097÷00112

7

40057÷40064 00113÷00128


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

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

45-72-00-00-00-06 01 03 00-00 00-01

-> 45-72-00-00-00-05 01 03 02 B8-FA


• Odczyt stanu DI2-DI5 w module ADAM-6060:

45-72-00-00-00-06 01 02 00-02 00-04

-> 45-72-00-00-00-04 01 02 01 0F


• Odczyt zawartości licznika CNT0 (DI0) w module ADAM-6060:

45-72-00-00-00-06 01 03 00-00 00-02

-> 45-72-00-00-00-07 01 03 04 00-19-00-00


• Skasowanie zawartości licznika CNT0 (na DI0) w module ADAM-6060:

45-72-00-00-00-06 01 05 00-21 FF-00

-> 45-72-00-00-00-06 01 05 00-21 FF-00


• Wyłączenie/włączenie licznika CNT0 (na DI0) w module ADAM-6060:

45-72-00-00-00-06 01 05 00-20 00-00

-> 45-72-00-00-00-06 01 05 00-20 00-00

45-72-00-00-00-06 01 05 00-20 FF-00

-> 45-72-00-00-00-06 01 05 00-20 FF-00


• Ustawienie wartości 7.000V dla wyjścia analogowego A03 w module ADAM-5024 (slot 2 kasety ADAM-
5000/TCP
):

45-72-00-00-00-06 01 06 00-13 0B-32

-> 45-72-00-00-00-06 01 06 00-13 0B-32

gdzie:

- adres rejestru pobrany ze schematu adresowania (40020 -> 0x0013)
- wartość docelowa rejestru obliczona jako 7/10*4095=2866=0x0B32
- wykorzystana nie opisana tutaj dotychczas funkcja 0x06 - Write Single Register:

Write Single Register - struktura zapytania
FUNCTION CODE

1 bajt

0x06

DATA

Register Address

2 bajty 0x0000-0xFFFF

Register Value

2 bajty 0x0000-0xFFFF

Write Single Register - struktura odpowiedzi
FUNCTION CODE

1 bajt

0x06

DATA

Register Address

2 bajty 0x0000-0xFFFF

Register Value

2 bajty 0x0000-0xFFFF

background image

Na podstawie powyższych informacji możemy już ponownie próbować zaimplementować ten protokół w
naszej aplikacji. Nasza bardzo prosta procedura ustawiająca wyjście cyfrowe DO-0 w module ADAM-
6060
o adresie IP=192.168.2.130, korzystająca z gotowej kontrolki ClientSocket mógłaby więc wyglądać
następująco:

procedure DO0ON;

var start,aktu:word;
komenda:string;
begin
//KONFIGURACJA GNIAZDA
Clientsocket1.Address:='192.168.2.130';
Clientsocket1.Port:=502;
//NAWI

ĄZANIE POŁĄCZENIA

Clientsocket1.Open;
start:=gettickcount;
repeat
aktu:=gettickcount;
Application.ProcessMessages;
until (aktu-start>500)or(Clientsocket1.Socket.Connected=true);
if aktu-start>500 then
begin
ShowMessage('Po

łączenie nie zostało nawiązane...');

exit;
end;
//KOMENDA=MBAP+ID+FUNCTIONCODE+DATA
komenda:=chr($AA)+chr($BB)+chr($00)+chr($00)+chr($00)+chr($06)+chr($01)+chr($05)+chr($00)+chr($10)+chr($FF)+c
hr($00);
//WYS

ŁANIE KOMENDY (ZAPYTANIA)

Clientsocket1.Socket.SendText(komenda);
//ZERWANIE PO

ŁĄCZENIA

Clientsocket1.Close;
end;


Wyszukiwarka

Podobne podstrony:
MODBUS RTU, PLC Fatek -HMI Weintek, Fatek
mFAQ 3 5 Komunikacja MODBUS RTU
Protok c3 b3 c5 82+Modbus
Biblioteka Modbus master RTU Modbus master e
Protokół ADAM
Wykład12 Sieć z protokołem X 25 i Frame Relay
Wykład10a Sieć z protokołem X 25 i Frame Relay
05 LAN Protokol IPid 5733 ppt
Protokół o zapobieganiu, zwalczaniu oraz karaniu handlu ludźmi
protokol2
PROTOKOL DYPLOMATYCZNY manulas MBak
II seria, Protokól 11ME wersjab
3 Wzm operacyjny protokol zima
ćw 10 tabelki do protokołu
Protokół sekcji zagadnienia

więcej podobnych podstron