Funzioni Modbus
Funzioni Modbus degli script TapHome — MODBUSR, MODBUSW, MODBUSWNE e le funzioni a blocchi MODBUSRBLOCK, MODBUSWBLOCK, MODBUSWBLOCKNE — e i tipi di registro Modbus C, D, H e A.
Le funzioni Modbus leggono e scrivono i coil e i registri del dispositivo Modbus a cui appartiene uno script. Funzionano solo negli script di un modulo o di un dispositivo Modbus; altrove lo script si interrompe con ModbusFunction - unknown modbus device to work with. I nomi dei tipi di dati (Uint16, BigEndianFloat, …) si trovano in Tipi di dati Modbus. La configurazione del modulo e dei modelli è descritta in Integrazione Modbus.
Tipi di registro
Il primo argomento di ogni funzione Modbus è il tipo di registro.
| Tipo | Oggetto Modbus | Codici funzione | Accesso |
|---|---|---|---|
C | Coil | FC01 lettura, FC05 / FC15 scrittura | lettura e scrittura |
D | Discrete input | FC02 | sola lettura |
H | Holding register | FC03 lettura, FC06 / FC16 scrittura | lettura e scrittura |
A | Input register | FC04 | sola lettura |
SC e SH sono valori più vecchi che gli script accettano ancora. Indirizzano gli stessi coil e holding register di C e H, ma il modulo li legge dal dispositivo a ogni chiamata invece che dalla cache e li scrive un registro per richiesta (FC05 / FC06). Negli script nuovi usa C e H. Questo comportamento è ricavato dal codice del motore e non è stato verificato su un dispositivo.
MODBUSR
MODBUSR legge un valore da un coil, da un discrete input o da uno o più registri e lo converte nel tipo di dati indicato.
| |
| Nome | Tipo | Descrizione |
|---|---|---|
registerType | C, D, H, A | Vedi Tipi di registro. |
register | numero | Indirizzo del registro 0 – 65535, decimale o esadecimale (0x14). |
dataType | tipo di dati Modbus | Decide quanti registri vengono letti: 1, 2 o 4. |
numberOfRegisters | numero | Obbligatorio per String, 0 – 123. Un registro contiene 2 caratteri. |
Valore restituito — un numero per i tipi a 16 e 32 bit, Float e Double; bool per Bool; int64 o uint64 per Int64 e UInt64; una stringa per String, che termina al primo byte zero.
Note — Un valore su più registri viene letto in un’unica richiesta, quindi tutti i suoi registri provengono dallo stesso istante.
Esempio
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 charactersErrori — Invalid register number: X; String data type must have specified length - number of registers to read.
MODBUSW
MODBUSW scrive un valore, oppure fino a 101 valori in registri consecutivi, e restituisce TRUE.
| |
Note
- Con più valori l’indirizzo del registro avanza della dimensione del tipo di dati — 1, 2 o 4 registri per valore.
- Un coil (
C) accetta solo il tipo di datiBool;DeAnon si possono scrivere. - Come i valori vengono arrotondati e controllati è descritto in Scrittura dei valori.
Esempio
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);Errori — WriteInt16: Cannot write Int16 to coils (e lo stesso per gli altri tipi); Invalid register number: X.
MODBUSWNE
MODBUSWNE (“write if not equal”, scrivi se diverso) scrive un valore come MODBUSW, ma solo quando è diverso dal valore contenuto nel registro, il che riduce il traffico sul bus e i cicli di scrittura EEPROM del dispositivo.
| |
Note
- Il valore viene confrontato con la cache dei registri del modulo. Con il prefetch attivo, è il valore letto dall’ultimo prefetch (il registro viene aggiunto al prefetch); un registro non ancora letto viene letto prima. Con No prefetch il registro viene letto dal dispositivo subito prima del confronto.
- Non viene mai confrontato con il valore scritto l’ultima volta: una scrittura non cambia il valore in cache finché il registro non viene letto di nuovo.
- Un valore su più registri viene confrontato e scritto per intero.
Esempio — configurazione nello script di inizializzazione
MODBUSWNE(H, 27, Uint16, 0);MODBUSRBLOCK
MODBUSRBLOCK legge un blocco di registri o coil consecutivi in un’unica transazione Modbus e li restituisce come collezione.
| |
| Tipo di registro | Restituisce | count massimo |
|---|---|---|
H, A | collection<uint16> | 123 (FC03 / FC04) |
C, D | collection<bool> | 2000 (FC01 / FC02) |
Note — Con il prefetch attivo, i registri già presenti nella cache non vengono letti di nuovo; quelli mancanti vengono letti in un’unica richiesta. Leggi i valori tipizzati dal blocco con UNPACKVALUE. Una lettura a blocco sostituisce molte letture singole.
Esempio
collection<uint16> data := MODBUSRBLOCK(H, 100, 4);
UNPACKVALUE(data, 0, BigEndianFloat);
# Result: the float in registers 100 and 101Errori — MODBUSRBLOCK: count must be between 1 and 123 for 16-bit registers (H); MODBUSRBLOCK: invalid register range X..Y.
Disponibile — Core 2026.1, build 39001 o più recente (app build 39016 o più recente). Lo stesso vale per MODBUSWBLOCK e MODBUSWBLOCKNE.
MODBUSWBLOCK
MODBUSWBLOCK scrive un’intera collezione in holding register o coil consecutivi in un’unica transazione Modbus e restituisce TRUE. Un blocco più lungo della dimensione del gruppo di prefetch del modulo (100 per impostazione predefinita) viene suddiviso in più richieste consecutive.
| |
| Tipo di registro | Collezione | Lunghezza massima |
|---|---|---|
H | collection<uint16> | 123 (FC16) |
C | collection<bool> | 1968 (FC15) |
Esempio — attivare i coil 0 e 3, disattivare i coil 1, 2 e da 4 a 7
collection<bool> coils := BOOLCOLLECTION(8);
SETAT(coils, 0, TRUE);
SETAT(coils, 3, TRUE);
MODBUSWBLOCK(C, 0, coils);Errori — MODBUSWBLOCK: cannot write to read-only registers (D); MODBUSWBLOCK: register type C expects Collection<Bool>, got Collection<UInt16>.
MODBUSWBLOCKNE
MODBUSWBLOCKNE scrive una collezione come MODBUSWBLOCK, ma solo quando almeno un valore è diverso dal contenuto attuale dei registri; un blocco cambiato viene scritto allo stesso modo, suddiviso con la stessa dimensione del gruppo.
| |
Note — Il contenuto attuale viene letto allo stesso modo che per MODBUSWNE.
Esempio — cambiare un registro di un blocco con il minimo traffico sul bus
collection<uint16> c := MODBUSRBLOCK(H, 100, 4);
PACKVALUE(c, 1, Uint16, 9);
MODBUSWBLOCKNE(H, 100, c);Vedi anche — Script Modbus e prefetch, Dati binari, Operazioni sui bit.