Automazione Industriale – Esempi di programmazione IEC 61131-3
Transcript
Automazione Industriale – Esempi di programmazione IEC 61131-3
Automazione Industriale – Esempi di programmazione IEC 61131-3 Marcello Bonfè Dipartimento di Ingegneria Universita’ di Ferrara Novembre 2001 Capitolo 1 Linguaggi di programmazione base dello Standard IEC 61131-3 1.1 Introduzione Lo Standard IEC 61131-3 definisce gli elementi basilari la programmazione di sistemi di controllo basati su Controllori Logici Programmabili (PLC), quali linguaggi, tipi di dato, unità organizzative del software. I dispositivi di controllo commerciali, d’altra parte, hanno molto spesso caratteristiche peculiari fortemente legate alla Casa Costruttrice, come: • l’esatta sintassi del (o dei) linguaggi di programmazione supportati dall’ambiente di sviluppo. • le modalità di dichiarazione ed utilizzo delle variabili di programma. • i costrutti per la scomposizione del software in moduli riutilizzabili. Tuttavia, è innegabile che le metodologie e le tecniche di programmazione siano maggiormente in relazione con la funzionalità svolta da un certo dispositivo di controllo, piuttosto che con le sue caratteristiche hardware. Pertanto, si desidera fornire con questi pochi esempi di programmazione, basati sulla sintassi dei linguaggi standardizzati nel documento IEC 61131-3, un primo approccio, generico e svincolato da particolari tecnologie proprietarie, alle problematiche di Controllo Logico e Supervisione tipiche dell’Automazione Industriale. Sebbene lo Standard non sia vincolante sintatticamente come avviene per altri linguaggi di programmazione (ANSI C, Java, ecc.), si auspica che l’acquisizione dei suoi concetti basilari da parte dello studente permetta comunque una fase di apprendistato sui sistemi reali, (eventualmente) fronteggiati in futuro, più agevole (o almeno, meno “ostica”...). Dal punto di vista pratico, nonostante il linguaggio maggiormente diffuso nella programmazione dei PLC sia il Ladder Diagram, in virtù della sua semplicità di comprensione anche da parte di tecnici (in particolare elettrotecnici) grazie alla similitudine con i diagrammi elettromeccanici a contatti e bobine (relè) utilizzati fino a qualche decina di anni fa nell’Automazione Industriale, si vedrà come le stesse problematiche possano essere risolte in modo equivalente in ciascuno dei linguaggi IEC 61131-3. 1.2 Controllo dell’avviamento di dispositivi di attuazione Molte delle operazioni tipiche del controllo di Macchine Automatiche sono riconducibili alla abilitazione di una singola uscita booleana, che potrebbe essere il comando di avviamento di un semplice dispositivo di attuazione, per tutta la durata della produzione dell’impianto. Un esempio di tale necessità è rappresentata dalla movimentazione di nastri trasportatori, i quali devono fare scorrere il prodotto all’interno dell’impianto automatizzato fintanto che tutte le macchine sono in funzione, 2 i quali sono normalmente azionati da motori elettrici la cui velocità viene regolata meccanicamente in funzione del carico del nastro. Per tali motori è quindi sufficiente la chiusura del contatto di alimentazione tramite un segnale logico in uscita dal PLC. Tale segnale sarà disabilitato in funzione dell’arresto della macchina, sia esso dovuto al termine “normale” della produzione o ad una condizione di emergenza. Ipotizzando di avere dichiarato le seguenti variabili: VAR Avvio_Macchina: BOOL AT %I0.0; Stop_Macchina: BOOL AT %I0.1; Emergency: BOOL AT %M0.0; Motore_Nastro: BOOL AT %Q0.0; END_VAR uno schema di programma classico per l’avvio del motore del nastro trasportatore è rappresentato dal seguente segmento di codice LD, che realizza la cosiddetta “bobina con autoritenuta”: | Avvio_Macchina Emergency Stop_Macchina Motore_Nastro | +-----| |---------+------|/|----------|/|---------------( )------+ | | | | Motore_Nastro | +-----| |---------+ | Ricordando che la scansione del programma da parte del PLC avviene in modo ciclico, e che il valore delle variabili di memoria e di uscita viene mantenuto tra due cicli di elaborazione successivi, la valutazione del segmento permette l’inserimento del motore del nastro quando il segnale Avvio Macchina è vero anche per un solo ciclo di elaborazione, mantre per tutti i cicli successivi verrà mantenuto grazie al passaggio di “corrente virtuale” nel contatto condizionato dal valore dell’uscita Motore Nastro (autoritenuta). Tale bobina sarà eccitata fintanto che non si ha un valore vero nè dall’ingresso Stop Macchina, nè dalla condizione di allarme Emergency, variabile di memoria interna del PLC modificata in altri segmenti di programma in funzione di eventuali condizioni di malfunzionamento generale della macchina. Naturalmente, questo semplice segmento può essere modificato in maniera molto intuitiva per considerare altre condizioni necessarie all’avviamento o sufficienti per lo spegnimento, rispettivamente inserite nel ramo a monte della diramazione di autoritenuta o a valle di essa. Come si può notare, tale schema risulta perfettamente compatibile con la creazione di un circuito elettromeccanico reale, in quanto non utilizza nessun tipo di istruzione diversa da operazioni puramente logico-combinatorie. Inoltre, anche la sua implementazione con il linguaggio Instruction List (IL) risulta di facile lettura: LD OR ANDN ANDN ST Avvio_Macchina Motore_Nastro Emergency Stop_Macchina Motore_Nastro Un’altra situazione molto comune nell’utilizzo di un attuatore semplice come un motore elettrico direttemente connesso all’alimentazione, è quella nella quale il motore può essere alimentato in modalità perfettamente simmetrica, in maniera tale che si possa selezionarne anche la direzione 3 di marcia. In questo caso, una semplice soluzione consiste nel controllare l’abilitazione dei comandi di rotazione oraria o anti-oraria con segmenti analoghi al precedente, ma nei quali sia inserito un “interblocco” che impedisca un’attivazione contemporanea dei due segnali (condizione che provocherebbe un cortocircuito sui terminali del motore). VAR ... Rotaz_Sx:BOOL AT %M0.1 Rotaz_Dx:BOOL AT %M0.2 Marcia_Nastro_Sx:BOOL AT %Q0.1 Marcia_Nastro_Dx:BOOL AT %Q0.2 END_VAR (* Avviamento macchina e condizioni per la rotazione oraria *) | Avvio_Macchina Rotaz_Sx Emergency Stop_Macchina +-----| |-------------| |-----+------|/|----------|/|------>Continua> | | | Marcia_Nastro_Sx | +-----| |---------------------+ | Marcia_Nastro_Dx Marcia_Nastro_Sx | >Continua>-------------|/|------------------( )------+ | (* Avviamento macchina e condizioni per la rotazione anti-oraria *) | Avvio_Macchina Rotaz_Dx Emergency Stop_Macchina +-----| |-------------| |-----+------|/|----------|/|------>Continua> | | | Marcia_Nastro_Dx | +-----| |---------------------+ | Marcia_Nastro_Sx Marcia_Nastro_Dx | >Continua>-------------|/|------------------( )------+ Come si può notare, l’interblocco è rappresentato dal valore dell’uscita di comando della rotazione simmetrica a quella attivata dalla bobina in esame. In tal modo, è effettivamente impossibile abilitare contemporaneamente entrambe le uscite, anche se per un errore del programma vi fosse un ciclo di esecuzione nel quale le variabili booleane Rotaz Dx e Rotaz Sx fossero contemporaneamente vere. L’equivalente in IL dei due segmenti precedenti è: (* Avviamento macchina e condizioni per la rotazione oraria *) LD( AND ) OR ANDN ANDN ANDN ST Avvio_Macchina Rotaz_Dx Marcia_Nastro_Sx Emergency Stop_Macchina Marcia_Nastro_Dx Marcia_Nastro_Sx 4 (* Avviamento macchina e condizioni per la rotazione anti-oraria *) LD( AND ) OR ANDN ANDN ANDN ST Avvio_Macchina Rotaz_Sx Marcia_Nastro_Dx Emergency Stop_Macchina Marcia_Nastro_Sx Marcia_Nastro_Dx La realizzazione delle funzionalità equivalenti in linguaggio Function Block Diagram (FBD) e Structured Text (ST) è lasciato come esercizio allo studente. 1.3 Controllo diagnostico e rilevazione di allarmi Una funzionalità indispensabile realizzata dai Controllori Logici Programmabili è rappresentata dalla diagnostica e dalla rilevazione di condizioni di malfunzionamento generale dell’automatismo controllato. Tali condizioni possono essere, ad esempio, l’apertura di un pannello di protezione che permette l’accesso a zone della macchina pericolose per l’operatore, la segnalazione di un surriscaldamento o di una sovracorrente da parte del driver di un motore elettrico, ecc. Le condizioni di errore e malfunzionamento di un automatismo possono generare da parte del controllore diverse reazioni, a seconda del livello di “gravità” dell’allarme. Tipicamente, vi possono essere condizioni che richiedono un arresto immediato della macchina, nel qual caso il programma di controllo deve in genere disabilitare il prima possibile tutte le uscite di comando degli attuatori (es. Motore Nastro), oppure condizioni che richiedono un arresto controllato della macchina (il cosiddetto “arresto in fase”) in modo che al ripristino delle condizioni operative, la fase di riavvio della macchina richieda il minor tempo possibile. Nell’esempio seguente, si considera il caso in cui il PLC debba monitorare i segnali provenienti da sensori che rilevano la presenza di un incendio in una zona a rischio, come schematizzato in Figura 1.1. Nella zona da controllare sono presenti tre sensori identici, posizionati in punti opportuni, e si desidera che nel caso in cui uno solo di questi sensori fornisca un segnale logico vero, venga avviata una segnalazione di “pre-allarme” con l’accensione di un segnale luminoso. Tale segnalazione può essere spenta se il sensore non fornisce più un valore vero. Se invece, più sensori sono attivi contemporaneamente, allora verrà generata una condizione di allarme e di arresto immediato della parte operativa, condizione che potrà essere resettata solamente attraverso un intervento dell’operatore umano. La sequenza di segmenti LD per il monitoraggio dei sensori è la seguente: VAR Sens1:BOOL AT %I0.0 Sens2:BOOL AT %I0.1 Sens3:BOOL AT %I0.2 MAN1:BOOL AT %I0.3 (* E’ possibile anche una segnalazione manuale di incendio *) CL_Alarm:BOOL AT %I0.4 (* Reset manuale della condizione di allarme*) Alarm:BOOL AT %Q0.0 Pre_alarm:BOOL AT %Q0.1 END_VAR (* Verifica delle condizioni di pre-allarme *) 5 Figura 1.1: Sistema di controllo anti-incendio | Sens1 Pre_alarm +-----| |------+-------------------------( )----| | | | Sens1 | +-----| |------+ | | | Sens1 | +-----| |------+ | (* Verifica delle condizioni di allarme generale *) | Sens1 Sens2 Alarm +-----| |-----| |----+-------------------------(S)----| | | | Sens1 Sens3 | +-----| |-----| |----+ | | | Sens2 Sens3 | +-----| |-----| |----+ | | | MAN1 | +-----| |------------+ (* Reset manuale della segnalazione di allarme *) | CL_Alarm Alarm +-----|P|-----------------------------(R)----| | 6 Come si può notare, in questo esempio si è fatto uso di istruzioni LD leggermente evolute rispetto alle semplici repliche di contatti e bobine elettromeccaniche, come le bobine ritentive (---(S)-- e ---(R)--) e il contatto rilevatore di fronti di salita (---|P|---). Per quanto riguarda una implementazione in IL dei segmenti precedenti, occorre notare che la rilevazione del fronte di salita non è prevista come istruzione nativa del linguaggio, ma è necessario utilizzare un’istanza del Function Block Standard di tipo R TRIG (Rising edge Trigger), un blocco avente un unico ingresso booleano, CLK ed un unica uscita booleana Q che assume valore vero in corrispondenza di un fronte di salita dell’ingresso. Come per ogni Function Block, occorre che l’uso di tale trigger sia dichiarato espressamente tra le variabili di programma. Pertanto il codice IL diventa: VAR Sens1:BOOL AT %I0.0 Sens2:BOOL AT %I0.1 Sens3:BOOL AT %I0.2 MAN1:BOOL AT %I0.3 (* E’ possibile anche una segnalazione manuale di incendio *) CL_Alarm:BOOL AT %I0.4 (* Reset manuale della condizione di allarme*) Alarm:BOOL AT %Q0.0 Pre_alarm:BOOL AT %Q0.1 Fronte_Reset:R_TRIG; END_VAR (* Verifica delle condizioni di pre-allarme *) LD OR OR ST Sens1 Sens2 Sens3 Pre_alarm (* Verifica delle condizioni di allarme generale *) LD( AND ) OR( AND ) OR( AND ) OR S Sens1 Sens2 Sens1 Sens3 Sens2 Sens3 MAN1 Alarm (* Reset manuale della segnalazione di allarme *) LD CLK LD R CL_alarm Fronte_Reset Fronte_Reset.Q Alarm Si noti come sia possibile per il Function Block Standard R TRIG utilizzare l’ ingresso del blocco come un operatore del linguaggio. Infatti, la riga di codice CLK Reset trigger corrisponde in 7 modo implicito alla chiamata dell’FB ed all’assegnazione al suo ingresso del valore dell’accumulatore. Tale meccanismo di estensione del linguaggio può essere utilizzato solamente per alcuni dei Function Blocks Standard (si veda per una panoramica completa la descrizione del linguaggio IL). L’uscita del FB deve poi essere riferita esplicitamente e caricata nell’accumulatore: se ha valore vero, impone il reset della variabile Alarm. La realizzazione in FBD e ST viene lasciata come esercitazione allo studente (si noti che in FBD occorrerebbe istanziare esplicitamente anche i Function Block di tipo SR, set/reset, utilizzati). 1.4 Elaborazione di numeri reali L’evoluzione dei dispositivi di Controllo Logico, grazie all’utilizzo di microprocessori “general-purpose” (cioè non più orientati esclusivamente ad operazioni logiche) ed all’espansione delle capacità di memoria ed elaborazione, ha fatto sı̀ che le funzionalità che possono essere egregiamente svolte dai PLC non siano limitate alle sole operazioni di logica combinatoria e sequenziale, ma anzi, siano sempre più efficienti anche nell’esecuzione di operazioni matematiche che coinvolgano valori numerici interi o reali. Negli esempi successivi, vedremo appunto alcune semplici situazioni che richiedono operazioni di confronto e aritmetiche su valori reali. Si supponga di dover controllare la temperatura di un forno, avendo a disposizione un sensore analogico ed una serpentina comandata tramite un interruttore “acceso/spento”. Il tipo di controllo normalmente utilizzato in questi casi è il cosiddetto controllo on/off con isteresi. In sostanza, il valore numerico reale fornito dal sensore viene confrontato con il valore di temperatura che si desidera mantenere. Se la serpentina è accesa e questi differiscono per una quantità maggiore di un certo la serpentina viene spenta. Viceversa, se la serpentina è spenta e la temperatura scende oltre al di sotto del riferimento, essa viene riaccesa, come schematizzato in Figura 1.2. Comando 1 0 -Eps Set_Point + Eps Temperatura Figura 1.2: Controllo temperatura con ciclo di isteresi Dato che tale tipo di controllo è molto comune nella pratica e che esso può essere necessario per molteplici attuatori nello stesso sistema automatizzato, risulta molto efficiente incapsulare la funzionalità in un Function Block riutilizzabile, che abbia come ingressi il valore misurato, il riferimento di temperatura ed , e come uscita il comando booleano di accensione della serpentina. La realizzazione del controllo con isteresi in linguaggio ST è la seguente: FUNCTION_BLOCK Isteresi VAR_INPUT Temperatura:REAL; Set_Point:REAL; Eps:REAL; END_VAR 8 VAR_OUTPUT Comando:BOOL; END_VAR (* Algoritmo interno del Function Block *) IF Comando THEN IF Temperatura > (Set_Point + Eps) THEN Comando := FALSE; END_IF; ELSIF Temperatura < (Set_Point - Eps) THEN Comando := TRUE; END_IF; END_FUNCTION_BLOCK Si noti che fintanto che il valore di comando è vero, viene testato solamente il superamento del valore di temperatura più alto consentito, resettando eventualmente il comando, il viceversa se tale valore è falso. Per una realizzazione in IL del Function Block, occorre utilizzare delle operazioni di salto condizionato, come è intuibile per il fatto di aver utilizzato un costrutto di selezione nel linguaggio di alto livello ST. Il codice del FB diventa quindi: (* Algoritmo interno del Function Block *) LD JMPCN Comando Caso_Spento Caso_Acceso: LD Temperatura GT( Set_Point ADD Eps ) R Comando JMP Fine (* Salto eseguito solo se Comando = FALSE *) (* se non esegue il salto continua da qui *) (* Salto incondizionato *) Caso_Spento: LD Temperatura LT( Set_Point SUB Eps ) S Comando Fine: END_FUNCTION_BLOCK Per realizzare la funzionalità con un linguaggio grafico, sia LD che FBD occorre invece utilizzare i blocchi di istruzione di confronto, addizione e sottrazione, definiti nella IEC 61131-3 come Functions Standard (non Function Blocks, pertanto non occorre la loro dichiarazione). Ad esempio, i segmenti LD che permettono di realizzare il ciclo di isteresi potrebbero essere: (* Algoritmo interno del Function Block *) 9 | +------------+ | Comando | GT | Comando | +-------------| |----------------+ EN +-----(R)-----+ | | | | | Temperatura -----+ | | | | | +-------+ | | | ADD | +---+ | Set_Point ---+ | | | | | +---+ +------------+ Eps ---+ | | | +-------+ | +------------+ | Comando | LT | Comando | +-------------|/|----------------+ EN +-----(S)-----+ | | | | | Temperatura -----+ | | | | | +-------+ | | | SUB | +---+ | Set_Point ---+ | | | | | +---+ +------------+ Eps ---+ | | | +-------+ Si noti come le operazioni di confronto siano abilitate o disabilitate (pertanto eseguite o meno) in relazione al valore di Comando, e come l’uscita di tali blocchi permetta di settare o resettare tale valore. Si supponga ora di avere la necessità di monitorare dal punto di vista statistico e diagnostico una batteria di sensori di temperatura analogici, allo scopo di rilevarne il valore massimo, minimo e il valore medio. Per realizzare tale operazione, si può pensare di collezionare il valore acquisito dai sensori in un vettore di numeri reali e di eseguire quindi un ciclo di istruzioni con le operazioni di somma e confronto necessarie: VAR Temperature:ARRAY[1..32] OF REAL; Max, Min, Media: REAL; END_VAR VAR_TEMP Somma:REAL; Count:INT; END_VAR Max := 0; Min := 0; Somma := 0; FOR Count := 1 TO 32 DO 10 Somma := Temperature[Count] + Somma; IF Temperature[Count] > Max THEN Max := Temperature[Count]; END_IF; IF Temperature[Count] < Min THEN Min := Temperature[Count]; END_IF; END_FOR Media := Somma / 32; La realizzazione di tale funzionalità con il linguaggio IL, richiede ancora l’utilizzo di istruzioni di salto condizionato. Tuttavia, al contrario dell’esempio precedente, che realizzava un costrutto tipo IF .. THEN, in questo caso occorre realizzare un costrutto iterativo, pertanto è necessario introdurre anche salti “all’indietro”, per i quali cioè la label che indica il punto di arrivo del salto si trova in una posizione precedente a quella dell’istruzione di salto: (* Variabili ... *) LD 1 ST Count Ciclo: LD Somma ADD Temperature[Count] ST Somma LD Temperature[Count] GT Max JMPCN Nonmassimo (* Salto condizionato dal risultato del confronto *) LD Temperature[Count] ST Max Nonmassimo: LD Temperature[Count] LT Min JMPCN Nonminimo (* Salto condizionato dal risultato del confronto *) LD Temperature[Count] ST Min Nonminimo: LD Count ADD 1 ST Count GT 32 JMPCN Ciclo (* Se Count <= 32 riparte dalla label iniziale Ciclo *) LD Somma (* altrimenti esegue queste ultime istruzioni fuori dal ciclo *) DIV 32 ST Media Fine: (* Label non strettamente necessaria *) 11 La realizzazione in LD è soggetta a problematiche analoghe relative all’utilizzo di istruzioni di salto, condizionate dall’uscita logica di blocchi come quelli utilizzati nell’esempio del ciclo di controllo con isteresi. In tal caso, occorrerà inserire come elemento terminale del segmento LD contentente le istruzioni di confronto l’elemento grafica che indica il salto: | +---- (* Elementi grafici di confronto ... *) -->>Nonmassimo | ... Nonmassimo: ... La descrizione completa del codice LD e FBD (molto simile) è lasciata come esercizio allo studente. 1.5 Selezione tra molteplici alternative. Nel controllo di un automatismo, può talvolta essere necessario discriminare le operazioni da eseguire in risposta ad un determinato evento, quale potrebbe essere un comando dell’operatore, tra differenti possibili alternative. Tali alternative sono in genere condizionate dallo stato del sistema al momento dell’evento o dalla tipologia dell’evento stesso. Si consideri, ad esempio, un serbatoio di materiale liquido che debba essere riempito o svuotato a seconda delle operazioni selezionate da un supervisore, umano o meno, dell’impianto. Il programma di controllo deve agire opportunamente aprendo o chiudendo le valvole di ingresso prodotto e di scarico in base al comando ricevuto ed al livello di liquido contenuto nel serbatoio. Si supponga inoltre che il materiale nel serbatoio possa essere mescolato azionando le pale di un agitatore, e che quest’ultimo possa essere attivato solamente quando il serbatoio sia completamente pieno. Il sistema è schematizzato in Figura 1.3. Agitatore Riempimento Livello Alto Livello basso Scarico Figura 1.3: Serbatoio con miscelatore Il livello della vasca può essere determinato in base a due sensori logici che rilevano la presenza di un galleggiante in posizioni opportune, Livello Basso e Livello Alto; ciascuna valvola viene 12 comandata con un unico segnale logici, se vero la valvola si apre, se falso si chiude; il motore dell’agitatore viene comandato con un segnale on/off. Il comando richiesto viene codificato con un numero intero: 1 per il riempimento del serbatoio, 2 per mantenere stabile il livello, 3 per la miscelazione, 4 per lo svuotamento. In questo caso, un metodo efficace per definire il programma di controllo può essere basato su meccanismi di selezione in grado di discriminare diversi casi possibili, come ad esempio il costrutto CASE .. OF nel linguaggio ST. Per migliorare ulteriormente la leggibilità del codice, prima di effettuare il test sul comando richiesto, viene determinato lo stato del serbatoio, memorizzandolo in un variabile che può assumere i soli valori Pieno, Non Pieno, Vuoto: (* Definizione con enumerazione di un tipo di dato per memorizzare lo stato della vasca *) TYPE T_Serbatoio:(Pieno, Non_Pieno, Vuoto); END_TYPE; VAR Comando:INT AT %IB0; Livello_Alto:BOOL AT %I1.0; Livello_Basso:BOOL AT %I1.1; Apri/Chiudi_Valvola_Riempimento:BOOL AT %Q0.0; Apri/Chiudi_Valvola_Scarico:BOOL AT %Q0.1; Motore_Agitatore:BOOL AT %Q0.2; Stato_Serbatoio:T_Serbatoio; (* Variabile interna *) END_VAR (* Verifica dello stato del serbatoio *) IF NOT(Livello_Basso) THEN Stato_Serbatoio := Vuoto; ELSIF NOT(Livello_Alto) THEN Stato_Serbatoio := Non_Pieno; ELSE Stato_Serbatoio := Pieno; END_IF; (* Selezione del comando *) CASE Comando OF 1: (* Riempimento *) Apri/Chiudi_Valvola_Scarico := FALSE; Motore_Agitatore := FALSE; IF Stato_Serbatoio <> Pieno THEN Apri/Chiudi_Valvola_Riempimento := TRUE; ELSE Apri/Chiudi_Valvola_Riempimento := FALSE; END_IF; 2: (* Mantenimento *) Apri/Chiudi_Valvola_Scarico := FALSE; Apri/Chiudi_Valvola_Riempimento := FALSE; Motore_Agitatore := FALSE; 3: (* Miscelazione *) Apri/Chiudi_Valvola_Scarico := FALSE; Apri/Chiudi_Valvola_Riempimento := FALSE; IF Stato_Serbatoio = Pieno THEN Motore_Agitatore := TRUE; 13 ELSE Motore_Agitatore := FALSE; END_IF; 4: (* Svuotamento *) Apri/Chiudi_Valvola_Riempimento := FALSE; Motore_Agitatore := FALSE; IF Stato_Serbatoio <> Vuota THEN Apri/Chiudi_Valvola_Scarico := TRUE; ELSE Apri/Chiudi_Valvola_Scarico := FALSE; END_IF; END_CASE La traduzione del costrutto di selezione multipla in un linguaggio differente dal ST, richiederebbe una notevole quantità di salti condizionati dal risultato di operazioni di confronto, per verificare ogni caso possibile del valore della variabile intera. Tuttavia, nell’esempio in esame, si può notare come le istruzioni eseguite nei vari casi non richiedono altro che di abilitare o meno certe uscite booleane. In particolare, il comando di apertura della valvola di scarico va abilitato solamente nel caso 4, quello della valvola di riempimento nel caso 1 e cosı̀ via. Pertanto, una soluzione più efficiente potrebbe essere quella di memorizzare in variabili booleane interne del controllore il risultato dei confronti sulla variabile intera Comando, condizionando poi con queste il valore dell’uscita logica interessata. Ad esempio, una realizzazione delle funzionalità richiesta con il linguaggio LD potrebbe essere: VAR ... Comando1, Comando2, Comando3, Comando4:BOOL; (* Variabili interne *) ... END_VAR (* Verifica del comando richiesto *) | +------+ Comando1 | +------------+EN +-------( )----+ | | | | | Comando --+ EQ | | | 1 --+ | +------+ | Comando1 +------+ Comando2 | +-----|/|------------+EN +-------( )----+ | | | | | Comando --+ EQ | | | 2 --+ | +------+ | Comando1 Comando2 +------+ Comando3 | +-----|/|--------|/|------------+EN +-------( )----+ | | | | | Comando --+ EQ | | | 3 --+ | +------+ 14 | Comando1 Comando2 Comando3 +------+ Comando4 | +-----|/|-------|/|--------|/|---------+EN +-------( )----+ | | | | | Comando --+ EQ | | | 4 --+ | +------+ (* Attuazione delle uscite in base al comando impostato *) | Comando1 Livello_Alto Apri/Chiudi_Valvola_Riempimento | +----| |----------|/|-----------------------( )----------------+ | | | Comando4 Livello_Basso Apri/Chiudi_Valvola_Scarico | +----| |----------|/|-----------------------( )----------------+ | | | Comando3 Livello_Alto Motore_Agitatore | +----| |----------| |-----------------------( )----------------+ | | Si noti la semplificazione sulla controllo dello stato del serbatoio, limitata alla valutazione dei contatti di livello basso o alto, e l’inibizione delle operazioni di confronto successive a quella che dia un eventuale risultato positivo (che permette una riduzione del tempo di esecuzione del programma). La realizzazione in linguaggio IL e FBD è lasciata come esercizio allo studente. 1.6 Operazioni con temporizzatori Gran parte delle operazioni compiute da dispositivi come i PLC durante l’attività di controllo e supervisione di impianti automatizzati richiedono istruzioni che permettano di verificare se siano o meno trascorsi determinati intervalli di tempo, dette istruzioni di temporizzazione o temporizzatori (timers). Ad esempio, il ciclo operativo di una macchina automatica può richiedere che tra due fasi successive vi sia un certo ritardo, oppure l’esecuzione di una di queste fasi deve essere completata entro un certo tempo limite, pena il malfunzionamento dell’impianto. Si supponga di voler comandare l’apertura e chiusura di una valvola che regola il passaggio di fluidi, verificando che tali operazioni siano completate entro un certo tempo limite. Se la posizione della valvola non raggiunge il fine corsa richiesto (completamente aperta o completamente chiusa) prima di questo tempo, occorre generare una condizione di errore. Poichè tale funzionalità di controllo ha spiccate caratteristiche di generalità e ripetibilità, si può pensare di incapsularla in un Function Block: FUNCTION_BLOCK Valvola_Timeout VAR_INPUT Richiesta_Apertura:BOOL; Richiesta_Chiusura:BOOL; FineCorsa_Aperta:BOOL; FineCorsa_Chiusa:BOOL; Reset_Errore:BOOL; Tempo_Limite:TIME; END_VAR 15 VAR_OUTPUT Comando_Apertura:BOOL; Comando_Chiusura:BOOL; Errore:BOOL; END_VAR VAR Timer_Controllo:TON; END_VAR (* Attivazione e Disattivazione comando apertura *) | Richiesta_Apertura Comando_Chiusura Comando_Apertura | +----------| |----------------|/|------------------(S)------+ | | | Comando_Apertura FineCorsa_Aperta Comando_Apertura | +---------| |----------------| |---------+-----------(R)----+ | | | | Errore | +---------| |----------------------------+ | (* Attivazione e Disattivazione comando chiusura *) | Richiesta_Chiusura Comando_Apertura Comando_Chiusura | +----------| |----------------|/|------------------(S)------+ | | | Comando_Chiusura FineCorsa_Chiusa Comando_Chiusura | +---------| |----------------| |---------+-----------(R)----+ | | | | Errore | +---------| |----------------------------+ | (* Controllo sul timeout *) Timer_Controllo +-----------+ | Comando_Apertura FineCorsa_Aperta | TON | +-------| |---------------|/|------------+----+IN | Errore | | | | Q+---(S)---+ | Comando_Chiusura FineCorsa_Chiusa | | | | +-------| |---------------|/|------------+ | | | | ET+-Tempo_Limite ---+PT | | | +-----------+ (* Richiesta di reset delle condizione di errore *) 16 | Reset_Errore Errore | +--------|P|----------------------------------(R)----+ | | END_FUNCTION_BLOCK Per realizzare in modo analogo l’algoritmo del Function Block in linguaggio IL, occorre considerare nuovamente la necessità di rilevare fronti di salita di segnali, introducendo tre instanze del Function Block Standard R TRIG, per le richieste di apertura e chiusura e per il reset dell’errore. Si noti inoltre l’utilizzo dell’istruzione CAL nella chiamata del blocco temporizzatore: FUNCTION_BLOCK Valvola_Timeout VAR_INPUT ... VAR_OUTPUT ... VAR ... Fronte_Reset_Err:R_TRIG; END_VAR (* Attivazione e Disattivazione comando apertura *) LD Richiesta_Apertura ANDN Comando_Chiusura S Comando_Apertura LD Comando_Apertura AND FineCorsa_Aperta OR Errore R Comando_Apertura (* Attivazione e Disattivazione comando chiusura *) LD Richiesta_Chiusura ANDN Comando_Apertura S Comando_Chiusura LD Comando_Chiusura AND FineCorsa_Chiusa OR Errore R Comando_Chiusura (* Controllo sul timeout *) LD Comando_Apertura ANDN FineCorsa_Aperta OR( Comando_Chiusura ANDN FineCorsa_Chiusa ) ST Timer_Controllo.IN LD Tempo_Limite 17 ST Timer_Controllo.PT (* Dopo aver assegnato i parametri del timer, effettuo la chiamata *) CAL Timer_Controllo LD Timer_Controllo.Q S Errore LD Reset_Errore CLK Fronte_Reset_Err LD Fronte_Reset_Err.Q R Errore END_FUNCTION_BLOCK Un altro esempio di uso di temporizzatori, non impiegati per scopi diagnostici, ma per controllare l’evoluzione stessa del ciclo operativo, è rappresentato dal tempratore ad induzione analizzato nel seguito. Spruzzatore Spira Pezzo FC Pistone Alto + xxxxxxxxxxxxxx xxxxxxxxxxxxxx xxxxxxxxxxxxxx xxxxxxxxxxxxxx FC Pistone Basso Valvola salita pistone Figura 1.4: Dispositivo per la tempra ad induzione di pezzi metallici Il processo di tempra ad induzione richiede che un pezzo metallico sia posto in prossimità di un circuito elettrico induttore, ottenendo cosı̀ il riscaldamento ad elevatissima temperatura del pezzo, il quale viene poi raffreddato velocemente per mezzo di uno spruzzo di acqua. Nel sistema in esame, schematizzato in Figura 1.4, il pezzo viene avvicinato alla spira sollevandolo con uno spintore pneumatico attivato con un singolo comando logico (1 = alza, 0 abbassa). Le fasi di riscaldamento e di raffreddamento del ciclo di lavoro devono avere una durata prestabilita, verificata tramite opportuni temporizzatori. La realizzazione del programma di controllo in linguaggio LD è la seguente: VAR Start_Ciclo:BOOL AT %I0.0; Emergenza:BOOL AT %I0.1 Pezzo_Presente:BOOL AT %I0.3; FC_Pistone_Alto:BOOL AT %I0.4; FC_Pistone_Basso:BOOL AT %I0.5; Salita_Pistone:BOOL AT %Q0.0; Riscaldamento_Pezzo:BOOL AT %Q0.1; Spruzzo_Acqua:BOOL AT %Q0.2; 18 Timer_Risc, Timer_Raff:TON; END_VAR (* Abilitazione del comando salita pistone *) | Start_Ciclo FC_Pistone_Basso Pezzo_Presente Salita_Pistone | +------| |-------------| |---------------| |--------------(S)-----+ | | (* Disabilitazione del comando salita pistone => fine ciclo *) | Timer_Raffr.Q Salita_Pistone | +------| |----------+----------(R)-------+ | | | | Emergenza | +------| |----------+ (* Pistone alto => partenza conteggio tempo di riscaldamento *) Timer_Risc | Salita_Pistone FC_Pistone_Alto +------------+ +-------| |-------------| |----------+ IN Q+| | TON | | 20s ----+ PT ET++------------+ (* Riscaldamento fino al termine del tempo conteggiato *) | Salita_Pistone FC_Pistone_Alto Timer_Risc.Q Riscaldamento_Pezzo +--------| |------------| |-------------|/|----------------( )-------+ | (* Terminato il riscaldamento, conteggio del tempo di raffreddamento *) Timer_Raffr | Timer_Risc +------------+ +------| |--------------------------+ IN Q+-| | TON | 10s ----+ PT ET+-+------------+ (* Attivazione spruzzatore fino al termine del tempo richiesto *) | Timer_Risc Timer_Raffr Spruzzo_Acqua | +------| |----------|/|------------( )--------+ | | La realizzazione dei due esempi negli altri linguaggi non presentati è lasciata come esercizio allo 19 studente. 1.7 Operazioni di conteggio Oltre ai temporizzatori, anche i blocchi funzionali di conteggio eventi, o contatori, sono molto importanti nel controllo logico e di supervisione di macchine automatiche. Tali istruzioni permettono di tenere traccia del numero di occorrenze del fronte di salita o di discesa di una certa informazione logica. Il sistema di controllo dovrà poi valutare le operazioni da effettuare una volta raggiunto un determinato numero di queste occorrenze, in modo analogo a quanto analizzato in precedenza per i temporizzatori. Vale a dire che raggiungere un certo valore di conteggio dell’evento di timeout di apertura di un valvola, rilevato come descritto nel paragrafo precedente, può essere indice della necessità di sostituire l’azionamento, condizione che impedisce il ripristino della produzione. Oppure, il conteggio di un certo numero di prodotti su di un nastro trasportatore può essere necessario per attivare il sistema di confezionamento dei prodotti. Fotocellula passaggio prodotto xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxx xxxxxxxx xxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxx Nastro1 Nastro2 Fine Passo Nastro2 Figura 1.5: Linea di movimentazione e raggruppamento prodotti Si consideri ad esempio, il sistema automatizzato rappresentato in Figura 1.5, costituito da due nastri trasportatori in cascata, il primo dei quali movimenta in modo continuo dei prodotti che si presentano con frequenza casuale, mentre il secondo serve per raggruppare i prodotti in un numero adatto a riempire una confezione di cartone. Il secondo nastro viene attivato, con un movimento “a passi”, solamente quando il primo vi abbia trasferito tale quantità di prodotti, ed arrestato quando tutti questi prodotti siano stati trasferiti al sistema di confezionamento, condizione rilevata da un sensore di “fine-passo”. Durante il periodo di attività del nastro a valle, quello a monte viene arrestato. Il passaggio di prodotti tra i due nastri viene rilevato da una fotocellula (sensore logico). Il programma di controllo del movimento dei due nastri, potrebbe essere realizzato in linguaggio LD come segue: VAR Start_Linea:BOOL AT %I0.0; Stop_Linea:BOOL AT %I0.1; Passaggio_Prodotto:BOOL AT %I0.2; FinePasso_Nastro2:BOOL AT %I0.3; Motore_Nastro1:BOOL AT %Q0.0; Motore_Nastro2:BOOL AT %Q0.1; Attiva_Passo:BOOL; (* Variabile interna *) Conteggio_Prod:CTU; END_VAR 20 (* Verifica delle condizioni di produzione con autoritenuta *) | Start_Linea Stop_Linea Produzione | +------| |-------+-----|/|------------( )-----+ | | | | Produzione | +------| |-------+ | (* Conteggio dei prodotti trasferiti tra i due nastri *) Conteggio_Prod +--------------+ | Produzione Passaggio_Prodotto | CTU | +------| |-------------| |-------------->CU | | | Q+-| 5 ---+PV | | Attiva_Passo | | +-------| |-----------------------------+R CV+-| | | | +--------------+ (* Abilitazione e disabilitazione del movimento del nastro a passi *) | Conteggio_Prod.Q Produzione Attiva_Passo | +--------| |-------------| |---------------(S)-------+ | | | Attiva_Passo FinePasso_Nastro2 Attiva_Passo | +--------| |-------------|P|---------------(R)-------+ | | (* Attivazione delle uscite di comando per i motori dei nastri *) | Produzione Attiva_Passo Motore_Nastro1 | +--------| |--------------|/|--------------( )-------+ | | | Produzione Attiva_Passo Motore_Nastro2 | +--------| |--------------| |--------------( )-------+ | | Anche in questo caso, l’implementazione della funzionalità con gli altri linguaggi IEC 61131-3 può essere svolta come esercizio dallo studente. 21 Capitolo 2 Descrizione di sequenze operative con SFC IEC 61131-3 2.1 Introduzione Tra gli elementi comuni dello Standard IEC 61131-3 si trova anche la descrizione sintattica del formalismo chiamato Sequential Function Chart, il quale riveste un ruolo molto importante tra i concetti introdotti nel documento IEC. Infatti, tale formalismo rappresenta prima di tutto un metodo di modellazione del funzionamento richiesto al sistema automatizzato, in grado di fornire una specifica formale per la realizzazione del software di controllo esente da possibili errori di interpretazione. In seconda analisi, esso rappresenta anche un metodo per organizzare il software scomponendo le istruzioni da eseguire in base alle sequenze operative che il sistema controllato deve compiere. Infine, essendo sempre più numerosi gli Ambienti di Programmazione commerciali che supportano questo formalismo come un vero e proprio linguaggio di programmazione, esso rappresenta anche un modo per realizzare il programma di controllo in grado di rispecchiare fedelmente il risultato della fase iniziale di analisi, descrizione e modellazione del progetto. Negli esempi che seguono, vedremo infatti come un diagramma SFC sia in grado di fornire una descrizione dettagliata e non ambigua delle specifiche di funzionamento di un automatismo, dal punto di vista del progettista del sistema di controllo logico. 2.2 Sistema di movimentazione con piattaforma rotante. Si consideri la linea di nastri schematizzata in Figura 2.1, composta da due nastri trasportatori, disposti ad “L”, e da una piattaforma rotante dotata anch’essa di nastro trasportatore, necessaria per realizzare la continuità di trasporto prodotti dal nastro 1 al nastro 2. La linea di trasporto deve funzionare nel seguente modo: il nastro 1 viene azionato fintanto che un prodotto non arrivi al termine rilevato dalla fotocellula FC Nastro1. Se la piattaforma rotante è posizionata in modo tale che il suo nastro sia in linea con il nastro 1, questi ultimi possono essere azionati entrambi per permettere il trasferimento del prodotto tra i due, finchè il prodotto non viene più rilevato dalla fotocellula sul nastro 1. A questo punto, occorre ruotare la piattaforma in direzione anti-oraria, fermando il suo nastro (il nastro 1 può continuare a muoversi per far avanzare un prodotto successivo), in modo da porla in asse con il nastro 2. Quando ciò avviene, vengono azionati il nastro della piattaforma ed il nastro 2: il primo fino al rilevamento del prodotto da parte della fotocellula FC InNastro2, il secondo fino al rilevamento del prodotto da parte della fotocellula FC OutNastro2. Il prodotto sarà poi rimosso anche da quest’ultima posizione da un altro dispositivo non considerato. Quando il prodotto non occupa più la piattaforma rotante, questa deve riportarsi in asse con il nastro 1 con ad una rotazione oraria, posizione che rappresenta anche quella iniziale del dispositivo. Una descrizione con il formalismo SFC del programma di controllo può essere realizzata in modo molto efficace scomponendo l’automatismo in moduli funzionali (nastro 1, piattaforma, nastro 22 FC_OutNastro2 Mov_Nastro2 FC_InNastro2 FC_Nastro1 Rot_Oraria Rot_AntiOr Mov_Nastro1 Figura 2.1: Linea di trasporto con nastri ad L 2) indipendenti, opportunamente sincronizzati grazie alle variabili booleane di attivazione di ciascuno stato, definite nella sintassi del SFC dallo Standard IEC 61131-3 come elementi impliciti di programma. VAR (* Input del controllore *) FC_Nastro1:BOOL; FC_InNastro2:BOOL; FC_OutNastro2:BOOL; Fine_Rot_AntiOr:BOOL; (* sensore che asse con il piattaforma Fine_Rot_Oraria:BOOL; (* sensore che asse con il piattaforma rileva nastro *) rileva nastro *) (* Output del controllore *) Mov_Nastro1:BOOL; Mov_Nastro2:BOOL; Mov_NastroPiatt:BOOL; Rot_Oraria:BOOL; Rot_AntiOr:BOOL; END_VAR 23 il posizionamento in 2 da parte della il posizionamento in 1 da parte della S10 S30 Mov_Nastro1 FC_Nastro1 S11.X S11 S31 S31.X S12 Mov_NastroPiatt NOT FC_Nastro1 Mov_Nastro1 S32 NOT FC_Nastro1 Rot_AntiOr Fine_Rot_AntiOr S33 S21.X S20 S34 S33.X S21 Mov_NastroPiatt FC_InNastro2 Mov_Nastro2 S35 FC_OutNastro2 Rot_Oraria Fine_Rot_Oraria S22 NOT FC_OutNastro2 24 2.3 Piattaforma rotante con selezione direzione. Si consideri il sistema rappresentato in Figura 2.2, composto da un nastro trasportatore, una piattaforma rotante, due stazioni di foratura ed un nastro di scarico. Il dispositivo di controllo deve essere in grado di gestire la selezione della stazione di foratura con la quale lavorare il pezzo, in base alle dimensioni del pezzo stesso. A tale scopo, sul nastro di ingresso è posizionata una fotocellula che permette di rilevare la lunghezza del prodotto in base al tempo che esso impiega a transitare completamente oltre la fotocellula stessa. Se tale tempo risulta essere inferiore a 500 ms il pezzo dovrà essere lavorato dalla stazione di foratura destra, altrimenti da quella di sinistra. Il nastro prosegue la movimentazione del pezzo, solamente se la piattaforma è in uno stato ideneo (cioè un pezzo precedentemente ricevuto è stato espulso), ed è possibile valutare le dimensioni di un nuovo pezzo dopo che quello in esame è stato trasferito completamente sulla piattaforma (segnale FC Piattaforma attivo). Si suppone che i pezzi sul nastro di ingresso siano sufficientemente distanziati. Per posizionare opportunamente la piattaforma, occorre azionare il motore di rotazione con uno dei comandi ROT DX o ROT SX, fino al rilevamento di un fronte di salita del sensore di prossimità FC Rotazione, che rileva una delle quattro tacche metalliche montate sulla piattaforma, in modo che essa effettui un quarto di giro. Terminata la lavorazione, una nuova rotazione di un quarto di giro nella stessa direzione permetterà di spingere il pezzo sul nastro di scarico, azionando per almeno 800 ms il segnale di avanzamento dell’espulsore Espulsione (lo spintore ritorna in posizione di riposo per effetto di una molla se il segnale di comando non è attivato). FC_PIATTAFORMA Stazione di Foratura sinistra Espulsore pezzo FC_NASTRO ROT_SX ROT_DX NASTRO A FC_Rotazione NASTRO B Stazione di Foratura destra Figura 2.2: Piattaforma rotante con stazioni di foratura Trascurando per semplicità il controllo delle stazioni di lavorazione e del nastro di scarico, un diagramma SFC modulare per il controllo indipendente dei due moduli considerati (nastro A e piattaforma) è il seguente: VAR (* Input del controllore *) FC_Nastro:BOOL; FC_Piattaforma:BOOL; FC_Rotazione:BOOL; Termine_Foratura_DX:BOOL; (* Segnale dal sottosistema di foratura della stazione di destra che indica il completamento della lavorazione *) 25 Termine_Foratura_SX:BOOL; (* Segnale dalla stazione di sinistra *) (* Output del controllore *) Mov_NastroA:BOOL; ROT_DX:BOOL; ROT_SX:BOOL; Espulsione:BOOL; END_VAR S10 Mov_NastroA FC_Nastro S11 S12 S11.T > 500 ms AND FC_Nastro NOT FC_Nastro S13 S21.X S27.X S14 Mov_NastroA FC_Piattaforma Figura 2.3: SFC del nastro trasportatore con selezione dimensione prodotto Si noti, nella soluzione proposta, come il fronte di salita da parte del segnale FC Rotazione sia rilevato dall’evoluzione di due passi consecutivi condizionata da un segnale prima falso e poi vero da parte di tale sensore. Una soluzione alternativa poteva essere rappresentata dall’utilizzo di un Function Block R TRIG, chiamato in una azione del passo opportuno, la cui uscita Q fosse la condizione di transizione del passo stesso. Si noti inoltre, come sia possibile che il SFC di controllo del nastro rilevi la dimensione di un pezzo e si ponga in attesa, mentre il SFC di controllo della piattaforma sta ancora elaborando un pezzo precedente. Al termine delle operazioni su quest’ultimo, il nastro sarà riattivato e verrà selezionata la corretta sequenza di lavorazione del pezzo. 26 S20 S12.X S13.X S21 S27 FC_Piattaforma S22 FC_Piattaforma ROT_SX NOT FC_Rotazione S23 NOT FC_Rotazione ROT_SX FC_Rotazione S24 S30 Termine_Foratura_SX ROT_SX Termine_Foratura_DX NOT FC_Rotazione ROT_SX ROT_DX S32 FC_Rotazione FC_Rotazione S33 ROT_DX S31 NOT FC_Rotazione S26 ROT_DX S29 FC_Rotazione S25 ROT_DX S28 Espulsione S33.T > 800 ms Figura 2.4: SFC della piattaforma rotante con selezione direzione 2.4 Controllo di un distributore di bibite. Si consideri una macchina distributrice di bibite che sia in grado di riconoscere monete da 0.1, 0.2 e 0.5 Euro e di erogare tre differenti tipi di bibita, A, B e C. La bibita A costa 0.6 Euro, la bibita B ne costa 0.8 e la bibita C costa 1 Euro. La macchina è dotata di display, sul quale viene visualizzata la stringa “Inserire Monete” fino a quando il cliente non inserisce una prima moneta, dopodichè viene visualizzato l’importo totale inserito. L’utente ha a disposizione i pulsanti di selezione di ciascuna bibita e un pulsante di espulsione monete, con il quale può annullare l’operazione. La macchina infatti non dà resto! Il riconoscimento della moneta viene effettuato da un sottosistema di scansione, il quale fornisce al sistema di controllo principale quattro soli segnali logici: Moneta 01, Moneta 02, Moneta 05, Non Valida. Ad ogni nuova moneta riconosciuta viene aggiornata la somma memorizzata e la moneta viene messa in uno scompartimento di pre-incasso, mentre se la moneta non è valida viene immediatamente espulsa. Se l’utente preme un tasto di selezione bibita e l’importo introdotto è sufficiente, la bibita richiesta viene espulsa e le monete vengono incassate definitivamente. La durata minima di apertura degli sportelli di contenimento bibite e monete della macchina è: • 300 ms per lo sportello dello scomparto dell’ultima moneta inserita. • 1 s per lo sportello dello scomparto di pre-cassa. • 2 s per lo sportello degli scomparti contenenti le bibite. 27 Uno schema SFC in grado di descrivere il funzionamento del dispositivo di controllo potrebbe essere il seguente (si noti che l’importo inserito viene mantenuto in una variabile intera): VAR (* Input del controllore *) Passaggio_Moneta:BOOL; (* Fotocellula d’ingresso delle monete *) Richiesta_A:BOOL; (* pulsanti utente *) Richiesta_B:BOOL; Richiesta_C:BOOL; Richiesta_Annulla:BOOL; Moneta_01:BOOL; Moneta_02:BOOL; Moneta_05:BOOL; Non_Valida:BOOL; (* Segnali ricevuti dal sottosistema di controllo monete *) (* Output del controllore *) PreCassa_Ultima:BOOL; (* Gestione monete *) Espulsione_Ultima:BOOL; Acquisizione_PreCassa:BOOL; Espulsione_PreCassa:BOOL; Espulsione_A:BOOL; (* Gestione bibite *) Espulsione_B:BOOL; Espulsione_C:BOOL; Attiva_Controllo:BOOL; (* Segnale di attivazione sottosistema di controllo monete *) Importo:INT; (* Somma del valore delle monete riconosciute *) END_VAR 28 Figura 2.5: SFC per l’aggiornamento dell’importo inserito 29 := P Importo Importo + 1 PreCassa_Ultima S22.T > 300 ms AND (S10 OR S11) S22 Moneta_01 Moneta_02 := S23 P Importo Importo + 2 PreCassa_Ultima S23.T > 300 ms AND (S10 OR S11) Attiva_Controllo Passaggio_Moneta S21 S20 S24 := P Importo Importo + 5 PreCassa_Ultima S24.T > 300 ms AND (S10 OR S11) Moneta_05 S25 S25.T > 300ms Espulsione_Ultima Non_Valida Figura 2.6: SFC di controllo dell’espulsione bibite e monete 30 Importo <6 S12 S13 Richiesta_B Importo >=6 Importo>= 8 Importo <8 S16 Espulsione_A S17 Espulsione_B Acquisizione_PreCassa S11 Acquisizione_PreCassa S16.T > 2s S17.T > 2s Richiesta_A Display(Importo) S14 S11 Importo>=10 Espulsione_C S18 Acquisizione_PreCassa S18.T > 2s Richiesta_C Importo < 10 Importo :=0 P Display("Inserire Monete") S22.X OR S23.X OR S24.X S11 S10 S15.T > 1s Richiesta_Annulla S15 Espulsione_PreCassa 2.5 Carroponte con elettromagnete. Si consideri il sistema di movimentazione magazzino rappresentato schematicamente in Figura 2.7, costituito da un carrello sopraelevato in grado di sollevare o abbassare un elettromagnete. Il ciclo di movimentazione che si desidera realizzare, prevede che il carroponte trasferisca uno per volta i pezzi metallici contenuti nel contenitore in basso a sinistra nella figura, in quello in alto a destra. FC_Sx Pos_Sicura FC_Dx Altezza_Max Altezza_Scarico xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Altezza_Carico Figura 2.7: Carroponte con elettromagnete Il carrello è supposto essere inizialmente nella posizione orizzontale indicata dal sensore di fine corsa FC Sx e con il magnete completamente sollevato. Pertanto, occorre innanzitutto, alla richiesta di inizio del ciclo, prelevare un pezzo abbassando il magnete ad Altezza Carico ed in seguito attivandone l’alimentazione. Si supponga che un tempo di attesa di 2 secondi dall’istante di attivazione del magnete sia sufficiente per garantire la presa di un pezzo. Per trasferire il pezzo, occorre effettuare il movimento di sollevamento e spostamento orizzontale verso destra, in modo simultaneo per ottimizzare il tempo di ciclo, avendo cura di impedire che il carrello possa proseguire oltre la posizione indicata dal sensore Pos Sicura se l’elettromagnete non ha raggiunto la posizione Altezza Max, al fine di evitare possibili collisioni del pezzo con il piano rialzato. Terminato il movimento orizzontale, il ciclo può terminare abbassando il magnete ad Altezza Scarico, disattivandone l’alimentazione, e riportando il carrello nella posizione iniziale con l’elettromagnete completamente sollevato. Anche per il rilascio del pezzo, si richiede un tempo di attesa di 2 secondi, prima di effettuare ulteriori movimenti. Tale sequenza operativa può essere descritta con il seguente diagramma SFC: VAR (* Input del controllore *) Altezza_Max:BOOL; Altezza_Carico:BOOL; Altezza_Scarico:BOOL; FC_Dx:BOOL; FC_Dx:BOOL; Pos_Sicura:BOOL; (* Output del controllore *) Abbassa_Magnete:BOOL; Solleva_Magnete:BOOL; 31 Attiva_Magnete:BOOL; Motore_Carrello:BOOL; (* Segnale di attivazione del motore *) Dir_Carrello_Dx:BOOL; Dir_Carrello_Sx:BOOL; END_VAR (* Segnali di selezione della direzione di movimento del carrello *) S10 Start_Ciclo Abbassa_Magnete S11 Altezza_Carico S S12 Attiva_Magnete S12.T > 2 s S13 Solleva_Magnete S14 Altezza_Max S15 Motore_Carrello Dir_Carrello_Dx Pos_Sicura S16 True S17 S18 Motore_Carrello Dir_Carrello_Dx FC_Dx Abbassa_Magnete Altezza_Scarico S19 R Attiva_Magnete S19.T > 2 s S20 Solleva_Magnete S21 Altezza_Max Motore_Carrello Dir_Carrello_Sx FC_Sx S22 S23 True 32 2.6 Impilatore prodotti con spintore Si consideri il sistema automatizzato indicato schematicamente in Figura 2.8 preposto allo stoccaggio di prodotti in un deposito. BARRA_ALTA SOLLEVA_BARRA ABBASSA_BARRA BARRA_BASSA MOV_BARRA_DX MOV_BARRA_SX GRIGLIA_LIBERA FC_SX aaa aaa aaa aaa aaa MOTORE_NASTRO FC_DX GRIGLIA_PIENA MOTORE_GRIGLIA aaaa aaa aaa a a GRIGLIA_IN_FASE Vista frontale griglia impilatrice FC_PRODOTTO Figura 2.8: Impilatore prodotti con spintore La macchina riceve i prodotti opportunamente distanziati da un nastro trasportatore con funzionamento continuo, i quali vanno ad inserirsi in nel ripiano inferiore di una griglia. Attivando la rotazione del motore connesso alla griglia si ha la traslazione verso l’alto di tutti i ripiani con un conseguente sollevamento ed impilatura dei prodotti. Il motore deve essere attivato fino a quando un ripiano della griglia non sia nuovamente in fase con il nastro, condizione rilevata dal sensore di prossimità Griglia in fase. Quando una pila di prodotti sia stata completata, vale a dire quando il sensore Griglia piena rilevi la presenza di un prodotto, occorre attivare la barra di spinta che permette il trasferimento della pila nel deposito di stoccaggio, traslandola lungo le guide in linea con la griglia di impilatura. Durante il movimento iniziale dello spintore, occorre che il nastro di ingresso prodotti e l’impilatore siano assolutamente inattivi, mentre quando lo spintore ha raggiunto la posizione orizzontale Griglia libera, il procedimento di impilatura può riprendere. Completato il movimento di spinta fino al fine corsa FC Dx, lo spintore deve tornare nella posizione iniziale. Tuttavia, al fine di impedire che nel movimento di rientro della barra di spinta vi sia una collisione con i nuovi prodotti impilati nella griglia durante il completamento del ciclo di stoccaggio precedente, la barra deve essere sollevata attivando il comando Solleva barra fino all’altezza Barra alta. Questo movimento può essere effettuato in modo ottimizzato, cioè contemporaneamente alla traslazione orizzontale verso sinistra, avendo però cura che il sollevamento sia completato prima del raggiungimento della posizione indicata dal sensore Griglia libera. La descrizione tramite diagramma SFC del ciclo operativo dei moduli macchina “Impilatore” e “Spintore” può essere effettuata come segue: VAR (* Input del controllore *) FC_Prodotto:BOOL; Griglia_In_Linea:BOOL; Griglia_Piena:BOOL; Barra_Alta:BOOL; Barra_Bassa:BOOL; FC_Sx:BOOL; 33 Griglia_Libera:BOOL; FC_Dx:BOOL; (* Output del controllore *) Motore_Nastro:BOOL; Motore_Griglia:BOOL; Mov_Barra_Sx:BOOL; Mov_Barra_Dx:BOOL; Solleva_Barra:BOOL; Abbassa_Barra:BOOL; END_VAR S1 S Motore_Nastro FC_Prodotto S2 Motore_Griglia NOT Griglia_In_Linea S3 Motore_Griglia Griglia_In_Linea AND NOT Griglia_Piena S4 Griglia_In_Linea AND Griglia_Piena R Motore_Nastro S12.X Figura 2.9: Diagramma SFC per il controllo del modulo impilatore con nastro 34 S10 S4.X Mov_Barra_Dx S11 Griglia_Libera Mov_Barra_Dx S12 FC_Dx S13 Solleva_Barra Mov_Barra_Sx S14 Barra_Alta Griglia_Libera S15 S16 True Mov_Barra_Sx S17 FC_Sx S18 Abbassa_Barra Barra_Bassa Figura 2.10: Diagramma SFC per il controllo dello spintore 35 2.7 Carrelli ferroviari con binario condiviso Si consideri il sistema di trasporto rappresentato schematicamente in Figura 2.11, costituito da due differenti carrelli su rotaia automatizzati A e B, ciascuno dei quali deve trasferire del materiale dalla propria stazione di carico alla stazione di scarico. I carrelli vengono attivati dal relativo pulsante di inizio ciclo e percorrono un tratto di binario separato fino ad una determinata posizione di controllo, oltre la quale possono proseguire solamente se il tratto di binario centrale non è attualmente occupato dall’altro carrello. Se il carrello è abilitato a proseguire, terminerà il proprio ciclo arrivando alla postazione di scarico, attendendo due minuti o la pressione di un pulsante di “recupero carrello” ed attivandosi per il rientro. Anche durante il rientro, occorre verificare prima di proseguire oltre la posizione di controllo, se il tratto di binario condiviso non sia occupato dall’altro carrello. La presenza dei carrelli nelle posizioni di carico, scarico e di controllo viene rilevata da sensori logici opportunamente collocati. Zona di Carico A Punto di attesa ritorno Punto di attesa andata Zona di Scarico A A Zona condivisa B Zona di Carico B Zona di Scarico B Figura 2.11: Carrelli su rotaia con binario condiviso Per evitare collisioni sul tratto di binario condiviso, una possibile soluzione è rappresentata dall’introduzione nel diagramma di un passo che rappresenta la condizione del binario centrale: se il passo è attivo, significa che il carrello che arrivi per primo alla posizione di controllo è abilitato a proseguire, se invece è disattivo significa che il binario è occupato. La gestione dell’attivazione e disattivazione di questo passo richiede una connessione tramite divergenze e convergenze parallele con i diagrammi sequenziali di ciascuno dei due carrelli, ottenendo quindi il diagramma SFC globale descritto nel seguito. Si noti che il passo S100 rappresenta appunto lo stato del tratto di binario condiviso. Tale passo deve essere attivo affinchè l’SFC del carrello A (a sinistra) o del carrello B (a destra) possano evolvere oltre i passi S13, S17, S23 o S27, secondo le regole delle convergenze simultanee. L’evoluzione del diagramma porta alla disattivazione del passo S100 e, a seconda dei casi, di uno dei passi precedentemente nominati, ed all’attivazione di uno fra i passi S14, S18, S24 o S28. Questi passi rappresentano una situazione nella quale uno dei due carrelli sta transitando, durante il movimento di andata o di ritorno, sul binario condiviso, situazione che termina al passaggio del carrello per la posizione di controllo opportuna. Si noti inoltre che in caso di arrivo contemporaneo dei due carrelli in una posizione di controllo per l’avanzamento sul binario centrale, viene data la precedenza sempre al carrello A. VAR (* Input del controllore *) Start_A:BOOL; Start_B:BOOL; Recupero_A:BOOL; Recupero_B:BOOL; Scarico_A_OK:BOOL; Scarico_B_OK:BOOL; 36 Pos_A_Carico:BOOL; Pos_B_Carico:BOOL; Pos_A_Controllo_Andata:BOOL; Pos_B_Controllo_Andata:BOOL; Pos_A_Controllo_Rientro:BOOL; Pos_B_Controllo_Rientro:BOOL; Pos_A_Scarico:BOOL; Pos_B_Scarico:BOOL; (* Output del controllore *) Motore_A_Avanti:BOOL; Motore_A_Indietro:BOOL; Motore_B_Avanti:BOOL; Motore_B_Indietro:BOOL; END_VAR S10 S20 Start_A Start_B Motore_A_Avanti S11 S21 Pos_A_Controllo_Andata Motore_B_Avanti Pos_B_Controllo_Andata S12 S22 True NOT S12.X AND NOT S17,X Motore_A_Avanti S13 Pos_A_Controllo_Ritorno Pos_B_Controllo_Ritorno Motore_A_Avanti S14 Pos_A_Scarico S15 Motore_B_Avanti S23 S24 Pos_B_Scarico S100 S25 S15.T > 2 min OR Recupero_A Motore_A_Indietro S16 S25.T > 2 min OR Recupero_B Motore_B_Indietro S26 Pos_A_Controllo_Ritorno Pos_B_Controllo_Ritorno S17 S27 True S18 NOT S12.X AND NOT S17,X Motore_A_Indietro Motore_B_Indietro S28 Pos_A_Controllo_Andata S19 Motore_B_Avanti Pos_B_Controllo_Andata Motore_A_Avanti S29 Pos_A_Carico Motore_B_Avanti Pos_B_Carico 37 2.8 Sincronizzazione robot mobili con postazione comune Si consideri la cella robotizzata rappresentata schematicamente in Figura 2.12, costituita da due semplici robot A e B preposti rispettivamente al carico ed allo scarico di prodotti da una piattaforma di saldatura. Quest’ultima è costituita da una tavola rotante con due postazioni per il collocamento dei prodotti, una idonea al ricevimento o al prelievo di prodotti da parte dei robot, l’altra idonea alle operazioni di saldatura da parte di un terzo robot non considerato. Presenza__Rob_Sx Motore_A_Avanti Motore_A_Indietro Motore_B_Avanti Motore_B_Indietro Presenza_Rob_Centro Solleva_Pinza_A Abbassa_Pinza_A Chiudi_Pinza_A Pinza_A_Alta Pinza_A_Bassa Presenza_Rob_Dx Pres_Pezzo_Carico Pres_Pezzo_Scarico Tavola_In_Fase Figura 2.12: Cella robotizzata con robot mobili e tavola rotante I robot devono prelevare i pezzi abbassando completamente la pinza e chiudendola attivando il segnale Chiudi Pinza (A o B), che deve essere mantenuto attivo per tutta la durata del trasporto pezzo, muoversi verso la destinazione finale (la postazione centrale per il robot A, quella di scarico per il robot B), quindi abbassare la pinza e disattivarne il comando di chiusura. Al termine di queste operazioni, il robot può risollevare la pinza e tornare alla propria posizione iniziale. Si desidera controllare la sequenza di lavoro dei due robot mobili in modo tale da impedire possibili collisioni sulla postazione centrale, quella al di sopra della piattaforma di saldatura, trascurando invece le operazioni di saldatura e rotazione della tavola al termine dei cicli di lavoro di ciascun robot. Si suppone pertanto, per semplicità, che le condizioni iniziali della cella siano tali per cui il robot A occupa la posizione indicata dal sensore Presenza Rob Sx (con la pinza in alto), mentre il robot B occupa la posizione indicata dal sensore Presenza Rob Centro (con la pinza in alto), e che l’avvio del ciclo dei robot sia condizionato solamente dal segnale Pres Pezzo Arrivo per il robot incaricato del caricamento, e dai segnali Pres Pezzo Scarico e Tavola In Fase per il robot incaricato del prelievo dei pezzi già saldati. Un possibile diagramma SFC che descriva il funzionamento della cella è quindi il seguente: VAR 38 (* Input del controllore *) Pinza_A_Alta:BOOL; Pinza_A_Bassa:BOOL; Pinza_B_Alta:BOOL; Pinza_B_Bassa:BOOL; Pres_Pezzo_Carico:BOOL; Pres_Pezzo_Scarico:BOOL; Tavola_In_Fase:BOOL; Presenza_Rob_Sx:BOOL; Presenza_Rob_Centro:BOOL; Presenza_Rob_Dx:BOOL; (* Output del controllore *) Motore_A_Avanti:BOOL; Motore_A_Indietro:BOOL; Abbassa_Pinza_A:BOOL; Solleva_Pinza_A:BOOL; Chiudi_Pinza_A:BOOL; Motore_B_Avanti:BOOL; Motore_B_Indietro:BOOL; Abbassa_Pinza_B:BOOL; Solleva_Pinza_B:BOOL; Chiudi_Pinza_B:BOOL; END_VAR 39 S20 S10 Pres_Pezzo_Scarico AND Tavola_In_Fase Abbassa_Pinza_B Pres_Pezzo_Carico S21 Abbassa_Pinza_A S11 Pinza_B_Bassa Chiudi_Pinza_B S22 Solleva_Pinza_B Pinza_A_Bassa Chiudi_Pinza_A S12 Solleva_Pinza_A S S Pinza_B_Alta Pinza_A_Alta Motore_B_Avanti S23 S13 S14 Pos_Rob_Dx S13 True Motore_A_Avanti Abbassa_Pinza_B S24 Pinza_B_Bassa Pos_Rob_Centro S15 Abbassa_Pinza_A R Chiudi_Pinza_B Solleva_Pinza_B S25 Pinza_A_Bassa Chiudi_Pinza_A S16 Solleva_Pinza_A Pinza_B_Alta R S26 Pinza_A_Alta S17 Motore_A_Indietro Pos_Rob_Sx S13 True S27 Motore_B_Indietro Pos_Rob_Centro 40 2.9 Movimentazione e capovolgimento prodotti Si consideri il sistema di movimentazione magazzino raffigurato schematicamente in Figura 2.13, il cui compito è quello di scomporre pile costituite da due prodotti, capovolgere i singoli prodotti, e conseguentemente ricomporre la pila in modo tale che il prodotto precedentemente in cima si ritrovi al di sotto e viceversa. Pinza_B_Stop_Rot NB: + Chiudi_Pinza_A(B,C) Solleva_Pinza_A Pinza_A_alta Abbassa_Pinza_A Pinza_B_Alta Pinza_B_Bassa Rot_Pinza_B Solleva_Pinza_B Solleva_Pinza_C Abbassa_Pinza_B Abbassa_Pinza_C Pinza_C_alta Pinza_A_media Pinza_C_media Pinza_A_bassa Pinza_C_bassa Nastro_A Nastro_B Peso_A Nastro_C Presenza_B Peso_C Figura 2.13: Sistema di movimentazione e capovolgimento prodotti Per realizzare tale procedura, vengono adoperati tre nastri trasportatori e tre semplici robot in grado di afferrare gli oggetti su ciascuno di questi nastri e sollevarli. Il primo robot (A), pertanto, è incaricato della scomposizione della pila, sollevando dapprima il prodotto in cima, attendendo la traslazione dell’altro prodotto dal nastro A al nastro B, e quindi riposizionando il prodotto afferrato sul nastro. L’ultimo robot (C) ha invece il compito di ricomporre la pila, sollevando il primo prodotto (già capovolto) che arriva sul nastro C, attendendo l’arrivo del secondo prodotto e quindi riposizionando il prodotto afferrato in precedenza, sulla cima della pila. Il robot B al centro, infine, ha il compito di sollevare ogni prodotto che si trovi sul nastro sottostante, capovolgerlo agendo sul motore di rotazione della pinza e riposizionare il prodotto sul nastro. Come si può notare dal disegno schematico dell’impianto, il movimento verticale dei robot A e C può essere arrestato in tre posizioni, che permettono il prelievo o il posizionamento di un oggetto che poggia sul nastro, che poggia su un altro prodotto, oppure il completo sollevamento della pinza (che afferri o meno il prodotto). Il robot B ha invece solamente due possibili posizioni (alta e idonea per la rotazione; bassa e idonea al prelievo o posizionamento prodotto). Il segnale di comando della chiusura della pinza va mantenuto abilitato per tutta la durata della presa di un oggetto, avendo cura di attendere almeno 500 ms dall’attivazione o dalla disattivazione di tale segnale prima di iniziare qualunque movimento. Trascurando per semplicità la sequenza di movimentazione dei nastri, regolata in base a sensori di peso o di presenza, che permettono di rilevare la quantità di prodotti che gravano sul nastro, e applicando una modularizzazione funzionale dell’impianto, è possibile definire il ciclo operativo di ciascun robot con un diagramma SFC indipendente, come descritto nel seguito, nel quale si suppone che i robot siano inizialmente in posizione alta e non vi siano prodotti sui nastri: VAR (* Input del controllore *) Pinza_A_Alta:BOOL; 41 Pinza_A_Media:BOOL; Pinza_A_Bassa:BOOL; Pinza_B_Alta:BOOL; Pinza_B_Bassa:BOOL; Pinza_B_Stop_Rot:BOOL; Pinza_C_Alta:BOOL; Pinza_C_Media:BOOL; Pinza_C_Bassa:BOOL; (* Output del controllore *) Solleva_Pinza_A:BOOL; Abbassa_Pinza_A:BOOL; Solleva_Pinza_B:BOOL; Abbassa_Pinza_B:BOOL; Rot_Pinza_B:BOOL; Solleva_Pinza_C:BOOL; Abbassa_Pinza_C:BOOL; (* Variabili di sincronizzazione, semplificate, da parte del programma di controllo dei nastri *) Nastro_A_Pronto:BOOL; Nastro_B_Pronto:BOOL; Nastro_C_Pronto:BOOL; END_VAR 42 S10 S20 Nastro_A_Pronto S11 Abbassa_Pinza_A Nastro_B_Pronto S21 Pinza_A_Media S12 S Chiudi_Pinza_A Solleva_Pinza_A S22 S23 S24 Abbassa_Pinza_A R Chiudi_Pinza_A S25 Solleva_Pinza_A Pinza_A_Alta Solleva_Pinza_B Rot_Pinza_B Abbassa_Pinza_B S26 R Chiudi_Pinza_B S33 Solleva_Pinza_B Pinza_B_Alta Solleva_Pinza_C Pinza_C_Alta S34 Nastro_C_Pronto S35 Abbassa_Pinza_C Pinza_C_Media S36 S26.T > 500 ms S27 S Chiudi_Pinza_C S22.T > 500 ms Pinza_B_Bassa S16.T > 500 ms S17 S32 Pinza_B_Stop_Rot Pinza_A_Bassa S16 S Chiudi_Pinza_B Abbassa_Pinza_C Pinza_C_Bassa Pinza_B_Alta Nastro_A_Pronto S15 S31 S22.T > 500 ms Pinza_A_Alta S14 Abbassa_Pinza_B Nastro_C_Pronto Pinza_B_Bassa S12.T > 500 ms S13 S30 R Chiudi_Pinza_C S36.T > 500 ms S37 Solleva_Pinza_C Pinza_C_Alta Come si può notare, il funzionamento di ciascun robot è sostanzialmente identico, in particolare per il robot A e C: ogni robot effettua un primo movimento di presa di un oggetto (abbassamento, chiusura pinza, sollevamento), si pone in attesa delle condizioni idonee al riposizionamento del prodotto sul nastro e quindi effettua un secondo movimento di rilascio (abbassamento, apertura pinza, sollevamento). Ciò che differisce è solamente la posizione raggiunta durante ciascun movimento verso il basso. Nella realizzazione del programma, sarà quindi una soluzione efficiente creare un Function Block che contenga il controllo del generico robot, vale a dire che realizzi un SFC identico ai precedenti, ma con azioni e transizioni basate sui parametri di Input/Output del Function Block, anzichè su specifici segnali del controllore. Occorrerà poi creare due istanze differenti di tale Function Block, ed assegnare opportunamente i parametri di Input/Output richiesti, come descritto nel seguito. Si noti che per “adattare” tale blocco funzionale al controllo del robot B, occorrerebbe modificare la transizione di uscita dal passo S14, ed aggiungere un parametro di Input e uno di Output, rispettivamente per ricevere il segnale di fine rotazione e per attivare il comando di rotazione. VAR .... Robot_A: Robot_FB; Robot_C: Robot_FB; END_VAR 43 S10 Nastro_Pronto S11 Abbassa_Pinza Posizione_Abbassamento_1 S S12 Chiudi_Pinza S12.T > 500 ms S13 Solleva_Pinza Pinza_Alta S14 Nastro_Pronto S15 Abbassa_Pinza Posizione_Abbassamento_2 S16 R Chiudi_Pinza S16.T > 500 ms S17 Solleva_Pinza Pinza_Alta Robot_A Robot_FB Nastro_A_Pronto Pinza_A_Media Pinza_A_Bassa Pinza_A_Alta Nastro_Pronto Posizione_Abbassamento_1 Posizione_Abbassamento_2 Pinza_Alta Abbassa_Pinza Chiudi_Pinza Solleva_Pinza Abbassa_Pinza_A Chiudi_Pinza_A Solleva_Pinza_A Robot_C Robot_FB Nastro_C_Pronto Pinza_C_Bassa Pinza_C_Media Pinza_C_Alta Nastro_Pronto Posizione_Abbassamento_1 Posizione_Abbassamento_2 Pinza_Alta Abbassa_Pinza Chiudi_Pinza Solleva_Pinza 44 Abbassa_Pinza_C Chiudi_Pinza_C Solleva_Pinza_C