Modbus RTU - Programowanie od podstaw i diagnostyka błędów

Leonard Wojciechowski .

20 kwietnia 2026

Laptop z logo Modbus i napisem "rysuje SCADA". Program do komunikacji Modbus RTU.

Dobry program do Modbus RTU nie zaczyna się od samego wysyłania bajtów, tylko od zrozumienia magistrali, ramek i tego, jak urządzenia naprawdę odpowiadają na żądania. W tym tekście pokazuję, jak ułożyć komunikację krok po kroku, jakie parametry ustawić, gdzie najczęściej pojawiają się błędy i jak diagnozować problemy bez zgadywania.

Najważniejsze rzeczy, które trzeba ustawić od razu

  • W RTU liczy się poprawny format portu, CRC16, adres urządzenia i przerwy czasowe między ramkami.
  • Na jednej magistrali jeden klient inicjuje zapytania, a urządzenia odpowiadają po kolei, bez równoległych transakcji.
  • Najczęstsze ustawienia startowe to 9600 lub 19200 bodów, 8E1 i RS-485 w topologii liniowej.
  • Adres 0 oznacza broadcast, więc program nie powinien oczekiwać odpowiedzi po zapisie rozgłoszeniowym.
  • Wiele problemów wynika nie z kodu, tylko z okablowania, terminacji i złego mapowania rejestrów.

Jak działa komunikacja RTU, zanim napiszesz pierwszą linię kodu

W RTU wszystko opiera się na prostej zasadzie: jedno urządzenie inicjuje pytanie, drugie odpowiada. W nowszych materiałach Modbus Organization opisuje ten model jako client/server, choć w automatyce nadal często słychać stare określenia master/slave. Dla programu oznacza to jedno: trzeba pilnować kolejności żądań, adresowania i czasu odpowiedzi, bo magistrala nie wybacza chaosu.

Ramka RTU ma stałą logikę: adres, kod funkcji, dane i CRC16 na końcu. Dokumentacja dla serial line podaje też bardzo konkretne reguły czasowe: między ramkami musi być cisza trwająca co najmniej 3,5 znaku, a przerwa dłuższa niż 1,5 znaku wewnątrz ramki oznacza błąd i taką wiadomość należy odrzucić. To jeden z powodów, dla których program do Modbus RTU nie może być napisany jak zwykły „send and forget”.

Typ danych Kody funkcji Zakres adresów widziany przez człowieka Uwagi praktyczne
Coils 01, 05, 15 00001–09999 Bitowe wyjścia, zwykle zapis i odczyt stanu.
Discrete inputs 02 10001–19999 Wejścia tylko do odczytu.
Input registers 04 30001–39999 Rejestry 16-bitowe, tylko odczyt.
Holding registers 03, 06, 16 40001–49999 Najczęstszy obszar konfiguracji i nastaw.

W praktyce ważny jest jeszcze jeden szczegół: w ramce wysyła się zwykle adres względny, a nie „ludzki” numer z zakresu 40001 czy 30001. To właśnie tu najczęściej rodzą się pomyłki, bo programista widzi w dokumentacji 40011, a w pakiecie powinien wysłać adres 10. Kiedy to uporządkuję na początku, reszta pracy staje się dużo prostsza.

Schemat magistrali szeregowej Modbus RTU z serwerami i klientem.

Jak zbudować program do Modbus RTU krok po kroku

Ja zwykle zaczynam od trzech rzeczy: ustawień portu, mapy rejestrów i czasu odpowiedzi. Bez tego nawet poprawnie napisana biblioteka niewiele da, bo urządzenie może milczeć tylko dlatego, że program wysyła zapytanie z inną parzystością albo pod zły adres.

Konfiguruję port szeregowy

Najbezpieczniejszy punkt startowy to ustawienia zgodne z dokumentacją urządzenia, a jeśli jej nie ma pod ręką, to najczęściej 9600 bodów, 8E1 i interfejs RS-485. Taki zestaw daje 11 bitów na znak i dobrze pasuje do typowych sterowników, liczników oraz falowników. Gdy urządzenie wymaga 19200 bodów lub innej parzystości, przepisuję to 1:1, zamiast zgadywać.

