ModbusSlave, modbus slave

List

Questa pagina fa parte del Manuale Programmazione IEC 61131-3. Vai all indice.

Sui sistemi SlimLine e Netsyst il protocollo modbus slave è già implementato dal sistema operativo (Vedi articolo), pertanto non occorre inserire blocchi funzione appositi nel programma utente. Questo blocco si utilizza in casi particolari, dove non è possibile utilizzare la gestione implementata nel sistema operativo. Per esempio quando si vuole consentire l’accesso ad un propria area di memoria diversa dalla DB100.

Il blocco funzione esegue la gestione del protocollo modbus slave con Type è possibile selezionare il tipo di protocollo RTU, Ascii ed over IP. Con File è possibile definire il terminale di I/O su cui effettuare la comunicazione.

Occorre definire il nodo modbus Node, e l’eventuale offset di indirizzo frame modbus Offset. I comandi modbus ricevuti operano sul buffer di memoria il cui indirizzo è definito in Buffer e la dimensione in bytes è definita in Size.

Alla ricezione di ogni comando modbus corretto si attiva per un loop l’uscita Done e si incrementa Packets. In caso di errore comando viene attivata per un loop l’uscita Fault ed incrementato il valore in Errors.

Upgrade list

ModbusSlave_v2

Implementa una gestione ottimizzata della acquisizione dei frames modbus di comando evitando la dichiarazione del parametro IFTime. Tutti gli altri parametri in ingresso rimangono invariati, aggiunto i parametri CTime e Packets in uscita.

ModbusSlave_v3

Aggiunta gestione ingresso Absolute, se attivo considera indirizzamento assoluto e non viene sommato 1 all’indirizzo Modbus ricevuto. Visto che è stato aggiunto il solo parametro di ingresso Absolute mantenendo identico il funzionamento può sostituire la ModbusSlave_v2 nei progetti esistenti.

ModbusSlave_v4

Ingresso Type di definizione tipo di protocollo ora è di tipo MODBUS_PROTOCOL. Il parametro in uscita CTime ora è di tipo TIME.

ModbusSlave_v5

Inserito parametro Timeout in ingresso.

Information Circle

Blocco funzione

CODESYS: Non disponibile

LogicLab: eLLabModbusLib

Descrizione

