Skip to content

Normative per PLC

Una norma è un insieme di specifiche che servono a standardizzare un certo ambito.

Nell’ambito dell’automazione industriale si è sentita l’esigenza di “normare”: avere una certa standardizzazione e una certa portabilità del software. Avere la possibilità di far girare lo stesso programma su PLC di ditte diverse.

Le normative, in tutto il mondo, sono emesse da due enti normatori:

  • ISO: emette norme di orientamento generale in quasi tutti i campi,
  • IEC: emette norme nel settore Elettrico ed Elettronico.

In Europa questa struttura si riflette sui due comitati tecnici “equivalenti”:

  • CEN: lavora al pari con l’ISO,
  • CENELEC: lavora al pari con l’IEC.

In Italia la situazione è praticamente la stessa con questi due enti:

  • UNI: lavora al pari con l’ISO, ed il CEN,
  • CEI: lavora al pari con l’IEC ed il CENELEC per le nome elettriche

La parte terza dello Standard, IEC 1131-3, definisce:

  • elementi comuni per la configurazione delle applicazioni, la dichiarazione di variabili, la strutturazione dei programmi.
  • Quattro linguaggi di programmazione, due di tipo grafico e due di tipo testuale (un quinto linguaggio, l’SFC, è definito in un’altra sezione della norma)
  • Funzioni e blocchi funzionali standard, per definire un set minimo di operazioni di conteggio, temporizzazione, elaborazioni matematiche, conversioni di tipo

La norma sconsiglia di scrivere un unico programma che controlla e dirige tutti gli aspetti di una macchina automatica o di un impianto, ma consiglia invece di scomporre il codice in più parti, ciascuna delle quali si occupa di un aspetto della macchina. Le varie parti del codice si scambiano informazioni per mezzo delle variabili in modo da poter gestire al meglio il processo da controllare.

  • tipi di dato e dichiarazioni delle variabili
  • POU, gli elementi di organizzazione dell’applicativo (Program Organization Units):
    • functions,
    • function blocks,
    • programs
  • Configurazione di sistema,
  • Resource
  • Tasks

Una variabile è un dato che il mio programma di controllo della macchina automatica deve memorizzare e gestire.

Si può dover gestire dati riferiti a:

  • produzione (numerici),
  • allarmi (valori booleani),
  • presenza pezzi (valori booleani),
  • conteggio dei pezzi lavorati (intero),
  • timer (tempo),
  • ora del giorno (orario),
  • valore numerico di grandezze rilevate dai sensori analogici (numeri con la virgola),
  • messaggi da visualizzare su HMI (stringe di caratteri alfanumerici).

Ogni variabile risiede in memoria e possiede:

  • nome: corrisponde all’indirizzo in memoria,
  • tipo: tipo di informazioni contiene e quanto spazio occupa in memoria,
  • contenuto: valore attuale della variabile,
  • classe di visibilità: chi può vedere la variabile (in programmazione è detta appunto visibility).

Una variabile può avere anche degli attributi.

I tipi di dato possono essere: base o derivati.

I tipi di dato base sono:

  • booleani: BOOL,
  • interi: INT,
  • reali: REAL,
  • data e ora: DATE, TIME, DATE AND TIME,
  • stringhe di caratteri: STRING.

Ognuno di questi tipi di dato può a sua volta avere sotto-categorie in base a diversi criteri.

In base al numero di bit che occupano, gli interi si suddividono in:

  • intero a 8 bit: BYTE,
  • intero a 8 bit: SHORT INT,
  • intero a 16 bit: INT,
  • intero a 32 bit: DOUBLE INTEGER (DINT).

A partire dal numero di bit scelto, lo stesso range di valori utilizzabile potrebbe partire da 0 o essere centrato nello zero.

Nel primo caso si ammettono solo valori positivi, dunque UNSIGNED. Nel secondo caso si ammettono valori sia positivi che negativi, dunque SIGNED. Se non specificato, si sottintende che una variabile sia SIGNED.

