ModbusAsciiRTUGw, modbus ascii from/to RTU gateway

  1. Home
  2. Knowledge Base
  3. Manualistica
  4. Programmazione IEC 61131-3
  5. Libreria dispositivi Modbus
  6. ModbusAsciiRTUGw, modbus ascii from/to RTU gateway

Questo blocco funzione esegue la conversione di protocollo tra il Modbus Ascii ed il Modbus RTU. Il protocollo Ascii ricevuto dallo stream FpAscii viene convertito in RTU e trasmesso sullo stream FpRTU e viceversa. E' quindi possibile fare dialogare tra di loro sistemi che utilizzano i due tipi di protocollo diversi.

In IFTime occorre definire il tempo di interframe dei comandi modbus, cioè il tempo che intercorre tra la ricezione di un comando ed il comando successivo. Su linea seriale questo tempo coincide con il tempo di ricezione di 3 caratteri al baud rate definito.

I frames modbus ricevuti vengono controllati verificando il LRC per i frame Ascii ed il CRC per i frames RTU. In caso di errore comando viene attivata per un loop l'uscita Fault.

Function block
CODESYS: Non disponibile
LogicLab: eLLabMdbDevsLib

Enable (BOOL) Comando di abilitazione blocco funzione.

SpyOn (BOOL) Se attivo permette di spiare il funzionamento della FB (Vedi articolo).

FpAscii (eFILEP) Flusso dati stream da per la gestione del protocollo Modbus Ascii.

FpRTU (eFILEP) Flusso dati stream da per la gestione del protocollo Modbus RTU.

IFTime (UDINT) Tempo ricezione caratteri (μS) riferito al protocollo RTU, se comunicazione su porta seriale il tempo deve essere definito in base al baud rate (Vedi tabella). Nel caso di comunicazione su rete ethernet è possibile definire il valore minimo.

Timeout (DSINT) Tempo massimo gestione pacchetto (mS).

Enabled (BOOL) Blocco funzione abilitato.

Fault (BOOL) Attivo per un loop se errore esecuzione comando.

Trigger di spy

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

Errori

In caso di errore eseguendo immediatamente dopo la funzione SysGetLastError è possibile rilevare il codice di errore. Fare riferimento alla tabella seguente per la descrizione.

Esempi

Come utilizzare gli esempi.
L'esempio può essere eseguito su di un sistema SlimLine. Tramite una connessione TCP in localhost un FB ModbusMaster_v1 comunica in Ascii con il FB ModbusAsciiRTUGw che converte in RTU e lo invia sulla porta seriale COM0. Collegando con un cavo cross le seriali COM0 con la COM1 del sistema lo slave Modbus integrato risponderà alla richiesta in RTU. Il mesaggio di rispostae verrà ritornato al ModbusMaster convertito in ascii.

LogicLab (Ptp141)
PROGRAM ST_ModbusAsciiRTUGw
VAR
    i : UDINT;    (* Aux counter *)
    CaseNr : USINT; (* Program case *)
    Errors : UDINT;  (* Error counter *)
    WHRegs : ARRAY[0..7] OF WORD; (* Holding registers (Write) *)
    RHRegs : ARRAY[0..7] OF WORD; (* Holding registers (Read) *)
    Sp : SysSerialPort; (* Serial port *)
    Mdb : ModbusMaster_v1; (* Modbus master FB *)
    TCPClient : SysTCPClient; (* TCP client management *)
    MdbGw : ModbusAsciiRTUGw; (* Modbus ascii to RTU gateway *)
    TCPServer : SysTCPServer; (* TCPServer management *)
END_VAR

