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.
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]
Ultimo aggiornamento: 5 Ottobre 2020