Questo progetto ha come obbiettivo la costruzione di un sistema di tomografia ad impedenza elettrica (EIT). Quest'ultima è una tecnica di diagnostica non invasiva per la ricostruzione della forma di campioni biologici. Il principio di funzionamento si basa sull'applicazione di una corrente sul campione in esame. La corrente attraversando il campione genera un profilo di potenziale all'interno di esso che può essere campionato in un numero finito di punti attraverso degli elettrodi metallici. I campioni così ottenuti permettono di ricostruire una mappa di conducibilità del campione sotto esame. L'intera informazione è quindi riassunta nella matrice impedenza del n-polo costituito dagli elettrodi e a partire da questa si può risolvere il problema inverso per la ricostruzione della forma, ad esempio mediante l'algoritmo di monotonicità. Il progetto in particolare si è focalizzato sulla costruzione del sistema necessario alla misura della matrice di impedenza. Si è quindi realizzata una parte hardware per la generazione e gestione dei segnali di eccitazione opportuni e una parte software dedicata all'acquisizione delle tensioni agli elettrodi e del calcolo della matrice di impedenza. I risultati ottenuti sono stati validati su un prototipo di matrice resistiva.
La fase di progettazione si è basata sulle seguenti specifiche derivanti da considerazioni teoriche sulle dimensioni del problema.
La figura seguente illustra il diagramma a blocchi del sistema e la tabella descrive brevemente la la funzione implementata da ciascun blocco.
Nome blocco | Funzione | |
---|---|---|
Oscillatore | Genera una forma d'onda sinusoidale secondo specifiche. | |
Filtro | Passa banda per regolare l'ampiezza e la purezza spettrale della sinusoide. | |
Switching | Invia il segnale analogico presente all'ingresso all'uscita selezionata dall'ingresso digitale | |
Condizionamento | Rende il segnale adatto all'acquisizione da parte della scheda. | |
Acquisizione | Acquisisce i segnali di tensione agli elettrodi e comanda gli ingressi digitali del blocco Switching |
L'oscillatore sinusoidale implementato è un ponte di Wien. Il circuito con i parametri scelti per i componenti è mostrato in figura. Il dimensionamento si basa nel determinare R, C e l'amplificazione corretta al fine di soddisfare le condizioni di Barkhausen. Per la rete RC la funzione di trasferimento: \begin{equation} H(s)=\frac{s \omega_0}{s^2+3s \omega_0+ \omega_0^2} \end{equation} dove ω0 = 1/RC. Inoltre H(jω0) = 1/3, quindi l'amplificatore deve avere guadagno maggiore di 3. Si ottengono R = 10kΩ e C = 100pF per una frequenza di oscillazione pari 159 kHz. Per quanto riguarda l'amplificazione si utilizzano le resistenze da 2.7 kΩ e 1 kΩ. Un blocco di attenuazione regola l'ampiezza della sinusoide ottenuta, tenendo conto del filtro passa banda posto a valle.
Il filtro passa banda è composto da un filtro passa basso e un passa alto. Per tale filtro sono state selezionate le resistenze e le capacità opportune per ottenere una funzione di trasferimento del tipo: \begin{equation} H(s) = \frac{s}{(1+\tau_1 s)(1+\tau_2 s)} \end{equation} dove τ1 è l'inverso di R1 C1 e τ2 l'inverso di R2 C2. L'uscita del filtro permette di ottenere una tensione picco-picco di 270 mV picco-picco rispettando le specifiche.
Il codice digitale in ingresso viene convertito mediante un decoder e si ottengono i segnali di comando per gli switch analogici. Questi collegano il segnale sinusoidale precedentemente generato ai vari elettrodi alimentandoli uno alla volta. Il codice digitale viene generato dalla scheda di acquisizione che si occupa anche dell'acquisizione delle tensioni agli elettrodi. La corrente totale entrante nel n-polo viene convertita in una tensione mediante convertitore IV. Ad ogni elettrodo alimentato quindi si determina una colonna della matrice impedenza. Il valore della resistenza RIV deve essere misurata con la maggiore accuratezza possibile per limitare errori di guadagno.
Il programma è strutturato come mostrato nella figura sottostante dove viene mostrato il programma principale EIT dal quale vengono chiamati gli altri subVI.
La tabella seguente riassume brevemente la funzione implementata da ciascun VI.
Nome VI | Funzione |
---|---|
EIT | Costituisce il "main" del software. Da qui vengono le varie chiamate a funzione. |
Impostazioni | Permette la modifica delle modalità di acquisizione e gestione dei dati. |
CaricaImpostazioni | Legge le impostazioni dal file; se non presente nella directory corrente crea un nuovo file e lo riempe con dei parametri di default inseriti nel sorgente come costanti. |
SalvaMatrici | Salva su file le tensioni lette agli elettrodi e la matrice impedenza calcolata a partire da queste. |
ImpostaUscitaDigitale | Cambia i segnali di uscita alle porte digitali specificate (costanti del sorgente) per comandare i segnali di apertura/chiusura degli switch analogici. |
Misura | Gestisce l'acquisizione dei segnali degli elettrodi. |
CampionaCanali | Effettua un'acquisizione sequenziale delle tensioni agli elettrodi. |
Il codice è composto da tre cicli while.
L'immagine sottostante si riferisce al ciclo Eventi utente contenente una Event Structure che si occupa di verificare quando l'utente effettua un azione. Per ogni caso viene inserito un messaggio nella coda di gestione dell'interfaccia utente e il ciclo si ripete rimanendo in attesa di altri comandi. Questo meccanismo evita stalli nella risposta del programma: se la gestione del compito fosse particolarmente lunga il programma rimarrebbe fermo nell'esecuzione di questa funzione e non risponderebbe ad altri stimoli dell'interfaccia utente.
Il ciclo riguardante Interfaccia utente (vedi sotto) si occupa di gestire le singole funzioni dell'interfaccia utente. I compiti a bassa latenza vengono gestiti immediatamente mentre quelli a latenza maggiore (ad esempio l'acqusizione dei segnali da parte della scheda di acquisizione) vengono ancora gestiti tramite un altro ciclo while, sempre per evitare stalli da parte del programma.
Infine il ciclo Acquisizione si occupa della misura delle tensioni mediante la scheda di acquisizione.
Il codice è composto da un unico ciclo while con una Event Structure che permette di gestire i vari eventi che l'utente esegue sull'interfaccia utente. Nel caso che le impostazioni vengono salvate i nuovi valori vengono salvati sul file di modo che le modifiche siano disponibili per le prossime esecuzioni.
La modalità di salvataggio dei dati scelta è molto versatile in quanto indipendentemente da quali siano i parametri scelti come configurabili le informazioni vengono convertite in una stringa in formato XML mediante la funzione Flatten To XML la quale accetta in ingresso un dato di qualunque tipo. Mediante la funzione Write To XML la stringa in formato XML viene salvata su file con nome fissato "impostazioni.xml". In fase di lettura per dualità si recuperano i dati scritti in precedenza. Nel caso in cui il file non sia presente all'inizio oppure erroneamente cancellato la lettura iniziale fallisce; in questo caso viene quindi creato il file con dei parametri di default, assegnati come costanti nel codice.
Il file delle misure viene creato a partire dalla date e l'ora corrente ottenute mediante la funzione Get DateTime In Seconds. La stringa ottenuta viene combinata con l'opportuna estensione ".csv" mediante la funzione ConcatenateStrings e da questa partendo dal percorso del VI corrente viene generato il path del file delle misure. La funzione Array To Spreadsheet String converte i dati in ingresso in dati tabulati adatti alla visualizzazione in un editor di testo.
Il canale da impostare viene convertito mediante la funzione Number To Boolean Array in una rappresentazione digitale.
Il ciclo for itera per tutti i canali analogici tranne l'ultimo che per specifica del progetto è assunto essere il canale associato al convertitore IV. Dalle tesioni lette si estrae l'ultimo elemento e lo si divide per il guadagno del convertitore. Infine il valore ottenuto lo si divide alle tensioni lette agli elettrodi; si ottiene quindi per ogni ciclo un vettore riga che rappresenta la prima colonna della matrice. Per ottenere il vettore si utilizza la funzionalità di indexing di cui dispone nativamente il ciclo for. La disposizione dei vettori avviene comunque per righe anche se l'output della funzione Misura fosse un vettore colonna. Risulta quindi necessario al termine del ciclo effettuare una trasposizione della matrice ottenuta. Equivalentemente si poteva configurare il nodo di uscita del ciclo for con la modalità Shift Register e creare il vettore accodando una alla volta le varie colonne.
I ciclo for itera sull'entrata del vettore canali analogici e per ciascun canale vengono acquisiti il numero di campioni specificati. L'acquisizione segue la schema standard previsto da LabVIEW DAQ, creando un nuovo canale, acquisendo i dati ed infine chiudendo il canale appena creato. Esistono altri modi per campionare in sequenza un numero di campioni prefissati da un certo numero di canali. Anche se l'approccio implementato può non essere il piĆ¹ efficiente, ha sicuramente il pregio della semplicità e della chiarezza. Per l'applicazione in esame non sono state assegnate specifiche riguardanti il tempo in cui effettuare una completa acquisizione sequenziale non risultando quindi necessari altri accorgimenti oltre l'approccio implementato.
L'interfaccia si compone di due videate.
le quali vengono analizzate di seguito.
La videata consente la gestione completa del programma. I controlli in basso permettono di accedere alle funzionalità mentre tutti gli output del programma vengono visualizzati all'interno di una struttura tab. Qui mediante selezione si sceglie cosa si vuole visualizzare ad ogni volta. L'interfaccia permette l'esecuzione di misure ripetute con pattern diversi ed è estendibile ad aggiunta di altre funzionalità. La gestione di un interfaccia con queste funzionalità richiede una buona porzione di codice che ne ha complicato la struttura. La tabella seguente riassume gli elementi che compongono l'interfaccia.
Elemento | Tipologia | Funzione |
---|---|---|
Start | Pulsante | Permette di iniziare una nuova acquisizione, il nuovo stato viene segnalato nella barra indicatrice Stato attuale |
Impostazioni | Pulsante | Permette di aprire la pagina per modificare le impostazioni del programma. |
Esci | Pulsante | Riporta lo stato attuale in cui il programma si trova; ad esempio durante l'acquisizione mediante il testo "acquisizione...". |
Tab | Controllo | Permette di selezionare quali output visualizzare. |
Stato attuale | Indicatore | Indica mediante testo l'operazione che il programma sta eseguendo. |
Tensioni RMS misurate agli elettrodi | Indicatore | Visualizza in forma matriciale le tensioni lette agli elettrodi in [Volt]. L'entrata ij contiene la tensione all'elettrodo i (nella lista dei canali analogici da impostazioni) quando è alimentato l'elettrodo j. |
Matrice Impedenza | Indicatore | Visualizza la matrice impedenza in [Ohm]. L'entrata ij corrisponde a Rij. |
Canale | Controllo | Modifica il segnale visualizzato dal grafico. |
Grafico | Indicatore | Visualizza la forma d'onda con possibili modifiche sulla visualizzazione. |
È presente una lista di controlli modificabili dall'utente. Le scelte effettuate possono essere salvate oppure no. La figura sottostante rappresenta la schermata delle impostazioni.
La tabella seguente riassume gli elementi che compongono l'interfaccia.
Elemento | Tipologia | Funzione |
---|---|---|
Frequenza di campionamento | Controllo | Modifica la frequenza di campionamento dell'acquisizione. Misurata in [Hz]. |
Canali analogici | Controllo | Lista dei canali analogici della scheda da utilizzare per l'acquisizione. L'ultimo canale della lista deve essere il canale del convertitore IV. |
Numero di campioni | Controllo | Modifica del numero di campioni acquisiti per ciascun canale. |
Tensione max | Controllo | Tensione massima dei segnali in ingresso. |
Tensione min | Controllo | Tensione minima dei segnali in ingresso. |
Guadagno IV | Controllo | Guadagno del convertitore IV necessario per ottenere la tensione RMS della corrente. |
Ok | Pulsante | Chiude l'interfaccia e salva le modifiche effettuate. |
Cancella | Pulsante | Chiude l'interfaccia ed annulla le modifiche effettuate. |
In questa scheda viene mostrato un esempio di misura fatta con sette elettrodi. Vengono messe a confronto i valori teorici e i valori ottenuti dalle misure. Utilizzando MatLAB viene simulato il circuito mostrato in figura a destra e quindi si ottiene la seguente matrice di resistenze teorica:
4183 | 3739 | 3202 | 2832 | 2188 | 1817 | 1447 |
3739 | 7453 | 6383 | 5646 | 4362 | 3623 | 2884 |
3202 | 6383 | 10228 | 9047 | 6989 | 5805 | 4621 |
2832 | 5646 | 9047 | 11390 | 8799 | 7308 | 5817 |
2188 | 4362 | 6989 | 8799 | 11951 | 9926 | 7901 |
1817 | 3623 | 5805 | 7308 | 9926 | 11433 | 9101 |
1447 | 2884 | 4621 | 5817 | 7901 | 9101 | 10300 |
Con il programma EIT si ottiene la seguente matrice:
4149 | 3686 | 3153 | 2785 | 2142 | 1781 | 1413 |
3712 | 7379 | 6289 | 5571 | 4284 | 3559 | 2829 |
3170 | 6303 | 10084 | 8928 | 6873 | 5710 | 4541 |
2806 | 5575 | 8933 | 11250 | 8663 | 7199 | 5726 |
2160 | 4303 | 6880 | 8667 | 11806 | 9781 | 7777 |
1797 | 3573 | 5710 | 7207 | 9760 | 11257 | 8974 |
1426 | 2836 | 4547 | 5721 | 7779 | 8968 | 10139 |
Nelle immagini sottostanti viene mostrata l'interfaccia grafica e il modo in cui vengono letti i dati campionati. Dalla sinistra a destra: Matrice delle impedenze, matrice delle tensioni, segnali campionati per ogni elettrodo:
L'errore percentuale fatto sulle matrici ottenute è il seguente:
0,8 | 1,4 | 1,5 | 1,7 | 2,1 | 2,0 | 2,3 |
0,7 | 1,0 | 1,5 | 1,3 | 1,8 | 1,8 | 1,9 |
1,0 | 1,3 | 1,4 | 1,3 | 1,7 | 1,6 | 1,7 |
0,9 | 1,3 | 1,3 | 1,2 | 1,6 | 1,5 | 1,6 |
1,3 | 1,4 | 1,6 | 1,5 | 1,2 | 1,5 | 1,6 |
1,1 | 1,4 | 1,6 | 1,4 | 1,7 | 1,6 | 1,4 |
1,4 | 1,6 | 1,6 | 1,7 | 1,6 | 1,5 | 1,6 |