• Non ci sono risultati.

I dati acquisiti e inviati tramite il protocollo iLinkRT vengono ricevuti da LabVIEW sotto forma di cluster, sia per quanto riguarda le measurements sia per quanto riguarda le ca- librations. Si `e visto in figura 4.12 che tutti i dati acquisiti vengono inseriti nella queue di salvataggio ma ancora nulla `e stato detto su come prelevare gli stessi dati o salvarli

su disco o in variabili locali per consentirne l’analisi e il trattamento. Per prima cosa `e necessario definire cosa si intende per queue: in LabVIEW una coda viene utilizzata per scambiare dati che vengono generati da una porzione di codice di un VI e vengono utilizzati da un’altra porzione di codice dello stesso VI. La logica con la quale tale coda viene alimentata `e di tipo FIFO: nella pratica, se un elemento della coda viene inserito per primo, esso sar`a anche il primo a venire prelevato. A differenza di un array standard, pertanto, non `e possibile accedere a tutti gli elementi della coda, ma soltanto ad uno per volta; l’unico modo per visualizzare l’intero contenuto della coda `e svuotarla completa- mente. L’aspetto veramente interessante di una coda `e per`o la possibilit`a di scambiare dati tra cicli while o timed loop che lavorano a frequenze diverse senza perdere nessun dato e consentendo quindi una perfetta sincronizzazione tra chi alimenta la coda e chi la svuota. Quanto appena illustrato si applica perfettamente al caso in esame; si osservi la figura 4.21: essa rappresenta il loop utilizzato per salvare i dati acquisiti in un file di tipo tdms, che rappresenta il formato standard in ambiente LabVIEW per il salvataggio di dati generati da un codice.

Figura 4.21: Codice per il salvataggio dei dati acquisiti

Il ciclo principale `e un timed loop che viene eseguito ad una frequenza di 5 Hz (si veda la costante 200 in alto a sinistra che indica ogni quanti millisecondi viene eseguita un’iterazione) e contiene al suo interno tre case structure comandate, ognuna in modo diverso, dalla variabile globale ‘REC’, la quale a sua volta viene triggerata dagli stati ‘REC on’ e ‘REC off’ appartenenti alla macchina a stati 3 descritta in precedenza:

1. la prima, pi`u a sinistra, si occupa dell’apertura (e della creazione, qualora non sia ancora stato creato) del file tdms destinato a ricevere i dati acquisiti, tramite il bloc- co ‘TDMS Open’; si fa notare che il codice contenuto all’interno di questa case structure viene eseguito soltanto se la variabile globale passa da false a true, altri-

menti il contenuto dei tunnel di sinistra viene semplicemente trasferito ai tunnel di destra;

2. la seconda, in basso a destra, si occupa dello svuotamento della coda di registrazio- ne, tramite il blocco ‘Flush Queue’, e del trasferimento del suo contenuto prima in una variabile locale di tipo matrice, ‘DATA’, utilizzata per l’analisi dati, e poi nel file vero e proprio tramite il blocco ‘TDMS Write’. `E interessante notare che tale case structureviene comandata direttamente dalla variabile globale ‘REC’, pertan- to il codice al suo interno viene eseguito ogniqualvolta la macchina a stati 3 del loop principale si trova negli stati seguenti a ‘REC on’; inoltre la variabile ‘DATA’ viene alimentata da uno shift register di tipo double, in modo che quando il timed loopsvuota la coda e trasferisce i dati acquisiti tale variabile non viene sovrascritta, ma i nuovi valori vengono aggiunti al termine della matrice stessa;

3. la terza, in alto a destra, si occupa della chiusura del file appena scritto, tramite il blocco ‘TDMS Close’ e della rimozione dei file temporanei di tipo index, tramite il blocco ‘TDMS Defragment’, e tale codice viene eseguito soltanto se la variabile globale che comanda la case structure passa da true a false.

A questo punto `e d’obbligo una precisazione: l’utilizzo di un buffer di registrazione si `e reso necessario dal momento che il loop principale che gestisce l’automazione e riceve i dati dalla ECU la- vora ad una frequenza di 100 Hz, mentre il loop di salvataggio dei dati `e stato volutamente impostato ad una frequenza di lavoro pa-

ri a 5 Hz per non sovraccaricare il processore del PC realtime e per limitare gli accessi all’hard disk dello stesso PC, rendendo l’intero processo di salvataggio pi`u efficiente e meno oneroso. Tuttavia, essendo le frequenze di lavoro dei due cicli nettamente diver- se, `e stato necessario rimediare all’asincronia tra i due loop utilizzando un approccio che prevedesse lo scambio di dati tra i due loop per mezzo di una queue; tale queue, deno- minata ‘SaveQueue’ come si vede nella figura a destra, prima che il software acceda al timed loopprincipale viene inizializzata tramite il blocco ‘Obtain Queue’ in modo che essa contenga un array di cluster, ognuno dei quali costituito da una stringa, che conterr`a il nome della measurement o della calibration, e da una costante numerica di tipo double, che ne conterr`a il valore.

Vale la pena soffermarsi sulla dimensione della coda, qui impostata a 30 elementi: dato che il ciclo di salvataggio dei dati svuota la coda cinque volte al secondo, mentre il ciclo principale la riempie cento volte al secondo, si vede bene che ogni iterazione del primo dei due cicli deve gestire una queue costituita da 20 elementi, pertanto tale sar`a la dimensione minima con la quale dovr`a essere inizializzata la coda. Si `e scelto tuttavia di

inizializzarla a 30 elementi per mantenere un certo margine di sicurezza, in modo tale che se per una qualunque ragione il ciclo di salvataggio dovesse svuotare la coda in ritardo non ci sar`a alcun pericolo di perdere dei dati.