Enable (BOOL) Comando di abilitazione blocco funzione.
SpyOn (BOOL) Se attivo permette di spiare il funzionamento della FB (Vedi articolo).
Absolute (BOOL) Il FB somma 1 all’indirizzo Modbus per compensare l’offset -1. Se bit attivo si considera indirizzamento assoluto e non si compensa l’offset.
File (eFILEP) Flusso dati stream da utilizzare per la comunicazione.
Type (MODBUS_PROTOCOL) Tipo di protocollo modbus (Definizione).
Node (USINT) Numero di nodo modbus (Range da 0 a 255).
Offset (UINT) Offset su indirizzo modbus ricevuto nel frame dati (Range da 16#0000 a 16#FFFF).
Buffer (PVOID) Indirizzo buffer dati su cui operano i comandi modbus.
Size (UDINT) Dimensione in byte del buffer dati su cui operano i comandi modbus.
Timeout (TIME) Definizione timeout di esecuzione.
Done (BOOL) Si attiva per un loop di programma al termine della esecuzione richiesta.
Fault (BOOL) Attivo per un loop se errore esecuzione richiesta.
CTime (TIME) Tempo richiesto per la ricezione di una interrogazione Modbus e invio della risposta.
Packets (UDINT) Numero di richieste modbus gestite, incrementato ad ogni richiesta, raggiunto massimo riparte da 0.
Errors (UDINT) Numero di errori, incrementato ad ogni errore, raggiunto massimo riparte da 0.

Immagine FB_ModbusSlave_v5
FCode, funzioni modbus supportate

16#01 Read coil status (Massimo 250 coils)
16#02 Read input status (Massimo 125 inputs)
16#03 Read holding registers (Massimo 125 registri)
16#04 Read input registers (Massimo 125 registri)

      +----+-----------+---+---+---+---+           +----+-----------+-----+--...--+
Query |Node|01/02/03/04|Address|Points |  Response |Node|01/02/03/04|Bytes| Data  |
      +----+-----------+---+---+---+---+           +----+-----------+-----+--...--+

16#05 Force single coil
16#06 Preset single register

      +----+-----+---+---+--+--+           +----+-----+---+---+--+--+
Query |Node|05/06|Address|Data |  Response |Node|05/06|Address|Data |
      +----+-----+---+---+--+--+           +----+-----+---+---+--+--+

16#0F Force Multiple Coils (Massimo 250 coils)
16#10 Preset multiple registers (Massimo 125 registri)

      +----+-----+---+---+---+---+-----+--...--+           +----+-----+---+---+---+---+
Query |Node|0F/10|Address|Points |Bytes| Data  |  Response |Node|0F/10|Address|Points |
      +----+-----+---+---+---+---+-----+--...--+           +----+-----+---+---+---+---+

16#41 Read memory bytes (Funzione custom, massimo 250 bytes)

      +----+--+---+---+---+---+           +----+--+-------+--...--+
Query |Node|41|Address|Points |  Response |Node|41|Points | Data  |
      +----+--+---+---+---+---+           +----+--+-------+--...--+

16#42 Write memory bytes (Funzione custom, massimo 250 bytes)

      +----+--+---+---+---+---+--...--+           +----+--+-------+
Query |Node|42|Address|Points | Data  |  Response |Node|42|Points |
      +----+--+---+---+---+---+--...--+           +----+--+-------+

I codici 16#41 e 16#42 sono stati implementati per compatibilità con i vecchi sistemi programmabili con Remoter.

Messaggi di errore (Eccezione)

Il dispositivo, se non è in grado di eseguire l’operazione richiesta dal comando ricevuto, risponde con un messaggio di errore che prevede il seguente formato:

+-------------+---------------+----------------+---+---+
| Modbus node | Function code | Exception code |  CRC  |
+-------------+---------------+----------------+---+---+
  • Modbus node: Indirizzo del dispositivo slave che risponde.
  • Function code: Codice funzione con MSB=1 (per indicare l’eccezione); esempio 16#83 (per la lettura 16#03 ) o 16#86 (per la scrittura 16#06).
  • Exception code: Codice eccezione.
Codici eccezione
CodeNameDescription
16#01Illegal functionE’ stato richiesto un codice funzione che il dispositivo non supporta.
16#02Illegal data addressViene generato in diverse situazioni:
  • Richiesto un registro non implementato (o un’area inesistente)
  • Richiesta la lettura di un numero di registri che va oltre l’area implementata (partendo dall’indirizzo richiesto)
  • Si è tentato di scrivere in un’area read‐only
16#03Illegal data valueIl dato definito nella richiesta non è accettato dal dispositivo.
16#04Slave device failureSi è verificato un errore irreversibile mentre lo slave stava tentando di eseguire l’azione richiesta.
16#05AcknowledgeLo slave ha accettato la richiesta e la sta elaborando, ma per farlo sarà necessario un lungo periodo di tempo. Questa risposta viene restituita per evitare che si verifichi un errore di timeout nel master.
16#06Slave device busyLo slave è impegnato nell’elaborazione di un comando che richiede una lunga elaborazione.
16#07Negative acknowledgeLo slave non può eseguire la funzione di programma ricevuta nella query.
16#08Memory parity errorLo slave ha tentato di leggere la memoria ma ha rilevato un errore di parità.

Trigger di spy

Se SpyOn attivo è possibile utilizzare utilizzare la console di spionaggio per verificare il funzionamento della FB. Sono previsti vari livelli di triggers.

Livelli di trigger
TriggerDescrizione
16#00000001Rx: Ricezione frame comando modbus.
16#00000002Tx: Invio frame risposta modbus.
16#10000000Lg: Log esecuzione.
16#40000000Er: Errore di esecuzione.

Esempi

Come utilizzare gli esempi.

ST_ModbusSlave: E’ possibile utilizzare l’esempio in TCP su di un unico sistema SlimLine definendo come indirizzo IP dello slave il localhost ADR(‘127.0.0.1’). Oppure in RTU o ascii selezionando la comunicazione seriale. Nell’esempio il FB si comporta esattamente come la gestione Modbus del sistema operativo, è possibile utilizzare l’esempio insieme all’esempio del FB ModbusMaster.

LogicLab (Ptp205, ST_ModbusSlave)
PROGRAM ST_ModbusSlave
VAR
    SerialOrTCP : BOOL; (* FALSE:Serial, TRUE:TCP communication *)
    Fp : eFILEP; (* File pointer *)
    Sp : SysSerialPort; (* Serial port *)
    TCPServer : SysTCPServer; (* TCPServer management *)
    SMdb : ModbusSlave_v5; (* Modbus slave FB *)
END_VAR

// *****************************************************************************
// PROGRAM "ST_ModbusSlave"
// *****************************************************************************
// It's instantiated a Modbus slave FB connected to the defined serial port. It
// operates over the DB100 memory area exactly as the embedded Modbus.
// -----------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    // INITIALIZATION
    // -------------------------------------------------------------------------
    // Program initializations.

    IF (SysFirstLoop) THEN

        // Serial port settings.

        Sp.COM:=ADR('COM0'); //COM port definition
        Sp.Baudrate:=115200; //Baudrate
        Sp.Parity:='E'; //Parity
        Sp.DataBits:=8; //Data bits
        Sp.StopBits:=1; //Stop bits
        Sp.DTRManagement:=DTR_AUTO_WO_TIMES; //DTR management
        Sp.DTRComplement:=FALSE; //DTR complement
        Sp.EchoFlush:=FALSE; //Received echo flush
        Sp.DTROnTime:=0; //DTR On time delay (mS)
        Sp.DTROffTime:=0; //DTR Off time delay (mS)
        Sp.FlushTm:=0; //Flush time (mS)
        Sp.RxSize:=0; //Rx buffer size
        Sp.TxSize:=0; //Tx buffer size

        // TCP server settings.

        TCPServer.FilesArr:=ADR(Fp); //Files array
        TCPServer.LocalAdd:=ADR('0.0.0.0'); //Local address
        TCPServer.LocalPort:=3000; //Local port
        TCPServer.MaxConn:=1; //Accepted connections
        TCPServer.FlushTm:=50; //Flush time (mS)
        TCPServer.LifeTm:=60; //Life time (S)
        TCPServer.RxSize:=256; //Rx buffer size
        TCPServer.TxSize:=256; //Tx buffer size

        // Modbus slave settings.

        SMdb.Absolute:=FALSE; //Absolute addressing
        SMdb.Node:=1; //Device modbus node
        SMdb.Offset:=40000; //Modbus address offset
        SMdb.Buffer:=eToPVoid(ADR(%MX100.0)); //Modbus buffer address
        SMdb.Size:=4096; //Modbus buffer size
        SMdb.Timeout:=T#1s; //Timeout
    END_IF;

    // -------------------------------------------------------------------------
    // MODBUS MANAGEMENT
    // -------------------------------------------------------------------------
    // Eseguo selezione canale comunicazione.

    IF NOT(SerialOrTCP) THEN

        // Serial port management.

        Sp(Open:=TRUE); //Serial port management
        SMdb.File:=Sp.File; //File pointer
        SMdb.Type:=MODBUS_PROTOCOL#MDB_RTU; //Modbus type (RTU)
        // SMdb.Type:=MODBUS_PROTOCOL#MDB_ASCII; //Modbus type (Ascii)
    ELSE

        // TCP server management.

        TCPServer(Enable:=TRUE); //TCPServer management
        SMdb.File:=Fp; //File pointer
        SMdb.Type:=MODBUS_PROTOCOL#MDB_TCP; //Modbus type (TCP)
    END_IF;

    // Manage the modbus slave communication.

    SMdb(Enable:=SysFIsOpen(SMdb.File)); //Modbus slave

// [End of file]
Was this article helpful?