CamiSCADA

Avevo iniziato con un precedente post su Processing e SCADA, ed ora la continuazione

L’INIZIO

Il progetto si chiama CamiSCADA perchè le prime righe di codice le ho scritte a Camignolo, presso la Scuola Media, in questa primavera.

In questo articolo descrivo più dettagliatamente il progetto, ma prima di tutto…a che serve?

Cosa si può fare con CamiSCADA

CamiSCADA è una applicazione scritta in linguaggio Java, o meglio in Processing, che si occupa di visualizzare l’andamento di controllori, quali PLC ed Arduini varii.

In pratica uno SCADA è una sorta di “cruscotto” che permette di avere la “visione d’insieme”.

La novità di CamiSCADA è…

CamiSCADA integra una interessante funzionalità: la modalità demo.

è possibile quindi simulare il funzionamento di un sistema facendolo apparire come se il tutto stesse funzionando: tank che si riempiono , valvole che si aprono e via dicendo.

Primo demo: birrificio

Il primo demo simula un birrificio ad una linea di maltatura e tre linee di fermentazione.

Per eseguire la demo “birrificio” basterà copiare (=sostituire) i due file “camiscada.dat” e “camiscada.ini” nella directory home di CamiSCADA.

Video esempio

Un video-esempio è stato caricato su Youtube: questo è il link.

Secondo demo: creazione filamenti

In questo caso si simula la produzione di filamenti polimerici per estrusione a bassa pressione.

Anche in questo caso per eseguire la demo basterà copiare (=sostituire) i due file “camiscada.dat” e “camiscada.ini” nella directory home di CamiSCADA.

Come installare

Scompattare il file zip ( cliccare qui per scaricarlo ) in una directory, per esempio “camiscada”. Verranno automaticamente create le sotto-directory relative.
Dopo l’installazione è già “in linea” la demo per il birrificio, quindi basterà avviare Processing e successivamente caricare lo script presente nella directory “som_lab50_10”: som_lab50_10.pde.

Requisiti

Processing richiede poche risorse, è parsimonioso. Unica nota è la versione di Processing che deve essere almeno la 5.3.

Codice

Il codice, o sorgente, di CamiSCADA, è diviso in due parti: oggetti e run-time.

Oggetti

Gli oggetti sono tipicamente delle macchine, per esempio un tank è un oggetto. allo stesso modo una saldatrice automatica è un oggetto, così come lo è una valvola.

Tra gli oggetti vi sono i diversi apparati che si possono incontrare in questi ambiti: tank, valvole e tubi.
Ogni oggetto è provvisto di “maniglie” per poter effettuare il legame con gli oggetti.

Struttura oggetti

Tutti gli oggetti di CamiSCADA, sono dotati di due tipi di attributi:

  • attuatori
  • sensori

I metodi principali sono:

  • mshow – per visualizzare graficamente
  • mgethole – per conoscere le coordinate delle “maniglie”
  • minfo – per visualizzare i testi

Sensori

I sensori inviano dei valori alla console SCADA. La tipologia ed il numero dei sensori possono variare da oggetto ad oggetto: per esempio un tank avrà tre tipi di sensori:

