Se trovi utile il mio blog sostienimi con una piccola donazione. GRAZIE

8 – Tutorial 5

Tutorial SCADA e HMI open source

<– INDIETROAVANTI–>

Ora che abbiamo creato un’interfaccia ed un demone ModBus che si occupa di leggere i dati dal nostro slave dobbiamo capire come recuperare questi dati dalla memoria condivisa e utilizzarli per valorizzare la nostra interfaccia HMI.

Per prima cosa dovremo preparare la nostra applicazione in modo che possa utilizzare alcune librerie aggiuntive tramite il menù rlib come nella figura sotto .

librerie

Da questo menù dovremo scegliere la voce Uncomment rlib e poi la voce Uncomment modbus .

Vedrete che nella sezione Project le righe di codice inerenti le librerie rlib non saranno più precedute dal simbolo # e nella sezione Main la riga inerente il rlModbusClient non sarà più preceduta dai simboli // (commento)

Ora dobbiamo provare a compilare il progetto per vedere se l’inclusione di queste librerie non ha portato errori e quindi proviamo a fare un Make selezionando l’opzione dal menù Action.

Se i path che abbiamo impostato nella fase di installazione sono corretti la compilazione deve andare a buon fine . (nessuna segnalazione di errori)

Ora siccome la nostra è un applicazione di tipo Event-driven , ovvero che aspetta che si scateni un’evento per eseguire qualcosa , dovremo capire in base a quale evento dovremo valorizzare la nostra interfaccia.

Ovviamente ( anche se non necessariamente) vorremmo che i nostri BarGraph visualizzino i valori di processo il più velocemete possibile e magari in modo continuo.

In base a quanto detto sopra un qualunque evento legato all’interazione con l’interfaccia da parte dell’operatore non fà al caso nostro perchè vogliamo aggiornare sempre la nostra interfaccia (HMI).

Per ottenere questo risultato ci viene in aiuto un evento che si chiama slotNullEvent che viene eseguito tutte le volte che non succede nulla (nel senso che l’operatore non interagisce).

Per trovare rapidamente un’evento della nostra applicazione dalla barra di sinistra di Pdevelop dovremo selezionare la sezione slot e tramite il menù a tendina SlotPosition dovremo scegliere l’evento che vogliamo trovare .

Questa operazione farà si che nell’area di editazione del codice ci si posizioni sull’evento cercato che verrà anche evidenziato come in figura .

A questo punto dovremo modificare il codice di questo evento come riporto sotto :

static int slotNullEvent(PARAM *p, DATA *d)
{
 int Val;
 char Buffer[5];

 Val = modbus.readShort(modbusdaemon_CYCLE1_BASE,0);
 qwtThermoSetValue(p,Thermo1,Val);
 itoa(Val,Buffer,10);
 pvSetText(p,LabelValue1,Buffer);

 Val = modbus.readShort(modbusdaemon_CYCLE2_BASE,0);
 qwtThermoSetValue(p,Thermo2,Val);
 itoa(Val,Buffer,10);
 pvSetText(p,LabelValue2,Buffer);

 Val = modbus.readShort(modbusdaemon_CYCLE3_BASE,0);
 qwtThermoSetValue(p,Thermo3,Val);
 itoa(Val,Buffer,10);
 pvSetText(p,LabelValue3,Buffer);

 if(p == NULL || d == NULL) return -1;
 return 0;
}

Dopo di che proveremo a compilare l’applicativo scegliendo la voce Make dal menù Action.

Purtroppo il risultato non sarà quello che volevamo infatti il compilatore ci segnalarà l’errore che riporto sotto :

Errore del compilatore

Come potete veder (click sull’immagine per ingrandire) il compilatore ci segnala che non sà cosa sia ‘modbus’ .

Per risolvere questo problema dovremo decommentare una riga di codice che è all’inizio del modulo slot divenendo come vi riporto sotto .

//###############################################################
//# mask1_slots.h for ProcessViewServer created: sab ott 9 09:15:51 2010
//# please fill out these slots
//# here you find all possible events
//# Yours: Lehrig Software Engineering
//###############################################################

// todo: uncomment me if you want to use this data aquisiton
// also uncomment this classes in main.cpp and pvapp.h
// also remember to uncomment rllib in the project file
extern rlModbusClient     modbus;
//extern rlSiemensTCPClient siemensTCP;
//extern rlPPIClient        ppi;

Ora se ricompilerete l’operazione andrà tutto a buon fine (se non avete commesso errori).

Prima di procedere al collaudo della nostra applicazioni dobbiamo fare ancora una modifca alla funzione slotinit trasformandola come segue :

static int slotInit(PARAM *p, DATA *d)
{
 qwtThermoSetScale(p,Thermo1,0,100,5,0);
 qwtThermoSetRange(p,Thermo1,0,1000);
 qwtThermoSetFillColor(p,Thermo1,0,255,0);

 qwtThermoSetScale(p,Thermo2,0,100,5,0);
 qwtThermoSetRange(p,Thermo2,0,1000);
 qwtThermoSetFillColor(p,Thermo2,255,0,0);

 qwtThermoSetScale(p,Thermo3,0,100,5,0);
 qwtThermoSetRange(p,Thermo3,0,1000);
 qwtThermoSetFillColor(p,Thermo3,0,0,255);

 if(p == NULL || d == NULL) return -1;
 //memset(d,0,sizeof(DATA));
 return 0;
}

Questa funzione viene richiamata tutte le volte che viene inizializzata la maschera ( caricata e visualizzata) e viene utilizzata per effettuare le operazioni preliminari .

Nel nostro caso la utilizzeremo per settare la scala,il range ed il colore degli oggetti Thermo ( nel mio caso il valore che mi arriva dall’unità remota tramite la lettura dei registri modbus è tra 0 e 1000 ma il suo valore reale è 0-100 , quidi devo effettuare una scalatura ).

NOTA

Utilizzando il protocollo Modbus standard si possono trasferire solo numeri interi ma per ovviare al problema basta cambiare il compo scala dello strumento di campo .

MI spiego meglio :

se voglio visualizzare un numero dopo la virgola configuro lo strumnto di campo in modo che abbia una scalatura 10 volte maggione , ovvero se volgio misurare i metri a 1 m mi dovrà restituire 10 e poi dal lato programma farò le operazioni necessarie per visualizzare 1,0 mt.

Nella prossima sezione del tutorial collauderemo l’applicazione .

<– INDIETROAVANTI–>