TapHome

Funcții Modbus

Funcțiile Modbus din scripturile TapHome — MODBUSR, MODBUSW, MODBUSWNE și funcțiile de bloc MODBUSRBLOCK, MODBUSWBLOCK, MODBUSWBLOCKNE — și tipurile de registre Modbus C, D, H și A.

Funcțiile Modbus citesc și scriu bobinele și registrele dispozitivului Modbus căruia îi aparține scriptul. Funcționează doar în scripturile unui modul sau dispozitiv Modbus; în orice alt loc scriptul se oprește cu ModbusFunction - unknown modbus device to work with. Numele tipurilor de date (Uint16, BigEndianFloat, …) se află pe pagina Tipuri de date Modbus. Configurarea modulului și a șabloanelor este descrisă în Integrarea Modbus.

Tipuri de registre

Primul argument al fiecărei funcții Modbus este tipul de registru.

TipObiect ModbusCoduri de funcțieAcces
CCoil (bobină)FC01 citire, FC05 / FC15 scrierecitire și scriere
DDiscrete input (intrare discretă)FC02doar citire
HHolding registerFC03 citire, FC06 / FC16 scrierecitire și scriere
AInput registerFC04doar citire

SC și SH sunt valori mai vechi pe care scripturile le acceptă în continuare. Adresează aceleași bobine și holding registers ca C și H, dar modulul le citește de la dispozitiv la fiecare apel în loc de cache și le scrie câte un registru per cerere (FC05 / FC06). În scripturile noi folosiți C și H. Acest comportament este preluat din codul motorului și nu a fost verificat pe un dispozitiv.

MODBUSR

MODBUSR citește o valoare dintr-o bobină, o intrare discretă sau unul ori mai multe registre și o convertește în tipul de date dat.

1
2
MODBUSR(registerType, register, dataType)
MODBUSR(registerType, register, String, numberOfRegisters)
NumeTipDescriere
registerTypeC, D, H, AConsultați Tipuri de registre.
registernumărAdresa registrului 0 – 65535, zecimal sau hexazecimal (0x14).
dataTypetip de date ModbusDecide câte registre se citesc: 1, 2 sau 4.
numberOfRegistersnumărObligatoriu pentru String, 0 – 123. Un registru conține 2 caractere.

Returnează — un număr pentru tipurile pe 16 și 32 de biți, Float și Double; bool pentru Bool; int64 sau uint64 pentru Int64 și UInt64; un șir de caractere pentru String, care se termină la primul octet zero.

Observații — O valoare pe mai multe registre se citește într-o singură cerere, așa că toate registrele ei provin din același moment.

Exemplu

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

Erori — Invalid register number: X; String data type must have specified length - number of registers to read.

MODBUSW

MODBUSW scrie o valoare sau până la 101 valori în registre consecutive și returnează TRUE.

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

Observații

  • Cu mai multe valori, adresa registrului avansează cu dimensiunea tipului de date — 1, 2 sau 4 registre pe valoare.
  • O bobină (C) acceptă doar tipul de date Bool; D și A nu se pot scrie.
  • Cum se rotunjesc și se verifică valorile este descris în Scrierea valorilor.

Exemplu

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

Erori — WriteInt16: Cannot write Int16 to coils (și la fel pentru celelalte tipuri); Invalid register number: X.

MODBUSWNE

MODBUSWNE („scrie dacă nu este egal") scrie o valoare ca MODBUSW, dar doar când diferă de valoarea pe care o conține registrul, ceea ce economisește traficul pe magistrală și ciclurile de scriere EEPROM ale dispozitivului.

1
MODBUSWNE(registerType, register, dataType, value)

Observații

  • Valoarea se compară cu cache-ul de registre al modulului. Cu prefetch activ, aceasta este valoarea citită de ultimul prefetch (registrul se adaugă la prefetch); un registru încă necitit se citește mai întâi. Cu No prefetch registrul se citește de la dispozitiv chiar înainte de comparație.
  • Nu se compară niciodată cu valoarea scrisă ultima dată: o scriere nu schimbă valoarea din cache până când registrul nu este citit din nou.
  • O valoare pe mai multe registre se compară și se scrie ca întreg.

Exemplu — configurare în scriptul de inițializare

MODBUSWNE(H, 27, Uint16, 0);

MODBUSRBLOCK

MODBUSRBLOCK citește un bloc de registre sau bobine consecutive într-o singură tranzacție Modbus și le returnează ca o colecție.

1
MODBUSRBLOCK(registerType, register, count)
Tip de registruReturneazăcount maxim
H, Acollection<uint16>123 (FC03 / FC04)
C, Dcollection<bool>2000 (FC01 / FC02)

Observații — Cu prefetch activ, registrele aflate deja în cache nu se citesc din nou; cele lipsă se citesc într-o singură cerere. Valorile cu tip se citesc din bloc cu UNPACKVALUE. O singură citire de bloc înlocuiește multe citiri individuale.

Exemplu

collection<uint16> data := MODBUSRBLOCK(H, 100, 4);
UNPACKVALUE(data, 0, BigEndianFloat);
# Result: the float in registers 100 and 101

Erori — MODBUSRBLOCK: count must be between 1 and 123 for 16-bit registers (H); MODBUSRBLOCK: invalid register range X..Y.

Disponibilitate — Core 2026.1, build 39001 sau mai nou (aplicația cu build 39016 sau mai nou). Același lucru este valabil pentru MODBUSWBLOCK și MODBUSWBLOCKNE.

MODBUSWBLOCK

MODBUSWBLOCK scrie o colecție întreagă în holding registers sau bobine consecutive într-o singură tranzacție Modbus și returnează TRUE. Un bloc mai lung decât dimensiunea grupului de prefetch a modulului (implicit 100) se împarte în mai multe cereri consecutive.

1
MODBUSWBLOCK(registerType, register, collection)
Tip de registruColecțieLungime maximă
Hcollection<uint16>123 (FC16)
Ccollection<bool>1968 (FC15)

Exemplu — setarea bobinelor 0 și 3, ștergerea bobinelor 1, 2 și 4 până la 7

collection<bool> coils := BOOLCOLLECTION(8);
SETAT(coils, 0, TRUE);
SETAT(coils, 3, TRUE);
MODBUSWBLOCK(C, 0, coils);

Erori — MODBUSWBLOCK: cannot write to read-only registers (D); MODBUSWBLOCK: register type C expects Collection<Bool>, got Collection<UInt16>.

MODBUSWBLOCKNE

MODBUSWBLOCKNE scrie o colecție ca MODBUSWBLOCK, dar doar când cel puțin o valoare diferă de conținutul actual al registrelor; un bloc modificat se scrie la fel, împărțit după aceeași dimensiune a grupului.

1
MODBUSWBLOCKNE(registerType, register, collection)

Observații — Conținutul actual se citește la fel ca la MODBUSWNE.

Exemplu — schimbarea unui singur registru dintr-un bloc cu trafic minim pe magistrală

collection<uint16> c := MODBUSRBLOCK(H, 100, 4);
PACKVALUE(c, 1, Uint16, 9);
MODBUSWBLOCKNE(H, 100, c);

Consultați și — Scripturi Modbus și prefetch, Date binare, Operații pe biți.