Aggiungere porte seriali ad un sistema

Con un convertitore Ethernet/Seriale o WiFi/Seriale è possibile aggiungere porte seriali ai nostri sistemi SlimLine o Netsyst. E’ possibile connettere il convertitore al modulo CPU sia in UDP che in TCP in modalità client o server.

Trattandosi di comunicazioni seriali (Esempio Modbus) dove è già previsto un sistema di controllo errori consiglio di utilizzare una connessione UDP per evitare overhead di rete ed essendo il modulo CPU che gestisce la comunicazione con il convertitore configurerei il convertitore in modalità server.

Nel programma sullo SlimLine verrà istanziato un FB SysUDPClient configurato con indirizzo IP e porta del convertitore Ethernet/Seriale. Lo stream File di I/O in uscita al blocco funzione potrà essere utilizzato come stream di comunicazione.

SlimLine con Ethernet/Serial converter

Programma COMRemote

Ecco lo screenshot del programma COMRemote che utilizza un ATC-1200 per gestire un dispositivo Modbus. Nell’esempio il convertitore Ethernet/Seriale agisce da server UDP e lo SlimLine da Client. Nella configurazione del convertitore come si vede è definita la porta UDP 5000 sia come porta di listening del server che come porta di destinazione del client. questo perchè nel FB SysUDPClient si definisce la porta 5000 come PeerPort e si definisce 0 come LocalPort, quindi il client si pone in ascolto dei dati dal server dalla stessa porta cui ha inviato i dati.

Se si desidera aggiungere più porte seriali si dovranno istanziare più FB SysUDPClient, una per ogni porta COM aggiuntiva. Anche se nel programma di esempio il convertitore Ethernet/Seriale agisce da server è possibile invertire i ruoli configurando il convertitore come client. In questo caso si dovrà utilizzare nel programma il FB SysUDPServer. Questo FB accetta e gestisce più connessioni sulla stessa porta quindi con un unico FB si possono gestire più convertitori e quindi più seriali.

Screenshot programma COMRemote

Comunicazione Multicast

Nelle comunicazioni in RS485 è normale avere un nodo master che comunica con più nodi slaves, ecco il programma COMMulticast dove un modulo CPU SlimLine invia i dati ricevuti dalla porta seriale verso più convertitori Ethernet/Seriale. Ipotizzando una comunicazione Modbus RTU su rete RS485 dove il nodo master è il dispositivo connesso al modulo SlimLine sarà necessario configurare i convertitori come server UDP.

Come si vede dal programma dopo il tempo definito in TxTime che non vengono più ricevuti caratteri dalla seriale i dati sono inviati verso tutti i convertitori configurati. Nello stesso modo dopo il tempo definito i dati ricevuti dai convertitori sono inviati alla seriale. Naturalmente in una comnicazione multidrop sarà solo uno dei nodi periferici connessi ai convertitori a rispondere.

Nel caso rispondesse più di un nodo periferico si sommerebbero i dati ricevuti dai vari convertitori in uscita sulla porta seriale dello SlimLine.

LogicLab (COMMulticast)
PROGRAM COMMulticast
VAR
    i : UDINT; (* Auxiliary variable *)
    ScNr : USINT; (* Serial converters number *)
    IDx : USINT; (* Server interface index *)
    ChNr : INT; (* Character number *)
    TimeBf : ARRAY[0..4] OF UDINT; (* Time buffer (uS) *)
    TxTime : UDINT := 10000; (* Transmit time (uS) *)
    DBSize : INT := 256; (* Data buffer size (SysRMalloc) *)
    DBuffer : STRING[ 256 ];    (* Data buffer *)
    Sp : SysSerialPort; (* Serial port management *)
    Sc : ARRAY[0..3] OF SysUDPClient; (* Serial converter *)
END_VAR