Składam ramkę bez zgadywania adresów

Do własnego kodu lub biblioteki sprowadzam tylko to, co naprawdę trzeba wysłać. Struktura zapytania wygląda zwykle tak:

[adres urządzenia][kod funkcji][adres startowy_hi][adres startowy_lo][ilość_hi][ilość_lo][CRC_lo][CRC_hi]

Nie warto dorabiać tu „inteligencji” na siłę. Jeśli chcę odczytać jeden holding register, używam funkcji 03. Jeśli zapisuję pojedynczą wartość, sięgam po 06. Jeśli przenoszę większy blok danych, używam 16. Zbyt kreatywne kodowanie ramek kończy się tym, że program niby działa, ale tylko z jednym egzemplarzem urządzenia z biurka.

Przeczytaj również: Regulator PID - Jak działa, jak stroić i unikać błędów?

Odbieram odpowiedź i od razu ją weryfikuję

Odbiór powinien być równie zdyscyplinowany jak wysyłka. Sprawdzam adres, kod funkcji, długość odpowiedzi i CRC. Jeśli urządzenie zwróci wyjątek, bit 7 w kodzie funkcji będzie ustawiony, a w polu danych pojawi się kod błędu. To nie jest „szum z linii”, tylko normalna odpowiedź protokołu, która mówi mi, że trzeba poprawić adres, zakres albo funkcję.

W kodzie trzymam też jedną zasadę: jedna magistrala, jeden tor komunikacji w danym momencie. Jeśli aplikacja ma wiele wątków, to dostęp do portu serial musi być serializowany. W przeciwnym razie nawet poprawne zapytania zaczynają się mieszać i diagnostyka staje się męcząca.

  1. Otwieram port z poprawnym baud rate, parzystością i liczbą bitów stopu.
  2. Buduję ramkę zgodną z mapą rejestrów urządzenia.
  3. Wysyłam ją jako ciągły strumień, bez sztucznych przerw w środku.
  4. Czekam na odpowiedź w czasie dostosowanym do prędkości i długości magistrali.
  5. Weryfikuję CRC, adres, kod funkcji i długość danych.
  6. Dopiero potem zamieniam bajty na wartość liczbową.

Najlepszy efekt daje prosta implementacja z logowaniem surowych ramek. Gdy coś się psuje, od razu widzę, czy problem leży po stronie kodu, czy po stronie magistrali.

Jakie parametry i ograniczenia decydują o stabilności

W RTU najwięcej problemów robi nie sam protokół, tylko granica między logiką a fizycznym łączem. Jeśli topologia, przewód i terminacja są słabe, program będzie wyglądał na winnego, choć faktycznie tylko pokazuje objawy.

Obszar Dobry punkt startowy Dlaczego to ma znaczenie
Baud rate 9600 lub 19200 To najczęstsze, stabilne ustawienia dla urządzeń polowych.
Format znaku 8E1 Zapewnia typowy format 11-bitowy dla RTU.
Przerwa między ramkami Co najmniej 3,5 znaku Bez tej ciszy odbiornik nie wie, gdzie zaczyna się kolejna wiadomość.
Terminacja Na obu końcach magistrali Ogranicza odbicia sygnału i przypadkowe błędy CRC.
Topologia Linia główna z krótkimi odgałęzieniami RS-485 nie lubi gwiazd i długich odnóg.
Timeout programu Startowo 100–300 ms, potem korekta Za krótki timeout daje fałszywe błędy, za długi spowalnia cały system.

Dokumentacja dla serial line podaje, że przy 9600 bodów i kablu AWG26 lub grubszym można dojść do 1000 m długości magistrali, ale w praktyce liczy się też jakość ekranowania, liczba urządzeń i odgałęzienia. Jeśli robisz własny stos komunikacyjny, pamiętaj jeszcze o tym, że powyżej 19200 bodów specyfikacja zaleca stałe wartości timerów t1.5 i t3.5 zamiast wyliczania ich z bieżącej prędkości transmisji. To ma znaczenie szczególnie wtedy, gdy program pracuje na słabszym sterowniku lub mikrokontrolerze z ograniczonym czasem procesora.

