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 urzadzenia. 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 |
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 | odp. | 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 | odp. | 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 | odp. | 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 | odp. | 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 | odp. | 45-72-00-00-00-06 | 01 | 05 | 00-20 | 00-00 |
45-72-00-00-00-06 | 01 | 05 | 00-20 | FF-00 | odp. | 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 | odp. | 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 |
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:
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)+chr($00);
//WYSŁANIE KOMENDY (ZAPYTANIA)
Clientsocket1.Socket.SendText(komenda);
//ZERWANIE POŁĄCZENIA
Clientsocket1.Close;
end;
Skontaktuj się ze specjalistą Elmark
Masz pytania? Potrzebujesz porady? Zadzwoń lub napisz do nas!