Funkcje Modbus
Funkcje Modbus w skryptach TapHome — MODBUSR, MODBUSW, MODBUSWNE i funkcje blokowe MODBUSRBLOCK, MODBUSWBLOCK, MODBUSWBLOCKNE — oraz typy rejestrów Modbus C, D, H i A.
Funkcje Modbus odczytują i zapisują cewki i rejestry urządzenia Modbus, do którego należy skrypt. Działają tylko w skryptach modułu lub urządzenia Modbus; gdzie indziej skrypt zatrzymuje się błędem ModbusFunction - unknown modbus device to work with. Nazwy typów danych (Uint16, BigEndianFloat, …) są na stronie Typy danych Modbus. Konfigurację modułu i szablonów opisuje Integracja Modbus.
Typy rejestrów
Pierwszym argumentem każdej funkcji Modbus jest typ rejestru.
| Typ | Obiekt Modbus | Kody funkcji | Dostęp |
|---|---|---|---|
C | Coil (cewka) | FC01 odczyt, FC05 / FC15 zapis | odczyt i zapis |
D | Discrete input (wejście dyskretne) | FC02 | tylko odczyt |
H | Holding register | FC03 odczyt, FC06 / FC16 zapis | odczyt i zapis |
A | Input register | FC04 | tylko odczyt |
SC i SH to starsze wartości, które skrypty nadal akceptują. Adresują te same cewki i holding registers co C i H, ale moduł odczytuje je z urządzenia przy każdym wywołaniu zamiast z pamięci podręcznej i zapisuje je po jednym rejestrze na żądanie (FC05 / FC06). W nowych skryptach używaj C i H. To zachowanie pochodzi z kodu silnika i nie zostało sprawdzone na urządzeniu.
MODBUSR
MODBUSR odczytuje jedną wartość z cewki, wejścia dyskretnego lub jednego albo kilku rejestrów i konwertuje ją na podany typ danych.
| |
| Nazwa | Typ | Opis |
|---|---|---|
registerType | C, D, H, A | Zobacz Typy rejestrów. |
register | liczba | Adres rejestru 0 – 65535, dziesiętnie lub szesnastkowo (0x14). |
dataType | typ danych Modbus | Decyduje, ile rejestrów zostanie odczytanych: 1, 2 lub 4. |
numberOfRegisters | liczba | Wymagany dla String, 0 – 123. Jeden rejestr mieści 2 znaki. |
Zwraca — liczbę dla typów 16- i 32-bitowych, Float i Double; bool dla Bool; int64 lub uint64 dla Int64 i UInt64; tekst dla String, kończący się na pierwszym bajcie zerowym.
Uwagi — Wartość zajmująca kilka rejestrów jest odczytywana jednym żądaniem, więc wszystkie jej rejestry pochodzą z tej samej chwili.
Przykład
MODBUSR(H, 20, Int16) / 100;
# Result: the register as a signed number, divided by 100
MODBUSR(A, 0x0040, Uint32);
MODBUSR(H, 14, String, 4);
# Result: text of up to 8 charactersBłędy — Invalid register number: X; String data type must have specified length - number of registers to read.
MODBUSW
MODBUSW zapisuje jedną wartość albo do 101 wartości do kolejnych rejestrów i zwraca TRUE.
| |
Uwagi
- Przy kilku wartościach adres rejestru przesuwa się o rozmiar typu danych — 1, 2 lub 4 rejestry na wartość.
- Cewka (
C) akceptuje tylko typ danychBool;DiAnie da się zapisać. - Jak wartości są zaokrąglane i sprawdzane, opisuje Zapis wartości.
Przykład
MODBUSW(H, 20, Int16, Te * 100);
MODBUSW(H, 100, Uint16, 1, 2, 3);
# Result: TRUE — registers 100, 101 and 102 are written
MODBUSW(C, 5, Bool, St);Błędy — WriteInt16: Cannot write Int16 to coils (i analogicznie dla innych typów); Invalid register number: X.
MODBUSWNE
MODBUSWNE („write if not equal” — zapisz, jeśli różne) zapisuje jedną wartość jak MODBUSW, ale tylko wtedy, gdy różni się od wartości w rejestrze, co oszczędza ruch na magistrali i cykle zapisu EEPROM urządzenia.
| |
Uwagi
- Wartość jest porównywana z pamięcią podręczną rejestrów modułu. Przy włączonym prefetch jest to wartość odczytana przez ostatni prefetch (rejestr zostaje dodany do prefetch); rejestr jeszcze nieodczytany jest najpierw odczytywany. Przy No prefetch rejestr jest odczytywany z urządzenia tuż przed porównaniem.
- Nigdy nie jest porównywana z wartością zapisaną ostatnio: zapis nie zmienia wartości w pamięci podręcznej, dopóki rejestr nie zostanie ponownie odczytany.
- Wartość zajmująca kilka rejestrów jest porównywana i zapisywana w całości.
Przykład — konfiguracja w skrypcie inicjalizacji
MODBUSWNE(H, 27, Uint16, 0);MODBUSRBLOCK
MODBUSRBLOCK odczytuje blok kolejnych rejestrów lub cewek w jednej transakcji Modbus i zwraca je jako kolekcję.
| |
| Typ rejestru | Zwraca | Maksymalne count |
|---|---|---|
H, A | collection<uint16> | 123 (FC03 / FC04) |
C, D | collection<bool> | 2000 (FC01 / FC02) |
Uwagi — Przy włączonym prefetch rejestry, które już są w pamięci podręcznej, nie są odczytywane ponownie; brakujące są odczytywane jednym żądaniem. Wartości z typem odczytasz z bloku przez UNPACKVALUE. Jeden odczyt bloku zastępuje wiele pojedynczych odczytów.
Przykład
collection<uint16> data := MODBUSRBLOCK(H, 100, 4);
UNPACKVALUE(data, 0, BigEndianFloat);
# Result: the float in registers 100 and 101Błędy — MODBUSRBLOCK: count must be between 1 and 123 for 16-bit registers (H); MODBUSRBLOCK: invalid register range X..Y.
Dostępność — Core 2026.1, kompilacja 39001 lub nowsza (aplikacja w kompilacji 39016 lub nowszej). To samo dotyczy MODBUSWBLOCK i MODBUSWBLOCKNE.
MODBUSWBLOCK
MODBUSWBLOCK zapisuje całą kolekcję do kolejnych holding registers lub cewek w jednej transakcji Modbus i zwraca TRUE. Blok dłuższy niż rozmiar grupy prefetch modułu (domyślnie 100) jest dzielony na kilka kolejnych żądań.
| |
| Typ rejestru | Kolekcja | Maksymalna długość |
|---|---|---|
H | collection<uint16> | 123 (FC16) |
C | collection<bool> | 1968 (FC15) |
Przykład — ustawienie cewek 0 i 3, wyzerowanie cewek 1, 2 i 4 do 7
collection<bool> coils := BOOLCOLLECTION(8);
SETAT(coils, 0, TRUE);
SETAT(coils, 3, TRUE);
MODBUSWBLOCK(C, 0, coils);Błędy — MODBUSWBLOCK: cannot write to read-only registers (D); MODBUSWBLOCK: register type C expects Collection<Bool>, got Collection<UInt16>.
MODBUSWBLOCKNE
MODBUSWBLOCKNE zapisuje kolekcję jak MODBUSWBLOCK, ale tylko wtedy, gdy co najmniej jedna wartość różni się od aktualnej zawartości rejestrów; zmieniony blok jest zapisywany tak samo, dzielony według tego samego rozmiaru grupy.
| |
Uwagi — Aktualna zawartość jest odczytywana tak samo jak dla MODBUSWNE.
Przykład — zmiana jednego rejestru bloku przy minimalnym ruchu na magistrali
collection<uint16> c := MODBUSRBLOCK(H, 100, 4);
PACKVALUE(c, 1, Uint16, 9);
MODBUSWBLOCKNE(H, 100, c);Zobacz też — Skrypty Modbus i prefetch, Dane binarne, Operacje bitowe.