Ja zawsze traktuję parametry seriala i magistrali jako część programu, a nie osobny temat. To podejście oszczędza najwięcej czasu, bo eliminuje fałszywe tropy już na starcie.

Najczęstsze błędy w programie i na magistrali

Najwięcej czasu traci się na błędy, które nie wyglądają jak błędy wprost: timeouty, wyjątki Modbus albo odpowiedzi z błędnym CRC. Ja zawsze rozdzielam je na trzy grupy, bo od tego zależy diagnostyka.

Objaw Najbardziej prawdopodobna przyczyna Co sprawdzić w pierwszej kolejności
Brak odpowiedzi Zły adres, zła parzystość, zły baud rate albo urządzenie poza zasięgiem Ustawienia portu, adres urządzenia i ciągłość okablowania.
Błąd CRC Zakłócenia, odbicia sygnału, za długie odgałęzienia, zły format seriala Terminację, ekranowanie, topologię i 8E1.
Exception 02 Nieprawidłowy adres rejestru Mapę rejestrów i to, czy używasz adresu względnego, a nie 4xxxx.
Exception 01 Urządzenie nie obsługuje danej funkcji Instrukcję urządzenia i listę dostępnych kodów funkcji.
Brak odpowiedzi po zapisie broadcast Prawidłowe zachowanie protokołu Nie czekać na reply, bo adres 0 służy do rozgłoszenia zapisu.
Losowe błędy przy większej prędkości Za szybka transmisja dla danej instalacji Długość magistrali, jakość przewodu i sensowność timeoutów.

Jeśli w odpowiedzi widzę kod funkcji z ustawionym najwyższym bitem, nie próbuję zgadywać. To oznacza wyjątek protokołu, a nie „dziwną ramkę” z linii. Wtedy najpierw poprawiam adres, funkcję albo typ danych, a dopiero później sprawdzam warstwę elektryczną.

Warto też pilnować jednego, często pomijanego tematu: serializacja dostępu do portu. Dwa procesy albo dwa wątki, które wysyłają jednocześnie, potrafią wywołać objawy łudząco podobne do uszkodzonego kabla. W praktyce aplikacja powinna mieć jeden kolejkujący punkt dostępu do magistrali.

Jak wygląda odczyt rejestru w praktyce

Najprostszy sensowny scenariusz to odczyt jednego rejestru holdingowego i zamiana surowych bajtów na wartość liczbową. Dla przykładu: urządzenie ma adres 17, a program czyta rejestr 40011. W ramce nie wysyłam jednak numeru 40011, tylko adres względny 10, bo tak działa większość implementacji i tak opisuje to dokumentacja protokołu.

17 03 00 0A 00 01 CRC_lo CRC_hi
  1. Wybieram adres urządzenia 17 i funkcję 03.
  2. Wysyłam startowy adres rejestru w postaci względnej.
  3. Ustalam liczbę rejestrów, tutaj: 1.
  4. Odbieram odpowiedź, sprawdzam CRC i długość danych.
  5. Składam dwa bajty w 16-bitową wartość.

Przy danych typu float trzeba uważać jeszcze bardziej, bo dwa 16-bitowe rejestry mogą być ułożone w innej kolejności niż oczekuje biblioteka. To jeden z tych problemów, które wyglądają jak błąd komunikacji, a są tylko błędem interpretacji. Dlatego przed uruchomieniem odczytu sprawdzam nie tylko adresy, ale też kolejność bajtów i słów w dokumentacji urządzenia.

Jeśli zapisuję wartość, używam funkcji 06 albo 16. Przy broadcastach dozwolone są tylko operacje zapisu i nie wolno zakładać, że urządzenie odeśle odpowiedź. To szczegół, który często psuje testy robione „na skróty”.

