Vai al contenuto
Progettazione di Sistemi di Automazione

Programmare i PLC: IEC 61131-3, tempo di risposta e blocchi funzionali

I cinque linguaggi, tempo di risposta nel caso peggiore dimostrato con esempio, compiti e priorità, blocco funzionale in testo strutturato, buone pratiche di progetto e prova.

Il software di un impianto moderno può avere centinaia di migliaia di righe e restare in servizio per decenni, modificato da persone diverse. La norma IEC 61131-3 fissa i linguaggi dei PLC, ma scrivere un buon programma richiede anche le regole dell’ingegneria del software. In questa lezione vediamo i linguaggi della norma, il tempo di risposta del PLC nel caso peggiore con la dimostrazione e un esempio, i compiti e le priorità, i blocchi funzionali con un esempio in testo strutturato, e le buone pratiche di progetto e di prova.

I linguaggi

La IEC 61131-3 definisce cinque linguaggi, che possono convivere nello stesso progetto:

  • LD (ladder diagram, a contatti): lo schema a relè, leggibile dagli elettricisti, adatto alla logica booleana semplice (lezione sui PLC di Controllo dei processi);
  • FBD (function block diagram): blocchi collegati da fili, naturale per le regolazioni;
  • ST (structured text): un linguaggio testuale simile al Pascal, con espressioni, cicli e strutture; il più adatto ad algoritmi, calcoli e macchine a stati;
  • SFC: le sequenze (lezione sulle sequenze);
  • IL (instruction list), simile all’assembly, dichiarato obsoleto nella terza edizione della norma.

La terza edizione (2013) ha aggiunto la programmazione a oggetti: metodi, interfacce, ereditarietà dei blocchi funzionali.

Il ciclo e il tempo di risposta

Un PLC esegue in ciclo: legge tutti gli ingressi in un’immagine di memoria, esegue il programma su quell’immagine, scrive tutte le uscite. Il ciclo dura T_s, da meno di un millisecondo a qualche decina.

Tempo di risposta di un PLC nel caso peggiore
Ogni ciclo di durata T s comprende la lettura degli ingressi I, l’esecuzione del programma P e la scrittura delle uscite O. Se l’ingresso x cambia subito dopo la lettura, viene visto solo al ciclo successivo, e l’uscita y cambia alla fine di quel ciclo: circa due cicli dopo.

Teorema. Il tempo tra il cambiamento di un ingresso e il cambiamento dell’uscita che ne dipende è al massimo circa 2T_s, più i ritardi del filtro d’ingresso e dell’uscita.

Dimostrazione. Nel caso peggiore l’ingresso cambia subito dopo la lettura degli ingressi: il programma di quel ciclo usa ancora il valore vecchio, e il nuovo viene letto all’inizio del ciclo successivo, dopo quasi T_s. Il programma lo elabora e l’uscita viene scritta alla fine di quel ciclo, dopo un altro T_s. In totale quasi 2T_s, cui si sommano il filtro dell’ingresso (contro i rimbalzi e i disturbi) e il tempo di commutazione dell’uscita. ∎

Esempio. Ciclo di 10 ms, filtro d’ingresso di 3 ms, uscita a relè di 10 ms: fino a 2\cdot 10 + 3 + 10 = 33 ms. Un impulso d’ingresso più breve di un ciclo può addirittura non essere mai visto. Per eventi veloci si usano ingressi a interruzione, contatori veloci in hardware o compiti con ciclo più breve.

Compiti e priorità

Il programma si divide in compiti (task) con periodi e priorità diversi: un compito veloce (1-2 ms) per le funzioni critiche, uno normale (10-20 ms) per la logica, uno lento (100 ms o più) per le funzioni di servizio, più compiti attivati da eventi. È la stessa pianificazione a priorità fisse dei sistemi in tempo reale (lezione sui sistemi in tempo reale di Sistemi operativi): il carico dei compiti veloci va tenuto basso, e il PLC sorveglia il tempo di ciclo con un watchdog che porta le uscite in uno stato sicuro se viene superato.

Blocchi funzionali

Un blocco funzionale (FB) è un modulo con ingressi, uscite e memoria interna; se ne creano tante istanze quante sono le macchine uguali. La norma ne fornisce alcuni standard, come i temporizzatori (TON, TOF, TP) e i rilevatori di fronte (R_TRIG). Un esempio in testo strutturato: il comando di una pompa come macchina a stati, con protezione termica e riarmo.

FUNCTION_BLOCK FB_Pompa
VAR_INPUT
    Avvio, Arresto, Termico : BOOL;   (* Termico = relè termico scattato *)
END_VAR
VAR_OUTPUT
    Contattore, Allarme : BOOL;
END_VAR
VAR
    Stato : INT := 0;                 (* 0 ferma, 1 in marcia, 2 guasto *)
END_VAR

CASE Stato OF
    0:  Contattore := FALSE;
        IF Avvio AND NOT Arresto AND NOT Termico THEN Stato := 1; END_IF;
    1:  Contattore := TRUE;
        IF Termico THEN Stato := 2;
        ELSIF Arresto THEN Stato := 0; END_IF;
    2:  Contattore := FALSE;
        Allarme := TRUE;
        IF NOT Termico AND Arresto THEN   (* riarmo: guasto sparito e conferma *)
            Allarme := FALSE; Stato := 0;
        END_IF;
END_CASE;
END_FUNCTION_BLOCK

Ogni stato dichiara esplicitamente le uscite; il guasto ha la precedenza sull’arresto; il riarmo richiede che la causa sia sparita e un’azione dell’operatore, così la pompa non riparte da sola. Dieci pompe sono dieci istanze dello stesso blocco, provato una volta.

Buone pratiche

  • Struttura: blocchi piccoli con un compito chiaro; niente variabili globali usate ovunque; nomi parlanti e una convenzione condivisa.
  • Separazione tra logica di processo, gestione dei modi, allarmi e interfaccia con l’operatore.
  • Librerie di blocchi provati per i componenti ricorrenti (motori, valvole, regolatori), che rendono il codice uniforme e riducono gli errori.
  • Controllo delle versioni del codice, con la storia delle modifiche: gli ambienti moderni esportano i progetti in formato testuale (PLCopen XML) proprio per questo.
  • Prove: prove dei blocchi su simulatore, prove automatiche di regressione, e messa in servizio virtuale con un modello dell’impianto (lezione sulla messa in servizio).
  • Commenti che spiegano il perché, non il come.
  • Per il controllo del moto, le specifiche PLCopen standardizzano i blocchi (MC_MoveAbsolute e simili) tra costruttori diversi (lezione sugli azionamenti).
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
0
Would love your thoughts, please comment.x
()
x