if ( match(wparm[0], "CAP") != null  ) {
  this.wfiller=float(wparm[1]);
}
if ( match(wparm[0], "TEM") != null  ) {
  this.wtempc=float(wparm[1]);
}
if ( match(wparm[0], "BAR") != null  ) {
  this.wpress=float(wparm[1]);

dove TEM è una sonda termica, BAR per la pressione e CAP per il livello.

Struttura camiscada.ini

è il file che contiene l’elenco degli oggetti e la loro disposizione (layout). Si tratta di un file di testo, strutturato e diviso in due sezioni.
Nella prima sezione troviamo gli oggetti, menre nella seconda i collegamenti.
Una riga della prima sezione ha la forma:


TANK;p1b1d1m1c1;90;50;HLT


dove “TANK” è il tipo di oggetto (ed è definito all’interno del programma), poi “p1b1d1m2c1” è il codice di questo tank. La coppia di numeri identifica il punto da dove verrà disegnato il tank, nel formato x e y. Ultimo “HLT” è il nome col quale verrà visualizzato il tank.

Per la seconda sezione, i raccordi la struttura è un po’ diversa:


PIPE;p1b1d1m4c6;p1b1d1m1c3;DX;p1b1d1m3c6;SX;to_pump3a

anche qui “PIPE” è il tipo di oggetto, “p1b1d1m4c6” è il nome del raccordo.
La coppia “p1b1d1m1c3;DX” indica che il raccordo partirà dalla maniglia DX dell’oggetto “p1b1d1m1c3” e si raccorderà alla SX di “p1b1d1m3c6”.
Infine “to_pump3a” è il nome che verrà visualizzato.

Denominazione dispositivi

Per assegnare un codice ai diversi dispositivi ho utilizzato una codifica già presente: la DNP3. In sintesi una stringa “p1b1d1m1c1” significa:

  • p1 = impianto
  • b1 = building, edificio
  • d1 = department, settore
  • m1= machine
  • c1 = component, parte della macchina, sensore o attuatore.

Ovviamente il numero è un progressivo quindi un nome possibile potrebbe essere: p1b4d2m21c5.

Struttura camiscada.dat

Questo file è opzionale in quanto contiene i comandi che l’applicazione riceve e che dovrà visualizzare.

La posizione di questo file è la stessa dalla quale viene avviata l’applicazione ovvero dove si trova il file som_lab50_10.pde.

è possibile inserire dei commenti all’interno del file, tramite il simbolo “#” posto all’inizio della riga.

# camiscada demo brewery
# 2019
 p1b1d1m1c1;CAP=10
 p1b1d1m1c1;CAP=20
 p1b1d1m1c1;CAP=30
 p1b1d1m1c1;CAP=40
 p1b1d1m1c1;CAP=50
 p1b1d1m1c1;CAP=60
 p1b1d1m1c1;CAP=70
 p1b1d1m1c1;CAP=80
 p1b1d1m1c1;CAP=90
# tank HLT al max

Collegamento con Arduino

Il collegamento con Arduino avviene attraverso porta USB. Il formato dell’informazione è quello già descritto in camiscada.dat, quindi il modulo Arduino dovrà rispettare il protocollo utilizzando la corretta sintassi:

Serial.println("p1b1d1m1c1;CAP=90");

In questo caso il codice del dispositivo (p1b1d1m1c1) è cablato nello sketch di Arduino. In alternativa è possibile associare il codice dispositivo ad una specifica porta USB.

Conclusione

Per usare Processing è necessaria una seppur minima conoscenza di Java e programmazione ad oggetti.

Il vantaggio di utilizzare una libreria consiste nel fatto che molto del lavoro è già stato fatto e si tratta solo di adattamenti.

Il discorso cambia quando è necessario creare un nuovo oggetto: in questo caso basterà duplicarne uno già esistente ed apportare le necessarie variazioni.

L’argomento sulla modifica degli oggetti verrà affrontato in un articolo successivo.

Semaforo con Arduino

Negli esercizi di programmazione di automazione, il controllo semaforico è un classico esempio.

Usare il semaforo come esempio è utile perchè permettere di comprendere i meccanismi (a volte sofisticati) che un oggetto molto comune contiene. Solitamente per gli automobilisti il semaforo è una seccatura che non finisce mai.

Oggi vediamo come realizzane un semplice semaforo con una normale scheda Arduino UNO.

Per complicare un pochino le cose, il nostro semaforo potrà essere regolato in maniera da avere cicli (=tempi) variabili a nostro piacimento. A proposito: scrivendo di tempi del semaforo, mi è venuto in mente quello di Via Cattaneo a Lugano: sembra eterno!

 

COSA SERVE?

  • Arduino UNO
  • 7 resistenze 1/4W 1KΩ
  • 6 LED bianchi (da colorare con acrilico) oppure 2 coppie R/V/G
  • jumper
  • potenziometro 5-10KΩ A

Tutto materiale facilmente reperibile presso rivenditori oppure qui.

In questo esempio ho utilizzato solo LED bianchi, che ho poi colorato. La scelta di usare gli stessi LED (bianchi) è stata fatta per non dover variare le resistenze di caduta dei LED: come noto i LED di diversi colori hanno diverse cadute di tensione.

CIRCUITO

La disposizione dei componenti sulla breadboard è molto semplice: basterà fare attenzione alla denominazione dei pins:

 

semaforo fzz

POTENZIOMETRO

Nella scelta del potenziomentro, magari recuperato da un vecchio circuito, bisogna ricordarsi di usarne uno di tipo lineare (A) e non logaritrmico (B).

IL CODICE

Il programma è composto dalle due funzioni canoniche di Sketching: setup e loop.

In particolare, setup non contiene solo l’impostazione delle porte e modalità, ma anche una piccola parte di processo. Infatti in setup troviamo il lampeggio dei LED gialli, prologo al funzionamento successivo col verde e rosso. In pratica all’inizio (setup), il nostro semaforo lavorerà in modalità notturna per passare poi, dopo alcuni cicli, in modalità diurna.

Una nota merita il potenziomentro. Questo componente, lavorando come partitore resistivo, fornirà una tensione variabile al pin analogico 0. Su questo pin avremo una tensione che va da 0 a 4.7Vdc che varierà proporzionalmente alla rotazione della manopola per tutto l’arco (che nei potenziometri rotativi è di 270°).

 

/*
  FLW,2016
mauro rossolato
  
   project:    lab13_ard1
  file name:  som_lab13_00.ino
  porpouse:   light traffic
 
who       when        what 
---------------------------------------------
mr       16.07.2016   creates 


*/

#define msem1v 13
#define msem1g 12
#define msem1r 11
#define msem2v 10
#define msem2g 9
#define msem2r 8
#define mratepot 0

void setup() {
  int wjell;
  int wspeed;
  float wratio;
  float wratepot;
  pinMode(msem1v, OUTPUT);
pinMode(msem1g,OUTPUT);
pinMode(msem1r, OUTPUT);
 pinMode(msem2v, OUTPUT); 
 pinMode(msem2g, OUTPUT);
 pinMode(msem2r, OUTPUT);
  digitalWrite(msem1v, LOW);
 digitalWrite(msem1g, LOW);
 digitalWrite(msem1r, LOW);
 
 pinMode(mratepot, INPUT);
 
     Serial.begin(9600);
Serial.print( "Sensore pot: ");
// pinMode(6, OUTPUT);
// pinMode(7, OUTPUT);

 for (wjell=0;wjell<10;wjell++) {
   digitalWrite(msem1g, LOW);
     digitalWrite(msem2g, LOW);
   delay(500);
   digitalWrite(msem1g, HIGH);
     digitalWrite(msem2g, HIGH);
   delay(500);
 }
 // sem 1
 digitalWrite(msem1v, HIGH);
 digitalWrite(msem1g, LOW);
 digitalWrite(msem1r, LOW);
 // sem2
 digitalWrite(msem2v, LOW);
 digitalWrite(msem2g, LOW);
 digitalWrite(msem2r, HIGH);
 delay(4000);
}

void loop() {
  // read rate
  float wratepot;
  float wspeed;
  wratepot = analogRead(mratepot);
  wspeed = (wratepot *100)/1023;
    Serial.print("valore: ");
  Serial.println(wratepot); 
  // sem 1
  digitalWrite(msem1v, HIGH);
  digitalWrite(msem1g, LOW);
  digitalWrite(msem1r, LOW);  
  digitalWrite(msem2v, LOW);
  digitalWrite(msem2g, LOW);
  digitalWrite(msem2r, HIGH);  
  delay(50*wspeed);  
  digitalWrite(msem1g, HIGH);
  digitalWrite(msem2g, HIGH);  
  delay(50*wspeed);  
  digitalWrite(msem1v, LOW);
  digitalWrite(msem1g, LOW);
  digitalWrite(msem1r, HIGH);  
  digitalWrite(msem2v, HIGH);
  digitalWrite(msem2g, LOW);
  digitalWrite(msem2r, LOW);  
  delay(50*wspeed);  
  digitalWrite(msem1g, HIGH);
  digitalWrite(msem2g, HIGH);  
  delay(50*wspeed);
}

E buon controllo traffico a tutti!

 

 

Salva