Co sprawdzam przed wdrożeniem na obiekcie

Przed uruchomieniem instalacji patrzę na kilka rzeczy, które w praktyce decydują o tym, czy system będzie działał stabilnie przez miesiące, czy będzie wymagał ciągłych poprawek:

  • czy mapa rejestrów jest zgodna z dokumentacją konkretnego urządzenia,
  • czy port serial ma ustawione dokładnie te same parametry po obu stronach,
  • czy magistrala ma jedną linię główną i krótkie odgałęzienia,
  • czy na końcach RS-485 są terminacje,
  • czy program loguje surowe ramki i czas odpowiedzi,
  • czy timeouty i liczba prób nie obciążają niepotrzebnie magistrali,
  • czy jeden proces ma wyłączny dostęp do portu.

Jeśli mam z tego zostawić jedną regułę, to taką: w RTU najpierw porządkuję fizykę łącza, potem mapę rejestrów, a dopiero na końcu sam kod. Taki porządek oszczędza najwięcej czasu, bo eliminuje fałszywe tropy i pozwala odróżnić błąd programu od problemu magistrali.

FAQ - Najczęstsze pytania

Modbus RTU to protokół komunikacyjny używany w automatyce przemysłowej do wymiany danych między urządzeniami. Działa na zasadzie master/slave (klient/serwer) przez port szeregowy, np. RS-485, wykorzystując ramki danych z sumą kontrolną CRC16.
Najczęściej spotykane ustawienia to 9600 lub 19200 bodów, format 8E1 (8 bitów danych, parzystość Even, 1 bit stopu) oraz interfejs RS-485. Ważne jest, aby parametry były identyczne dla wszystkich urządzeń w sieci.
Brak odpowiedzi może wynikać ze złego adresu urządzenia, niepoprawnych ustawień portu (baud rate, parzystość), problemów z okablowaniem (brak terminacji, zakłócenia) lub braku zasilania urządzenia. Zawsze sprawdź fizyczne połączenie i konfigurację portu.
Błędy CRC często wskazują na zakłócenia w transmisji, odbicia sygnału na magistrali lub nieprawidłową terminację. Sprawdź jakość okablowania, ekranowanie, topologię magistrali (RS-485 lubi linie, nie gwiazdy) oraz upewnij się, że terminatory są prawidłowo zainstalowane na końcach.
W dokumentacji często widzimy adresy rejestrów typu 40001, ale w ramce Modbus RTU wysyła się adres względny, np. dla 40011 będzie to 10. To częste źródło pomyłek; zawsze upewnij się, że używasz poprawnego adresu w ramce.

Oceń artykuł

Średnia: 0.0 / 5 · 0 ocen

Tagi

modbus rtu program program do modbus rtu jak zaprogramować modbus rtu
Autor Leonard Wojciechowski
Leonard Wojciechowski
Nazywam się Leonard Wojciechowski i od 14 lat zajmuję się techniką warsztatową, elektryką oraz automatyką. Moje zainteresowanie tymi dziedzinami zaczęło się już w dzieciństwie, kiedy to zafascynowany działaniem różnych urządzeń, spędzałem godziny na ich naprawianiu i ulepszaniu. Teraz, jako doświadczony autor, staram się dzielić swoją wiedzą i doświadczeniem z innymi, pomagając im zrozumieć złożoność zagadnień związanych z elektryką i automatyką. Pisząc, skupiam się na jasnym i przystępnym przedstawianiu informacji, co pozwala mi na skuteczne przekazywanie wiedzy. Regularnie sprawdzam źródła i porównuję różne podejścia, aby zapewnić czytelnikom najaktualniejsze i rzetelne dane. Lubię uprościć trudne tematy, aby każdy mógł z nich skorzystać, niezależnie od poziomu zaawansowania. Wierzę, że dobrze zorganizowana wiedza to klucz do sukcesu w każdej dziedzinie, dlatego dokładam wszelkich starań, aby moje artykuły były nie tylko informacyjne, ale także inspirujące.

Komentarze (0)

Dodaj komentarz