Ad esempio: data una variabile INT a 16 bit: 216=655362^{16} = 65536. Un INT di tipo SIGNED và da:

215    (2151)    32768    32767-2^{15} \; \dots \; (2^{15}-1) \implies -32768 \; \dots \; 32767

Un INT di tipo UNSIGNED và da:

0    (2161)0 \; \dots \; (2^{16}-1)

Il “-1” serve per poter mettere anche lo zero tra i valori disponibili.

Si distinguono quindi ulteriori casi per gli interi:

  • intero a 8 bit: BYTE,
  • intero a 8 bit: SHORT INT (SINT),
  • intero a 8 bit: USIGNED SHORT INT (USINT),
  • intero a 16 bit: INT (INTEGER),
  • intero a 16 bit: UINT (UNSIGNED INTEGER),
  • intero a 32 bit: DINT (DOUBLE INTEGER),
  • intero a 32 bit: USIGNED DOUBLE INTEGER (UDINT).

La sintassi per dichiarare una variabile è del tipo:

nome_variabile: TIPO_DI_DATO;

Ad esempio:

fotocellula: BOOL;

Se in fase di dichiarazione si vuole attribuire un valore iniziale, dopo il tipo di dato, si può aggiungere := ed il valore iniziale:

fotocellula: BOOL := true;

