TapHome

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.

TypObiekt ModbusKody funkcjiDostęp
CCoil (cewka)FC01 odczyt, FC05 / FC15 zapisodczyt i zapis
DDiscrete input (wejście dyskretne)FC02tylko odczyt
HHolding registerFC03 odczyt, FC06 / FC16 zapisodczyt i zapis
AInput registerFC04tylko 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.

1
2
MODBUSR(registerType, register, dataType)
MODBUSR(registerType, register, String, numberOfRegisters)
NazwaTypOpis
registerTypeC, D, H, AZobacz Typy rejestrów.
registerliczbaAdres rejestru 0 – 65535, dziesiętnie lub szesnastkowo (0x14).
dataTypetyp danych ModbusDecyduje, ile rejestrów zostanie odczytanych: 1, 2 lub 4.
numberOfRegistersliczbaWymagany 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 characters

Błę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.

1
MODBUSW(registerType, register, dataType, value [, value2, …])

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 danych Bool; D i A nie 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.

1
MODBUSWNE(registerType, register, dataType, value)

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

1
MODBUSRBLOCK(registerType, register, count)
Typ rejestruZwracaMaksymalne count
H, Acollection<uint16>123 (FC03 / FC04)
C, Dcollection<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 101

Błę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ń.

1
MODBUSWBLOCK(registerType, register, collection)
Typ rejestruKolekcjaMaksymalna długość
Hcollection<uint16>123 (FC16)
Ccollection<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.

1
MODBUSWBLOCKNE(registerType, register, collection)

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.