// *****************************************************************************
// PROGRAM "ST_ModbusAsciiRTUGw"
// *****************************************************************************
// A ModbusMaster communicate in modbus ascii  with the ModbusAsciiRTUGw FB
// using a localhost TCP connection. The FB converts the protocol to modbus RTU
// and communicate to the embedded modbus slave by using a serial connection.
// -----------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    // 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(MdbGw.FpAscii); //Files array
        TCPServer.LocalAdd:=ADR('0.0.0.0'); //Local address
        TCPServer.LocalPort:=3100; //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

        // TCP client settings.

        TCPClient.PeerAdd:=ADR('127.0.0.1'); //Peer address
        TCPClient.PeerPort:=3100; //Peer port
        TCPClient.LocalAdd:=ADR('0.0.0.0'); //Local address
        TCPClient.LocalPort:=0; //Local port
        TCPClient.FlushTm:=50; //Flush time (mS)
        TCPClient.LifeTm:=20; //Life time (S)
        TCPClient.RxSize:=128; //Rx buffer size
        TCPClient.TxSize:=128; //Tx buffer size

        // Modbus master settings.

        Mdb.SpyOn:=TRUE; //Spy On
        Mdb.Type:=1; //Modbus type (Ascii)
        Mdb.Node:=1; //Device modbus node
        Mdb.Timeout:=0.5; //Timeout time (S)
        Mdb.Delay:=1.0; //Delay time (S)

        // Modbus master settings.

        MdbGw.SpyOn:=TRUE; //Spy On
        MdbGw.IFTime:=286; //Device modbus node
        MdbGw.Timeout:=100; //Timeout time (mS)
    END_IF;

    // -------------------------------------------------------------------------
    // MODBUS MANAGEMENT
    // -------------------------------------------------------------------------
    // Serial port management.

    Sp(Open:=TRUE); //Serial port management
    MdbGw.FpRTU:=Sp.File; //Modbus RTU file pointer

    // TCP server management.

    TCPServer(Enable:=TRUE); //TCPServer management

    // TCP client management.

    TCPClient(Connect:=TRUE); //TCPClient management
    Mdb.File:=TCPClient.File; //File pointer

    // Manage the modbus master communication.

    Mdb(); //Modbus master
    Mdb.Enable:=NOT(Mdb.Done); //Modbus enable

    // Manage the modbus gateway.

    MdbGw(Enable:=SysFIsOpen(Mdb.File)); //Modbus ascii to RTU gateway
    IF NOT(SysFIsOpen(Mdb.File)) THEN Mdb.Enable:=FALSE; CaseNr:=0; RETURN; END_IF;

    // -------------------------------------------------------------------------
    // PROGRAM CASES
    // -------------------------------------------------------------------------
    // Manage the program cases.

    CASE (CaseNr) OF    

        // ---------------------------------------------------------------------
        // Execute a Preset multiple registers.

        0:
        Mdb.FCode:=16#10; //Modbus function code    
        Mdb.Address:=40000+(16/2); //Modbus register address    
        Mdb.Points:=SIZEOF(WHRegs)/2; //Modbus register points    
        Mdb.Buffer:=ADR(WHRegs); //Memory buffer address    
        IF NOT(Mdb.Done) THEN RETURN; END_IF;
        CaseNr:=CaseNr+1; //Program case

        // ---------------------------------------------------------------------
        // Execute a Read holding registers.

        1:
        Mdb.FCode:=16#03; //Modbus function code    
        Mdb.Address:=40000+(16/2); //Modbus register address    
        Mdb.Points:=SIZEOF(RHRegs)/2; //Modbus register points    
        Mdb.Buffer:=ADR(RHRegs); //Memory buffer address    
        IF NOT(Mdb.Done) THEN RETURN; END_IF;
        CaseNr:=0; //Program case

        // Checks if read values are correct and change them.

        FOR i:=0 TO ((SIZEOF(WHRegs)/SIZEOF(WHRegs[0]))-1) DO
            IF (RHRegs[i] <> WHRegs[i]) THEN Errors:=Errors+1; END_IF;
            WHRegs[i]:=TO_WORD(SysGetRandom(TRUE)*65535.0); //Mapped holding register
        END_FOR;
    END_CASE;

// [End of file]

Ti è stato utile questo articolo ?

Ultimo aggiornamento: 5 Ottobre 2020