|
Appunti informatica |
|
Visite: 2262 | Gradito: | [ Grande appunti ] |
Leggi anche appunti:Il dispositivo PIA Periferal Interface AdapterIl dispositivo PIA Periferal Interface Adapter I campi relativi alla configurazione Sistemi Operativi (JAVA)Sistemi Operativi (JAVA) Introduzione al linguaggio Fin dalla sua presentazione Appunti computer internetCHE COS'E' UN COMPUTER ? Un computer è una grande scatola in cui vengono |
Università Politecnica delle Marche
Corso di Laurea in Ingegneria Elettronica
Corso di Laurea in Ingegneria Informatica e dell'Automazione
Tecnologia per l'Automazione e la Robotica
Controllo Remoto con WinLC di
un processo simulato in Visual Basic
Introduzione al controllo di processo con PLC
L'automazione dei processi industriali
Volendo dare una definizione di automazione industriale, possiamo adottare la seguente: "L'automazione industriale è la disciplina che studia i metodi e le tecnologie che permettono il controllo dei flussi di energia, di materiali e di informazioni necessari alla realizzazione di processi produttivi".
L'importanza dell'automazione nei processi produttivi moderni deriva da molti fattori, non solo economici, come ad esempio:
In generale, in un sistema automatizzato possono essere individuati il processo fisico ed il sistema di controllo.
Il processi fisico può essere definito come "una combinazione di operazioni che agiscono su entità appartenenti al mondo fisico e che cambiano alcune delle loro caratteristiche". Esempi di queste azioni possono essere le azioni di movimento, le lavorazioni meccaniche, le reazioni chimiche e lo scorrere di flussi di energia.
Un processo fisico riceve in ingresso dei materiali, sotto forma di prodotti grezzi, dell'energia e delle informazioni che possono assumere la forma di valori di tensione o corrente elettrica, di pressione di un fluido, oppure essere codificate in sequenze di valori binari. Le uscite sono invece dei materiali, sotto forma di prodotti finiti e scarti, ancora dell'energia e delle informazioni sulle azioni avvenute.
I disturbi provenienti dall'ambiente che agiscono sul processo possono anch'essi essere considerati come ingressi del processo.
Le informazioni in uscita sono fornite da appositi dispositivi formati da un sensore, il quale trasforma la variabile da misurare nel tipo di grandezza che si adotta per la misura, e da un trasduttore, il quale accetta una informazione sotto forma di variabile fisica e la converte in una grandezza di differente natura (tipicamente elettrica). Molto spesso sensore e trasduttore coincidono nello stesso elemento.
Le informazioni in entrata sono utilizzate dagli attuatori per alterare il valore di variabili di controllo per il processo. Di solito gli attuatori sono preceduti dai preattuatori, i quali provvedono a realizzare le conversioni delle informazioni e le amplificazioni di potenza. Come esempio di attuatore possiamo citare un motore: in questo caso il preattuatore è il circuito di potenza che lo pilota.
I sensori, gli attuatori e i preattuatori possono essere considerati come facenti parte del processo fisico e ne costituiscono l'interfaccia verso il sistema di controllo.
Il sistema di controllo riceve informazioni sullo stato del processo tramite i sensori, le elabora secondo algoritmi specificati, e invia agli attuatori le informazioni relative alle azioni da mettere in atto per realizzare il controllo del processo fisico.
A tale scopo esso riceve anche informazioni da una o più entità esterne, le quali possono essere degli operatori umani o altri sistemi di controllo gerarchicamente superiori; esso è inoltre in grado di fornire a queste entità esterne informazioni sul suo stato e su quello del processo controllato
Sistema di controllo e misura di un processo industriale
Secondo lo standard IEC 1131, "un sistema di controllo e di misura di un processo industriale può essere descritto come un insieme di dispositivi interconnessi e comunicanti tra di loro attraverso una o più reti di comunicazione".
Una funzionalità svolta da tale sistema è modellata come un'applicazione che può risiedere in un singolo dispositivo o essere distribuita tra diversi dispositivi. Per esempio, un'applicazione può consistere nella chiusura di uno o più anelli di controllo dove l'acquisizione delle misure è realizzata da un dispositivo, l'algoritmo di controllo da un altro e l'invio dei comandi per il controllo da un altro ancora.
Il dispositivo è definito come una entità fisica indipendente capace di realizzare una o più funzionalità ed è limitato dalle sue interfacce, ossia dai componenti hardware e software che gli permettono di comunicare con l'esterno. Un dispositivo deve comunque contenere almeno una risorsa e almeno una interfaccia, intesa o verso il processo o verso la rete di comunicazione.
Una risorsa può essere considerata una suddivisione logica della struttura software di un dispositivo la quale abbia un controllo indipendente delle sue operazioni. La sua funzione è quella di accettare dati e/o eventi dal processo e/o dalla rete di comunicazione, di processarli, di restituire dati e/o eventi al processo e/o alla rete di comunicazione, così come specificato dalla applicazione che la sta utilizzando.
I dati sono delle rappresentazioni di fatti in una maniera formalizzata adatta alla comunicazione, alla interpretazione o al processamento da parte della risorsa; un esempio di dato è il codice binario corrispondente a una misura.
Gli eventi rappresentano l'occorrenza di particolari condizioni come, per esempio, il raggiungimento di una determinata temperatura.
Una interfaccia di processo mette in relazione le risorse contenute nel dispositivo con il processo fisico, comunicando con i sensori e gli attuatori. Le informazioni scambiate con il processo fisico sono presentate alle risorse come dati e/o come eventi associati al processo.
Una interfaccia di comunicazione mette in relazione le risorse con quelle appartenenti ad altri dispositivi, per lo scambio di informazioni attraverso una rete di comunicazione.
Una applicazione specifica le operazioni che devono essere svolte sui dati come conseguenza degli eventi e, può essere distribuita tra molte risorse nello stesso o in differenti dispositivi.
Nei moderni sistemi di controllo e di misura per processi industriali, le cui architetture prevedono l'interconnessione di numerosi dispositivi, si impiegano sia controllori a logica programmabile (o PLC) che dei calcolatori di tipo tradizionale.
In linea di principio si utilizzano i PLC quando vi è la necessità di collegarsi direttamente ai sensori e agli attuatori; un calcolatore di tipo tradizionale è invece utilizzato come dispositivo se deve soprattutto colloquiare con altri dispositivi, PLC o altri calcolatori, attraverso le reti di comunicazione.
Il controllore a logica programmabile
Lo standard IEC 1131 definisce controllore a logica programmabile come "un sistema elettronico a funzionamento digitale, destinato all'uso in ambito industriale, che utilizza una memoria programmabile per l'archiviazione interna di istruzioni orientate all'utilizzatore per l'implementazione di funzioni specifiche, come quelle logiche, di sequenziamento, di temporizzazione, di conteggio e di calcolo aritmetico, e per controllare, mediante ingressi ed uscite sia digitali che analogici, vari tipi di macchine e processi"
Viene inoltre definito come sistema controllore a logica programmabile o sistema PLC "la configurazione realizzata dall'utilizzatore, formata da un controllore a logica programmabile e dalle periferiche associate, necessarie al sistema automatizzato previsto".
La configurazione minima di un sistema PLC è composta dai seguenti cinque componenti fondamentali: l'armadio, il modulo processore, i moduli di ingresso/uscita, il modulo alimentatore, il terminale di programmazione.
L'armadio, o cestello o rack, contiene e racchiude tutti gli altri moduli, assicurandone la connessione meccanica e il collegamento elettrico. Ha in genere la forma di un parallelepipedo aperto su di un lato per permettere l'inserimento dei moduli che risultano collegati elettricamente tra loro grazie alla presenza, sul lato opposto, di un circuito stampato con dei connettori. Solitamente è di metallo e deve essere connesso elettricamente a terra, sia per ragioni di sicurezza sia per meglio schermare i moduli alloggiati.
Il modulo processore è il vero e proprio PLC ed è costituito essenzialmente da una scheda a microprocessore con una architettura simile a quella dei calcolatori convenzionali. Esso controlla e supervisiona tutte le operazioni eseguite all'interno del sistema, attraverso l'esecuzione delle istruzioni contenute nella memoria.
I moduli di ingresso/uscita, o moduli di I/O, sono delle schede che permettono l'interfacciamento tra la microelettronica del PLC e il mondo esterno, e devono perciò provvedere al condizionamento dei segnali e all'isolamento.
Il modulo alimentatore è una scheda che alimenta tutti gli altri moduli presenti nell'armadio, Connesso alla rete di alimentazione elettrica, tale modulo fornisce una o più tensioni stabilizzate con un massimo di corrente erogabile.
Il terminale di programmazione può essere o un dispositivo particolare o un semplice personal computer e serve per al programmazione del PLC che non ha, usualmente, dispositivi di interfaccia con l'uomo. Il terminale di programmazione viene connesso al PLC solo quando viene utilizzato tramite una porta seriale e/o una rete informatica.
E' importante sottolineare che sono i moduli di ingresso/uscita a determinare il successo dei PLC rispetto ad esempio ad un sistema di controllo basato su PC: mentre l'utente di quest'ultimo deve di volta in volta scegliere, interfacciare (e talvolta anche progettare) tutto un insieme di periferiche che permettano la comunicazione fra il PC e il particolare processo considerato, nel modulo I/O del PLC sono sempre presenti un certo numero di ingressi e uscite digitali, di ingressi e uscite analogiche con tensioni e potenze diverse, che permettono invece un collegamento diretto al processo senza ulteriori interventi del controllista. Non di rado sono presenti anche moduli speciali, come dei PID per la regolazione proporzionale-integrale-derivativa o dei moduli SERVO, per il controllo di motori passo-passo, idraulici o in corrente continua.
Esistono anche alcuni piccoli sistemi PLC che non sono modulari, non prevedono il rack, e racchiudono in un unico dispositivo alcuni o tutti i componenti sopra descritti.
Lo standard IEC 1131 definisce anche i linguaggi di programmazione per i sistemi di controllo, in generale, e i controllori a logica programmabile, in particolare.
Lo standard prevede i seguenti linguaggi di programmazione per i PLC: diagramma funzionale (o SFC), diagramma a blocchi (o FBD), linguaggio a contatti (o Ladder Diagram), lista di istruzioni, testo strutturato. I primi tre sono linguaggi di programmazione grafici, gli ultimi due sono linguaggi testuali.
Il diagramma funzionale sequenziale permette di formulare le applicazioni di controllo di processi fisici utilizzando i concetti di fase e di transizione.
Brevemente, le fasi rappresentano le azioni da compiere, eventualmente in parallelo, mentre le transizioni rappresentano le condizioni da soddisfare affinché si possa passare da una fase all'altra.
Esso può essere anche utilizzato per la definizione delle specifiche funzionali del sistema automatizzato.
Tra le sue caratteristiche si ricordano la possibilità di prevedere sequenze che si sviluppano in parallelo o in alternativa, eventualmente assegnando loro delle priorità, e la possibilità di prevedere sequenze di retroazione che modifichino lo svilupparsi delle sequenze normali.
Il linguaggio a contatti (o Ladder Diagram) prevede l'utilizzo degli elementi contatto aperto, contatto chiuso e bobina, tipici degli schemi di controllo a relè elettromeccanici. Sono inoltre previste delle istruzioni per realizzare funzioni di temporizzazione, conteggio, operazioni aritmetiche, ecc.
Il linguaggio a contatti è stato concepito per trattare principalmente logica binaria anche se è stato esteso attraverso l'uso di funzioni speciali per permettergli, ad esempio, di poter trattare numeri reali e realizzare funzionalità di controllo di processo.
Il diagramma a blocchi funzionali è anch'esso un linguaggio di programmazione concepito per trattare principalmente logica binaria. Utilizza una simbologia derivante dalla progettazione dei circuiti elettronici.
La lista di istruzioni è un linguaggio di programmazione testuale simile ai linguaggi assemblativi dei calcolatori tradizionali. Presente soprattutto nei PLC di origine tedesca con la sigla AWL, è utilizzato soprattutto da programmatori che provengono dal mondo informatico.
Il testo strutturato è un linguaggio di programmazione testuale ad alto livello, simile al Pascal, con adattamenti all'utilizzo nei sistemi di controllo.
I linguaggi di programmazione più utilizzati al giorno d'oggi restano il linguaggio a contatti e la lista di istruzioni, offerti, da soli o insieme, da tutti i costruttori di PLC.
Cominciano a diffondersi anche applicazioni in diagramma funzionale sequenziale. Le quali permettono una maggiore facilità di scrittura e leggibilità dei programmi; molto spesso però le singole fasi e transizioni debbono poi essere descritte attraverso altri linguaggi.
Il testo strutturato è stato recentemente introdotto da alcuni costruttori, anche se il suo utilizzo non si è ancora diffuso; molto probabilmente si affermerà nel futuro, con il diffondersi della cultura informatica e la necessità di combinare insieme PLC e calcolatori tradizionali
Presentazione del progetto
Nel progetto realizzato abbiamo voluto affrontare tre importanti tematiche inerenti il corso di ingegneria e tecnologie dei sistemi di controllo:
il funzionamento e la programmazione dei plc, dal punto di vista chi si affaccia per la prima volta a questo mondo e non dispone di un plc reale su cui esercitarsi; siamo ricorsi al software WinLc, il controllore logico su PC del pacchetto WinAc: WINdows Automation Center. WinAc permette il "pc based control", ovvero la sostituzione del modulo Cpu di un sistema di automazione con un calcolatore. Per questo la complessità di winlc sta tutta nella configurazione dell'hardware (per la comunicazione su profibus e l'integrazione con cpu step7 reali): noi abbiamo "by-passato" questa configurazione grazie al controllo ocx s7data del software computing (fornito con lo stesso pacchetto WinAc) che ci ha permesso di leggere e scrivere i segnali interni di winlc senza passare per la configurazione dell'hardware.
la simulazione di processi e il loro controllo con linguaggi di programmazione grafica; in fase di progetto ci siamo trovati a dover scegliere fra l'implementazione in Visual Basic o in Labview di National Instruments: abbiamo scelto il primo per la semplicità del processo simulato, per la possibilità di realizzare eseguibili autonomi (file exe) e per la predisposizione di Winlc a interagire con Visual Basic attraverso il componente s7data. Labview andrebbe invece preferito per simulare processi complessi, per progettare moduli che necessitino una complessa comunicazione con l'esterno attraverso schede di acquisizione come la LabPc della National Instruments.
il controllo remoto di processi attraverso reti di calcolatori abbiamo collaudato il nostro progetto su due calcolatori collegati punto-punto attraverso un cavo incrociato. Si tratta di una rete locale elementare, che non presenta però grosse differenze con una normale rete LAN e quindi il corretto funzionamento è garantito anche su una normale LAN. La versatilità del controllo winsock permette inoltre di estenderne l'utilizzo con piccole modifiche anche sulla rete internet.
I programmi utilizzati
In questo paragrafo descriviamo in dettaglio i programmi utilizzati, ovvero:
Il controllore Winlc che implementa le funzionalità di un plc S7 su sistema operativo windows
Il software di programmazione Step7 per i Plc della serie S7, con il quale abbiamo caricato il programma a contatti nel controllore
Visual Basic per l'implementazione del processo, dell'interfaccia verso il controllore e della comunicazione fra i due moduli
Il controllore logico su pc: winlc del pacchetto Simatic WinAc
WinLc è il controllore logico fornito con il pacchetto WinAC (windows automation center), che permette di realizzare il "PC-based control", ovvero il controllo di processo basato su Pc ma con le tecniche proprie dei controllori logici programmabili.
Gli altri componenti del pacchetto WinAc sono:
software computing, che è un insieme di controlli Ocx attraverso i quali accedere e manipolare i dati di un controllore logico, quale WinLc fornito con la versione base di WinAc o la CPU 416-DP Isa fornita con la versione Pro di WinAc.
il Toolmanager che permette di richiamare in modo semplice e immediato gli eseguibili costruiti con Computing , grazie a una comoda barra di lavoro.
WinLC offre una soluzione computer-based per i progetti di automazione e, come mostrato in figura, è possibile collegarlo attraverso una rete profibus-DP alle unità di I/O distribuite e tramite queste al processo.
Winlc fa parte della famiglia dei prodotti per l'automazione della Siemens e quindi risulta totalmente compatibile con i software del pacchetto Simatic; in particolare il software di programmazione Step 7 e il centro di controllo WinCC.
Nelle intenzioni del costruttore anche il pacchetto computing si integra in questo schema, fornendo un insieme di strumenti che permettono di accedere e/o manipolare i dati del controllore logico WinLc da una qualsiasi applicazione "exe", realizzando così interfacce e applicazioni che estendono le funzionalità del "Pc Based Control" rispetto al controllo basato esclusivamente su PLC. L'interfacciamento del controllore con il processo resta però una prerogativa dei moduli remoti di I/O, collegati al PC tramite bus di campo. Tutto questo è riassunto nella seguente figura, tratta dal manuale:
Non avendo a disposizione un processo reale, però, nel nostro progetto questo schema non viene rispettato: oltre ad utilizzare gli OCX di computing per interfacciare winlc all'utente, noi li adoperiamo per interfacciarlo al processo, leggendo le uscite di WinLc per inviarle al serbatoio e scrivendo negli ingressi di WinLc quanto ci arriva dal serbatoio stesso.
E' una differenza sostanziale: possiamo dire di aver "snaturato" l'utilizzo di WinLc per adattarlo ai nostri scopi, modificando lo schema previsto dal costruttore nel modo seguente:
Questo ci ha permesso di evitare la configurazione dell'hardware col Simatic Manager, semplicemente perché l'hardware non c'è ed è stato "by-passato" ricorrendo agli OCX di Computing.
Il software WinLC, giunto alla versione 2.0 ha le seguenti caratteristiche:
funzionalità di un PLC S7-300 (o 400) della Siemens
gestisce l'organizzazione in blocchi funzionali del software
pannello di controllo che permette una semplice gestione del progetto
possibilità di protezione attraverso password
possibilità di utilizzo di EEPROM per la programmazione
funziona come un servizio NT di rete permettendo l'accesso da computer remoti.
Dopo l'avvio del programma, all'utente si presenta una interfaccia che rappresenta la CPU del PLC S7-300 e che permette di gestire tutte le operazioni gestibili dal controllore WinLC:
monitoraggio dello stato
scelta delle modalità operative
settaggio del PLC
stato della CPU
reset della memoria del PLC
Una volta in lanciato WinLC, attraverso lo Step 7 andiamo a creare il progetto di controllo e lo carichiamo nella memoria del WinLC attraverso il comando "restore". Il programma viene compilato nel formato .wlc che può essere salvato col comando "archive" e ricaricato successivamente senza passare per step7. Nella versione demo non è consentita questa compilazione, ma solo il caricamento e il salvataggio di programmi già compilati in formato wlc.
La programmazione del controllore: Simatic manager e step7
Il SIMATIC Manager gestisce i dati appartenenti a un progetto di automazione, indipendentemente dal sistema di destinazione per cui sono realizzati (S7/M7/C7). Le applicazioni necessarie per la modifica dei dati prescelti vengono avviate automaticamente dal SIMATIC Manager.
Editor di simboli
Con l'editor di simboli vengono gestite tutte le variabili globali. Sono disponibili le seguenti funzioni:
definizione di nomi simbolici e commenti sui segnali di processo (ingressi/uscite), marker e blocchi;
funzioni di ordinamento;
importazione/esportazione con altri programmi Windows.
La tabella dei simboli che viene così creata è a disposizione di tutte le applicazioni. La modifica di un parametro simbolico viene pertanto riconosciuta da tutte le applicazioni.
Diagnostica hardware
La diagnostica hardware offre una panoramica sullo stato del sistema di automazione. In una visione d'insieme è possibile visualizzare per ogni unità, mediante un simbolo, se l'unità è avariata o meno. Con un doppio clic sull'unità avariata vengono visualizzate informazioni dettagliate sull'avaria stessa. Il volume delle informazioni dipende dalla singola unità:
visualizzazione di informazioni generali sull'unità (p. es. numero di ordinazione, versione, nome) e dello stato dell'unità (p. es. guasta);
visualizzazione dell'errore dell'unità (p. es. errore canale) della periferia centrale e slave DP;
visualizzazione dei messaggi dal buffer di diagnostica.
Per le CPU vengono visualizzate informazioni supplementari:
causa del guasto nell'esecuzione del programma utente;
visualizzazione della durata del ciclo (ciclo massimo, minimo e ultimo);
possibilità e carico della comunicazione MPI;
visualizzazione dei dati utili (numero di ingressi/uscite possibili, marker, contatori, temporizzatori e blocchi).
Linguaggi di programmazione
I linguaggi di programmazione KOP, AWL e FUP per S7-300/400 sono parte integrante del software di base.
KOP (schema a contatti) è un linguaggio di programmazione grafico. La sintassi delle istruzioni assomiglia ad uno schema di circuito. KOP consente all'utente di seguire in modo semplice il flusso dei segnali tra sbarre collettrici, contatti, elementi complessi e bobine.
AWL (lista istruzioni) è un linguaggio di programmazione testuale vicino al linguaggio macchina. Quando si crea un programma in AWL, le singole istruzioni corrispondono in larga misura alle operazioni con le quali la CPU elabora il programma. Per facilitare la procedura di programmazione, AWL è stato ampliato con alcune espressioni di linguaggi avanzati (come per es. accessi ai dati strutturati e parametri di blocco).
FUP (schema funzionale) è un linguaggio grafico di programmazione che rappresenta la logica mediante i box dell'algebra booleana. Esso consente inoltre di rappresentare funzioni complesse (ad es. le funzioni matematiche) direttamente in connessione con i box logici.
Altri linguaggi di programmazione sono disponibili come software opzionali.
Configurazione hardware
Questa applicazione viene utilizzata per la configurazione e la parametrizzazione dell'hardware di un progetto di automazione. Sono disponibili le seguenti funzioni.
Per configurare il sistema di automazione selezionare telai di montaggio (rack) da un catalogo elettronico, e assegnare le unità selezionate ai posti connettore desiderati.
La configurazione della periferia decentrale avviene in maniera identica a quella della periferia centrale. Viene così supportata anche la configurazione della periferia canale per canale.
Nella parametrizzazione della CPU possono essere impostate in modo interattivo proprietà come comportamento all'avviamento e controllo del tempo di ciclo. Viene supportato il multicomputing. I dati immessi vengono salvati nei blocchi dati di sistema.
Nella parametrizzazione delle unità è possibile definire tutti i parametri impostabili mediante finestre di dialogo. Non avvengono impostazioni tramite selettore DIP. La parametrizzazione delle unità avviene automaticamente nell'avviamento della CPU. È pertanto possibile, p. es., sostituire unità senza dover riparametrizzarle.
La parametrizzazione dei moduli funzionali (FM) e dei processori di comunicazione (CP) avviene anche all'interno della configurazione hardware in modo identico alla parametrizzazione delle restanti unità. A questo scopo, per ogni FM e CP sono disponibili finestre di dialogo e regole specifiche (nella fornitura del pacchetto funzionale FM/CP). Il sistema impedisce digitazioni erronee, offrendo nelle finestre di dialogo soltanto possibilità di introduzione ammesse.
NetPro
Con NetPro si rende possibile il trasferimento di dati ciclico comandato a tempo per mezzo di MPI con:
selezione dei nodi della comunicazione;
introduzione di sorgente dati e destinazione dati in una tabella; avvengono automaticamente la generazione di tutti i blocchi da caricare (SDB) e il loro completo trasferimento.
È inoltre possibile una trasmissione dati controllata dagli eventi con:
definizione dei collegamenti di comunicazione;
selezione dei blocchi di comunicazione/blocchi funzionali dall'integrata biblioteca dei blocchi;
parametrizzazione dei blocchi funzionali e di comunicazione prescelti nel consueto linguaggio di programmazione.
Struttura del progetto
I progetti hanno la funzione di raccogliere e ordinare i dati e i programmi creati nell'ambito di una soluzione di automazione. I dati raggruppati in un progetto sono costituiti in particolare da:
dati di configurazione relativi alla struttura hardware e dati di parametrizzazione per le unità
dati di progettazione per la comunicazione in rete
programmi per le unità programmabili.
Nella creazione di un progetto l'operazione principale è costituita dalla preparazione di tali dati e dalla programmazione.
I dati vengono collocati nei progetti sotto forma di oggetti. Essi vengono disposti in una struttura ad albero (gerarchia del progetto). La rappresentazione della gerarchia nella finestra di progetto è simile a quella della Gestione risorse di Windows. Le icone degli oggetti hanno però un aspetto dissimile da Windows.
Il vertice della gerarchia del progetto ha la seguente struttura.
livello1 : progetto
livello2 : sottoreti, stazioni o programmi S7/M7
livello3 : dipende dall'oggetto del 2° livello.
Finestra di progetto
La finestra di progetto è suddivisa in due parti. A sinistra viene rappresentata la struttura del progetto. A destra viene visualizzato il contenuto dell'oggetto selezionato nella parte sinistra, con il tipo di visualizzazione prescelto (icone grandi, icone piccole, elenco, dettagli) .
Nel lato sinistro della finestra cliccare sulla casella con il segno più per visualizzare la struttura completa del progetto.
Al vertice della gerarchia degli oggetti si trova l'oggetto 'S7_Pro1' che rappresenta l'intero progetto. Lo si può utilizzare per visualizzare le proprietà del progetto, e serve da cartella delle reti (per la progettazione delle reti), delle stazioni (per la configurazione dell'hardware) e dei programmi S7 o M7 (per la creazione del software). Selezionando il simbolo del progetto, gli oggetti in esso contenuti vengono visualizzati nella parte destra della finestra. Gli oggetti che si trovano al vertice della gerarchia (oltre ai progetti, le biblioteche) sono il punto da cui inizia la selezione degli oggetti all'interno delle finestre di dialogo.
Visualizzazione del progetto
È possibile visualizzare in finestre di progetto la struttura del progetto per la base di dati del sistema di origine nel modo 'offline', e per la rispettiva base di dati del sistema di destinazione nel modo 'online'.
È impostabile anche la visualizzazione della gestione dell'impianto se è caricato il relativo pacchetto opzionale.
Avvertenza: la configurazione dell'hardware e la progettazione dei collegamenti in rete possono essere eseguite solo nella visualizzazione offline.
Introduzione alla configurazione dell'hardware
Configurazione
Per 'configurazione' si intende la disposizione di telai di montaggio, unità, dispositivi di periferia decentrata e moduli di interfaccia nella finestra della stazione. I telai di montaggio vengono riportati in una tabella di configurazione che contiene sia i telai 'reali' che un dato numero di unità innestabili.
Nella tabella di configurazione, STEP 7 assegna automaticamente un indirizzo ad ogni unità. Gli indirizzi delle unità di una stazione possono essere modificati se la CPU è liberamente indirizzabile.
La configurazione può essere copiata più volte in altri progetti di STEP 7, ed essere eventualmente modificata e caricata in uno o più impianti esistenti. All'avvio del controllore programmabile, la CPU confronta la configurazione prefissata creata con STEP con la configurazione attuale dell'impianto, consentendo di individuare e segnalare immediatamente gli eventuali errori.
Parametrizzazione
Per 'parametrizzazione' si intende:
l'impostazione delle proprietà delle unità parametrizzabili per la struttura centrale e per una rete. Esempio: una CPU è un'unità parametrizzabile. Il tempo di controllo del ciclo è un parametro che l'utente può impostare.
l'impostazione dei parametri di bus, master DP e slave DP per un sistema master (PROFIBUS DP).
Questi vengono caricati nella CPU e trasmessi dalla CPU alle relative unità. Le unità possono essere sostituite facilmente, in quanto i parametri creati con STEP 7 possono essere caricati all'avviamento automaticamente nella nuova unità.
Quando eseguire la configurazione hardware
Le proprietà dei controllori programmabili S7 e delle unità sono impostate in modo tale che in molti casi non occorre fare la configurazione.
La configurazione è assolutamente necessaria nei seguenti casi:
se si vogliono modificare i parametri preimpostati di un'unità (ad es. abilitazione di allarme di processo in un'unità)
se si vogliono progettare i collegamenti di comunicazione
nelle stazioni con periferia decentrata (PROFIBUS DP)
nelle stazioni S7-400 con più CPU (multicomputing) o telai di ampliamento.
in controllori programmabili a elevata disponibilità (pacchetto opzionale)
Osservare le seguenti regole per la configurazione di reti.
Ogni nodo di una sotto-rete deve avere un diverso indirizzo di nodo.
Le CPU fornite hanno l'indirizzo di default 2. Dato che questo indirizzo può essere usato per un solo nodo, bisogna modificare l'indirizzo preimpostato in tutte le altre CPU.
Per le stazioni S7-300: nella progettazione di indirizzi MPI per diverse CPU è necessario prevedere 'spazi vuoti (intervalli) negli indirizzi MPI' per FM e CP con indirizzo MPI proprio per evitare la doppia occupazione di indirizzi.
Soltanto quando ogni unità di una sotto-rete dispone di un indirizzo diverso, e la configurazione reale corrisponde a quella creata, sarà possibile caricare le impostazioni nella rete.
Assegnazione di indirizzi MPI
Assegnare gli indirizzi MPI in ordine crescente
Riservare l'indirizzo MPI 0 per un PG
Sono collegabili tra loro in una sotto-rete MPI fino a 127 nodi (indirizzabili).
Ogni indirizzo MPI di una sotto-rete MPI deve essere diverso dagli altri.
Per ulteriori regole sulla configurazione di reti consultare i manuali sulla configurazione di SIMATIC 300 e SIMATIC 400.
Assegnazione di indirizzi PROFIBUS
Assegnare per ogni master DP e ogni slave DP nella rete PROFIBUS un indirizzo PROFIBUS univoco nel campo da 0 a 125.
Assegnare gli indirizzi PROFIBUS in ordine crescente.
Riservare l'indirizzo PROFIBUS '0' per un dispositivo di programmazione collegabile in seguito alla rete PROFIBUS ai fini di assistenza tecnica.
Gli utenti che utilizzano per la prima volta il SIMATIC Manager troveranno qui di seguito una descrizione molto semplice che faciliterà loro l'accesso. La descrizione si basa sulla programmazione di un SIMATIC S7.
Procedere nella maniera seguente:
Creare un nuovo progetto con l'aiuto del comando di menu File T Nuovo
Selezionare il simbolo del progetto nella finestra del progetto
Immettere un programma S7 con il comando di menu Inserisci T Programma T Programma S7
Fare doppio clic sul programma utente (oggetto 'Blocchi') contenuto nella cartella 'Programma S7'
Fare doppio clic sull'OB1 che ora viene visualizzato nella parte destra della finestra del progetto.
Una volta avviata l'applicazione è possibile elaborare il blocco o crearne di nuovi
Definire nelle proprietà dell'oggetto del programma S7 l'indirizzo MPI dell'unità nella quale testare i blocchi creati. Selezionare perciò nella visualizzazione online il programma S7 e quindi il comando di menu Modifica T Proprietà dell'oggetto
Selezionare nella visualizzazione offline della finestra del progetto il programma utente (cartella 'Blocchi') o i blocchi da caricare
Caricare gli oggetti selezionati nel sistema di destinazione utilizzando il comando di menu Sistema di destinazione T Carica
Il programma utente caricato può essere testato con la funzione Controlla e Comanda
A titolo indicativo riportiamo di seguito il set di "istruzioni" del linguaggio a contatti step7:
Due esempi di possibili programmi di controllo
Portiamo ora due esempi di semplici programmi in linguaggio a contatti per controllare il serbatoio; Il primo mostra come utilizzare ingressi di tipo on-off quali i finecorsa, il secondo utilizza invece l'ingresso analogico IW1, che è un intero a 16 bit su cui viene scritto il valore del livello.
In questo modo intendiamo mostrare come l'introduzione di uscite ridondanti (in fondo è sufficiente controllare il livello per capire se il serbatoio è pieno o vuoto, i finecorsa potevano anche essere omessi) renda possibile, vista la natura didattica del nostro progetto, sia il controllo on-off che quello "analogico".
Programma per il riempimento e lo svuotamento ciclico del serbatoio
Il programma è molto semplice e costituito da due soli rung: il primo per il comando della valvola di ingresso del liquido e il secondo per il controllo della valvola di uscita.
Il diagramma a contatti è il seguente:
Ricordiamo il seguente significato delle variabili:
I0.0: |
ingresso di winlc che rileva il finecorsa di serbatoio pieno |
I0.1: |
ingresso di winlc che rileva il finecorsa di serbatoio vuoto |
Q0.0: |
uscita di winlc che comanda la valvola di ingresso del liquido |
Q0.1: |
uscita di winlc che comanda la valvola di uscita del liquido |
Per capire il funzionamento del primo rung poniamoci nella situazione di serbatoio pieno: il bit I0.0 vale 1 e I0.1 vale 0, quindi la bobina Q0.1 viene attivata. A questo punto, nella scansione successiva è il marker di questa bobina che mantiene attivo il rung. Quando il serbatoio si è svuotato, il contatto si interrompe perché I0.1 è un contatto normalmente aperto.
Il funzionamento del secondo rung è duale al precedente.
Programma per la regolazione del livello
Questo programma controlla che il serbatoio resti pieno a metà, cioè al livello 50. Il diagramma a contatti è il seguente:
Il funzionamento è banale: se il livello supera 50 si attiva la valvola di uscita finché non scende sotto il valore 50. Quando si scende sotto tale valore, si attiva la valvola di ingresso.
L'esempio è però interessante perché mostra gli inconvenienti della regolazione con controllori on-off rispetto ai controllori analogici: non si ottiene un assestamento al valore 50 ma una continua oscillazione fra i valori 49 e 51.
Visual Basic: l'implementazione del processo, del controllore e la loro comunicazione
Visual Basic è un linguaggio di programmazione "event driven", in cui cioè l'esecuzione del codice è regolata dal verificarsi o meno di opportuni eventi. Gli eventi possono essere generati dai diversi oggetti che l'utente introduce nel form del progetto: bottoni, caselle di testo, liste, contatori, ecc
Perciò questo software si presta bene alla realizzazione di "processi virtuali" e al loro controllo tramite "pannelli virtuali" che generano gli eventi di pilotaggio: apertura e chiusura di valvole, accensione e spegnimento di luci, ecc
Nel nostro caso abbiamo implementato un serbatoio del quale è possibile controllare il riempimento, lo svuotamento e la portata.
Realizzazione del processo
In questo paragrafo descriviamo i principi generali di funzionamento dell'applicazione server.exe che simula un serbatoio con due valvole, due finecorsa e un trasduttore di livello. L'applicazione si presenta sullo schermo come nella seguente figura:
Il fulcro del processo è un timer che genera eventi ad intervalli regolari, che si possono variare attraverso il cursore di controllo della portata. Gli eventi generati dal timer vengono conteggiati in una opportuna variabile chiamata conteggio.
Un'altra variabile svolge il ruolo di "flag" per la direzione del conteggio e può essere settata attraverso i comandi "apri" e "chiudi".
Cliccando sul bottone "apri" la variabile viene settata al valore "avanti" e ad ogni evento del timer il contatore viene incrementato.
Cliccando sul bottone "chiudi" la variabile viene settata al valore "indietro" e ad ogni evento del timer il contatore viene decrementato.
Il bottone "stop" disabilita invece la generazione degli eventi da parte del timer col conseguente arresto del conteggio.
La rappresentazione grafica del serbatoio non è altro che la sovrapposizione di 10 immagini con differenti livelli del liquido: settando la proprietà .visible in base al valore del contatore, si rende l'idea di un serbatoio in movimento.
Quando il contatore raggiunge il valore 100 viene settata a true una variabile che rappresenta il finecorsa di riempimento; lo stesso succede alla variabile associata al finecorsa di svuotamento quando il contatore torna a 0.
Una checkbox, infine, permette il controllo del contatore attraverso delle stringhe provenienti dal modulo client anziché in modo manuale.
Realizzazione del modulo di controllo remoto
Come mostra la figura che segue, nell'applicazione client.exe gli unici bottoni presenti riproducono apri, chiudi e stop del processo e svolgono gli stessi compiti quando nel modulo del server viene selezionato il comando automatico.
Gli altri comandi sono stati organizzati in menu: attraverso uno di questi si può affidare il controllo del processo al programma winlc; questo controllo può essere completamente automatico oppure supervisionato dall'utente.
Nel primo modo ciascuna uscita del processo (stato dei finecorsa e livello del liquido) viene sempre inviata allo stesso ingresso di winlc; lo stesso accade per le uscite del controllore che il codice assegna sempre agli stessi ingressi del processo (valvola di apertura e valvola di chiusura).
Riprendendo il modo di operare dei controllori logici programmabili abbiamo riprodotto un collegamento rigido fra ingressi e uscite del plc e del processo; l'utente deve conoscere questi collegamenti per realizzare il programma di controllo: a tale scopo può visualizzare la "morsettiera virtuale" selezionandola dal menu di aiuto.
Nel secondo modo l'utente preleva l'uscita del plc e la invia al processo; diversamente dal modo automatico è lasciata la facoltà di selezionare quale uscita prelevare e a quale ingresso del processo inviarla. Dualmente si può scrivere su uno qualsiasi degli ingressi del controllore una delle uscite del processo.
Questa modalità prescinde dai collegamenti della morsettiera virtuale ed è quindi particolarmente indicata in fase di stesura del programma a contatti, potendo osservare l'evolvere delle variabili in gioco e deciderne la destinazione.
Il componente s7data: proprietà e metodi utilizzati
Il controllo s7data è uno degli ocx (OLE custom controls) forniti nel tool "computing software" di WinAc, descritto nel paragrafo 3.1.
Gli altri controlli forniti con tale pacchetto sono:
Simatic Panel Control, che riproduce nel form di Visual Basic la schermata di WinLc e permette di scegliere fra le modalità Run, Run-P e Stop.
Simatic Button Control, che permette di settare o resettare singoli bit di Winlc con un bottone; è una funzionalità che può anche essere implementata combinando un bottone di Visual Basic e il metodo ReadVariable del controllo s7data (è la soluzione che abbiamo adottato).
Simatic Number control, che permette di accedere a parole o byte di Winlc con una casella di testo: abbiamo fatto a meno anche di questo componente, sostituendolo con la combinazione di una text_box di Visual Basic e dei metodi ReadVariable e WriteVariable di s7data .
Simatic Slider control, che permette le stesse funzioni del number control agendo però su una barra. Come i precedenti 2 controlli anche questo è ridondante, potendo essere sostituito dalla combinazione di una Scroll-Bar e del metodo WriteVariable di S7data.
I metodi e le proprietà del controllo S7data sono riassunti nella seguente tabella:
|
|
Noi però abbiamo utilizzato solo i due metodi più importanti:
ReadVariable per la lettura di una variabile in WinLc; la routine di esempio fornita col manuale è la seguente: le due variabili importanti sono name_s, a cui si assegna l'indirizzo da leggere, e value_v , a cui il metodo assegna il valore letto: |
|
WriteVariable, per la scrittura di una variabile in WinLc; il programma di esempio è il seguente: |
|
Comunicazione fra processo e controllore
In accordo col modello Client/server, dove un'applicazione chiede un servizio e l'altra lo eroga, la comunicazione avviene così:
il client invia al server il bit di controllo della valvola di apertura e il bit della valvola di chiusura ( più un eventuale campo per settare il livello desiderato, che viene utilizzato solo in modalità di setup, cioè in read/write manuale)
il server risponde con lo stato del finecorsa di apertura, lo stato del finecorsa di chiusura e il livello del serbatoio
E' pertanto il client a "guidare" lo scambio di informazioni, ed il server si limita ad eseguire il servizio richiesto (l'esecuzione del comando, in questo caso) e a rispondere con lo stato del processo.
Questo fa si che in modalità automatica lo stato del processo pervenga al client con sufficiente regolarità, ad ogni invio del comando.
In modalità manuale, invece, si rischierebbe di avere un'immagine del processo scaduta se l'utente agisse sul pannello di controllo con frequenza troppo bassa. Per questo abbiamo introdotto un timer che invia a intervalli regolari i segnali di comando (ovviamente sempre gli stessi, se l'utente non li modifica); questi intervalli sono piccoli, in modo che l'immagine del processo sia sufficientemente aggiornata.
Il componente winsock
Il controllo Winsock è stato integrato in Visual Basic dalla Microsoft, per gestire in maniera facile e veloce le connessioni tra due PC mediante il protocollo TCP/IP. In particolare, l'oggetto Winsock, viene impiegato nella realizzazione di applicazioni Client/Server.
Queste applicazioni sono particolari perché costituite da due parti: una Client e una Server. L'applicazione Server deve essere sempre connessa in rete e in ascolto, in attesa che un'applicazione Client richieda delle informazioni. Appena l'applicazione Server riceve la richiesta, risponde con le informazioni appropriate.
Winsock è contenuto nel file MSWINSCK.OCX: per adoperarlo, bisogna prima caricarlo nella Tool di Visual Basic attraverso la voce componenti del menu progetto.
Prima di esaminare le proprietà del controllo Winsock, bisogna scegliere uno dei due protocolli disponibili. Winsock, infatti, supporta le seguenti modalità operative:
Modalità TCP (Trasmission Control Protocol)
La modalità TCP permette di creare e mantenere una connessione con un computer remoto. Con questa modalità, entrambe i computer possono scambiare dati l'uno con l'altro (full-duplex).
Se si sta creando un'applicazione Client, bisogna trovare il nome del computer Server o l'indirizzo IP e assegnarlo alla proprietà RemoteHost e quello della porta che va impostato nella proprietà LocalPort su cui l'applicazione si metterà in attesa. Poi andrà chiamato il metodo Connect.
Se invece si sta progettando un'applicazione Server, bisogna impostare il valore della porta su cui l'applicazione ascolta, nella proprietà LocalPort, e successivamente chiamare il metodo Listen. Quando un'applicazione Client richiede una connessione, viene generato l'evento ConnectionRequest. Per completare la connessione, bisogna chiamare il metodo Accept all'interno dell'evento ConnectionRequest.
Quando la connessione è stata instaurata, entrambi i computer possono inviare e ricevere dati. Per inviare i dati, bisogna richiamare il metodo SendData. Se i dati sono stati ricevuti correttamente, dall'altra parte verrà generato l'evento DataArrival. Per recuperare i dati, bisogna chiamare il metodo GetData all'interno dell'evento DataArrival.
Modalità UDP (User Datagram Protocol)
La modalità UDP sfrutta un protocollo, l'UDP, senza connessione. A differenza del protocollo TCP, nell'UDP i computer non stabiliscono una connessione e quindi un'applicazione realizzata con questo protocollo può essere sia Server che Client.
Per trasmettere i dati con questa modalità, bisogna impostare prima la proprietà LocalPort del computer Client.
Nel Server andrà impostato alla proprietà RemoteHost il nome del computer Client o l'indirizzo IP, e richiamato il metodo SendData per iniziare ad inviare i messaggi. Il computer Client dovrà usare il metodo GetData all'interno dell'evento DataArrival per recuperare i messaggi inviati.
Proprietà del controllo Winsock
Winsock permette di creare applicazioni Client e Server con lo stesso controllo. Questa doppia funzionalità permette di specificare attraverso l'impostazioni delle proprietà il tipo di applicazione che si ha intenzione di realizzare.
Winsock utilizza molte proprietà uguali sia che l'applicazione che si sta costruendo è un Client che un Server. Questo oggetto è privo di interfaccia visiva, ovvero il controllo è visibile soltanto in fase di design ed appare con un piccolo quadretto raffigurante due computer connessi in rete.
Di seguito sono descritte le proprietà disponibili per il controllo Winsock e come queste possono essere richiamate all'interno di un'applicazione.
Proprietà BytesReceived
La proprietà BytesReceived indica il numero di byte presenti nel buffer di ricezione. Questa proprietà è di sola lettura e non è disponibile durante la fase di progettazione. Il valore restituito è di tipo Long Integer.
Sintassi:
<Variabile> = Winsock<index>.BytesReceived
La proprietà BytesReceived può essere usata per determinare le dimensioni di un' area in cui visualizzare i dati oppure per vedere se ci sono dati nel buffer.
Proprietà LocalHostName
La proprietà LocalHostName restituisce il nome del sistema Host locale (il computer su cui è in esecuzione l'applicazione). Questa proprietà è di sola lettura e non è disponibile durante la fase di progettazione. Il valore restituito è una stringa.
Sintassi:
<Variabile Stringa> = Winsock<indes>.LocalHostName
Proprietà LocalIP
La proprietà LocalIP restituisce l'indirizzo IP del sistema Host locale nel formato di una stringa, come 204.246.255.4. Questa proprietà è di sola lettura e non è disponibile durante la fase di progettazione. Il valore restituito è un stringa.
Sintassi:
<Variabile Stringa> = Winsock<indes>.LocalHostName
La proprietà LocalPort restituisce o imposta il numero della porta locale. LocalPort può essere letta e scritta ed è disponibile sia in fase di progettazione che durante l'esecuzione. Il valore restituito è di tipo Long Integer. La sintassi che segue, serve per leggere la proprietà:
Sintassi:
<Variabile Stringa> = Winsock<indes>.LocalPort
Per impostare la proprietà, la sintassi da usare è la seguente
Winsock<indes>.LocalPort = <valore da impostare>
In pratica questa proprietà va impostata prima dell'uso del metodo Listen per impostare il numero della porta per l'applicazione. Questo permette la selezione della porta in fase di run-time e non a priori
Proprietà Protocol
La proprietà Protocol restituisce o imposta il protocollo a UDP o TCP. Questa proprietà può essere letta e scritta ed è disponibile sia in fase di progettazione che durante l'esecuzione. Il valore restituito è 0 se il protocollo impostato è sckTCPProtocol, oppure 1 se il protocollo impostato è sckUDPProtocol. La sintassi per leggere il protocollo impostato è la seguente:
Sintassi:
<Variabile> = Winsock<indes>.Protocol
La sintassi da usare per impostare il protocollo è la seguente:
Winsock<indes>.Protocol = <valore da impostare>
Nell'ultima riga mostrata, il <valore da impostare> può essere sckTCPProtocol per il protocollo TCP e sckUDPProtocol per il protocollo UDP.
La proprietà RemoteHost restituisce o l'host remoto, cioè il computer con il quale si vuole stabilire una connessione. Questa proprietà può essere letta e scritta ed è disponibile sia in fase di progettazione che durante l'esecuzione. Il valore restituito è di tipo stringa è può essere specificato come indirizzo IP (es. 204.246.255.4) oppure come nome DNS. La seguente sintassi mostra come leggere la proprietà:
Sintassi:
<Variabile Stringa> = Winsock<indes>.RemoteHost
Per impostare la proprietà la sintassi è la seguente:
Winsock<indes>.RemoteHost = '<valore da impostare>'
L' impostazione di questa proprietà durante l'esecuzione permette all'utente di selezionare l'Host remoto quando l'applicazione parte, oppure permette di effettuare la selezione secondo dei criteri particolari.
Proprietà RemotePort
La proprietà RemotePort restituisce o imposta l'host remoto. RemotePort può essere letta e scritta ed è disponibile sia in fase di progettazione che durante l'esecuzione. Il valore restituito è di tipo Long Integer. La sintassi per leggere la proprietà è la seguente:
Sintassi:
<Variabile> = Winsock<indes>.RemotePort
Per impostare la proprietà, la sintassi è la seguente:
Winsock<indes>.RemotePort = '<valore da impostare>'
Questa proprietà può essere usata per selezionare l'applicazione che deve essere contattata all'Host remoto.
La proprietà State restituisce lo stato del controllo come espresso da un elenco numerato. Questa proprietà è di sola lettura e non è disponibile durante la fase di progettazione. La proprietà state viene impostata utilizzando i diversi metodi ed eventi disponibili. La sintassi per leggere la proprietà è la seguente:
Sintassi:
<Variabile> = Winsock<indes>.State
Nella tabella sono riportate le impostazioni possibili per la proprietà State.
Costante |
Valore |
Descrizione |
sckClosed |
|
Chiuso, default |
sckOpen |
|
Aperto |
sckListening |
|
In ascolto |
sckConnectionPending |
|
In attesa di connessione |
sckResolvingHost |
|
Risoluzione dell' Host |
sckHostResolved |
|
Risoluzione dell' Host completata |
sckConnecting |
|
Connessione in corso |
sckConnected |
|
Connessione completata |
sckClosing |
|
Connessione in chiusura |
sckError |
|
Errore |
Metodi del controllo Winsock
I metodi sono delle funzioni predefinite usate per eseguire vari compiti sul controllo. Ci sono metodi che aprono o chiudono una connessione e metodi che accettano una richiesta di connessione. I prossimi paragrafi trattano alcuni tra i metodi più importanti usati con il controllo Winsock.
Metodo Accept
Il metodo Accept è usato soltanto nella realizzazione di applicazioni di tipo Server TCP. Questo metodo accetta la richiesta di connessione inviata da un sistema Client. Per utilizzare il metodo Accept, il controllo Winsock deve essere in uno stato di ascolto. Questo metodo è usato in congiunzione con l'evento ConnectionRequest. La sintassi per il metodo Accept è:
Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
Winsock<index>(NumSockets).Accept requested
End Sub
Il metodo Close termina una connessione TCP sia da applicazioni Client che Server. La sintassi è la seguente:
Sintassi:
Winsock<index>.Close
GetData è il metodo che recupera il blocco di dati attualmente nel buffer e lo memorizza in una variabile di tipo variant <VariabileVariant>. La sintassi è la seguente:
Winsock<index>.GetData <VariabileVariant>
Metodo PeekData
Il metodo PeekData opera in maniera simile al metodo GetData, però non rimuove i dati dalla coda di input. Questo metodo è disponibile solo per le connessioni TCP.
Sintassi:
Winsock<index>.PeekData <VariabileVariant>
Il metodo Listen viene chiamato nelle applicazioni Server per mettere in attesa il Sever per una richiesta TCP di connessione da un sistema Client. La sintassi è:
Winsock<index>.Listen
Il metodo SendData invia i dati contenuti in una variabile di tipo Variant <VariabileVariant> al computer remoto. Questo metodo è disponibile sia per la progettazione di applicazioni Client che Server. La sintassi è la seguente:
Winsock<index>.SendData <VariabileVariant>
Metodo Connect
Il metodo Connect richiede una connessione ad un computer remoto. La sintassi per utilizzare questo metodo è la seguente:
Winsock<index>.Connect <RemoteHost>, <RemotePort>
L'argomento <RemoteHost> è richiesto per conoscere il nome del computer remoto a cui connettersi. L'argomento <RemotePort> contiene il nome della porta utilizzata sul computer remoto specificato.
Eventi del controllo Winsock
Gli Eventi sono quelli che richiamano i metodi. Un esempio di evento è un clic del mouse. Il controllo Winsock genera eventi che possono essere usati dall'utente. Alcuni di questi eventi, come l'evento ConnectionRequest, si verificano sul Server come risultato di una azione svolta dal Client. Gli eventi generati dal controllo Winsock rendono possibile la partecipazione di un sistema senza controllo ad una sessione di comunicazione di rete.
Evento Close
L'evento Close si verifica quando il computer remoto chiude la connessione. Alla chiusura della connessione, vengono eseguite tutte le istruzioni contenute all'interno dell'evento. La sintassi:
Private Sub Winsock<index>_Close()
<istruzione>
End Sub
Evento Connect
L'evento Connect si verifica dopo che è stata attivata la connessione con il computer remoto. La sintassi:
Private Sub Winsock<index>_Connect()
..
<istruzione>
..
End Sub
L'evento ConnectionRequest si verifica quando il server riceve una richiesta di connessione da un sistema Client. La sintassi:
Private Sub Winsock<index>_ConnectionRequest(ByVal requestID As Long)
<istruzione>
..
End Sub
Il codice contenuto nell'evento, viene eseguito sulla macchina che accetta la richiesta di connessione. Il parametro RequestID identifica il numero della richiesta. Questo viene passato al metodo Accept, per accettare la particolare richiesta
Questo evento si verifica quando arrivano dei nuovi dati. La sintassi è la seguente:
Private Sub Winsock<index>_DataArrival(ByVal bytesTotal As Long)
<istruzione>
End Sub
La variabile bytesTotal di tipo Long, contiene il numero totale dei bytes giunti.
Evento SendCompletate
L'evento SendCompletate si verifica quando una operazione di invio è completata.
Sintassi:
Private Sub Winsock<index>_SendComplete()
..
<istruzione>
..
End Sub
Evento SendProgress
L'evento SendProgress si verifica mentre i dati vengono inviati. La sintassi:
Private Sub Winsock<index>_SendProgress(ByVal bytesSent As Long, ByVal
bytesRemaining As Long)
..
<istruzione>
..
End Sub
La variabile bytesSent indica il numero di byte inviati dall'ultima volta che è stato generato questo evento. Mentre bytesRemaining indica il numero di byte nel buffer di invio in attesa di essere inviati.
Evento Error
L'evento Error si verifica quando un processo in backgroud, come una connessione, un invio o una ricezione di dati , non viene completato oppure genera un errore. La sintassi:
Private Sub Winsock<index>_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
<istruzione>
End Sub
Definizione di un semplice protocollo
Rimandando i dettagli del codice ai prossimi paragrafi, anticipiamo a grandi linee il protocollo stabilito per la comunicazione fra i due moduli. Il protocollo s'è reso necessario perché il modulo winsock di Visual Basic 6 non prevede la possibilità di inviare dati complessi come vettori, matrici, dati strutturati, ma solo tipi elementari come interi, stringhe.
Per questo motivo abbiamo accodato tutti i dati da inviare in un'unica stringa, separati da un apposito carattere. Questo è possibile anche dalla "promiscuità" che caratterizza i tipi di dato in Visual Basic: se ad esempio dichiariamo dato_s come una stringa e dato_d come un double, una sequenza di istruzioni del tipo:
dato_s="16"
dato_d=dato_s
assegna correttamente il valore 16 a dato_d, senza che l'utente debba ricorrere ad alcuna conversione di tipo.
L'alternativa al protocollo sarebbe stato un ciclo for, con il quale inviare il vettore dello stato elemento dopo elemento. Questo avrebbe creato problemi in fase di ricezione, con notevoli difficoltà nella ricostruzione del vettore a partire dai singoli elementi raccolti.
Secondo le regole che abbiamo stabilito il client invia una stringa al server mediante la quale comandare il serbatoio. Tale stringa è così strutturata:
bit valvola ingresso |
Bit valvola uscita |
Carattere di separazione "S" |
livello |
I primi due bit della stringa costituiscono quindi il vero e proprio comando, che può assumere le seguenti configurazioni:
|
Sia la valvola di ingresso che quella di uscita sono chiuse: il livello resta costante |
|
La valvola di ingresso è aperta e quella di uscita è chiusa: il serbatoio si riempie |
|
La valvola di ingresso è chiusa e quella di uscita è aperta: il serbatoio si svuota |
|
Entrambe le valvole sono aperte: il livello resta costante |
Il terzo campo viene utilizzato solo nella modalità "read/write manuale" (vedi paragrafo 4.1.2) per aggiustare dal client il livello nel serbatoio. In tutte le altre modalità il campo "livello" viene settato a 999 e così il server riconosce il comando come inattivo.
Un protocollo così semplice permette grande flessibilità in vista di ulteriori sviluppi del programma. Ad esempio con minime modifiche al codice si potrebbero comandare le portate delle singole valvole e la gestione da parte del client del passaggio da manuale ad automatico nel controllo del serbatoio (attualmente questa scelta è riservata al server). La relativa stringa di controllo assumerebbe la forma:
bit valvola in |
Bit valvola out |
S |
livello |
S |
Portata in |
S |
Portata out |
S |
Automatico/manuale |
Ricevuta la stringa di controllo, il server risponde comunicando lo stato del serbatoio, che immaginiamo rilevato leggendo tre ipotetici trasduttori:
il finecorsa di serbatoio pieno
il finecorsa di serbatoio vuoto
il trasduttore di livello
Il messaggio è quindi strutturato come segue:
bit finecorsa pieno |
S |
Bit finecorsa vuoto |
S |
livello |
L'applicazione client e il controllore
Nella comunicazione di due moduli attraverso la rete internet o attraverso la rete locale, il client è quello che inizia la comunicazione e chiede al server di erogare un dato servizio. Nel nostro caso, quindi, è il modulo su cui risiede il plc a chiedere di connettersi al server per poter controllare il processo.
I comandi del modulo client
Per non sovraccaricare l'interfaccia grafica del modulo client e renderla intuitiva, abbiamo organizzato i comandi in menu, lasciando ai bottoni i soli comandi "riempi", "svuota" e "stop".
Il menù connessione
Il menu connessione serve a inizializzare la comunicazione con il modulo server , del quale bisogna conoscere a priori l'indirizzo IP .
Il menu è costituito dalle seguenti voci:
connetti, selezionando la quale si hanno due possibili azioni:
o se non si è connessi, una input box chiede all'utente l'indirizzo IP del server a cui connettersi; se l'indirizzo digitato è esatto viene stabilita la connessione e l'indicatore di stato diventa verde.
o se si è già connessi un messaggio di warning segnala che per stabilire una nuova connessione è necessario prima disconnettersi.
disconnetti: selezionando questa voce la connessione precedentemente stabilita viene chiusa e l'indicatore di stato diventa di colore rosso.
Il menù modalità
Questo menu permette di scegliere il tipo di funzionamento del modulo client, fra le tre possibili:
modalità completamente manuale, che è l'unica funzionante quando non il controllore winlc non sta funzionando; questo modo permette infatti di controllare il processo dal client remoto con gli stessi bottoni che sono presenti nel lato server: apri, chiudi, stop.
modalità read/write manuale da winlc, mediante la quale il controllo del processo da parte di winlc può essere guidato dall'utente sia in ingresso che in uscita:
o in uscita, col comando "leggi variabile" si può vedere il valore che winlc ha prodotto per comandare ciascuna delle due valvole e decidere se:
inviarla al processo attraverso il comando "invia variabile"
comandare la valvola con un valore diverso da quello prodotto dal plc
o in ingresso, col comando "scrivi variabile"; selezionando la relativa voce dal menu "esegui" si può scegliere se:
scrivere nel rispettivo ingresso di winlc uno dei valori del vettore di stato (finecorsa pieno, finecorsa vuoto, livello) rilevato nell'ultima rilevazione
scrivere in una variabile qualsiasi
Questa modalità è particolarmente indicata in fase di stesura e test del programma del controllore.
Il funzionamento è intuitivamente riassunto nel seguente schema:
modalità completamente automatica, in cui le uscite del plc vanno automaticamente al server per controllare le valvole del processo e , analogamente, i finecorsa dal server inviati al client vengono scritti negli ingressi corrispondenti di winlc, secondo gli assegnamenti indicati nella morsettiera virtuale.
Il menù esegui
In questo menu sono raggruppate le azioni che non possono essere comandate con un semplice bottone, perché richiedono informazioni aggiuntive:
leggi variabile: viene chiesta la variabile da leggere in winlc, ne viene letto e visualizzato il valore e , se siamo in modalità "read/write manuale da winlc", viene memorizzato per poterlo inviare al processo col comando "invia variabile".
scrivi variabile: l'azione svolta dipende dalla modalità:
o in modalità read_write manuale si possono scrivere nei bit I0.0, I0.1 i valori dei finecorsa, oppure nel byte IW1 il valore del livello
o nelle altre modalità sia l'indirizzo che il valore sono arbitrari (ma va ricordato che nel modo automatico questo modifica l'esecuzione del programma)
invia variabile: è attiva solo nella modalità read/write manuale da winlc e si sceglie fra:
o inviare al corrispondente ingresso del processo l'uscita di winlc letta precedentemente
o inviare al processo una diverso valore;
o modificare direttamente il livello del serbatoio, senza dover ricorrere ai comandi apri e chiudi; questa opzione intende semplificare la verifica dell'esecuzione del programma di controllo.
rileva stato processo: selezionando questo comando viene comunicato lo stato del processo nell'ultima rilevazione.
Il menu visualizza
Questo menù permette di visualizzare o nascondere i seguenti comandi o informazioni:
pannello di comando del processo in modalità manuale
stato della connessione
indirizzo IP del server
Come opzione di default si è scelto di nasconderli, perché di solito vengono utilizzati una sola volta per ogni sessione.
Il menu help
Il menu help è costituito da due voci:
morsettiera virtuale, che riguarda la modalità automatica : visualizza infatti il collegamento fra ingressi di winlc e uscite del processo e fra uscite di winlc e ingressi del processo; questa associazione è implementata via software e simula il collegamento nella morsettiera di un plc, da cui il nome.
indirizzi di winlc, che riguarda la modalità read write manuale : riporta infatti l'indirizzo da introdurre per leggere o scrivere ingressi, uscite e variabili interne del winlc; si possono leggere e scrivere singoli bit (ad esempio Q0.0 e I0.0, dei byte come I1 o degli interi a 16 bit come IW1)
Analisi del codice del modulo "client"
La programmazione in visual basic è costituita principalmente da routine associate al verificarsi di opportuni eventi. Ciascun oggetto inserito nel form è sensibile al verificarsi di eventi che lo riguardano. Ad esempio un bottone è sensibile al click del mouse, al semplice passaggio del mouse, ecc.
Dichiarazione delle variabili globali |
|
Le variabili globali sono quelle che vanno condivise fra più subroutine; un metodo più "canonico" sarebbe quello di dichiararle localmente e di passarle come parametri da un sub all'altra, ma noi abbiamo scelto questa soluzione per semplificare il codice. |
|
Option Explicit Dim stato(2) As Long Dim name_s As String Dim stringa_controllo As String Dim flag_connessione As String Dim flag_modalità As String Dim server_ip As String Dim letta As Variant Dim scritta As Long Dim livello As Long Dim stringa_controllo_v() As String |
|
Stato(2) è un vettore di stringhe nel quale memorizzeremo lo stato del processo proveniente dal server: i due finecorsa e il livello Stringa_controllo è il comando vero e proprio che il client invia al server per controllare il processo ed ha la struttura indicata nel paragrafo 3.3.3.2 Flag_connessione viene settato con le voci del menu connessione ai valori "connesso" e "non_connesso" per tenere traccia dello stato della connessione Flag_modalità ricorda invece il tipo di funzionamento e può assumere i valori "read_write_manuale", "completamente_manuale" e "completamente_automatico" Server_ip contiene l'indirizzo IP del server Name_s serve ai metodi read_variable e write_variable del controllo s7data per indicare il nome della variabile di winlc da leggere o da scrivere Letta va dichiarata come variant perché il metodo read_variable del controllo s7data vi scrive il valore della variabile indicata da name_s Scritta è il valore che il metodo write_variable del controllo s7data scrive nella variabile indicata da name_s Livello è l'ultimo campo della stringa di controllo, che viene settato dalle subroutine della modalità read/write manuale per settare il livello del serbatoio dal client (questa possibilità non sarebbe consentita se dovessimo controllare un processo reale, ma è funzionale allo scopo della modalità read/write manuale: permette di testare il comportamento del ladder diagram caricato nel plc quando il serbatoio è a un livello stabilito) |
Subroutine di inizializzazione |
|
Form_load sta per "caricamento del form", quindi questa sub viene lanciata all'apertura dell'applicazione |
|
Private Sub Form_Load() flag_connessione = 'non_connesso' flag_modalità = 'completamente_manuale' Timer_automatico.Enabled = False Timer_manuale.Enabled = True stato(0) = 0 stato(1) = 0 stato(2) = 0 livello = 999 stringa_controllo = '00' & 'S' & livello End Sub |
|
La modalità di default al caricamento del form è quella manuale, quindi viene settato il relativo flag e viene abilitato il timer che regola l'invio periodico dei comandi provenienti dai bottoni. La stringa di controllo inviata è "00" in modo che il server la riconosca come valida e permetta il passaggio del controllo al client. Il livello a 999 è un'inizializzazione convenzionale: se il server riconosce un valore non valido (fuori dall'intervallo [0,100] ) ignora il comando "livello" |
Subroutine della voce "connetti" del menu connessione |
Private Sub mnu1001_Click(Index As Integer) Dim domanda, titolo, proposta If flag_connessione = 'connesso' Then MsgBox 'Si è già connessi al server.Per stabilire una nuova connessione è necessario disconnettersi', vbCritical, 'Attenzione: connessione già avvenuta' Else domanda = 'Inserire l'indirizzo ip del server' titolo = 'Finestra di connessione' proposta = '' server_ip = InputBox(domanda, titolo, proposta) Winsock1.RemoteHost = server_ip Winsock1.RemotePort = 4444 Winsock1.Connect flag_connessione = 'connesso' End If End Sub |
Il comando "connetti" si chiama mnu1001 ad indicare che è la prima voce del primo menu (mnu100). Se si è già connessi si provvede a segnalarlo attraverso un msgbox, altrimenti ci si connette e si setta il flag a "connesso". I passi per stabilire una connessione sono: assegnare alla proprietà remoteHost del controllo winsock l'IP del server a cui ci si vuole connettere assegnare il valore della proprietà remotePort del controllo winsock. E' la porta sulla quale il server è in ascolto e deve quindi essere la stessa per entrambe le applicazioni lanciare il metodo connect del controllo winsock |
Subroutine connect del controllo winsock |
Private Sub Winsock1_Connect() Shape1.BackColor = &HC000& End Sub |
La connessione chiesta con la sub precedente richiama il metodo "connect" dell'oggetto winsock; al verificarsi di questo evento il cerchio rosso che segnala lo stato della connessione diventa di colore verde |
Subroutine della voce "disconnetti" del menu connessione |
Private Sub mnu1002_Click(Index As Integer) Winsock1.Close Shape1.BackColor = 255 flag_connessione = 'non_connesso' End Sub |
Cliccando sulla voce disconnetti viene chiusa la connessione, aggiornato il flag di connessione e impostato rosso il visualizzatore di stato |
Subroutine della voce "completamente_manuale" del menu modalità |
Private Sub mnu2001_Click(Index As Integer) flag_modalità = 'completamente_manuale' Timer_automatico.Enabled = False Timer_manuale = True Command_apri.Enabled = True Command_chiudi.Enabled = True Command_stop.Enabled = True Label_I00.Visible = False Label_I01.Visible = False Label_q00.Visible = False Label_q01.Visible = False Label_I1.Visible = False Label_valore_I1.Visible = False Shape_i00.Visible = False Shape_i01.Visible = False Shape_q00.Visible = False Shape_q01.Visible = False End Sub |
Selezionando la voce "completamente manuale" viene aggiornato il flag di modalità, abilitato il timer che regola gli eventi in tale modalità e disabilitato quello che temporizza lo scambio di segnali con winlc; inoltre vengono visualizzati i comandi apri, chiudi e stop (che hanno lo stesso scopo di quelli presenti nel server) e nascosto il pannello della modalità automatica. |
Subroutine della voce "read/write manuale" del menu modalità |
Private Sub mnu2002_Click(Index As Integer) flag_modalità = 'read_write_manuale' Timer_automatico.Enabled = False Timer_manuale.Enabled = True Command_apri.Enabled = False Command_chiudi.Enabled = False Command_stop.Enabled = False Label_I00.Visible = False Label_I01.Visible = False Label_q00.Visible = False Label_q01.Visible = False Label_I1.Visible = False Label_valore_I1.Visible = False Shape_i00.Visible = False Shape_i01.Visible = False Shape_q00.Visible = False Shape_q01.Visible = False End Sub |
In questa routine vengono svolti compiti analoghi alla precedente: il timer attivo in questa modalità è ancora quello manuale, ma i comandi al server vengono inviati leggendo manualmente le uscite di winlc: non sono necessari quindi i bottoni riempi,svuota,stop che vengono quindi nascosti. |
Subroutine della voce "completamente automatico" del menu modalità |
Private Sub mnu2003_Click() flag_modalità = 'completamente_automatico' Timer_automatico.Enabled = True Timer_manuale.Enabled = False Command_apri.Enabled = False Command_chiudi.Enabled = False Command_stop.Enabled = False label_uscite.Visible = True Label_ingressi.Visible = True Label_I00.Visible = True Label_I01.Visible = True Label_q00.Visible = True Label_q01.Visible = True Label_I1.Visible = True Label_valore_I1.Visible = True Shape_i00.Visible = True Shape_i01.Visible = True Shape_q00.Visible = True Shape_q01.Visible = True End Sub |
Viene aggiornato il flag, attivato il timer automatico, disattivato quello manuale, nascosti i comandi riempi,svuota,stop e visualizzato il pannello di stato delle variabili di winlc |
Subroutine della voce "leggi variabile" del menu esegui |
Private Sub mnu3001_Click(Index As Integer) Dim prova As Long Dim state_l As Long Dim timeout_l As Long timeout_l = 0 name_s = InputBox('Inserire indirizzo (Q0.0 per la valvola di apertura, Q0.1 per la valvola di chiusura)', 'lettura variabile da winlc') prova = S7Data1.ReadVariable(name_s, letta, state_l, timeout_l) MsgBox 'Il valore della variabile è : ' & letta, vbCritical, 'La variabile è stata letta' End Sub |
Questa subroutine richiama il metodo readVariable del controllo s7data: attribuendo alla variabile name_s l'indirizzo da leggere scelto dall'utente viene visualizzato con un msgbox il relativo valore |
Subroutine della voce "scrivi variabile" del menu esegui |
Private Sub mnu3002_Click(Index As Integer) Dim prova As Long Dim state_l As Long Dim timeout_l As Long timeout_l = 0 If flag_modalità = 'read_write_manuale' Then box_variabile.Visible = True Else name_s = InputBox('Inserire indirizzo', 'scrittura variabile su winlc') scritta = InputBox('inserire valore della variabile', 'scrittura su winlc') prova = S7Data1.WriteVariable(name_s, scritta, timeout_l) End If End Sub |
Questa routine richiama il metodo readVariable del controllo s7data: se non si è in modalità di setup del programma si chiede l'indirizzo da scrivere e il relativo valore attraverso due inputbox e poi si scrive nella destinazione selezionata. In read-write manuale, invece, si guida l'utente alla scelta degli indirizzi su cui scrivere attraverso opportuni box di selezione. |
Private Sub box_variabile_Click() box_variabile.Visible = False Box_valore2.Visible = True End Sub |
Selezionando la destinazione attraverso il box variabile viene visualizzato il box per scegliere il valore da scrivere nella variabile selezionata: |
Private Sub Box_valore2_Click() Box_valore2.Visible = False Dim prova As Long Dim timeout_l As Long timeout_l = 0 If box_variabile.Text = 'variabile qualsiasi' Then name_s = InputBox('Inserire indirizzo', 'scrittura variabile su winlc') scritta = InputBox('inserire valore della variabile', 'scrittura su winlc') prova = S7Data1.WriteVariable(name_s, scritta, timeout_l) Else Select Case Box_valore2.Text Case 'finecorsa pieno' scritta = stato(0) Case 'finecorsa vuoto' scritta = stato(1) Case 'livello' scritta = stato(2) Case 'valore arbitrario' scritta = InputBox('inserire valore della variabile', 'scrittura su winlc') End Select Select Case box_variabile.Text Case 'I0.0' name_s = 'I0.0' prova = S7Data1.WriteVariable(name_s, scritta, timeout_l) MsgBox 'Nel bit I0.0 è stato scritto il valore del finecorsa pieno', vbCritical, 'La variabile è stata scritta' Case 'I0.1' name_s = 'I0.1' prova = S7Data1.WriteVariable(name_s, scritta, timeout_l) MsgBox 'Nel bit I0.1 è stato scritto il valore del finecorsa vuoto', vbCritical, 'La variabile è stata scritta' Case 'IW1' name_s = 'IW1' prova = S7Data1.WriteVariable(name_s, scritta, timeout_l) MsgBox 'Nel byte IW1 è stato scritto il valore del livello', vbCritical, 'La variabile è stata scritta' End Select End If End Sub |
Subroutine della voce "invia variabile" del menu esegui |
Private Sub mnu3003_Click(Index As Integer) Dim stringa_controllo As String Select Case flag_modalità Case 'completamente_manuale' MsgBox 'utilizzare i tasti riempi, svuota,stop", vbCritical, 'Attenzione: modalità manuale' Case 'read_write_manuale' box_destinazione.Visible = True Case 'completamente_automatico' MsgBox 'L'invio della variabile in questa modalità è riservato a winlc', vbCritical, 'Attenzione:' End Select End Sub |
Anche l'invio della variabile letta al server avviene con visualizzazioni successive di box-opzioni, come già accaduto per la scrittura della variabile. A differenza della routine precedente, però, questo comando è riservato alla modalità di read/write manuale: in modo automatico, infatti, è winlc ad inviare le variabili di controllo, mentre in modo manuale le variabili vanno inviate coi comandi opportuni. Il primo box visualizzato selezionando la voce "invia variabile" è il box destinazione: |
Private Sub box_destinazione_click() box_destinazione.Visible = False If box_destinazione.Text = 'livello' Then livello = InputBox('introdurre livello', 'Invio variabile') stringa_controllo_v = Split(stringa_controllo, 'S') stringa_controllo = stringa_controllo_v(1) & 'S' & livello If Winsock1.State = sckConnected Then Winsock1.SendData stringa_controllo Else MsgBox 'Per inviare bisogna essere connessi', vbCritical, 'Errore:' End If Else box_valore.Visible = True End If livello = 999 stringa_controllo_v = Split(stringa_controllo, 'S') stringa_controllo = stringa_controllo_v(0) & 'S' & livello End Sub |
Se l'utente ha scelto di inviare una variabile al server per controllare in modo diretto il livello del serbatoio (ripetiamo, non è un comando che rispecchia le possibilità di un processo reale, ma è utile in fase di test del programma, per cui è stata prevista la modalità read/write manuale) viene chiesto attraverso una input box il valore desiderato. Ottenuto il valore, viene inviato al server che imposta di conseguenza il valore del livello; dopo averlo inviata, la variabile "livello" va posta nuovamente ad un valore non riconoscibile dal server, altrimenti non si discosterebbe più dal valore impostato. Se invece viene scelto di comandare una delle due valvole del serbatoio, appare il box di scelta del bit con cui comandare la valvola: |
Private Sub box_valore_Click() box_valore.Visible = False Dim n As Long Dim appoggio_sinistro As String Dim appoggio_destro As String n = Len(stringa_controllo) Select Case box_valore.Text Case '1' Select Case box_destinazione.Text Case 'valvola apri' 'settiamo ad 1 il primo carattere di stringa_controllo appoggio_sinistro = Right(stringa_controllo, n - 1) stringa_controllo = '1' & appoggio_sinistro Case 'valvola chiudi' 'settiamo a 1 il secondo carattere di stringa_controllo appoggio_sinistro = Left(stringa_controllo, 1) appoggio_destro = Right(stringa_controllo, n - 2) stringa_controllo = appoggio_sinistro & '1' & appoggio_destro End Select Case '0' Select Case box_destinazione.Text Case 'valvola apri' 'settiamo a 0 il primo carattere di stringa_controllo appoggio_sinistro = Right(stringa_controllo, n - 1) stringa_controllo = '0' & appoggio_sinistro Case 'valvola chiudi' 'settiamo a 0 il secondo carattere di stringa_controllo appoggio_sinistro = Left(stringa_controllo, 1) appoggio_destro = Right(stringa_controllo, n - 2) stringa_controllo = appoggio_sinistro & '0' & appoggio_destro End Select Case 'variabile letta' Select Case box_destinazione.Text Case 'valvola apri' If letta = 1 Then 'settiamo a 1 il primo carattere di stringa_controllo appoggio_sinistro = Right(stringa_controllo, n - 1) stringa_controllo = '1' & appoggio_sinistro End If If letta = 0 Then 'settiamo a 0 il primo carattere di stringa_controllo appoggio_sinistro = Right(stringa_controllo, n - 1) stringa_controllo = '1' & appoggio_sinistro End If Case 'valvola chiudi' If letta = 1 Then 'settiamo a 1 il secondo carattere di stringa_controllo appoggio_sinistro = Left(stringa_controllo, 1) appoggio_destro = Right(stringa_controllo, n - 2) stringa_controllo = appoggio_sinistro & '1' & appoggio_destro End If If letta = 0 Then 'settiamo a 0 il secondo carattere di stringa_controllo appoggio_sinistro = Left(stringa_controllo, 1) appoggio_destro = Right(stringa_controllo, n - 2) stringa_controllo = appoggio_sinistro & '0' & appoggio_destro End If End Select End Select If Winsock1.State = sckConnected Then Winsock1.SendData stringa_controllo Else Shape1.BackColor = 65535 End If End Sub |
La difficoltà nel codice di questa routine sta soprattutto nell'isolare il bit della stringa di controllo che riguarda la valvola selezionata e nel settarlo al valore scelto dall'utente, senza cambiare i restanti caratteri. A tale scopo utilizziamo due stringhe di appoggio: appoggio sinistro per memorizzare la parte della stringa di controllo che precede il bit da cambiare e appoggio_destro per memorizzare la parte della stringa che segue il carattere da cambiare. In questo modo, una volta settato il bit interessato, è possibile ricomporre la stringa con tutte le altre parti inalterate. |
Subroutine della voce "rileva stato del processo" del menu esegui |
Private Sub mnu3004_Click(Index As Integer) Dim messaggio As String messaggio = 'il finecorsa-pieno vale: ' & stato(0) & ', il finecorsa-vuoto vale: ' & stato(1) & ', il livello nel serbatoio è: ' & stato(2) If Winsock1.State = sckConnected Then MsgBox messaggio, vbCritical, 'Stato del serbatoio pervenuto dal server:' Else MsgBox 'Per ricevere lo stato del processo bisogna connettersi', vbCritical, 'Attenzione:' End If End Sub |
Questa routine visualizza all'utente lo stato del processo rilevato nell'ultimo invio di una stringa di controllo: meno di un secondo fa se si è connessi, mentre se non si è connessi il valore memorizzato nel vettore di stato non è attuale o è addirittura quello inizializzato per convenzione al caricamento del form. Per questo motivo viene visualizzato un messaggio di errore. |
Subroutines del menu visualizza |
Private Sub mnu4001_Click(Index As Integer) If Command_apri.Visible = True Then Command_apri.Visible = False Command_chiudi.Visible = False Command_stop.Visible = False Else Command_apri.Visible = True Command_chiudi.Visible = True Command_stop.Visible = True End If End Sub Private Sub mnu4002_Click(Index As Integer) If Shape1.Visible = True Then Shape1.Visible = False Label_stato.Visible = False Else Shape1.Visible = True Label_stato.Visible = True End If End Sub Private Sub mnu4003_Click(Index As Integer) Label_ip_server.Caption = 'indirizzo del server: ' & server_ip If Label_ip_server.Visible = False Then Label_ip_server.Visible = True Else Label_ip_server.Visible = False End If End Sub |
Queste routine permettono di visualizzare o nascondere gli oggetti del modulo client: la prima riguarda i comandi "riempi", "svuota" e "stop" per il controllo manuale del serbatoio (ovviamente nelle altre due modalità vengono visualizzato ma non sono abilitati), la seconda riguarda lo stato della connessione (il led verde, rosso o giallo) e la terza l'indirizzo IP del server a cui si è connessi |
Subroutine della voce "morsettiera virtuale" del menu help |
Private Sub mnu5001_Click(Index As Integer) Dialog.Visible = True End Sub |
Questa routine visualizza il form dialog chiamato "morsettiera virtuale" in cui viene spiegato a quali ingressi di winlc (I0.0, I0.1 e IW1) vengono mandate le uscite del processo (finecorsa pieno, finecorsa vuoto, livello) e a quali ingressi del processo (valvola di ingresso e valvola di uscita) vengono mandate le uscite di winlc (q0.0 e q0.1). Il codice del form è banale, essendo costituito da quasi tutte etichette e un bottone di ok per nascondere il form stesso: |
Private Sub OKButton_Click() Dialog.Visible = False End Sub |
Subroutine della voce "indirizzi winlc" del menu help |
Private Sub mnu5002_Click(Index As Integer) Dialog.Visible = True End Sub |
Come la precedente, anche questa voce visualizza un form di dialogo, chiamato dialog1, in cui abbiamo riportato la tabella con tutti gli indirizzi delle variabili di winlc accessibili con il controllo s7data: ingressi, uscite, bit di memoria, ecc. Anche il codice del dialog1 è immediato, in quanto l'unico evento previsto è il bottone ok che chiude il form: |
Private Sub OKButton_Click() Dialog1.Visible = False End Sub |
Subroutine dell'evento click sul comando "riempi" |
Private Sub Command_apri_Click() stringa_controllo = '10' & 'S' & livello If flag_modalità = 'completamente_manuale' Then If Winsock1.State = sckConnected Then Winsock1.SendData stringa_controllo Else Shape1.BackColor = 65535 End If End If End Sub |
Ciccando sul comando "riempi" la prima parte della stringa di controllo viene impostata a "10": il primo bit a 1 indica infatti che la valvola di ingresso deve essere aperta, mentre il secondo bit a 0 indica che la valvola di uscita deve essere chiuso. Se a questo punto la modalità è manuale e se si è connessi al server, la stringa viene inviata; se invece si è in modalità manuale ma non si è connessi, il "led" di stato della connessione assume il colore giallo per segnalare che la trasmissione ha avuto esito negativo. |
Subroutine dell'evento click sul comando "svuota" |
Private Sub Command_chiudi_Click() stringa_controllo = '01' & 'S' & livello If flag_modalità = 'completamente_manuale' Then If Winsock1.State = sckConnected Then Winsock1.SendData stringa_controllo Else Shape1.BackColor = 65535 'Imposta giallo il colore del visualizzatore End If End If End Sub |
Il codice di questa subroutine è il duale del precedente: la prima parte della stringa di controllo viene settata al valore "01" ma viene inviata solo se siamo in modalità manuale |
Subroutine dell'evento click sul comando "svuota" |
Private Sub Command_stop_Click() stringa_controllo = '00' & 'S' & livello If flag_modalità = 'completamente_manuale' Then If Winsock1.State = sckConnected Then Winsock1.SendData stringa_controllo Else Shape1.BackColor = 65535 End If End If End Sub |
Si eseguono le stesse operazioni dei due eventi precedenti |
Subroutine dell'evento conteggio del timer_manuale |
Private Sub Timer_manuale_Timer() If Winsock1.State = sckConnected Then Winsock1.SendData stringa_controllo End If End Sub |
Il timer manuale genera un evento ogni secondo (proprietà timer_automatico.interval impostata a 1000 in fase di progetto) che ha il solo compito di inviare l'ultima stringa di controllo prodotta dal client: in questo modo il server risponde con lo stato del processo e si ha l'aggiornamento. Il timer manuale viene abilitato nella modalità manuale e in quella di read/write da winlc: si è reso necessario distinguerlo dal timer automatico per due motivi: in queste due modalità i tempi di lavoro sono molto più lunghi e non è quindi necessario caricare il calcolatore e soprattutto la rete con una doppia trasmissione ogni 100ms all'evento del timer manuale vanno eseguiti altri compiti che non il solo invio della stringa di controllo Era comunque possibile integrare i due timer, ma con lo svantaggio di rendere più complesso e meno comprensibile il codice (test del flag di modalità ad ogni evento, esecuzione di if annidati, ecc) |
Subroutine dell'evento conteggio del timer_automatico |
Private Sub Timer_automatico_Timer() Dim prova As Long Dim state_l As Long Dim timeout_l As Long Dim value_q00 As Variant Dim value_q01 As Variant timeout_l = 0 name_s = 'Q0.0' prova = S7Data1.ReadVariable(name_s, value_q00, state_l, timeout_l) name_s = 'Q0.1' prova = S7Data1.ReadVariable(name_s, value_q01, state_l, timeout_l) Label1.Caption = value_q00 If value_q00 = False And value_q01 = False Then stringa_controllo = '00' & 'S' & livello Shape_q00.FillColor = &HFF& Shape_q01.FillColor = &HFF& End If If value_q00 = True And value_q01 = False Then stringa_controllo = '01' & 'S' & livello Shape_q00.FillColor = &HFF& Shape_q01.FillColor = &HC000& End If If value_q01 = True And value_q00 = False Then stringa_controllo = '10' & 'S' & livello Shape_q00.FillColor = &HC000& Shape_q01.FillColor = &HFF& End If If value_q00 = True And value_q01 = True Then stringa_controllo = '11' & 'S' & livello Shape_q00.FillColor = &HC000& Shape_q01.FillColor = &HC000& End If If Winsock1.State = sckConnected Then Winsock1.SendData stringa_controllo Else Shape1.BackColor = 65535 End If End Sub |
Il timer manuale genera un evento ogni secondo 100ms perché la proprietà interval è stata impostata a 100 in fase di progetto. In corrispondenza di questo evento vengono svolte le seguenti azioni: il controllo s7data legge le variabili "q0.0" e "q0.1" con il metodo readVariable in base ai valori letti si costruisce la prima parte della stringa di controllo in base ai valori letti si aggiornano i relativi indicatori presenti sul pannello del modulo client (pannelli visibili solo in modalità automatica) la stringa di controllo viene inviata al server |
Subroutine dell'evento "arrivo dei dati" del controllo winsock |
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) Dim ricevuto As String Dim i As Integer Winsock1.GetData ricevuto, vbString . stato_s = Split(ricevuto, 'S') stato(0) = stato_s(1) 'per la convenzione che abbiamo stabilito nella comunicazione client-server il primo elemento di stato_s è una stringa nulla stato(1) = stato_s(2) stato(2) = stato_s(3) If flag_modalità = 'completamente_automatico' Then Dim prova As Long Dim state_l As Long Dim timeout_l As Long timeout_l = 0 If stato(0) = 0 Then Shape_i00.FillColor = &HFF& Else Shape_i00.FillColor = &HC000& End If name_s = 'I0.0' prova = S7Data1.WriteVariable(name_s, stato(0), timeout_l) If stato(1) = 0 Then Shape_i01.FillColor = &HFF& Else Shape_i01.FillColor = &HC000& End If name_s = 'I0.1' prova = S7Data1.WriteVariable(name_s, stato(1), timeout_l) name_s = 'IW1' prova = S7Data1.WriteVariable(name_s, stato(2), timeout_l) Label_valore_I1.Caption = stato(2) End If End Sub |
Questo evento viene generato quando arrivano i dati dal server, in risposta all'invio della stringa di controllo: la prima operazione consiste nel caricare i dati arrivati nella variabile ricevuto; sappiamo che i dati consistono nei 3 valori dello stato del processo divisi dal carattere di separazione "S", secondo il protocollo indicato nel paragrafo 3.3.3.2: infatti la seconda operazione eseguita consiste nel separare questi valori attraverso la funzione split e nell'assegnarli alle varie componenti del vettore stato( ). A questo punto se siamo nella modalità automatica dobbiamo scrivere questi valori negli ingressi di winlc e visualizzare i valori degli ingressi, altrimenti il compito della routine è terminato. |
L'applicazione server e il processo
Nel modello client/server l'applicazione server è quella che "ascolta" la rete in attesa della richiesta di connessione del client; tale richiesta riguarda solitamente l'erogazione di un servizio, che il server può evadere o meno. Nel nostro caso il processo deve risiedere nel lato server e il controllore nel lato client: quando winlc è stato programmato ed è in fase di run, il modulo client tenta di connettersi al processo e ne chiede il controllo. Il server a questo punto accetta la connessione e decide se cedere il controllo del processo al client o meno.
I comandi del modulo server
I comandi del server sono meno di quelli del client e non si è reso necessario organizzarli in menu. Non spetta al server richiedere la connessione, quindi i comandi riguardano tutti il controllo del processo:
riempi: comanda il riempimento del serbatoio (in pratica corrisponde all'apertura della valvola di ingresso e alla chiusura della valvola di uscita)
svuota: comanda lo svuotamento del serbatoio (in pratica corrisponde all'apertura della valvola di uscita e alla chiusura della valvola d'ingresso)
stop: ferma il livello del serbatoio al valore corrente (può corrispondere sia alla situazione con entrambe le valvole aperte che a quella con entrambe le valvole chiuse)
azzera: annulla il livello nel serbatoio (non è molto verosimile nella simulazione di un processo reale, ma è molto comodo in fase di test del programma di controllo su winlc)
cursore portata: permette di aumentare o diminuire la velocità di riempimento o svuotamento (immaginiamo che regolino la portata delle due valvole simultaneamente)
controllo manuale: deselezionando questa check box si permette il controllo al modulo remoto; il comando non è attivo finché il client non invia una stringa di controllo valida.
Oltre ai comandi sono visualizzate anche importanti informazioni:
il valore del livello attuale
il valore del finecorsa di serbatoio pieno
il valore del finecorsa di serbatoio vuoto
l'indirizzo IP del modulo server, che il client deve conoscere per potersi connettere e controllare il processo
la stringa di controllo inviata dal client, costituita da 2 bit: il primo per la valvola di ingresso e il secondo per la valvola di uscita
Analisi del codice del modulo server
Dichiarazione delle variabili globali
Option Explicit
Dim conteggio As Long
Dim flag As String
Dim pieno As Boolean
Dim vuoto As Boolean
Il codice dell'applicazione server è più semplice di quello del client e infatti servono anche meno variabili globali:
conteggio è la variabile più importante di tutto il processo, quella che viene incrementata e decrementata per rappresentare il livello nel serbatoio
Flag serve a tenere traccia della direzione del conteggio e può quindi essere impostata ai valori "avanti" e "indietro"
Pieno è la variabile booleana che rappresenta il finecorsa di serbatoio pieno, quindi assume il valore 1 quando il livello vale 100 e 0 altrimenti
Vuoto è la variabile booleana che rappresenta il finecorsa di serbatoio vuoto, quindi diventa 1 quando il livello scende a zero
Subroutine di caricamento del form
Private Sub Form_Load()
Check1.Enabled = False
Label2.Caption = Winsock1.LocalIP
Label3.Caption = Winsock1.LocalHostName
Winsock1.LocalPort = 4444
Winsock1.Listen
End Sub
Al caricamento del form il checkbox che distingue fra controllo remoto o controllo locale viene disabilitato e lo resta finché il client non invia un comando valido.
Nelle label 2 e 3 viene visualizzato il nome dell'Host Locale e il relativo IP, che deve essere noto al client per permettere la connessione.
Viene scelta la porta sulla quale effettuare la comunicazione (anche questa deve essere nota dal client: devono usare entrambi la stessa porta) e il controllo winsock si mette in ascolto.
Subroutine del comando "riempi"
Private Sub Commandavanti_Click()
Timer1.Enabled = True
flag = 'avanti'
End Sub
Cliccando sul bottone "riempi" viene abilitato il conteggio in avanti abilitando il timer e settando al valore opportuno il flag di direzione
Subroutine del comando "svuota"
Private Sub Commandindietro_Click()
Timer1.Enabled = True
flag = 'indietro'
End Sub
Le operazioni del comando "svuota" sono le stesse del comando "riempi", tranne che per il flag della direzione del conteggio, che viene posto a "indietro"
Subroutine
Private Sub Commandstop_Click()
Timer1.Enabled = False
End Sub
Il comando stop disabilita il timer del conteggio
Subroutine del comando "azzera"
Private Sub Commandazzera_Click()
conteggio = 0
Text_conteggio.Text = conteggio
End Sub
Il comando azzera agisce solo sul valore del livello e sulla sua visualizzazione: possiamo notare, infatti, che la proprietà enable del timer non viene modificata: se quindi si stava contando in avanti, si ricomincerà a contare in avanti dal livello zero, mentre se il livello era fermo resterà fermo al valore zero
Subroutine della barra della portata
Private Sub HScroll1_Change()
Timer1.Interval = HScroll1.Value
End Sub
La barra della portata permette di modificare attraverso un cursore la proprietà interval del timer, che determina l'intervallo fra due successivi eventi generati dal timer. In fase di progetto abbiamo fissato le proprietà max e min dell'Hscroll (che sta per Horizzontal scroll, ovvero per barra di scorrimento orizzontale, per distinguerla da quella verticale) a 2000 e 200: se il cursore viene portato all'estrema destra viene generato un evento ogni 2 secondi, se il cursore viene portato tutto a sinistra viene generato un evento ogni 200ms, mentre se il cursore è al centro la proprietà timer1.interval assume il valore 1000, lo stesso assegnatole inizialmente.
Subroutine dell'arrivo della stringa dal client
Private Sub Text_arrivato_Change()
If Text_arrivato.Text = '00' Or Text_arrivato.Text = '01' Or Text_arrivato.Text = '10' Or Text_arrivato.Text = '11' Then
Check1.Enabled = True
Else
Check1.Value = 1
Check1.Enabled = False
End If
If Check1.Value = 0 Then
Commandindietro.Enabled = False
Commandavanti.Enabled = False
Commandstop.Enabled = False
If Text_arrivato.Text = '10' Then
flag = 'avanti'
Timer1.Enabled = True
End If
If Text_arrivato.Text = '01' Then
flag = 'indietro'
Timer1.Enabled = True
End If
If Text_arrivato.Text = '11' Or Text_arrivato.Text = '00' Then
Timer1.Enabled = False
End If
End If
If Check1.Value = 1 Then
Commandavanti.Enabled = True
Commandindietro.Enabled = True
Commandstop.Enabled = True
End If
End Sub
In questa casella di testo viene visualizzata la prima parte della stringa di controllo, quella che riguarda il comando delle valvole. Come prima cosa viene effettuato un test sulla stringa pervenuta: se il valore è compatibile col comando delle valvole, viene concessa la possibilità di passare al controllo remoto abilitando il relativo checkbox, altrimenti lo si disabilita e si imposta il controllo locale.
Se la stringa è valida e l'utente decide di controllare dal modulo remoto il serbatoio, viene abilitato il timer e settato il flag in base alla stringa pervenuta; vengono inoltre disabilitati i comandi per il controllo manuale.
Se invece l'utente decide di restare in controllo locale, la stringa viene ignorata e i comandi "riempi", "svuota", "avanti" vengono abilitati.
Subroutine del check-box di controllo locale/remoto
Private Sub check1_Click()
If Check1.Value = 0 Then
Commandindietro.Enabled = False
Commandavanti.Enabled = False
Commandstop.Enabled = False
If Text_arrivato.Text = '10' Then
flag = 'avanti'
Timer1.Enabled = True
End If
If Text_arrivato.Text = '01' Then
flag = 'indietro'
Timer1.Enabled = True
End If
If Text_arrivato.Text = '11' Or Text_arrivato.Text = '00' Then
Timer1.Enabled = False
End If
End If
If Check1.Value = 1 Then
Commandavanti.Enabled = True
Commandindietro.Enabled = True
Commandstop.Enabled = True
End If
End Sub
Il codice di questa routine è praticamente lo stesso della sub precedente; per capire perché, si pensi alla seguente situazione: il client ha inviato un comando che viene ignorato dal server che è in controllo locale. Quando si decide di passare al controllo remoto, non viene riconosciuto un cambio di testo in text_arrivato e quindi le stesse azioni devono essere associate all'evento check1_click.
Subroutine del timer per il conteggio
Private Sub timer1_timer()
If flag = 'avanti' Then
conteggio = conteggio + 1
End If
If flag = 'indietro' Then
conteggio = conteggio - 1
End If
Text_conteggio.Text = conteggio
If conteggio <= 0 Then
vuoto = True
Timer1.Enabled = False
Image1.Visible = True
Shape3.Visible = True
Else
vuoto = False
Image1.Visible = False
Shape3.Visible = False
End If
If conteggio = 100 Then
pieno = True
Timer1.Enabled = False
Shape2.Visible = True
Else
Shape2.Visible = False
pieno = False
End If
If conteggio > 0 And conteggio <= 10 Then
Image2.Visible = True
Else
Image2.Visible = False
End If
If conteggio > 10 And conteggio <= 20 Then
Image3.Visible = True
Else
Image3.Visible = False
End If
If conteggio > 20 And conteggio <= 30 Then
Image4.Visible = True
Else
Image4.Visible = False
End If
If conteggio > 30 And conteggio <= 40 Then
Image5.Visible = True
Else
Image5.Visible = False
End If
If conteggio > 40 And conteggio <= 50 Then
Image6.Visible = True
Else
Image6.Visible = False
End If
If conteggio > 50 And conteggio <= 60 Then
Image7.Visible = True
Else
Image7.Visible = False
End If
If conteggio > 60 And conteggio <= 70 Then
Image8.Visible = True
Else
Image8.Visible = False
End If
If conteggio > 70 And conteggio <= 80 Then
Image9.Visible = True
Else
Image9.Visible = False
End If
If conteggio > 80 And conteggio <= 90 Then
Image10.Visible = True
Else
Image10.Visible = False
End If
If conteggio > 90 And conteggio <= 100 Then
Image11.Visible = True
Else
Image11.Visible = False
End If
End Sub
Quando il timer genera l'evento di temporizzazione, vengono svolte le seguenti operazioni:
incremento o decremento del contatore a seconda del valore assunto dal flag
aggiornamento della casella di testo che visualizza il livello
aggiornamento del finecorsa di serbatoio vuoto (con relativa segnalazione visiva) e disabilitazione del timer se il livello scende a zero
aggiornamento del finecorsa di serbatoio pieno (con relativa segnalazione visiva) e disabilitazione del timer se il livello è arrivato a 100
visualizzazione di una delle 10 immagini del serbatoio a seconda del valore assunto dal contatore, in modo da rendere l'impressione di un serbatoio che si sta riempiendo o svuotando
Subruotine di chiusura della connessione
Private Sub Winsock1_Close()
Shape1.BackColor = 255
Winsock1.Close
Winsock1.Listen
End Sub
Questa routine viene lanciata quando il client decide di chiudere la connessione: il server richiama il metodo close di winsock, imposta rosso il segnalatore dello stato della connessione e si pone nuovamente in attesa con il metodo listen di winsock
Subroutine della richiesta di connessione
Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
Shape1.BackColor = &HC000&
If Winsock1.State <> sckClosed Then Winsock1.Close
Winsock1.Accept requestID
End Sub
Questa routine viene richiamata quando il server, che è stato posto in ascolto, riconosce una richiesta di connessione da parte del client: chiude eventuali altre connessioni, imposta a verde il colore del visualizzatore di stato della connessione e accetta la richiesta di connessione col metodo accept
Soubroutine di arrivo dei dati
Dim InDati_v() As String
Dim Indati As String
Dim stato As String
Dim pieno_s As String
Dim vuoto_s As String
Winsock1.GetData Indati, vbString
InDati_v = Split(Indati, 'S')
Text_arrivato.Text = InDati_v(0)
If InDati_v(1) <= 100 And InDati_v(1) >= 0 Then
conteggio = InDati_v(1)
Text_conteggio.Text = conteggio
End If
If pieno = True Then
pieno_s = '1'
Else
pieno_s = '0'
End If
If vuoto = True Then
vuoto_s = '1'
Else
vuoto_s = '0'
End If
stato = '_' & 'S' & pieno_s & 'S' & vuoto_s & 'S' & conteggio
Winsock1.SendData stato
All'arrivo dei dati le due componenti della stringa di controllo vengono scisse con la funzione split, che riconosce il carattere di separazione "S", e assegnate al vettore indati_v.
Il primo elemento di questo vettore viene mandato alla casella text_arrivato che lo riconosce come stringa di controllo, il secondo viene sottoposto al test di livello valido: se è compreso fra 0 e 100, si riconosce che il client intende impostare un nuovo valore del livello e quindi viene assegnato alla variabile conteggio, altrimenti viene ignorato.
A questo punto il server risponde inviando la stringa di stato al client, costruendola in base al protocollo definito nel paragrafo 3.3.3.2
Conclusioni e possibili estensioni del progetto
Delle tre tematiche citate nel capitolo 2 abbiamo sviluppato prevalentemente la parte della programmazione in visual basic orientata alla simulazione e controllo di un processo, a discapito dello studio delle funzionalità del software WinLC.
Nell'ambito di questa programmazione abbiamo anche sviluppato la parte relativa alla comunicazione client-server approfondendo l'utilizzo dell'API WinSock per la trasmissione dati con windows.
Pertanto, restano ancora da sviluppare tematiche quali:
A tale scopo possiamo suggerire i seguenti sviluppi futuri del progetto:
Ampliamento delle capacità di controllo delle variabili del serbatoio. Come spiegato nel capitolo 3 questo è possibile grazie alla flessibilità del protocollo che abbiamo definito (come ad es. il controllo della portata delle valvole e/o il passaggio da controllo locale a controllo remoto gestito dal client).
Implementazione sul modulo server di diversi processi ai quali possono accedere altrettanti client; per far questo è sufficiente prevedere un componente winsock per ogni processo.
Interfacciamento con processi reali oltre che simulati.
Sincronizzazione dell'acquisizione degli ingressi e della scrittura delle uscite con i cicli di WinLC. E' una semplice modifica possibile introducendo un flag nel primo rung del programma di controllo per riconoscere lo scorrimento dei cicli ma che non abbiamo potuto implementare avendo avuto a disposizione la sola versione demo del software WinLC.
Appunti su: interfaccia computer remoto, plc integrazione interfacce grafiche visual basic, |
|