Utilizzare FB connesse con modello a cascata

List

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

Il modello a cascata, conosciuto come “waterfall model”, è il più classico dei modelli per il ciclo di vita del software. Prevede l’esecuzione lineare di una precisa sequenza di fasi, ciascuna delle quali genera un output utilizzato come input dalla fase successiva (da qui l’origine del termine “a cascata”).

Nella librerie da noi fornite abbiamo esteso questo modello di approccio sequenziale alla esecuzione di molti blocchi funzione. I vari FB vengono eseguiti sequenzialmente, il termine della esecuzione di un FB abilita l’esecuzione di quello successivo. In questo modo avendo sempre un unico FB in esecuzione è possibile condividere la stessa risorsa (Esempio uno stream di comunicazione) tra i vari FB.

Quasi tutti i blocchi funzione hanno un ingresso di Enable che ne abilita il funzionamento ed una uscita di Done che si attiva al termine della esecuzione. Nei FB realizzati per poter essere connessi con modello a cascata l’uscita Done rimane attiva fino alla disabilitazione dell’ingresso Enable così da essere connessa all’ingresso Enable del FB successivo per abilitarne il funzionamento.

Modello a cascata

Modello a cascata in pratica

Vediamo come sia possibile realizzare un programma con modello a cascata:

  • Un FB viene abiltato attivando il suo ingresso di Enable, quando il FB ha terminato il suo compito attiva la sua uscita Done che rimarrà attiva fino alla disabilitazione dell’ingresso Enable.
  • L’uscita Done del primo FB viene connessa all’ingresso Enable di un secondo FB che inizierà il suo compito al termine del quale attiverà la sua uscita Done che rimarrà attiva fino alla disabilitazione dell’ingresso Enable.
  • E così di seguito l’uscita Done di un FB potrà collegarsi all’ingresso Enable di un successivo FB fino a completare la catena. Quando un FB termina il suo compito il successivo inizia il suo.
  • L’uscita Done dell’ultimo FB della catena sarà connessa in modo negato all’ingresso Enable del primo. In questo modo quando si attiverà si resetta l’Enable del primo che disabiliterà la sua uscita Done ed in cascata l’Enable del successivo, fino all’ultimo FB della catena, che, disabilitando l’Enable disabiliterà il Done riabilitando l’Enable del primo FB della catena. Questo farà ripartire la sequenza di esecuzione di tutti gli FB della catena.

Ma credo sia più intuitivo vederne l’applicazione pratica che non a seguirne la descrizione teorica, ecco quindi di seguito il programma FBD_SDM120Waterfall che esegue l’acquisizione di alcuni registri Modbus da un contatore di energia SDM120. Siccome i valori acquisiti hanno MSB/LSB invertiti su Ok di ogni acquisizione ne eseguo lo swap.

PROGRAM FBD_SDM120Waterfall
VAR
    Sp : SysSerialPort; (* Serial port *)
    Mdb0 : ModbusMaster_v3; (* Modbus master FB *)
    Mdb1 : ModbusMaster_v3; (* Modbus master FB *)
    Mdb2 : ModbusMaster_v3; (* Modbus master FB *)
    ACQ : DWORD; (* Value acquisition *)
    VOLTAGE : REAL; (* Line voltage *)
    FREQUENCY : REAL; (* Line frequency *)
    ACTIVEPOWER : REAL; (* Active power *)
END_VAR
Programma FBD_SDM120Waterfall

Esempi

Come utilizzare gli esempi
ST_SDM120Waterfall: Lo stesso esempio realizzato precedentemente in linguaggio FBD realizzato in linguaggio ST che ne permette una facile integrazione nel proprio programma.

LogicLab (Ptp141, ST_SDM120Waterfall)
PROGRAM ST_SDM120Waterfall
VAR
    i : UDINT; (* Aux counter *)
    Sp : SysSerialPort; (* Serial port *)
    Mdb : ARRAY[0..2] OF ModbusMaster_v3; (* Modbus master FB *)
    Acq : DWORD; (* Value acquisition *)
    Voltage : REAL; (* Line voltage *)
    Frequency : REAL; (* Line frequency *)
    ActivePower : REAL; (* Active power *)
END_VAR

// *****************************************************************************
// PROGRAM "ST_SDM120Waterfall"
// *****************************************************************************
// An example how to write a program realized with the watwrfall model.
// -----------------------------------------------------------------------------

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

    IF (SysFirstLoop) THEN

        // Serial port settings.

        Sp.COM:=ADR('COM2'); //COM port definition
        Sp.Baudrate:=2400; //Baudrate
        Sp.Parity:='N'; //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

        // Modbus master settings.

        FOR i:=0 TO (SIZEOF(Mdb)/SIZEOF(Mdb[0]))-1 DO
            Mdb[i].SpyOn:=TRUE; //Spy On
            Mdb[i].Type:=0; //Modbus type
            Mdb[i].Absolute:=FALSE; //Absolute addressing
            Mdb[i].Node:=1; //Modbus node
            Mdb[i].FCode:=16#04; //Modbus function code
            Mdb[i].Timeout:=0.2; //Timeout time (S)
            Mdb[i].Delay:=0.1; //Delay time (S)
            Mdb[i].Points:=2; //Modbus register points
            Mdb[i].Buffer:=ADR(Acq); //Memory buffer address
        END_FOR;

        // SDM120 register settings.

         Mdb[0].Address:=1; //Modbus register address
         Mdb[1].Address:=71; //Modbus register address
         Mdb[2].Address:=13; //Modbus register address
    END_IF;

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

    Sp(Open:=TRUE); //Serial port management

    // Modbus management.

    Mdb[0](Enable:=NOT(Mdb[2].Done), File:=Sp.File); //Modbus master
    IF (Mdb[0].Ok) THEN i:=SwapData(ADR(Voltage), ADR(Acq), REAL_TYPE, SWAP_HALF); END_IF;

    Mdb[1](Enable:=Mdb[0].Done, File:=Sp.File); //Modbus master
    IF (Mdb[1].Ok) THEN i:=SwapData(ADR(Frequency), ADR(Acq), REAL_TYPE, SWAP_HALF); END_IF;

    Mdb[2](Enable:=Mdb[1].Done, File:=Sp.File); //Modbus master
    IF (Mdb[2].Ok) THEN i:=SwapData(ADR(ActivePower), ADR(Acq), REAL_TYPE, SWAP_HALF); END_IF;

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