La norma sancisce che ogni variabile deve avere un valore iniziale. Se questo non viene definito nel programma, gli viene assegnato il valore di default nullo (e D#0001-01-01 per le date).

Assegnazione di un valore ad una variabile di tipo TIME

Section titled “Assegnazione di un valore ad una variabile di tipo TIME”

L’assegnazione di un valore ad una variabile di tipo TIME prevede una sintassi in cui si usa il carattere T e il carattere speciale #.

Esempio: una variabile di nome mio_tempo di tipo TIME che, come valore iniziale, ha 5 secondi.

VAR
mio_tempo: TIME := T#5S;
END_VAR

Esempio: una variabile di nome mio_tempo1 di tipo TIME che, come valore iniziale, ha 300 millisecondi.

VAR
mio_tempo1: TIME := T#300ms;
END_VAR

Tipi di dato derivati/definiti dall’utente

Section titled “Tipi di dato derivati/definiti dall’utente”

La tipizzazione dei dati permette di eliminare incongruenze ed errori già in fase di compilazione e semplifica il compito del programmatore.

L’utilizzo di tipi di dato derivato contribuisce alla leggibilità del software (miglioramento della qualità del software).

I tipi di dato derivato possono essere definiti con la sintassi:

TYPE Nome_Tipo:
Descrizione
END_TYPE

Il nuovo tipo può essere:

  • ALIAS: un tipo standard che viene ridefinito per comodità,
  • subrange di un tipo standard, la descrizione del tipo è: TipoStandard (ValoreIniz..ValoreFin).
  • enumerativo: elenco di valori costanti che la variabile può assumere,
  • vettore di dimensione finita: ARRAY [Intervallo di Interi] OF Tipo
  • struttura: insieme di variabili di tipo non omogeneo, si scrive STRUCT Var1:Tipo1 … VarN:TipoN END_STRUCT

Si vuole definire tre variabili che contengono valori di pressione. Un modo per farlo sarebbe:

VAR
pump1, pump2, pump3: REAL;
END_VAR

Per rendere il software più chiaro, si potrebbe definire un nuovo tipo di dato chiamato PRESSURE che sia un alias di REAL. Il codice diventerebbe:

TYPE
PRESSURE: REAL;
END_TYPE
VAR
pump1, pump2, pump3: PRESSURE;
END_VAR

Si definisce il tipo MACHINE_STATUS per mezzo del costrutto TYPE. MACHINE_STATUS è un set di valori che sono scritti come alfanumerici ma non sono stringhe (non sono racchiusi dagli apici). Si definisce una variabile chiamata STATUS di tipo MACHINE_STATUS che ha un valore compreso (e che può variare) tra quelli definiti nella definizione del tipo MACHINE_STATUS.

TYPE
MACHINE_STATUS: (STOP, RUN, FAULT, STANDBY);
END_TYPE
VAR
STATUS: MACHINE_STATUS;
END_VAR
(* a quanto pare questo è un commento *)
(* nel algoritmo si può scrivere*)
IF STATUS = STOP THEN
...
...
...
END_IF

Il codice poi controlla che STATUS sia uguale al valore equivalente a STOP e, in tal caso, effettua delle operazioni.

Si può, ad esempio, ridurre il range degli interi. Come detto prima, una variabile intera può assumere valori da -32768 a +32767. Se si vuole ridurre il range di una variabile intera in modo che assuma solo valori tra +6 e +12 si può scrivere:

TYPE
MOTOR_VOLTS: INT(-6..+12)
END_TYPE

Il numero massimo della dimensione dei vettori dipende dalla implementazione e non è definito dalla norma. Nell’esempio che segue, si definisce POINTS come un array di numeri reali.

TYPE
POINTS: ARRAY [1..100] OF REAL;
END_TYPE

Si può inoltre definire una matrice, ovvero un array bi-dimensionale che possiede righe e colonne:

TYPE
MATRIX_POINTS: ARRAY [1..10, 1..100] OF REAL;
END_TYPE

Ovviamente si possono utilizzare variabili al posto dei valori numeri (se definite di tipo INT) e degli alias al posto del tipo di dato di cui è riempita la matrice o l’array.

La caratteristica dello struct è che i suoi campi sono generalmente di tipo diverso. Lo struct PRESSURE_SENSOR contiene: un numero reale, un byte, una data e infine un array di interi:

TYPE PRESSURE_SENSOR:
STRUCT
VALUE : REAL;
STATUS : BYTE;
CALIBRATION : DATE;
CALIBRATION_PARAMETERS : ARRAY[0..10] OF INT;
END_STRUCT;
END_TYPE

Come detto sopra, un unico programma che gestisce tutta la macchina non è tendenzialmente una buona idea. Diversi programmi devono quindi condividere le stesse variabili per gestire varie parti della macchina. Entra in gioco la classe di visibilità delle variabili per definire quali parti di software possono accede a quali variabili e con quali privilegi (lettura o scrittura).

Le variabili di access path sono visibili da configurations remote (quindi da altre CPU) come ad esempio i bus di campo.

Si può definire una variabile di tipo access path come segue:

VAR_ACCESS
MY_VAR: INT;
END_VAR

Le variabili globali sono visibili da tutte le parti del codice, da tutti i programmi, le funzioni e i function block:

VAR_GLOBAL
MY_VAR: INT;
END_VAR

Le variabili locali sono visibili solo dal modulo di codice che le dichiara:

VAR
MY_VAR: INT;
END_VAR

Le variabili di input sono visibili ma non modificabili dal codice chiamante:

VAR_INPUT
MY_VAR: INT;
END_VAR

Le variabili di input/output sono visibili e modificabili dal codice chiamante:

VAR_IN_OUT
MY_VAR: INT;
END_VAR

Le variabili di output sono… la descrizione non è chiara:

VAR_OUTPUT
MY_VAR: INT;
END_VAR

Gli attributi per le variabili sono opzioni da aggiungere dopo la keyword che identifica il tipo di variabile. Questi attributi possono essere:

  • RETAIN: indica che il valore delle variabili dichiarate in tale sezione deve essere ricordato anche in caso di caduta di alimentazione del PLC (memoria “tamponata” da batteria),
  • CONSTANT: il loro valore non può essere modificato nel programma. Nella dichiarazione occorre quindi anche inizializzarle al valore desiderato,
  • AT: seguito da un indirizzo fisico della memoria di sistema, indica che il nome della variabile rappresenta un alias per l’indirizzamento diretto.

Le variabili non indirizzate direttamente, se non hanno l’attributo AT, vengono allocate nella memoria di lavoro del PLC.

Esempi:

VAR_GLOBAL CONSTANT
presenza: BOOL := TRUE;
END_VAR
VAR_GLOBAL CONSTANT
max_pezzi_lavorati: INT := 1000;
END_VAR
VAR_GLOBAL RETAIN
num_pezzi_lavorati: INT;
END_VAR
VAR_GLOBAL
proximity_switch: BOOL AT %I0.3;
END_VAR

Memoria dati temporanea e indirizzamento diretto dell’hardware

Section titled “Memoria dati temporanea e indirizzamento diretto dell’hardware”

Variabili che riferiscono la memoria dati temporanea e variabili ad indirizzamento diretto dell’hardware.

Se si dichiara come variabile un nome che si riferisce a:

  1. morsetto fisico di ingresso,
  2. morsetto fisico di uscita,
  3. locazione fisica della memoria.

La norma prevede di dover specificare l’indirizzo con:

  • simbolo % seguito da lettera identificativa:
    • I: ingresso (physical input),
    • O o Q: uscita (physical output),
    • M: memoria merker (registro di memoria).
  • due numeri che codificano la posizione del morsetto o del registro in memoria:
    • il primo numero è il byte address,
    • il secondo numero è il bit address relativo al byte.

Il prefisso %M si riferisce alla memoria merker (memoria M), un’area di memoria che viene persa al riavvio del PLC, a meno che non sia esplicitamente configurata per essere conservata. Questo approccio è comunemente usato nella programmazione dei PLC quando si lavora con bit di memoria globali, flag o mappatura diretta degli I/O. L’area %M viene spesso utilizzata per:

  1. variabili temporanee: risultato intermedio, non deve “sprecare” un uscita fisica del PLC,
  2. segnali di interblocco (interlocking signals).

I merker possono essere sia digitali che analogici. Non tutti gli ambienti di sviluppo di produttori di PLC fanno uso di merker: alcuni utilizzano semplici variabili locali.

VAR
myVar: BOOL AT %M0.0;
END_VAR

Elenco di tutti i moduli hardware collegati al PLC ed i loro parametri (indirizzi, velocità, tempo di watchdog, …). In un sistema di controllo è possibile avere anche diverse configuration comunicanti tra loro, ognuna delle quali gestisce uno o più PLC.

Ogni configuration contiene una o più resource (sinonimo di modulo CPU).

Ogni resource contiene uno o più program, eseguiti sotto il controllo di zero o più task.

Un program può contenere zero o più function block (FB) e la chiamata a zero o più function.

Configurazione dell’applicazione: insieme di tutte le risorse hardware che si usano nell’applicazione.

Caratteristiche di una resource:

  • accede alle global ed alle directly represented variables (le variabili con attributo AT),
  • è l’interfaccia tra I/O fisici ed il programma.

Situazione comune: un PLC con una CPU (in nero nel disegno).

conf-app-1

Situazione: più PLC distinti collegati tramite una rete di bus di campo. Ogni PLC ha una CPU.

conf-app-2


Il codice dell’applicativo si suddivide in moduli di codice:

  • Program,
  • Function Block,
  • Function.

Questi moduli di codice sono chiamati POU.

Il program è la POU più “potente” e complessa. La function è la POU più semplice che offre meno possibilità (non può gestire tutti i tipi di variabile e non può essere scritta in tutti i linguaggi).

Si compone di due parti:

  1. dichiarazione di variabili,
  2. parte di codice.

Il program può dichiarare ed utilizzare variabili di qualunque tipo e classe di visibilità (anche le VAR_ACCESS).

Il codice del program può essere scritto in qualunque linguaggio di programmazione della norma. Un program può chiamare sia function block che funzioni, ma non viene chiamato da nessuno quindi non restituisce variabili.

Il meccanismo che chiama un programma è il TASK (che si vedrà in seguito).

POU di tipo intermedio. Si compone di due parti:

  1. dichiarazione di variabili,
  2. parte di codice.

Il FB non può dichiarare variabili globali né di tipo ACCESS PATH. Il codice del FB può essere scritto in qualunque linguaggio di programmazione della norma. Un FB può chiamare sia altri FB che funzioni e viene a sua volta chiamato o da FB, o da funzioni o da program. Quando viene chiamato, può restituire n variabili di uscita.

Le variabili di un FB sono statiche, ovvero tra una chiamata e la successiva il loro valore viene mantenuto in memoria. Se si passano sempre le stesse variabili di input, in base al valore delle variabili statiche, l’output del FB potrebbe essere differente.

In fase di programmazione, si può avere bisogno di variabili non statiche anche dentro ad un function block. La norma mette a disposizione un altro costrutto per la dichiarazione delle variabili di un function block, che le rende non statiche.

VAR_TEMP
a: REAL;
c: TIME;
END_VAR

La norma prevede che tutti gli IDE per la programmazione dei PLC che si vogliano dichiarare conformi ad essa, debbano fornire al programmatore la possibilità di:

  1. usare un set di FB già predefiniti,
  2. scrivere FB autonomamente.

Tra quelli predefiniti, che devono essere già a disposizione del programmatore, devono esserci almeno:

  1. timer Ton, Toff e Tp,
  2. contatori avanti e indietro,
  3. rilevatori dei fronti di salita e discesa.

La spiegazione di questi FB sarà fornita nel modulo didattico che riguarda la programmazione.


Dichiarazione testuale di un FB di nome FF_SERVO di tipo SR (Set Reset):

VAR
FF_SERVO: SR;
END_VAR
FF_SERVO(S := B, R := C); (* invocation *)
A := FF_SERVO.Q; (* assign output *)

Siccome un function block non restituisce un unico valore, come invece fa la funzione, per usarlo devo sempre scrivere due istruzioni:

  1. invocazione del FB,
  2. assegnazione di una uscita del FB alla variabile del codice.

Dichiarazione grafica:

FF_SERVO-visual

Esempi di FUNCTION BLOCKS standard definiti dalla norma 61131-3

Section titled “Esempi di FUNCTION BLOCKS standard definiti dalla norma 61131-3”

Function block timer on: ritardo all’inserzione.

Ingressi: IN (di tipo BOOL) e PT (di tipo TIME). Uscite: Q (di tipo BOOL) ed ET (di tipo TIME).

Quando ciò che è collegato a IN va a true, dopo PT secondi (o millisecondi) l’uscita Q va a true, e torna a false quando IN torna a false.

TON


Function block timer off: ritardo alla disinserzione.

TOFF

Ingressi: IN (di tipo BOOL) e PT (di tipo TIME). Uscite: Q (di tipo BOOL) ed ET (di tipo TIME).

Quando ciò che è collegato a IN va a true, Q va subito a true. Quando ciò che è collegato a IN va a false, dopo PT secondi (o ms) l’uscita Q torna a false.


Up counter: contatore in avanti.

CTU

Con un fronte di salita su RESET, azzera il termine del conteggio CV poi conta i fronti di salita su CU. Quando il valore di conteggio raggiunge PV, Q va alto.


Down counter: contatore all’indietro.

CTD

Con un fronte di salita su LOAD, inizializza il contatore CV al valore di PV e lo decrementa ad ogni fronte di salita di CU. Quando il valore di conteggio si annulla, Q va alto.

Il LOAD è equivalente al RESET. Invece di resettare, in questo caso si deve ricaricare il valore di partenza.


Un function block è istanziato a livello di program o di un altro function block. Il program è istanziato a livello di resource. Ogni istanza di un program o di un function block condivide lo stesso codice, ma ha la sua area dati privata in memoria.

Nell’ambito dello stesso program, è possibile utilizzare più istanze diverse dello stesso function block.

Cos’è un’istanza? Cosa vuol dire che un function block è istanziato a livello di program o di un altro function block?

Esempio: si prenda il caso di uno struct in linguaggio C.

TYPEDEF struct {
primo_campo: int;
secondo_campo: char
} my_record;

Il tipo di dato my_record è definito una sola volta al di fuori di tutte le funzioni e viene istanziato ogni volta che dichiaro una variabile di tipo my_record all’interno di una qualche funzione.

Ogni istanza occupa un’area di memoria dati.

Nel caso del FB per PLC, invece che di variabili si parla di una POU (insieme di variabili e codice).

L’FB si può definire dentro ad un program o dentro ad un altro FB, ma poi ogni volta che si vuole avere la possibilità di richiamare questo FB, lo si deve istanziare.

L’istanziazione è praticamente una dichiarazione:

VAR
counter1: counter;
END_VAR

A questo punto, se in qualche riga di codice si invoca counter1, si manderà in esecuzione un codice di tipo counter.


Perché ogni volta che si istanzia un FB si accede sempre alla stessa area di codice ma si riserva un’area dati diversa?

Esempio: contare due tempi diversi. Il sistema ha due controlli:

  • quando premi il pulsante P1, dopo 3 secondi accendi la luce L1,
  • quando premi il pulsante P2, dopo 5 secondi apri il portello Q2.

Il codice del temporizzatore, ovvero le istruzioni usate per controllare il tempo, è sempre lo stesso. I due tempi non si devono sovrapporre o incrociare, perché le due funzioni devono rimanere distinte. Quindi si hanno due istanze di Ton: l’algoritmo di controllo tempo è sempre lo stesso, ma i due tempi sono memorizzati nelle due aree diverse assegnate alle due istanze del timer ON.

I due tempi partono e terminano in due istanti diversi, quindi ognuno deve essere separato e avere una sua locazione indipendente di memoria.


Sul concetto di istanza si è innestata la terza edizione della norma IEC61131 per estendere il function block ad un modello ad oggetti. L’ultima edizione della norma infatti incoraggia l’OOP.

Si compone di una parte di dichiarazione di variabili e di una parte di codice. La funzione può dichiarare solo variabili locali e di input. Il codice di una funzione non può essere scritto nel linguaggio SFC.

Quando viene chiamata, la funzione restituisce al chiamante solo una variabile. Le variabili locali della funzione si resettano ad ogni chiamata, quindi sono volatili. Una funzione non ha memoria dell’esecuzione precedente. Ne consegue che ogni volta che si richiama una function passandole gli stessi parametri di ingresso, essa produrrà potenzialmente sempre la stessa uscita.

La definizione di una function creata dal programmatore richiede:

  • lista di variabili d’ingresso ed interne (temporanee),
  • descrizione dell’algoritmo implementato dalla funzione.

Tale algoritmo può essere implementato in un qualunque linguaggio della norma ad esclusione dell’SFC.

Esempio di function scritta in modo testuale:

FUNCTION SIMPLE_FUN : REAL
VAR_INPUT
A,B: REAL;
C: REAL := 1.0;
END_VAR
(* body specification: set the return value of the function *)
SIMPLE_FUN := A * B / C;
END_FUNCTION

La norma prevede che tutti gli IDE per la programmazione dei PLC che si vogliano dichiarare conformi ad essa, debbano fornire al programmatore la possibilità di:

  1. usare un set di funzioni già predefinite,
  2. scrivere funzioni proprie.

Tra quelle predefinite, che devono essere già a disposizione del programmatore, devono esserci almeno:

  1. tutte le funzioni aritmetico/logico/matematiche (somma, sottrazione, moltiplicazione, divisione, AND, OR, NOT, seno, coseno, …),
  2. tutte le funzioni di confronto (›=, ›, ‹=, ‹, =, ‹› per il “diverso”),
  3. tutte le funzioni di manipolazione di bit (SHL, SHR, ROL, ROR, …),
  4. tutte le funzioni per gestire le stringhe (INSERT, CONCAT, …),
  5. tutte le funzioni per convertire il formato dei numeri (INT TO REAL, BCD TO INT).

Program:

  • può essere scritto in qualsiasi linguaggio,
  • gestisce tutti i tipi di variabile,
  • non restituisce alcun valore di ritorno,
  • opera con variabili statiche,
  • può chiamare function e function block,
  • è eseguita quando chiamata da un task.

Function Block:

  • può essere scritto in qualsiasi linguaggio,
  • non gestisce variabili di tipo global e access,
  • restituisce n variabili di output,
  • opera con variabili statiche,
  • può chiamare function e function block,
  • è eseguita quando chiamata da un’altra POU.

Function:

  • non può essere scritta in lingiaggio SFC,
  • può gestire solo variabili di tipo local e input,
  • restituisce una sola variabile,
  • opera con variabili volatili,
  • può chiamare function e function block,
  • è eseguita quando chiamata da un’altra POU.

Il task è un processo software che si occupa di controllare e mettere in esecuzione un program, facendo in modo di assegnarlo al processore.

Può essere di due tipi:

  • INTERVAL: periodico,
  • SINGLE: mandato in esecuzione al verificarsi di un determinato evento.

N.B. Un program è solo un insieme di righe di codice e di dichiarazioni di variabili, che non interagisce con l’hardware se non viene mandato in esecuzione da un task.

Priorità del task: task a priorità maggiore possono interrompere task a priorità minore. La priority si identifica con un numero intero a partire dallo zero.

Eccezioni alla norma. Non tutti i PLC funzionano allo stesso modo. Ad esempio, l’ambiente di sviluppo dei PLC B&R non ammette task ad evento, ma solo ciclici (chiamati Cyclic). Sarà cura del programmatore associare ai task più veloci i compiti più critici.

Codesys ammette, oltre ai task interval (chiamati Cyclic) e single (chiamati Triggered by event), anche il task freewheeling che prevede la riesecuzione a ciclo continuo di un program senza aspettare un determinato tempo fisso. Appena l’esecuzione è terminata, riprende.

La norma IEC61131 è una norma mondiale, in continua evoluzione, che definisce le caratteristiche dell’ambiente di programmazione (IDE, Integrated Development Environment) tipico per la programmazione dei PLC. Alcuni produttori seguono la norma praticamente alla lettera, altri la seguono parzialmente. Anche i produttori che seguono scrupolosamente la norma possono comunque avere, nel loro ambiente di sviluppo, opzioni in numero maggiore rispetto a quanto espresso dalla norma stessa.

La maggior parte delle volte, cambiando marca di PLC e quindi ambiente di sviluppo, si devono fare degli aggiustamenti nel software. Siemens, leader di mercato, soddisfa la norma per quel che riguarda i linguaggi di programmazione, ma è totalmente diverso dalla norma per quel che riguarda l’architettura di un progetto software. POU e task sono gestiti in modo completamente diverso.

I più importanti IDE per la programmazione di PLC delle maggiori famiglie sono riportati di sotto. Una stessa marca può avere più IDE diversi per famiglie diverse dei suoi prodotti. Ad esempio, Siemens ha TIA Portal per le CPU più moderne e performanti, mentre per la serie dei PLC compatti Logo! ha un IDE che si chiama Logo Soft Comfort.

  • TIA Portal: Siemens,
  • RSLogix: Rockwell – Allen Bradley,
  • Automation Studio: B&R,
  • Twincat: Beckhoff,
  • CX-One: Omron