// *****************************************************************************
// PROGRAM "COMMulticast"
// *****************************************************************************
// This program allows to manage UDP multidrop connection to various ethernet to
// serial converters (ie ATC-1200). The converters act as server UDP and the CPU
// module acts as a client UDP. When data are received by the serial port of the
// CPU module they are immediately sent to all the converters and are
// transmitted to theirs serial port. When data are received back from the
// converter serial port they are immediately sent to the CPU that send out to
// its serial line.
// -----------------------------------------------------------------------------

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

    IF (SysFirstLoop) THEN

        ScNr:=TO_USINT(SIZEOF(Sc)/SIZEOF(Sc[0])); //Serial converters number

        // Initialize serial port.

        Sp.COM:=ADR('COM0'); //Serial port
        Sp.Baudrate:=115200; //Baud rate
        Sp.Parity:='E'; //Parity
        Sp.DataBits:=8; //Data bits
        Sp.StopBits:=1; //Stop bits
        Sp.DTRManagement:=DTR_AUTO_WO_TIMES; //DTR management

        // Initialize the server interface.

        FOR IDx:=0 TO ScNr-1 DO
            Sc[IDx].PeerPort:=5000; //Peer port
            Sc[IDx].LocalAdd:=ADR('0.0.0.0'); //Local address
            Sc[IDx].LocalPort:=0; //Local port
            Sc[IDx].FlushTm:=0; //Flush time (mS)
            Sc[IDx].LifeTm:=30; //Life time (S)
            Sc[IDx].RxSize:=256; //Rx buffer size
            Sc[IDx].TxSize:=256; //Tx buffer size
        END_FOR;

        // Set server IPs.

        Sc[0].PeerAdd:=ADR('192.168.0.90'); //Peer address
        Sc[1].PeerAdd:=ADR('192.168.0.91'); //Peer address
        Sc[2].PeerAdd:=ADR('192.168.0.92'); //Peer address
        Sc[3].PeerAdd:=ADR('192.168.0.184'); //Peer address
    END_IF;

    // -------------------------------------------------------------------------
    // COMMUNICATION STREAMS MANAGEMENT
    // -------------------------------------------------------------------------
    // Here are manged all communication streams.

    Sp(Open:=TRUE); //Serial port management
    FOR IDx:=0 TO ScNr-1 DO Sc[IDx](Connect:=TRUE); END_FOR;

    // -------------------------------------------------------------------------
    // SERIAL LINE TO CONVERTERS DATA EXCHANGE
    // -------------------------------------------------------------------------
    // When data are received by serial line are sent to converters.

    ChNr:=SysFGetIChars(Sp.File); //Character number
    IF (ChNr = 0) THEN TimeBf[0]:=SysGetSysTime(TRUE); END_IF;

    IF ((SysGetSysTime(TRUE)-TimeBf[0]) > TxTime) THEN
        ChNr:=Sysfread(ADR(DBuffer), DBSize, 1, Sp.File);
        FOR IDx:=0 TO ScNr-1 DO i:=Sysfwrite(ADR(DBuffer), ChNr, 1, Sc[IDx].File); END_FOR;
    END_IF;

    // -------------------------------------------------------------------------
    // CONVERTERS TO SERIAL LINE DATA EXCHANGE
    // -------------------------------------------------------------------------
    // When data are received by converters are sent to serial line.

    FOR IDx:=0 TO ScNr-1 DO
        ChNr:=SysFGetIChars(Sc[IDx].File); //Character number
        IF (ChNr = 0) THEN TimeBf[IDx+1]:=SysGetSysTime(TRUE); END_IF;
        IF ((SysGetSysTime(TRUE)-TimeBf[IDx+1]) > TxTime) THEN
            ChNr:=Sysfread(ADR(DBuffer), DBSize, 1, Sc[IDx].File);

            IF (SysFGetOSpace(Sp.File) < ChNr) THEN RETURN; END_IF;
            ChNr:=Sysfwrite(ADR(DBuffer), ChNr, 1, Sp.File);
        END_IF;
    END_FOR;

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