SCADA con Processing

Fare automazione con Arduino è possibile ed abbastanza facile.

Anche integrare Arduino con il PC è facile: Processing è lo strimento adatto.

E se volessimo realizzare un quadro sinottico? magari di un impianto idraulico? Certo, con Processing possiamo crare gli oggetti grafici, ma è tedioso!

Un sistema SCADA è un sistema che integra e riassume il funzionamento di diversi controller, tra i quali Arduino o simili.

SCADA

I dati di funzionamento vengono visualizzati ed è possibile anche inviarli a sistemi di controllo.

LIBRERIA

Cercando in Rete una libreria per SCADA su Processing, non ho trovato gran che, e quindi ho deciso di scriverne una direttamente. Da questo articolo vedremo come realizzare una libreria e un sistema SCADA con incluso il modulo PLANT-MGMT (che corrisponde al livello 5 della piramide CIM).

CLASSI

Il primo passo è descrivere le classi dibase che saranno utilizzate. Per farlo ho iniziato dal settore dei liquidi: tank e valvole.

CODICE

Questa è una prima versione che sarà estesa. Ecco la prima parte:

/*
fablabway.com
file: som_lab50_00.pde
progetto: lab50 - SCADA con Processing
descrizione: SCADA con Processing
author: Mauro Rossolato
licenza: Creative Commons BY-NC-ND
when who what

16.04.2019 mr creates
*/
// import
import processing.serial.*;
// global vars
short portIndex = 0;
// objects
Serial wport;
MTANK wtank1;
MTANK wtank2;
MVALVE wvalve1;
class MVALVE {
float wpx, wpy;
String wname, wdvcid;
MVALVE (String pdvcid, float ppx, float ppy, String pname) {
wdvcid = pdvcid;
wpx = ppx;
wpy = ppy;
wname = pname;
}
void mshow() {
stroke(127);
fill(200);
rect(wpx, wpy, ((20/1.41)2), 20); fill(0); fill(0x19BC0E); triangle(wpx, wpy, wpx+(20/1.41), wpy+(20/2), wpx, wpy+20); triangle( wpx+(20/1.41), wpy+(20/2), wpx+((20/1.41)2), wpy,
wpx+((20/1.41)*2), wpy+20);
textSize(18);
text(wname, wpx, wpy);
}
void maction (int pstatus) { // 0=chiusa
color wcolverde= color(43, 182, 8);
color wcolrosso= color(238, 29, 15);
if (pstatus==0) fill(wcolverde);
else fill(wcolrosso);
triangle(wpx, wpy, wpx+(20/1.41), wpy+(20/2), wpx, wpy+20);
triangle( wpx+(20/1.41), wpy+(20/2),
wpx+((20/1.41)2), wpy, wpx+((20/1.41)2), wpy+20);
}
}
class MTANK {
float wpx, wpy;
float wsizex = 50;
float wsizey = 100;
float wfiller;
float wplugxdx =wpx+wsizex;
float wplugydx= wpy+(wsizey/2);
String wname, wdvcid;
MTANK(String pdvcid, float ppx, float ppy, String pname) {
wpx = ppx;
wpy = ppy;
wdvcid = pdvcid;
wname = pname;
}
void mshow() {
stroke(255);
fill(0);
rect(wpx, wpy, wsizex, wsizey);
}
void minfo() {
fill(255);
textSize(14);
text(wname, wpx, wpy);
textSize(16);
text(wfiller+"%", wpx, wpy+wsizey+20);
}
void mfiller(float pfiller) {
color wcolblu= color(15, 32, 188);
wfiller=pfiller;
fill(wcolblu);
float wfilly = (wsizey*(1-(wfiller/100)));
fill(wcolblu);
rect(wpx, wpy+wfilly, wsizex, wsizey-wfilly);
}
}
void setup() {
colorMode(RGB);
background(51, 0, 0);
size(600, 300);
wtank1 = new MTANK("abc", 20, 30, "tank 1");
wvalve1 = new MVALVE("dec", 200, 70, "valve 1");
wtank2 = new MTANK("qwe", 360, 30, "tank 2");
}
void draw() {
// wport.readstring();
// while (wport.available() > 0) {
// String wbuffer = wport.readString();
// if (wbuffer != null) {
// println(wbuffer);
// }
// }
mrefresh();
delay(2000);
}
void mrefresh () {
wtank1.mshow();
wtank1.mfiller(70);
wvalve1.mshow();
wtank2.mshow();
wvalve1.maction(1);
wtank2.mfiller(20);
wtank1.minfo();
wtank2.minfo();
}
//}
/*
print (wfiller +";wpy=");
print (wpy);
print (";");
print ("wsizey=");
print (wsizey);
print (";");
println(wfilly);
*/

il risultato saranno due contenitori e una valvola. I tank hanno la gestione del riempimento e la valvola il controllo di apertura.


Leave a Reply