Università degli Studi di Roma “Tor Vergata” Dipartimento di Ingegneria Meccanica
TESI DI LAUREA DI PRIMO LIVELLO
Analisi sperimentale delle vibrazioni sul corpo umano: progettazione di un sistema per il condizionamento dei segnali
Relatore:
Candidato:
Prof. Ing.Ettore Pennestrì
Daniele Silvi
Correlatore:
Ing. Daniele Carnevale
Anno Accademico: 2009/2010
Alla mia famiglia
"Gli uomini vincenti trovano sempre una strada... i perdenti una scusa"
John Fitzgerald Kennedy
INDICE
Introduzione
6
Capitolo 1: Normativa di riferimento, ISO 2631
8
1.1 Introduzione
8
1.2 Misurazione delle vibrazioni
9
1.2.1 Sistemi di coordinate basicentrici 1.2.2 Durata delle misurazioni
1.3 Valutazione delle vibrazioni
11
1.3.1 Metodo base di valutazione 1.3.2 Valutazione addizionale delle vibrazioni 1.3.3 Ponderazione in frequenza
1.4 Salute
14
1.5 Benessere e Percezione
15
1.5.1 Benessere 1.5.2 Percezione
1.6 Male da trasporti
16
3
Capitolo 2: Acquisizioni dati
17
2.1 Introduzione
17
2.2 Strumentazione utilizzata
19
2.2.1 Accelerometri Bosh BMA180 2.2.2 Microcontrollore Arduino Uno
2.3 Connessione Arduino Uno – BMA180
24
2.4 Software acquisizione dati
30
2.5 Phidgets 1059
32
Capitolo3: Pedana vibrante
34
3.1 Introduzione
34
3.2 Problematiche riscontrate
35
3.3 Analisi della cinematica della pedana
37
3.4 Progettazione sedile
38
Capitolo4: Condizionamento dei segnali
4.1 Introduzione
43
43
4
4.2 Teoria dei segnali
44
4.3 Caratterizzazione del segnale
51
4.4 Modello del segnale
53
4.4.1 Accelerazioni filtrate dalla media 4.4.2 Velocità filtrate dalla media 4.4.3 Spostamenti filtrati dalla media
4.5 Orientazione accelerometro: influenza sul modello
59
Conclusioni
67
Bibliografia
68
Ringraziamenti
69
Allegati
70
1 Programma acquisizione dati
70
1.1 Programma microcontrollore Arduino Uno 1.2 Header file “bma180.h” 1.3 Programma calcolatore 2 Programma di filtraggio e condizionamento dei segnali
96
3 Esempio di filtraggio e condizionamento
103
3.1 accelerometro sedile (speed 5) 3.2 accelerometro testa (speed 5)
5
INTRODUZIONE
Questo lavoro di tesi si occupa dell’analisi delle vibrazioni sul corpo umano, in particolare delle vibrazioni sulla colonna vertebrale. Gli studi precedenti si occupavano dell’identificazione dei segnali, cercando di sviluppare un modello predittivo per valutarne gli effetti, ma tralasciavano l’analisi dei dati, necessaria invece a comprendere la reale qualità del segnale acquisito, quindi abbiamo posto l’attenzione sull’acquisizione dei dati e la loro valutazione e condizionamento. Per migliorare l’acquisizione dei dati abbiamo: 1.
Potenziato gli strumenti utilizzati per acquisire i segnali, aumentando di 40 Hz la frequenza di acquisizione.
2.
“Attrezzata” la macchina utilizzata per generare le vibrazioni in modo da riprodurre in laboratorio il tipo di sollecitazione oggetto del nostro studio.
3.
Stabilito la modalità con cui raccogliere i dati : - come posizionare il tester durante la prova (ISO 2631-1). - come posizionare gli strumenti di misura (ISO 2631-1). - quante misurazioni effettuare e a quali frequenze. - quanti e quali soggetti (unità statistiche) coinvolgere nello studio.
Per valutare i segnali abbiamo definito un modello che rispecchia chiaramente le caratteristiche dei dati acquisiti, dal quale ci siamo ricavati un modello ideale, rispetto al quale abbiamo definito i parametri di valutazione, tali parametri sono anche alla base del condizionamento del segnale .
6
7
CAPITOLO 1 Normativa di riferimento, ISO 2631-1
1.1 Introduzione Tale norma nasce con lo scopo di definire metodi per quantificare le vibrazioni trasmesse al corpo umano intero in relazione alla salute umana e benessere , alla probabilità di percezioni delle vibrazioni, all’ incidenza del male dei trasporti, escludendo così gli effetti delle vibrazioni trasmesse direttamente agli arti. Sono sorgenti di vibrazioni dannose per la salute, veicoli di terra e di mare, macchine industriali e macchine agricole, e attività industriali quali battitura di pali e brillatura di mine, la natura delle vibrazioni meccaniche generate da questo tipo di sorgenti è puramente periodica, casuale e transitoria, è inoltre importante chiarire che tale norma non può essere presa in considerazione per valutare singoli urti di estrema ampiezza. L’intervallo di frequenze considerate è: - da 0,5 Hz a 80 Hz per salute , benessere e percezione - da 0,1 Hz a 0,5 Hz per il male dei trasporti Oltre a fornire una guida alla quantificazione delle vibrazioni la norma riporta informazioni sui possibili effetti dedicando tre appendici: - APPENDICE B: effetti sulla salute - APPENDICE C: effetti sul benessere e la percezione - APPENDICE D: effetti sull’incidenza del male da trasporti La ISO 2631 non tratta gli effetti delle vibrazioni sulle prestazioni umane e sulla capacità di svolgimento di attività , dato che una simile guida dipende in modo 8
cruciale dai dettagli ergonomici correlati all’ operatore, dalla situazione e dalla struttura dell’ operazione.
1.2 Misurazione delle vibrazioni La grandezza primaria dell’ ampiezza di vibrazione deve essere l’ accelerazione nel caso in cui le frequenze e le ampiezze di vibrazione sono molto basse possono essere effettuate misurazioni della velocità che possono essere convertite in accelerazioni. 1.2.1 Sistemi di coordinate basicentrici Le vibrazioni devono essere misurate secondo un sistema di coordinate che trae origine da un punto dal quale si considera che le vibrazioni entrino nel corpo umano, cioè i sistemi di coordinate basicentrici (fig. 1.2.1).
9
Fig. 1.2.1 Sistemi di coordinate basicentrici
Se non è possibile ottenere l’allineamento preciso dei trasduttori di vibrazione con gli assi basicentrici preferiti, le aree sensibili dei trasduttori possono deviare dagli assi preferiti di un angolo massimo pari a 15° se necessario. I trasduttori inoltre devono essere posizionati all’interfaccia tra la sorgente di vibrazione e il corpo umano. Le principali aree di contatto tra sorgente di vibrazione e corpo umano sono, per la posizione seduta, il supporto del sedile, lo schienale del sedile e i piedi, le misurazioni devono essere effettuate sul supporto del sedile al di sotto delle tuberosità ischiali, sullo schienale nell’ area di principale sostegno del corpo. L’area di contatto nella posizione distesa va localizzata o al di sotto del bacino o al di sotto della schiena e del capo. 10
1.2.2 Durata delle misurazioni La durata delle misurazioni deve essere sufficiente ad assicurare una ragionevole accuratezza statistica e a garantire che le vibrazioni siano tipiche delle esposizioni in corso di valutazione. La durata delle misurazioni deve essere registrata. Laddove l’esposizione completa consista di vari periodi di caratteristiche differenti , possono essere necessarie analisi separate dei vari periodi.
1.3 Valutazione delle vibrazioni 1.3.1 Metodo base di valutazione La valutazione deve avvenire attraverso la misura dell’accelerazione quadratica media (r.m.s.) ponderata espressa in metri al secondo quadro (m/! ! ) per le vibrazioni traslatorie e in radianti al secondo quadro (rad/! ! ) per la vibrazione rotatoria.
!! !
1 !
! !
!! ! (!)!"
! !
Dove !! (!) è l’ accelerazione ponderata in funzione del tempo, e T è la durata delle misurazioni. Il metodo base non può essere sempre applicato a questo scopo definiamo come fattore di cresta ,il modulo di picco istantaneo del segnale di accelerazione ponderata in frequenza al suo valore r.m.s., che
deve essere
determinato sulla durata della misurazione. Per le vibrazioni con fattori di cresta minori o uguali a 9 il metodo di valutazione di base è sufficiente. In alcuni casi quali la valutazione del benessere si può utilizzare anche la combinazione delle vibrazioni in più di una direzione con la seguente formula:
11
!! =
! ! !!! !!" + !!! !!" +
! ! ! !! !!" !
Dove !! , !! , !! , sono fattori di moltiplicazione.
1.3.1
Valutazione addizionale delle vibrazioni
Esistono due metodi di valutazione addizionale delle vibrazioni : - Il metodo dei valori r.m.s. costanti - Il metodo alla quarta potenza della dose delle vibrazioni Il primo metodo tiene conto degli urti occasionali e delle vibrazioni transienti mediante l’ uso di una costante di tempo di integrazione breve . L’intensità di vibrazione è definita da un valore di vibrazione transienti massimo (MTVV) .
!! !! =
1 !
!! !!!!
!! (!) ! !"
! !
Dove: !! (!) è l’ accelerazione istantanea ponderata in frequenza ; τ è il tempo di integrazione per la definizione della media; t è il tempo; !! è il tempo di osservazione ( tempo istantaneo ); il massimo valore di vibrazione transiente, MTVV, è definito come MTVV = max [ !! !! ] 12
Il secondo metodo quello alla quarta potenza delle dose di vibrazioni è più sensibile ai picchi proprio perché utilizza la potenza quarta dell’ andamento delle vibrazioni come base per la definizione della media. Il valore alla quarta potenza della dose delle vibrazioni (VDV) è espressa in metri al secondo alla potenza di 1,75 o in radianti al secondo alla potenza di 1,75, è definito come:
!
!"! = !
!! (!) ! !"
! !
dove !! (!) è l’ accelerazione istantanea ponderata, e T è la durata delle misurazioni. Quando l’esposizione alle vibrazioni consiste in 2 o più periodi si ha che :
!"!!!
!"!!"!#$ =
! !
!
L’esperienza suggerisce che l’uso dei metodi addizionali per la valutazione delle vibrazioni quando si eccedono i seguenti valori:
!"## = 1,5 !!
!"! = 1,75 !! ! !
13
1.3.3 Ponderazione in frequenza Il modo in cui le vibrazioni influenzano la salute, il benessere, la percezione ed il male dei trasporti dipende dal loro contenuto di frequenza. Sono necessarie differenti ponderazioni in frequenza per i diversi assi di vibrazione. Le ponderazioni principali in frequenza sono: - Wk per la direzione z; - Wd per le direzioni x e y Ulteriori ponderazioni non utilizzate nelle prove sperimentali condotte sono riportate all'interno della norma: -Wc misurazione dello schienale del sedile; -We misurazione delle vibrazioni rotatorie; -Wj misurazione delle vibrazioni sotto il capo di una persona distesa; -Wf ponderazione in frequenza correlata al male dei trasporti;
1.4 Salute Gli effetti delle vibrazioni a lungo termine indicano un incremento del rischio per la salute della colonna vertebrale e del sistema nervoso autonomo dei segmenti affetti. Questo può essere dovuto al comportamento biodinamico della colonna: il dislocamento orizzontale e la torsione dei segmenti della colonna vertebrale. Un’eccessiva tensione meccanica e/o disturbi della nutrizione e diffusione del tessuto del disco vertebrale possono contribuire ai processi degenerativi dei segmenti lombari. L’esposizione a vibrazioni trasmesse al corpo intero può inoltre peggiorare certi disturbi patologici endogeni a carico della colonna. Sebbene generalmente si presume una correlazione dose-effetto, al momento non è disponibile alcuna relazione quantitativa.
14
Per valutare gli effetti delle vibrazioni sulla salute bisogna determinare l’accelerazione quadratica media ponderata per ciascun asse (x, y, z) di vibrazione traslatoria sulla superficie che supporta la persona. La valutazione deve essere effettuata in modo indipendente su ciascun asse. Di seguito riportiamo le ponderazioni in frequenza e i fattori di moltiplicazione k da utilizzare: Asse x: !! , k =1,4 Asse y: !! , k = 1,4 Asse z: !! , k = 1
1.5 Benessere e percezione 1.5.1 Benessere Per il benessere delle persone sedute questo punto si applica alle vibrazioni periodiche , casuali e transitorie nell’ intervallo di frequenza da 0,5 Hz a 80 Hz che si verifica su tutti e sei gli assi del sedile ( tre traslatori: asse x, asse y, asse z e tre rotatori : asse !! , asse !! , asse !! ). Questo si applica anche ai tre assi rotatori dello schienale e dei piedi delle persone sedute, con riferimento ai sistemi di coordinate basicentrici. La valutazione selle vibrazioni avviene determinando, su ciascun asse di vibrazione traslatoria sulla superficie che supporta la persona, l’accelerazione quadratica media ponderata. Di seguito si riportano le ponderazioni e i fattori di moltiplicazione k. Per le persone sedute: asse x (vibrazioni della superficie di supporto del sedile): !! , k=1 asse y (vibrazioni della superficie di supporto del sedile): !! , k=1 asse z (vibrazioni della superficie di supporto del sedile): !! , k=1 Per le persone erette:
15
asse x (vibrazioni sul pavimento): !! , k=1 asse y (vibrazioni sul pavimento): !! , k=1 asse z (vibrazioni sul pavimento): !! , k=1 Per le posizioni distese , quando la misurazione è effettuata al di sotto del bacino: asse orizzontale: !! , k=1 asse verticale:
!! , k=1
Laddove il benessere è influenzato dalle vibrazioni in più di un punto si può ricavare un valore totale di vibrazioni complessivo dalla somma quadratica dei valori totali di vibrazioni puntuali. 1.5.2 Percezione La valutazione degli effetti di una vibrazione sulla salute deve essere realizzata in relazione alla massima accelerazione quadratica determinata su qualsiasi asse , in qualunque punto di contatto e in ogni momento. Utilizziamo per la previsione della percettibilità delle vibrazioni due ponderazioni in frequenza, !! , per le accelerazioni verticali e !! per le vibrazioni orizzontali e fattori di moltiplicazione k pari a 1. 1.6
Male da trasporti
La cinetosi o male da trasporti è influenzata da movimenti oscillatori con frequenza
inferiore
a
0,5
Hz,
la
sua
valutazione
consiste
nel
calcolo
dell’accelerazione quadratica media per le vibrazioni secondo l’ asse z. utilizzando una sola ponderazione in frequenza !! .
16
CAPITOLO 2 Acquisizione dati
2.1 Introduzione In questo capitolo descriviamo la strumentazione utilizzata , le connessioni tra i diversi componenti e il calcolatore , Preliminarmente
occorre
chiarire
riportando alla fine alcuni
aspetti
sulla
i risultati ottenuti. disposizione
della
strumentazione indipendentemente dal tipo utilizzato. In figura 2.1 (I) mostriamo la posizione che deve mantenere il tester durante la prova , seduto con la schiena dritta ( evitando di incurvare le spalle), con le gambe a formare un angolo di circa 90 ° e le mani sulle ginocchia. Gli accelerometri devono essere posizionati uno sul sedile al di sotto delle tuberosità ischiali , l’ altro sulla testa facendo attenzione che siano allineati lungo l’ asse z del sistema di coordinate basicentrico indicato dalla norma ISO 26311 vedi anche figura 2.1( I ).
17
Figura 2.1( I )
18
2.2 Strumentazione utilizzata 2.2.1 Accelerometri Bosh BMA180
Il BMA180 è un accelerometro triassiale capacitivo costruito con tecnologia MEMS. La bontà del sistema attivo di misura permette un ampio range di accelerazioni rilevabili e un’accuratezza notevole ma è molto sensibile alle variazioni di temperatura che vanno quindi attentamente monitorate (è installato un termometro interno all’unità). Il vero punto di forza del BMA 180 (che lo differenzia nettamente da altri della stessa fascia) è la presenza di un vero e proprio processore integrato (ha 256 bit di EEPROM) che consente di processare i dati in uscita. E’ possibile applicare via software otto diversi filtri passa basso, un filtro passa alto, un filtro passa banda e diverse modalità di stand-by e riconoscimento della pendenza.
Un convertitore
analogico-digitale digitalizza a 14 bit le misurazioni delle accelerazioni ed il processore consente di utilizzare i protocolli di interfacciamento digitali SPI ed I2C. Come vedremo meglio in seguito si può scegliere il range di misura in modo da adattarlo alle proprie esigenze (al diminuire del range aumenta la risoluzione). La scelta viene effettuata scrivendo opportuni valori esadecimali specifici nei registri dell’accelerometro specificati dalla casa costruttrice ma bisogna tuttavia ricordare che gli stessi hanno una durata limitata a 1000 cicli di scrittura, quindi si consiglia di agire su di essi con attenzione. Come già accennato, il BMA180 mette a disposizioni
19
varie modalità di funzionamento. Noi utilizzeremo sempre la modalità che garantisce le massime prestazioni, chiamata “Low Noise Mode”. Il sistema di riferimento dell’accelerometro con la direzione ed il verso degli assi è stampato sulla vista frontale dello stesso e la temperatura operativa va da -40 °C a 80 °C. Utilizzeremo la risoluzione massima ottenibile dal BMA180 in uscita che è di 14 bit con segno: i valori misurati vanno da -8192 ad 8192, cioè 213 valori positivi e 213 valori negativi. Il range massimo misurabile è di ±16g ma è possibile sceglierne di intermedi che partono da ±1g; ovviamente scegliendo bassi range si ottiene una risoluzione migliore. La Tabella 2.2.1 (I) riassume i range selezionabili, il valore di ogni unità digitale in uscita (si ottiene dividendo il massimo valore del range per 213) e la sensibilità (calcolata sulla misura di 1g) al variare del range. Come già detto la sensibilità dello strumento varia leggermente al variare della temperatura. Tuttavia il processore, grazie al termometro integrato, è in grado di tener conto di tale variazione con un opportuno offset sulla misura. La taratura viene effettuata dalla casa costruttrice sul range ±2g. Il contributo relativo generato dalle misurazioni sui tre assi è inferiore al 2% e quindi trascurabile.
Range [± g]
Risoluzione [ (10-3 g) / 213 ]
Sensibilità [ 213/g ]
1 1.05
0.13 0.19
8192 ± 2.0% 5460 ± 2.0%
2 3
0.25 0.38
4096 ± 1.5% 2730 ± 2.0%
4 8
0.50 0,06875
2048 ± 2.0% 1024 ± 2.5%
16
0,109722222
512 ± 3.0%
Tabella 2.2.1 (I) – Range di misura, risoluzione e sensibilità BMA180
20
Nella modalità “Low Noise” la frequenza di acquisizione interna è di 2400 Hz. La banda passante massima in uscita è di 1200 Hz ma è possibile restringerla grazie alla presenza di numerosi filtri passa basso applicati direttamente dal processore del BMA180 e selezionabili agendo sul registro di quest’ultimo. Come già detto, oltre ai filtri passa basso ci sono anche un filtro passa alto e un filtro passa banda. Il livello del rumore è funzione della banda passante: è pari a circa 150x10-6 g/ !". Nella Tabella 2.2.1(II) troviamo l’elenco completo dei filtri disponibili e la densità del rumore riferita al range di ±2 g che otteniamo con la selezionata banda passante. Il termometro integrato fornisce il valore della temperatura con le frequenze di 275 Hz. Banda passante [ Hz ]
Tipo di filtro
Rumore [ 10-3 g ]
10 20
Passa Basso Passa Basso
0.48 0,046527778
40 75
Passa Basso Passa Basso
0,065972222 1.03
150 300
Passa Basso Passa Basso
0,1 2.06
600
Passa Basso
0,171527778
Tabella 2.2.1(II) – Filtri disponibili e rumore BMA180
Per l’alimentazione dell’accelerometro è necessaria una tensione che va da un minimo di 2 V ad un massimo di 3.6 V. E’ necessario mettere un condensatore da 22 nF tra la linea “Ground” e la linea che porta la tensione positiva. Il consumo del BMA180 è molto basso: circa 1mA nella modalità che garantisce le massime prestazioni. Come abbiamo già detto, il BMA180 supporta i protocolli di interfacciamento digitale I2C e SPI. Il condensatore installato per l’alimentazione deve filtrare anche tutti i pin che vengono connessi mediante le linee di alimentazione. 21
2.2.2 Microcontrollore Arduino Uno
I microcontrollori Arduino hanno avuto un grandissimo successo negli ultimi anni per diverse cause, tra tutte, i costi relativamente bassi e l’ uso di un software open source, basato sul linguaggio di programmazione Processing , che ha consentito di generare numerose librerie liberamente a disposizione degli utenti. Il modello da noi utilizzato è il modello UNO che si differenzia dai precedenti perché non utilizza l’ USB- seriale chip driver FTDI ma la AtmegaU2 programmato come convertitore seriale-USB. L’Arduino Uno è una scheda microcontrollore basato sul Atmega328. Dispone di 14 ingressi digitali / pin di uscita (di cui 6 possono essere utilizzati come uscite PWM), 6 ingressi analogici, un cristallo 16 MHz, oscillatore, un collegamento USB, un jack di alimentazione, un header ICSP, e un pulsante di reset. La memoria del microcontrollore è di 32 Kb di cui 0,5 utilizzati dal bootloader, dispone inoltre di 2 Kb di SRAM e 1 Kb di EPROM.
22
Può essere alimentato con una tensione che va da 6 a 20 volt, anche se è sempre consigliata una alimentazione che va dai 7 ai 12 volt. Al di sotto dei 7 volt si rischia di non avere il voltaggio necessario e la scheda rischia di non essere stabile, al di sopra dei 12 volt il regolatore di tensione può surriscaldarsi e danneggiare la scheda. Nel nostro caso l’alimentazione avviene attraverso la connessione USB quindi siamo al riparo dagli inconvenienti sopra elencati. Ognuno dei singoli pin digitali può essere utilizzato come input o come output, attraverso le funzioni, pinMode(), digitalWrite (), digitalRead(). Di seguito riassumiamo le principali caratteristiche dell’Arduino UNO:
Microcontroller
Atmega328
Tensione di funzionamento
5V
Tensione in ingresso (consigliato)
7-12V
Tensione in ingresso (limiti)
6-20V
I / O digitale Pins
14 (di cui 6 - output PWM)
Ingresso analogico Pins
6
Corrente continua per I / O Pin 40 mA Di corrente per Pin 3,3 V CC
50 mA
Flash Memory
32 KB (Atmega328) di cui 0,5 KB utilizzati dal bootloader
SRAM
2 KB (Atmega328)
EEPROM
1 KB (Atmega328)
Velocità di clock
16 MHz
23
Per quanto riguarda i protocolli di comunicazione supporta sia quello SPI che quello ! ! C. La lunghezza e larghezza massima sono a 2,7 e 2,1 pollici, rispettivamente, con il connettore USB e jack di alimentazione che si estende oltre la dimensione precedente. Quattro fori per le viti consentono il fissaggio.
2.3 Connessione Arduino Uno – BMA180
Per la connessione tra gli accelerometri e il microcontrollore abbiamo utilizzato il protocollo di comunicazione ! ! C nella tabella 2.3(Ia) , e nella tabella 2.3(Ib) sono riportati i pin di connessione accelerometri - microcontrollore:
pin_ accelerometro 1
pin_microcontrollore
1
non deve essere connesso, connesso internamente a VDD
DNC
2 VDD
voltaggio supplementare
VDD
3.3V
3 VSS
connessione a terra
GND
GND
4 INT
interruzione del pin INT/NC attiva alto
P2
5 CSB
selezione chip , attiva basso
VDDIO
3.3V
6
internamente connesso con VSS
DNC
24
7 SCK
serial clock
SCK
A5
8 SDO
set-‐up di indirizzo I²C
9 SDI
I²C serial data
SDA
A4
10 VDDIO
voltaggio supplementare connessione digitale
VDDIO
3.3 V
11
non connettere connesso internamente con VSS
DNC
12
non connettere connesso internamente con VSS
DNC
GDN OR GND VDDIO
Tabella 2.3(Ia)
pin_ accelerometro 2
pin_microcontrollore
1
non deve essere connesso, connesso internamente a VDD
DNC
2 VDD
voltaggio supplementare
VDD
3.3V
3 VSS
connessione a terra
GND
GND
25
4 INT
interruzione del pin INT/NC attiva alto
P3
5 CSB
selezione chip , attiva basso
VDDIO
3.3V
6
internamente connesso con VSS
DNC
7 SCK
serial clock
SCK
A5
8 SDO
set-‐up di indirizzo I²C
9 SDI
I²C serial data
SDA
A4
10 VDDIO
voltaggio supplementare connessione digitale
VDDIO
3.3 V
11
non connettere connesso internamente con VSS
DNC
12
non connettere connesso internamente con VSS
DNC
GDN OR 3.3V VDDIO
Tabella 2.3(Ib)
26
Facciamo notare che soltanto due pin differenziano le connessioni dei due accelerometri con il microcontrollore, l’interrupt dell’accelerometro in un caso è connesso con il pin 2 nell’altro con il pin 3 del microcontrollore, il pin SDO è invece connesso all’Arduino una volta con la linea di ground l’altra con il pin di tensione a 3,3 V. Per le connessioni in comune deve essere utilizzato un collegamento in parallelo, a questo proposito abbiamo utilizzato una breadboard ,figura 2.3(I), che facilita tali connessioni.
Figura 2.3(I)
Nelle figure 2.3(II)-(III)-(IV) mostriamo le connessioni tra microcontrollore e accelerometri , riportando i pin utilizzati.
27
Figura 22.3(I)
28
Figura 2.3 (III)
Figura 2.3(IV)
29
2.4 Software acquisizione dati L’acquisizione dati con Arduino si compone in due fasi : 1) Lettura dati dagli accelerometri e invio. 2) Acquisizione dati. Tutto ciò si realizza in due distinti programmi, il primo viene caricato nella memoria del microcontrollore il secondo invece viene mandato in “run” sul calcolatore. 1) Lettura dati dagli accelerometri e invio. Questo programma è scritto nel linguaggio di programmazione Arduino, che differisce dal Processing per la presenza di alcune librerie, definisce il protocollo di comunicazione ! ! C includendo la libreria wire. h, definisce gli accelerometri con cui comunica importando la libreria bma180.h (precedentemente creata), e distingue i due accelerometri definendo i loro indirizzi di comunicazione. Quando il calcolatore invia il carattere “I” all’Arduino questo inizia la lettura dei dati che essendo degli interi sono composti di due byte, registra in un array di dimensione 3 i valori lungo i tre assi di riferimento e li invia al calcolatore attraverso la funzione “sendInt” questa operazione viene fatta per entrambi gli accelerometri. Il microcontrollore invia al calcolatore i dati in questa sequenza: 1- Accelerazione x primo accelerometro 2- Accelerazione y primo accelerometro 3- Accelerazione z primo accelerometro 4- Tempo di trasferimento dati 5- Accelerazione x secondo accelerometro 6- Accelerazione y secondo accelerometro 7- Accelerazione z secondo accelerometro 8- Tempo di trasferimento dati
30
Il tempo di trasferimento dati (espresso in millisecondi) è il tempo che il calcolatore impiega per inviare la completa sequenza di byte sopra indicata, e dalle prove effettuate questo tempo si stabilizza mantenendosi costante quando si imposta come tempo minimo di campionamento 10 millisecondi questo equivale a dire che la frequenza di lettura dei dati è pari a 100 Hz. 2) Acquisizione dati Il programma che interfaccia Arduino con il calcolatore e consente l’acquisizione dei dati è scritto utilizzando il linguaggio Processing, i dati inviati dal microcontrollore vengono scritti in un due file txt. Questi file contengono 4 vettori colonna nel seguente ordine , accelerazione x, accelerazione y, accelerazione z e tempo di trasferimento. Nei due file abbiamo rispettivamente i valori del primo e del secondo accelerometro. Qui sotto riportiamo un esempio di acquisizione:
-7995 -8145 -8144 -8145 -8149 -8144 -8145 -8146 -8149 -7565 -7111 -6196 -5693
1032 1067 1080 1244 1213 1248 1232 1035 823 773 649 376 349
1927 2702 3194 3741 4255 4330 4156 3633 2992 2553 1865 999 410
6037 6048 6060 6071 6082 6093 6104 6115 6126 6137 6148 6159 6170
Si osserva come i valori sono tutti degli interi.
31
2.5 Phidgets 1059
Di più semplice utilizzo sono gli accelerometri Phidgets che non necessitano di nessuna programmazione e sono connessi direttamente al calcolatore mediante cavo USB, di seguito riportiamo le principali caratteristiche. I Phidgets 1059 sono accelerometri triassiali capacitivi ,il sensore vero e proprio è un ADXL330 della Analog Device, con tecnologia MEMS in grado di misurare sia accelerazioni dinamiche (vibrazioni) sia accelerazioni statiche quale ad esempio la forza di gravità oppure un urto. La sigla MEMS sta per Micro Electro-Mechanical System cioè dispositivo con componenti elettroniche e meccaniche miniaturizzate nell’ordine dei micrometri; su uno stesso substrato di silicio sono presenti sia le componenti meccaniche sia i circuiti ed il processore che si occupano del monitoraggio dei dispositivi meccanici installati. L’accelerazione viene misurata sfruttando la variazione della capacità elettrica di un condensatore (da qui la definizione di “capacitivo”). Le armature del condensatore sono composte da una parte fissa e da una parte mobile, che è realizzata a sua volta con una massa conduttrice sospesa da un elemento elastico relativamente rigido (in genere una membrana). Il range misurabile su ognuno dei tre assi è di ±3g, dove per g si intende l’accelerazione gravitazionale terrestre, mediamente 9.81 m/s². La frequenza di acquisizione è di 60 Hz mentre la banda passante complessiva sui tre assi è di 30 Hz. In uscita viene restituito un segnale analogico. Nella Tabella 2.5(I) riportiamo le caratteristiche dell’ accelerometro.
32
Caratteristica
Valore
Alimentazione
5 V (porta USB)
Tipo di banda in uscita
Analogica
Frequenza di acquisizione
60 Hz
Range di misura (sui tre assi)
±3 g (circa 29.4 m/s2)
Banda passante (sui tre assi)
30 Hz
Rumore asse X
1.9·10-3g
Rumore asse Y
1.9·10-3g
Rumore asse Z
2.9·10-3g
Consumo massimo
Circa 20 mA
Temperatura Operativa
0 – 70 °
Prezzo (Febbraio 2011)
80 €
Tabella 2.5(I)
33
CAPITOLO 3 Pedana vibrante
3.1 Introduzione Questo capitolo è dedicato all’analisi dello strumento utilizzato per “generare” le sollecitazioni oggetto del nostro studio, la scelta è caduta su un macchinario da palestra generalmente utilizzato come “brucia grassi”, la pedana vibrante, figura 3.1(I) . Il funzionamento è semplice la pedana oscilla su di un fulcro , realizzando una sollecitazione di natura armonica, le diverse velocità selezionabili consentono di far variare, anche se in modo discreto, la frequenza di eccitazione.
34
Figura 3.1(I)
3.2 Problematiche riscontrate Il primo utilizzo della pedana è stato semplicemente quello di trasformarla in un sedile costruendo un supporto in legno per l’ accelerometro vedi figura 3.2(I) e (II). Questa soluzione però si è dimostrata inadeguata , per due motivi : 1) La superficie che sosteneva il corpo era troppo ampia coinvolgeva sia i glutei che parte posteriore della
coscia, attenuando le vibrazioni sulle
tuberosità ischiali che sono connesse alla colonna vertebrale tramite il bacino. 35
2) La pedana non realizzava un moto rettilineo alternativo visto che oscilla su di un fulcro questo comportava una spinta lungo l’ asse x (vedi sistemi di coordinate basicentrici) che
durante la prova inducevano il tester a
contrarre gli addominali riducendo il carico effettivo sulla colonna vertebrale , di fatto invalidando la prova .
Figura 3.2(I)
Figura 3.2(II)
36
3.3 Analisi della cinematica della pedana Viste le problematiche sopra elencate abbiamo quantificato il parametro cinematico che caratterizza l’oscillazione della pedana per capire quale fosse la soluzione più appropriata da adottare . L’angolo massimo da noi misurato è pari a 2,5 ° rispetto al piano orizzontale, chiaramente sia per il punto morto superiore sia per quello inferiore (figura 3.3 (I) ).
Figura 3.3 (I) 37
La soluzione ideale al problema è un sistema bascolante, in grado di convertire l’oscillazione della pedana in un moto rettilineo alternativo in direzione z, ma viste le difficoltà di realizzazione e il piccolo angolo di oscillazione abbiamo optato per una soluzione ottimale decidendo di costruire un sedile incernierato ad una base fissa, solidale con la pedana, che garantisce durante la prova una superficie di sostegno sempre parallela al piano orizzontale, a patto però di posizionare correttamente il tester durante la prova, vedi il capitolo “Acquisizione dati”.
3.4 Progettazione sedile Il sedile in figura 3.4(I) e (II) è stato realizzato completamente in legno, materiale per noi più semplice da lavorare, rispetto a qualsiasi tipo di metallo, come cerniere abbiamo utilizzato una coppia di ruote da carrello , mantenendo soltanto il supporto, la boccola e il perno, abbiamo scelto delle ruote che possono sopportare un carico massimo di 50 Kg ciascuna. Tutti i collegamenti effettuati mediante organi filettati sono provvisti di sistemi di anti-svitamento, visto le vibrazioni che il sedile deve sopportare.
38
Figura 3.4 (I)
39
Figura 3.4 (II)
Il sedile presenta anche una scanalatura centrale dove alloggiare l’accelerometro e le sue dimensioni compatte consentono una pressione sui glutei tale da limitare il loro effetto di attenuazione delle vibrazioni. La base del sedile è provvista di feritoie che consentono di regolare la posizione del sedile rispetto all’asse della pedana, di fatto permettendo di variare anche l’ampiezza delle sollecitazioni. Le dimensioni del sedile sono riportate nelle figure 3.4 (III) e (IV).
40
Figura 3.4 (III)
41
Figura 3.4 (IV)
42
CAPITOLO 4 Condizionamento dei segnali
4.1 Introduzione In questo capitolo mostriamo il lavoro fatto sui segnali acquisiti durante le prove, mostrando le differenze prima e dopo il condizionamento. Qui riportiamo alcuni parametri che caratterizzano le prove. Per ogni tester abbiamo effettuato 18 misurazioni a sei diverse velocità (3 per ogni velocità ) quindi a sei diverse frequenze, questo per avere una panoramica più ampia possibile sugli effetti delle vibrazioni sul corpo umano, nella tabella 4.1 (I) riportiamo la corrispondenza tra la velocità della macchina e la frequenza di sollecitazione.
Velocità macchina
Frequenza di sollecitazione ( Hz )
1
4,3
5
5,15
10
6,37
15
7,6
20
8,82
25
10,05
43
I dati sono stai acquisiti, durante la prima parte del nostro lavoro in cui abbiamo affinato la metodologia con cui effettuare le prove sperimentali, tramite accelerometri Phidgets, nella seconda, dove ci siamo occupati del condizionamento dei segnali, tramite il sistema Arduino-accelerometri BMA180, per due motivi fondamentali, la velocità di acquisizione dati maggiore, e la capacità di misurare contemporaneamente l’ accelerazione statica ( gravità ), e dinamica ( vibrazioni ) e di sovrapporle. Questa seconda caratteristica è alla base del condizionamento dei segnali.
4.2 Teoria dei segnali Il termine Segnale è usato molto frequentemente non solo nel campo scientifico e tecnologico ma anche nell'uso quotidiano del linguaggio comune. Altrettanto spesso però ad esso viene attribuito, in modo improprio, indifferentemente il significato anche di Messaggio o di Informazione. Vale a dire non distinguiamo i concetti di Segnale, Messaggio, Informazione. Normalmente ciò non comporta confusione anche perché la sua derivazione etimologica latina Signum ha un ampio spettro di significati. Nello studio dei sistemi fisici e del loro comportamento possiamo comunque intendere il termine Segnale come una variazione temporale dello stato fisico di un sistema che serve per rappresentare, registrare e trasmettere messaggi. Modello matematico I segnali, in quanto variazione temporale dello stato fisico di un sistema, possono essere osservati ovvero sono suscettibili di una operazione di misura attraverso un gran numero di modi e di strumenti che possono variare enormemente a seconda della variabile fisica sorgente della variazione. Occorre però prestare molta attenzione all'approccio sperimentale in quanto può essere soggetto a forti limitazioni. Infatti il 44
processo osservato si manifesta sempre come specifico, come evento singolo o individuale che manca del grado di generalità necessario per formarsi un'idea circa le proprietà fondamentali che lo generano. Risulta quindi necessario affrontare lo studio dei comportamenti per via teorica e definire, successivamente, un modello matematico che sia capace, ovviamente, di descrivere il reale comportamento del processo, a tutti i tempi, cioè darne l'evoluzione temporale, in modo esatto se esso è di tipo deterministico o in modo probabilistico se invece è di tipo stocastico e quindi di predire i risultati sotto mutate condizioni fisiche. L'importanza della definizione di modello matematico risiede anche nel fatto che dà la possibilità allo sperimentatore di separare le proprie convinzioni dalla natura specifica del processo preso in esame. Un altro aspetto dell'utilità del metodo basato sul modello matematico consiste nel poter limitare l'analisi solo alle proprietà oggettivamente più importanti, a quelle ritenute fondamentali e tralasciare un gran numero di attributi secondari di minore importanza o comunque di minore interesse fisico. La scelta del modello è il primo importante passo verso lo studio sistematico di un fenomeno fisico che, nel nostro caso, è rappresentato da un segnale. E' anche interessante notare come uno stesso modello matematico può descrivere ugualmente bene diversi processi fisici. Si pensi al modello a strati atomico e al modello a shell nucleare o al modello dell'oscillatore armonico utilizzato nella meccanica, nell'elettromagnetismo, nella fisica nucleare e subnucleare e cosi via, al modello esponenziale che ben descrive i processi di assorbimento di radiazioni nella materia, la carica e scarica di capacità... ecc. Possiamo in sintesi dire .che intendiamo per modello matematico, di un processo fisico in generale, di un segnale in particolare, una relazione funzionale il cui argomento è il tempo e che indicheremo pertanto con s(t), f(t), u(t),... In ultima analisi il modello ci permette di confrontare, di classificare e di stabilire le somiglianze tra segnali. La loro classificazione può essere fatta in tanti modi diversi a seconda della proprietà che si intende classificare. Quindi avremo segnali di tipo Unidimensionale o
45
Multidimensionale (Vettori) se si vuole evidenziare la dimensionalità attraverso la quale essi si esibiscono. Saranno di tipo Deterministico oppure Stocastico se la loro modalità di evolversi nel tempo è prevedibile oppure casuale. Potranno ancora essere Analogici oppure Discreti se si presentano come Continui o Discontinui nel tempo. E' comunque possibile una combinazione qualsiasi delle suddette 3 modalità e risulta evidente la necessità di uno spazio rappresentativo per la definizione e la manipolazione dei medesimi. Segnali Deterministici Un segnale è deterministico se il suo valore istantaneo può essere predetto ad ogni istante. Esso può essere specificato: 1. Attraverso una formula matematica 2. Un algoritmo computazionale Tuttavia occorre notare che segnali di tale tipo non esistono in natura! Infatti a causa dell'inevitabile interazione tra la sorgente del segnale e l'ambiente circostante oppure per le caotiche fluttuazioni, a livello macroscopico, della stessa variabile fisica sorgente del segnale (si pensi alla temperatura, alla pressione, al campo elettrico, ecc.), o ancora ad effetti quantistici a livello microscopico, portano alla conseguenza che gli unici segnali reali sono di natura casuale o stocastica. Nelle tele o radiocomunicazioni, fluttuazioni casuali si manifestano come rumore dal quale occorre estrarre l'informazione. Questo è un problema molto serio quando si debbano ricomporre, ad esempio, immagini provenienti da satellite. Si richiede allora l'uso di tecniche molto sofisticate che impiegano algoritmi di ricostruzione dell'immagine ( come il filtro di Kalman). Non sempre però il segnale casuale è da considerarsi rumore o indesiderato. Infatti, ad esempio, una sorgente cosmica emette delle fluttuazioni che non sono rumore ma anzi ci danno informazioni importanti
46
circa l'evoluzione e la natura dell'oggetto cosmico e quindi va considerato come segnale significativo. Molto spesso, come si vede, è difficile distinguere tra evento significativo (segnale) e fluttuazione (rumore) comunque, come vedremo, si può assumere un modello matematico anche per segnali non deterministici o quasi stocastici. Segnali Unidimensionali Tali segnali sono descritti tramite una funzione del tempo come, ad esempio, la tensione V(t) agli estremi di un circuito elettrico, la temperatura T(t) di un sistema termodinamico, la velocità v(t) di efflusso dei gas di un razzo, ecc. Segnali Continui Volendo fare una classificazione utile in senso pratico possiamo distinguere i segnali in base alla loro evoluzione temporale. Essi quindi possono essere: Continui, Discreti, Digitali. I segnali sono Continui o Analogici quando il loro valore può essere misurato in ogni istante. L'aggettivo 'analogico' è usato in relazione al fatto che la loro forma in uscita da un sistema è analoga a quella in ingresso. Segnali Discreti I segnali sono Discreti quando il loro valore può essere misurato solo in determinati istanti di tempo. Un semplice modello matematico è quello in cui ad un set numerabile di punti { !! }, i = 1,2,3,... nel tempo è associata una ampiezza !! ; quindi a particolari istanti { !! }, meglio se equidistanti, si fa corrispondere il valore del segnale.
47
Segnali Digitali I segnali sono Digitali quando si tratta di segnali discreti la cui ampiezza è associata ad un numero che ne rappresenta il valore in quell'istante. In genere per esprimere il numero viene usata, per semplicità, la base numerica binaria {0,1}, che ha solo due ampiezze possibili, a quella minore è associato uno dei due (in genere "0"), all'altra il rimanente ("1"). Molto spesso i segnali discreti sono utilizzati per campionare quelli analogici, cioè per darne una rappresentazione. I vantaggi sono: 1) Non è necessario trasmettere il segnale “continuamente”, ma solo in quegli istanti di campionamento. 2) E' possibile utilizzare lo "stesso" sistema di comunicazione per trasmettere messaggi da diverse sorgenti a diversi utilizzatori. Questo modo è noto come "Time Division Multiplexing". Gli intervalli di campionamento sono, in genere, uguali con la condizione ovvia che loro durata deve essere minore di quella del segnale analogico da campionare. Vi sono due modi di campionare: 1) Tramite impulsi con equidurata temporale, ∆! = cost. e con ampiezza A proporzionale a quella del segnale analogico nel punto di campionamento
48
2) Tramite impulsi di uguale ampiezza e con durata ∆! proporzionale all'ampiezza del segnale nel punto di campionamento. Anche con segnali digitali è possibile campionare segnali analogico: il segnale continuo nel punto di campionamento è convertito in una serie di impulsi digitali, ad es. binari, codificati che equivalgono al valore dello stesso al tempo t.
49
Rappresentazione dinamica dei segnali Molto spesso è importante conoscere non solo il valore istantaneo (presente) di un segnale, ma anche il suo comportamento durante il tempo nel passato e nel futuro. Il principio della rappresentazione dinamica ci consente di rispondere a questa esigenza. Essa consiste nel descrivere un segnale reale attraverso una somma di segnali elementari contigui ovvero che si susseguono ad istanti successivi di tempo. Essi possono essere scelti in una classe di segnali arbitrari tuttavia quelli più usati per la loro semplicità e significatività sono: 1) Funzioni elementari a gradini o di Heaviside, distanziati a intervalli temporali Dt uguali e con ampiezza uguale alla variazione del segnale in questo intervallo.
2) Impulsi rettangolari o funzione d di Dirac, contigui in modo tale da formare una sequenza inscritta o circoscritta al segnale.
50
4.3 Caratterizzazione del segnale
Per caratterizzare il segnale facciamo riferimento ai dati acquisiti con il sistema Arduino – accelerometri BMA180, il segnale ha le seguenti caratteristiche : - Discreto ( abbiamo un tempo di campionamento pari a 10 millisecondi ) - Multidimensionale ( gli accelerometri sono triassiali ) e ad un generico istante di tempo può essere espresso nel modo seguente:
!""! (!) = !! + !""!"#!! (!)
51
i = ! , ! , ! , sistema di coordinate dell’ accelerometro . !!
,componente nella direzione i-esima dell’ accelerazione statica (gravità)
indirettamente dipendente dal tempo, infatti dipende dalla orientazione del sistema di riferimento dell’ accelerometro che può variare nel tempo. Vale la relazione :
!! = !!! + !!! + !!! , per ogni t
Con g, accelerazione di gravità. !""!"#!! !
, componente nella direzione i-esima dell’ accelerazione dinamica
(vibrazione) . Segnale ideale Occorre un chiarimento, in tutti i modelli di identificazione del segnale utilizziamo una sollecitazione monoassiale in genere l’ accelerazione lungo z, facendo riferimento ai sistemi di coordinate basicentrici, qui invece ci riferiamo ad una sollecitazione triassiale il motivo è da attribuire ad un non corretto posizionamento degli accelerometri o ad una variazione dell’ orientazione durante il test, il segnale ideale (monodimensionale ) è del tipo : !"" = ! + !""!"# (t)
Ed è diretto lungo l’asse dell’ accelerazione di gravità. Di seguito riportiamo un esempio di segnale acquisito durante una prova, con velocità macchina pari a 10, figura 4.3 (I).
52
Figura 4.3 (I).
Si osserva come i tre segnali hanno una componente media non nulla che ribadiamo essere la proiezione dell’ accelerazione di gravità lungo i tre assi .
4.4 Modello del segnale Dall’analisi dei dati e dalle caratteristiche riscontrate possiamo assumere come modello per i nostri segnali il seguente : !""! = !! ! + !! sin(!") !""! = !! ! + !! sin(!")
53
!""! = !! ! + !! sin(!") Approssimiamo la componente vibrazionale a una funzione sinusoidale osservando che la pulsazione per le tre accelerazioni è la medesima in quanto proiezioni sugli assi dell’ accelerazione vibrazionale ideale prima definita. La componente statica è funzione del tempo , il modello è il più generale possibile quindi assumiamo un’ orientazione del sistema di coordinate dell’ accelerometro dipendente dal tempo.
4.4.1 Accelerazioni filtrate dalla media Per il momento consideriamo un modello in cui : !! ! = cost. !! ! = cost. !! ! = cost. La frequenza delle accelerazioni vibrazionali pari a 5 Hz. Definiamo l’accelerazione filtrata come : !""!!! ! = !""! ! − !""!!!"#
%$Con !""!!!"#
%$1 = !
!
!""! ! !
54
N: numero di dati rilevati. Nelle figure 4.4.1(I) e (II) le accelerazioni prima e dopo il filtraggio.
Figura 4.4.1(I)
55
Figura 4.4.1(II) 4.4.2 Velocità filtrate dalla media
La velocità ad un generico istante di tempo vale: !
!! (!) =
!
!""!!! !"
Visto che il nostro segnale è discreto otteniamo : !! ! = !! ! − 1 + !""!!! ! − 1 !"! ! − 1 Con !! ! = 1 = 0. La velocità filtrata è: !
!!!! ! = !! ! − !!!!"#$% con , !!!!"#$% = !
! ! !!
!
Nelle figure 4.4.2(I) e (II) le accelerazioni prima e dopo il filtraggio dalla media.
56
Figura 4.4.2(I)
Figura 4.4.2(II)
4.4.3 Spostamenti filtrati dalla media La generica posizione ad un generico intervallo di tempo può essere espressa come : !
!! ! =
!
!""!!! !"
Poiché il segnale è discreto vale : !
!! ! = !! ! − 1 + !! ! − 1 !"! (! − 1) + ! !""!!! ! − 1 !"!! (! − 1); con !! ! = 1 = 0 ; La posizione filtrata è :
57
!!!! ! = !! ! − !!!!"#
%$con !!!!"#$% =
! !
! ! !! (!)
Nelle figure 4.4.3 (I) e (II) i risultati ottenuti.
Figura 4.4.3 (I)
58
Figura 4.4.3 (II)
4.5 Orientazione accelerometro: influenza sul modello. Per stabilire l’orientazione dell’ accelerometro dobbiamo definire un sistema di coordinate “fisso”, assumiamo che il suo asse z sia coincidente con la direzione e il verso dell’ accelerazione di gravità, in questo riferimento il segnale ha le seguenti componenti: !""!!!"##$ = 0 !""!!!"##$ = 0 !""!!!"##$ = ! + ! sin(!") Quindi coincide con il segnale da noi definito ideale. Il riferimento fisso può essere considerato come il sistema basicentrico (vedi capitolo 1 figura 1.2.1) ruotato di 180 ° intorno all’asse x.
59
L’orientazione dell’ accelerometro rispetto al riferimento fisso è data dalla matrice di rotazione : !!"# !, !, ! = !!,! !!,! !!,!
Dove: !!,! è la matrice elementare di rotazione intorno all’ asse z !!,! è la matrice elementare di rotazione intorno all’ asse y !!,! è la matrice elementare di rotazione intorno all’ asse x. !!"# !, !, ! = !"#$!"#% !"#$%&!' −!"#$
!"#$#%&'#%&( − !"#$%&!' !"#$!"#%!"#& − !"#$!"#% !"#$#%&'
!"#$#%&'!"#( − !"#$!"#% !"#$!"#%&'!( − !"#$#%&' ; !"#$!"#%
A determinare l’orientazione contribuiscono soltanto le accelerazioni statiche perché vale in qualsiasi istante t la relazione : 60
!! = !!! + !!! + !!! Ad un generico istante t, valgono le relazioni 1,2,3 ottenute moltiplicando la matrice !!"# per il vettore (0, 0 ,g). !! /! = !"#$#%&'!"#( − !"#$!"#% (1)
!! /! = !"#$!"#%&!"# − !"#$#%&' (2)
!! /! = !"#$!"#% (3) Per definire gli angoli di rollio φ, di beccheggio ϑ e imbardata ψ si può utilizzare la funzione arcotangente2 così definita: Data una coppia (x,y) appartenete a R con (x,y) ≠ (0,0) si definisce arcotangente2 della coppia (x,y) l'angolo –π < ! < π che soddisfa alle condizioni
cos ! =
sen ! =
! !! + !! ! !! + !!
;
61
!"#$ ! = !"!#2 !, ! = −!"#$
! !! + !! !
!"# ! ≥ 0
!! + !!
!"# ! < 0
Dalla valutazione delle prove possiamo introdurre un’ulteriore ipotesi semplificativa al modello, infatti gli accelerometri non subiscono alcuna rotazione intorno all’ asse z quindi possiamo considerare nullo l’ angolo φ. Ricaviamo così le seguenti equazioni (vedi figura 4.5(I)): !! /! = !"#$%&!' !! /! = −!"#$ !! /! = !"#$!"#% ! = !"!#2 !! , !! ! = !"!#2 ( !!! + !!! , !! ) Per il calcolo delle accelerazioni statiche, facciamo delle considerazioni sulla media del segnale, conosciamo dalle prove effettuate la frequenza di sollecitazione, e per le accelerazioni vibrazionali vale : !!! !
!""!"#!! ! !" = 0
Con T definito come il periodo dell’ accelerazione dinamica. Quindi calcolando la media per ogni intervallo di tempo (t, t + T) otteniamo la media del segnale statico.
62
Suddividendo il tempo totale in intervalli di tempo pari a n volte il periodo T con n numero intero positivo , possiamo calcolare per ogni intervallo la coppia degli angoli di rotazione , ottenendo il loro andamento discreto . In figura 4.5(II) e (III) mostriamo rispettivamente l’ andamento degli angoli di rotazione per un modello di segnale con !! = !"#$. e !! = !! (!),
63
²+
²+
²
²
²+
²+
²
Figura 4.5(I)
64
Figura 4.5(II)
Figura 4.5(III) 65
La necessità di studiare un modello con accelerazioni statiche in funzione del tempo dipende dal fatto che l’ orientazione degli accelerometri è influenzata dalle piccole oscillazioni del sedile intorno all’ asse y ,da possibili oscillazioni del cranio sia intorno all’ asse x che intorno all’ asse y e da una disposizione iniziale errata . I valori di oscillazione sono dell’ordine di qualche grado , valori maggiori rendono non valida la prova . Adesso non ci rimane che capire quale è l’ accelerazione dinamica diretta lungo l’ asse dell’ accelerazione di gravità , quindi nel sistema di coordinate fisso, per calcolarla basta invertire la matrice !!"# e moltiplicarla per il vettore (!! , !! , !! ), otteniamo così: !""!"#!! = (!""!"#!! cos ! + !""!"#!! sin !) cos ! − !""!"#!! sin !
Equivalente a: !""!"#!! =
!""!"#!! cos ! cos !
In figura 4.5(III) i risultati ottenuti in basso le accelerazioni dinamiche in direzione dell’ asse di gravità.
Figura 4.5(III) 66
In conclusione possiamo dire che il condizionamento dei segnali sta nel valutare quanto i segnali reali si discostano dal modello ideale , attraverso i parametri di orientazione dell’ accelerometro ! , ! . Noti gli angoli ricostruiamo l’ accelerazione dinamica in direzione dell’ asse dell’ accelerazione di gravità, ottenendo l’accelerazione dinamica prima definita. Nell’ allegato 3 i risultati del condizionamento dei segnali.
67
CONCLUSIONI L’analisi fatta sui dati ci consente di affermare come il lavoro svolto abbia effettivamente migliorato la qualità dei segnali acquisiti, rispetto ai dati a noi pervenuti da studi precedenti, questo dovrebbe garantire lo studio
di un modello
predittivo più affidabile. Chiaramente il lavoro fatto può essere ancora migliorato, a cominciare dall’utilizzo della pedana vibrante, si può pensare di sostituire il sedile da noi progettato con uno che utilizza un sistema bascolante , in modo da convertire l’ oscillazione della pedana in un effettivo moto rettilineo alternativo. Possiamo anche migliorare il calcolo dell’orientazione dell’accelerometro, calcolando per tutti gli intervalli di campionamento, l’accelerazione statica sui tre assi attraverso un filtraggio dinamico, con l’ utilizzo quindi di un filtro passa basso. Sicuramente devono essere migliorati i segnali acquisiti dall’accelerometro di testa che ricordiamo essere fissato con un semplice elastico, e proprio per questo meno affidabile di quello del sedile per il quale è previsto un alloggio progettato per le sue dimensioni . I possibili sviluppi futuri nell’analisi delle vibrazioni sul corpo umano vista la qualità dei dati raggiunta attraverso il loro condizionamento è quella di utilizzare per l’ acquisizione dei segnali un sistema a 4 accelerometri ciò dovrebbe garantire una correlazione più affidabile, rispetto al sistema a due accelerometri, tra i dati sperimentali e i modelli fisici-matematici, infatti tra più usati c’è quello che approssima il corpo umano a 4 masse vibranti connesse mediante 5 coppie mollasmorzatore.
68
BIBLIOGRAFIA Manuali d’uso Massimo Banzi, Arduino, la guida ufficiale, Tecniche nuove 2009 Bosch - BMA180 Digital, Triaxial acceleration sensor data sheet Manuale di Matlab AA.VV., Matlab 7, per l’ ingegneria e le scienze, McGraw-Hill
Siti Web consultati Arduino - www.arduino.cc Processing - www.processing.org
69
RINGRAZIAMENTI Desidero ringraziare il prof. Ettore Pennestrì per avermi dato la possibilità di cimentarmi in una disciplina non propriamente “meccanica” che mi ha affascinato e arricchito culturalmente, l’ing. Daniele Carnevale che con i suoi preziosi consigli ha saputo sempre indirizzarmi al meglio e Marco Nadile, mio collega con cui ho largamente collaborato nelle prima parte del mio lavoro. Un pensiero va alla mia famiglia che mi ha sempre sostenuto, sia economicamente che moralmente. In particolare dedico questa “vittoria” a mio nonno Antonio, con il quale ho da sempre un rapporto speciale.
Daniele
70
Allegato 1 Programma di acquisizione dati
1.1 Programma microcontrollore Arduino Uno
/* Comunicazione I2C con 2 accelerometri Bosch BMA180 */
#include #include "bma180.h" #define MYID 1
//Questo è l'ID dell'unità, la numerazione deve essere progressiva in base al
numero di unità utilizzate #define SerialBaudrate 115200 //Baud rate della comunicazione seriale //Parametri necessari alla comunicazione -----------------------------------------------------------#define TOTALARDUINOS 1 //Numero totale di unità che si trovano sullo stesso canale #define BURSTDATA
16 //Numero di Byte che invia l'unità ogni volta
#define LEFTBYTE(x) (x >> 8)
//Selezione il byte sinistro dell'intero (formato da 2 byte)
#define RIGHTBYTE(x) (x & 0xFF)
//Selezione il byte destro (quello significativo)
dell'intero (formato da 2 byte) #define JOINBYTES(x,y) ((y << 8 ) + x) //Unisce i Byte sinistro e destro per formare un intero //---------------------------------------------------------------------------------------------------//____________________________________________ // BMA180 pin's
|
ARDUINO 2009 (1280) Pin's
//____________________________________________ // POWER-------------------------------------// VDD
|
3.3V 71
// VDDIO (VIO)
|
3.3V
//-------------------------------------------#define SCK 13 //serial clock signal (to trigger data) (52) #define MISO 12 //Master Input Salve Output (50) #define MOSI 11 //Master output Slave Input (51) #define CS
10 //is also PB0 of PORTB, Slave selector pin for the BMA CS (or SS) (53)
//INTERRUPT DELL'ACCELEROMETRO --------------// INT
|
Pin Digitale 2 per l'interrupt 0 (19 - Interrupt 2)
//-------------------------------------------#define INT 2 //interrupt connesso al pin 2 //SPECIFICI COMUNICAZIONE I2C----------------// SDI
|
SDA (pin analogico 4)
// SCK
|
SCL (pin analogico 5)
// SDO
|
GROUND
// CS
|
VDD = 3.3V
//-------------------------------------------#define BMAi2cAddress 0x40 // indirizzo primo accelerometro
//INTERRUPT DELL'ACCELEROMETRO --------------// INT
|
Pin Digitale 3 per l'interrupt 0 (19 - Interrupt 2)
//-------------------------------------------#define INT 3 //interrupt connesso al pin 3 //SPECIFICI COMUNICAZIONE I2C----------------// SDI
|
SDA (pin analogico 4)
// SCK
|
SCL (pin analogico 5)
// SDO
|
VDD = 3.3V
72
// CS
|
VDD = 3.3V
//-------------------------------------------#define BMAi2cAddress1 0x41 // indirizzo secondo accelerometro //Funzioni Bitmask #define SetBitn1(var, bitn) ((var) |= (uint8_t)(1 << (bitn-1))) #define SetBitn0(var, bitn) ((var) &= (uint8_t)~(1 << (bitn-1))) #define BitnValue(var,bitn)
((var>>(bitn-1)) & (uint8_t)(1))
#define SetBitMask(var,value,mask,shift) (var = (var&(~mask))|(value<
//Funzioni Bitmask #define SetBitn1(var, bitn) ((var) |= (uint8_t)(1 << (bitn-1))) #define SetBitn0(var, bitn) ((var) &= (uint8_t)~(1 << (bitn-1))) #define BitnValue(var,bitn)
((var>>(bitn-1)) & (uint8_t)(1))
#define SetBitMask(var,value,mask,shift) (var = (var&(~mask))|(value<
73
int acceleration[3]={0}; int acceleration1[3]={0}; unsigned long time = 0; int valX = 0; int valY = 0; int valZ = 0; int valX1 = 0; int valY1 = 0; int valZ1 = 0; int temp = 0; int temp1 = 0; int Identificativo = MYID; //Parametri necessari alla comunicazione con il PC -----------------------------------------------boolean firstever = true;
//Serve a verificare se l'unità è la prima a dover inviare i dati subito dopo
in segnale di invio del PC int AllSentData = 0;
//Tiene conto dei dati arrivati in modo da capire quando è il proprio turno
int temp_new = 0; int temp_old = 0; //-------------------------------------------------------------------------------------------------//Funzioni I2C void I2Cioinit(void); void BMAi2cRead(uint8_t RegisterAddress,short int HowRWdata, char *Rdata); void BMAi2cWrite(uint8_t RegisterAddress, char *Wdata); void setup() { int k = 0; I2Cioinit();
74
Serial.println(); Serial.print("\nID = "); Serial.print(MYID); Serial.println(); Serial.print("\nNumero totale unita' connesse = "); Serial.print(TOTALARDUINOS); Serial.println(); Serial.println("\f"); Serial.println("\n***************Test BMA180****************\n\n"); //Controlla la connessione indicandone lo stato while(init_BMA180(BMAaccRange,DMAfilterBW) != 0) { Serial.println("Errore di connessione con BMA180 1\n"); delay(1000); } Serial.println("Connessione con BMA180 1 eseguita correttamente\n"); while(init_BMA1801(BMAaccRange,DMAfilterBW) != 0) { Serial.println("Errore di connessione con BMA180\n"); delay(1000); } Serial.println("Connessione con BMA180 2 eseguita correttamente\n"); BMAi2cRead(TEMPERATURE,1,ReadData); BMAi2cRead1(TEMPERATURE,1,ReadData1); //Serial.println(ReadData[0],DEC); time = millis(); establishContact(); } void establishContact() //La funzione aspetta la ricezione del segnale di avvio dal PC { boolean ok = false; char input;
75
digitalWrite(LedPin,LOW); //Spegne il led verde while(ok==false) { digitalWrite(LedPin,LOW); if(Serial.available()>0) {input = Serial.read(); if( input == 'I') //Il Pc ha inviato il segnale di avvio { ok = true; Serial.flush(); //Svuota il buffer digitalWrite(LedPin,HIGH); //Accende il led verde } } delay(2000); //Se non arriva il segnale di avvio aspetta 2 secondi } digitalWrite(LedPin,LOW); } void sendInt(int * int2send) //La funzione invia un intero (2 byte) un byte alla volta { Serial.print(LEFTBYTE(*int2send),BYTE); Serial.print(RIGHTBYTE(*int2send),BYTE); } void loop() { //time = millis(); if(time+dT<=millis()) { time = millis(); BMAi2cRead(ACCXLSB,6,ReadData); // lettura dati primo accelerometro if(ReadData[0]&1)
76
{ for (short int i=0;i<4;i++) { if (i < 3) { acceleration[i] = (ReadData[2*i+1]<<6) + (ReadData[2*i]>>2); if(i==0) { valX = -acceleration[0]; //Accelerazione asse X sendInt(&valX); } if(i==1) { valY = -acceleration[1]; //Accelerazione asse Y sendInt(&valY); } if(i==2) { valZ = -acceleration[2]; //Accelerazione asse Z sendInt(&valZ); } } else { temp = (int) time; //tempo sendInt(&temp); } // N.B. Cambio il segno dei valori delle accelerazioni per utilizzare il // sistema di riferimento stampato sugli accelerometri BMA 180. } } time = millis();
77
BMAi2cRead1(ACCXLSB,6,ReadData1); // lettura dati secondo accelerometro if(ReadData1[0]&1) { for (short int i=0;i<4;i++) { if (i<3) { acceleration1[i] = (ReadData1[2*i+1]<<6) + (ReadData1[2*i]>>2); if(i==0) { valX1 = -acceleration1[0]; //Accelerazione asse X sendInt(&valX1); } if(i==1) { valY1 = -acceleration1[1]; //Accelerazione asse Y sendInt(&valY1); } if(i==2) { valZ1 = -acceleration1[2]; //Accelerazione asse Z sendInt(&valZ1); } } else { temp1 = (int) time; //tempo sendInt(&temp1); } // N.B. Cambio il segno dei valori delle accelerazioni per utilizzare il // sistema di riferimento stampato sugli accelerometri BMA 180. } }
78
} } /* Controlla se il registro dell'EEPROM ctrl_reg0.ee_w è configurato per essere scritto o no in quanto è fondamentale limitarne la scrittura (possono essere riscritti al massimo 1000 volte). E' importante notare che tale valere deve essere impostato ad 1 non solo se deve essere modificata una voce di registro maggiore di 0x04, ma anche se devi modificare la memoria volatile. Voci di registro con indirizzi minori sono volatili. */ void SET_ee_w() { BMAi2cRead(CTRLREG0,1,ReadData); WriteData = ReadData[0]; //Serial.println(WriteData,DEC); if(!BitnValue(ReadData[0], EE_W_BIT)) // controlla se il valore è già impostato su 1 {
// Set ee_w bit SetBitn1(WriteData, EE_W_BIT); BMAi2cWrite(CTRLREG0,&WriteData);
// Bisogna impostare ee_w per scrivere su ogni
altro registro } } /* init_BMA180 Input: il range è un valore a 3 bit tra 0x00 e 0x06. Il range sarà impostato come descritto nel datasheet del BMA180 a pagina 27. bw è un valore a 4 bit tra 0x00 e 0x09. Tale valore è descritto nel datasheet del BMA180 a pagina 27. Output: -1 in caso di errore, 0 se non ci sono problemi. */ void SET_ee_w1() { BMAi2cRead1(CTRLREG0,1,ReadData1);
79
WriteData1 = ReadData1[0]; //Serial.println(WriteData,DEC); if(!BitnValue(ReadData1[0], EE_W_BIT)) // controlla se il valore è già impostato su 1 {
// Set ee_w bit SetBitn1(WriteData1, EE_W_BIT); BMAi2cWrite1(CTRLREG0,&WriteData1);
// Bisogna impostare ee_w per scrivere su ogni
altro registro } } /* init_BMA180 Input: il range è un valore a 3 bit tra 0x00 e 0x06. Il range sarà impostato come descritto nel datasheet del BMA180 a pagina 27. bw è un valore a 4 bit tra 0x00 e 0x09. Tale valore è descritto nel datasheet del BMA180 a pagina 27. Output: -1 in caso di errore, 0 se non ci sono problemi. */
int init_BMA180(uint8_t range, uint8_t bw) { unsigned long int tempo = 0; SET_ee_w(); // se il BMA180 è connesso correttamente il registro dovrebbe avere il valore 3. //tempo = micros(); BMAi2cRead(ID1,1,ReadData); //Serial.println(ReadData[0],DEC); //Serial.println(micros()-tempo,DEC); if(ReadData[0] != 3) return -1; //Imposto offest_t per la temperatura BMAi2cRead(OFFSET_T,1,ReadData); Serial.print("\nOffset temperatura:"); Serial.println(ReadData[0]>>1,DEC);
80
if((ReadData[0]>>1) != BMATemperatureOffset) { Serial.print("\nHo selezionato il nuovo offset di temperatura: "); WriteData = BMATemperatureOffset<<1; BMAi2cWrite(OFFSET_T,&WriteData); BMAi2cRead(OFFSET_T,1,ReadData); Serial.println(ReadData[0]>>1,DEC); } // Seleziono la frequenza del filtro BMAi2cRead(BWTCS,1,ReadData); Serial.print("\nFiltro:"); Serial.println(((ReadData[0] & BW_MASK)>>BW_SHIFT),DEC); if((ReadData[0] & BW_MASK) != (bw< in BWTCS, ma scrive il nuovo BW BMAi2cRead(BWTCS,1,ReadData); Serial.println(((ReadData[0] & BW_MASK)>>BW_SHIFT),DEC); } // Seleziona il range delle accelerazioni BMAi2cRead(OLSB1,1,ReadData); Serial.print("\nRange:"); Serial.println(((ReadData[0] & RANGE_MASK)>>RANGE_SHIFT),DEC); if(((ReadData[0] & RANGE_MASK)>>RANGE_SHIFT) != range) { Serial.println("\nHo selezionato un nuovo Range: "); WriteData = ReadData[0]; SetBitMask(WriteData,range,RANGE_MASK,RANGE_SHIFT); BMAi2cWrite(OLSB1, &WriteData); BMAi2cRead(OLSB1,1,ReadData); Serial.println(((ReadData[0] & RANGE_MASK)>>RANGE_SHIFT),DEC);
81
} //L'interrupt del BMA è disabilitato BMAi2cRead(CTRLREG3,1,ReadData); Serial.print("\nInterrupt flag:"); Serial.println(BitnValue(ReadData[0],NEWDATA_SHIFT+1),DEC); if(BitnValue(ReadData[0],NEWDATA_SHIFT+1) != 0) { Serial.println("\nDisabilito l'interrupt: "); WriteData = ReadData[0]; SetBitMask(WriteData,0,NEWDATA_MASK,NEWDATA_SHIFT); BMAi2cWrite(CTRLREG3, &WriteData); BMAi2cRead(CTRLREG3,1,ReadData); Serial.println(BitnValue(ReadData[0],NEWDATA_SHIFT+1),DEC); } return 0; } int init_BMA1801(uint8_t range, uint8_t bw) { unsigned long int tempo = 0; SET_ee_w1(); // se il BMA180 è connesso correttamente il registro dovrebbe avere il valore 3. //tempo = micros(); BMAi2cRead1(ID1,1,ReadData1); //Serial.println(ReadData[0],DEC); //Serial.println(micros()-tempo,DEC); if(ReadData1[0] != 3) return -1; //Imposto offest_t per la temperatura BMAi2cRead1(OFFSET_T,1,ReadData1); Serial.print("\nOffset temperatura:"); Serial.println(ReadData1[0]>>1,DEC); if((ReadData1[0]>>1) != BMATemperatureOffset)
82
{ Serial.print("\nHo selezionato il nuovo offset di temperatura: "); WriteData1 = BMATemperatureOffset<<1; BMAi2cWrite1(OFFSET_T,&WriteData1); BMAi2cRead1(OFFSET_T,1,ReadData1); Serial.println(ReadData1[0]>>1,DEC); } // Seleziono la frequenza del filtro BMAi2cRead1(BWTCS,1,ReadData1); Serial.print("\nFiltro:"); Serial.println(((ReadData1[0] & BW_MASK)>>BW_SHIFT),DEC); if((ReadData1[0] & BW_MASK) != (bw< in BWTCS, ma scrive il nuovo BW BMAi2cRead1(BWTCS,1,ReadData1); Serial.println(((ReadData1[0] & BW_MASK)>>BW_SHIFT),DEC); } // Seleziona il range delle accelerazioni BMAi2cRead1(OLSB1,1,ReadData1); Serial.print("\nRange:"); Serial.println(((ReadData1[0] & RANGE_MASK)>>RANGE_SHIFT),DEC); if(((ReadData1[0] & RANGE_MASK)>>RANGE_SHIFT) != range) { Serial.println("\nHo selezionato un nuovo Range: "); WriteData1 = ReadData1[0]; SetBitMask(WriteData1,range,RANGE_MASK,RANGE_SHIFT); BMAi2cWrite1(OLSB1, &WriteData1); BMAi2cRead1(OLSB1,1,ReadData1); Serial.println(((ReadData1[0] & RANGE_MASK)>>RANGE_SHIFT),DEC);
83
} //L'interrupt del BMA è disabilitato BMAi2cRead1(CTRLREG3,1,ReadData1); Serial.print("\nInterrupt flag:"); Serial.println(BitnValue(ReadData1[0],NEWDATA_SHIFT+1),DEC); if(BitnValue(ReadData1[0],NEWDATA_SHIFT+1) != 0) { Serial.println("\nDisabilito l'interrupt: "); WriteData1 = ReadData1[0]; SetBitMask(WriteData1,0,NEWDATA_MASK,NEWDATA_SHIFT); BMAi2cWrite1(CTRLREG3, &WriteData1); BMAi2cRead1(CTRLREG3,1,ReadData1); Serial.println(BitnValue(ReadData1[0],NEWDATA_SHIFT+1),DEC); } return 0; }
void BMAi2cRead(uint8_t RegisterAddress,short int HowRWdata, char *Rdata) { short int ReadCounter = 0; Wire.beginTransmission(BMAi2cAddress); // Trasmetti al BMA Wire.send(RegisterAddress);
// l'indirizzo del registro
Wire.endTransmission(); Wire.beginTransmission(BMAi2cAddress); Wire.requestFrom(BMAi2cAddress,HowRWdata); // Nuova richiesta della grandezza dei bytes di lettura massimi //Serial.println(sizeof(readings),DEC); while(Wire.available() && ReadCounter < HowRWdata) { Rdata[ReadCounter] = Wire.receive(); // Riceve i byte come caratteri //Serial.println(Rdata[ReadCounter],DEC);
// Stampa a schermo i caratteri
++ReadCounter;
84
} Wire.endTransmission(); //Serial.println(readings); } void BMAi2cRead1(uint8_t RegisterAddress1,short int HowRWdata1, char *Rdata1) { short int ReadCounter1 = 0; Wire.beginTransmission(BMAi2cAddress1); // Trasmetti al BMA Wire.send(RegisterAddress1);
// l'indirizzo del registro
Wire.endTransmission(); Wire.beginTransmission(BMAi2cAddress1); Wire.requestFrom(BMAi2cAddress1,HowRWdata1); // Nuova richiesta della grandezza dei bytes di lettura massimi //Serial.println(sizeof(readings),DEC); while(Wire.available() && ReadCounter1 < HowRWdata1) { Rdata1[ReadCounter1] = Wire.receive(); // Riceve i byte come caratteri //Serial.println(Rdata[ReadCounter],DEC);
// Stampa a schermo i caratteri
++ReadCounter1; } Wire.endTransmission(); //Serial.println(readings); }
void BMAi2cWrite(uint8_t RegisterAddress, char *Wdata) { Wire.beginTransmission(BMAi2cAddress); // trasmetti al BMA Wire.send(RegisterAddress); Wire.send(*Wdata);
// l'indirizzo del registro // valore da scrivere nel registro
Wire.endTransmission(); }
85
void BMAi2cWrite1(uint8_t RegisterAddress1, char *Wdata1) { Wire.beginTransmission(BMAi2cAddress1); // trasmetti al BMA Wire.send(RegisterAddress1); Wire.send(*Wdata1);
// l'indirizzo del registro // valore da scrivere nel registro
Wire.endTransmission(); }
//I2C su MASTER void I2Cioinit (void) { Serial.begin(SerialBaudrate); Wire.begin(); }
86
1.2 Header File “bma180.h” /* *
bma180.h
*
Created on: Mar 19, 2010
*/ #ifndef BMA180_H_ #define BMA180_H_ //Address defines for BMA180// //====================// //ID and Version Registers #define ID1 0x00 #define Version 0x01 #define ACCXLSB 0x02 //to check if there is a new data for acc x #define ACCXMSB 0x03 #define ACCYLSB 0x04 //to check if there is a new data for acc y #define ACCYMSB 0x05 #define ACCZLSB 0x06 //to check if there is a new data for acc z #define ACCZMSB 0x07 #define TEMPERATURE 0x08 #define OFFSET_T 0x37
//temperature offset
#define OFFSET_T_MASK 0xFE // mask 0xFE = 254 DEC or 1111110 #define STATREG1 0x09 #define STATREG2 0x0A #define STATREG3 0x0B #define STATREG4 0x0C #define CTRLREG0 0x0D #define CTRLREG1 0x0E #define CTRLREG2 0x0F
87
#define BWTCS 0x20 #define CTRLREG3 0x21 #define HILOWNFO 0x25 #define LOWDUR 0x26 #define LOWTH 0x29 #define tco_y 0x2F #define tco_z 0x30 #define OLSB1 0x35 //BIT POSITIONS (1 is the Last significant bit (LSB)) #define EE_W_BIT 5 //====================// //Settings #define RANGE_SHIFT 1 #define RANGE_MASK 0x0E #define BW_SHIFT 4 #define BW_MASK 0xF0 #define NEWDATA_SHIFT 1 #define NEWDATA_MASK 0x02
#endif /* BMA180_H_ */
88
1.3 Programma calcolatore
N.B: I file di salvataggio con lo stesso nome verranno SOVRASCRITTI dal programma; si consiglia caldamente di spostare i file generati di volta in volta oppure di cambiarne il nome con la stringa "name"; un avviso con il nome dei file (verranno creati sono una volta premuto un tasto del mouse o della tastiera) che si stanno per creare verrà dato all'avvio del programma.
*/ import processing.serial.*; Serial port; int BaudRate = 115200; int unit = 1; int BURSTDATA = 16; //Byte che ogni unità trasmette al suo turno (16 byte sono 8 interi) int WAITMULTIPLEBURST = 30; //Per aumentare la velocità della comunicazione il PC aspetta che siano presenti più byte long WaitSerial = 0; //Millisecondi di attesa prima di verificare i dati sul canale seriale int DimSerialBuffer = 30000; //Dimensione in byte del buffer seriale int accX1[] = new int[unit]; //Valore dell'accelerazione lungo l'asse X | int accY1[] = new int[unit]; //Valore dell'accelerazione lungo l'asse Y |----> accelerometro 1 int accZ1[] = new int[unit]; //Valore dell'accelerazione lungo l'asse Z | int accX2[] = new int[unit]; //Valore dell'accelerazione lungo l'asse X | int accY2[] = new int[unit]; //Valore dell'accelerazione lungo l'asse Y |----> accelerometro 2 int accZ2[] = new int[unit]; //Valore dell'accelerazione lungo l'asse Z | int tempo1[] = new int[unit]; int tempo2[] = new int[unit]; 89
int Ytext = 20; //Definisce la posizione verticale delle stringhe di testo int Count = 1; //Con questa variabile conto il numero di righe dei file di salvataggio String name = "Prova"; //Nome da aggiungere al nome file (ci devono essere anche le virgolette) boolean Exit = false; boolean start = false; PrintWriter[] output1 = new PrintWriter [unit]; /* Creo un array di PrintWriter necessario per salvare i dati delle unità connesse in documenti .txt */ PrintWriter[] output2 = new PrintWriter [unit]; /* Creo un array di PrintWriter //
necessario per salvare i dati delle unità connesse in documenti .txt */
PFont font; /* Alcune variabili utilizzate all'interno del programma */ long time = 0; long time1 = 0; int oldspare = 0; int newspare = 0; byte oldsparedata = 0; int howmanybytesIn = 0; boolean InitDone = false; //Serve ad indicare se è stato mandato il segnale di avvio alle unità int e = 0; int ii = 0; int jj = 0; int Written = 0; String b; String count; String inString;
void setup() { size(800,600); background(10); println(Serial.list());
90
port = new Serial(this, Serial.list()[3], BaudRate); port.buffer(DimSerialBuffer); smooth(); font = loadFont("TimesNewRomanPSMT-20.vlw"); textFont(font); text("Sono collegate " + unit + " unità.", 10, Ytext); Ytext = Ytext + 30; text("I nomi dei file di salvataggio sono:", 10, Ytext); Ytext = Ytext + 30; for(int i = 1; i<=unit; i++) { for (int j=1; j<=2; j++) { text("Dati accelerometro " + j + " (" + name + ").txt", 10, Ytext); Ytext = Ytext + 30; } } text("CONTROLLARE I FILE PER EVITARE L'ERRONEA SOVRASCRITTURA DEGLI STESSI", 10, Ytext); Ytext = Ytext + 30; text("Premere un tasto del mouse o della tastiera per avviare il programma...", 10, Ytext); Ytext = Ytext + 30; } void SincronizeSerialArduino() { text("Sincronizzazione in corso", 10, Ytext); Ytext = Ytext + 30; delay(1000); port.write("I"); //Codice 73 ascii; questo è il segnale di avvio per le unità delay(1000); port.clear(); //Elimina i dati ricevuti dalla seriale
91
text("Sincronizzazione eseguita con successo", 10, Ytext); Ytext = Ytext + 30; delay(2000); time1 = millis(); }
void draw() { if(start) { if(!Exit) { if(time + WaitSerial <= millis()) //Legge dalla seriale dopo un intervallo WaitSerial (se maggiore di 0) { time = millis(); if(InitDone) { howmanybytesIn = port.available(); //assegna alla variabile il numero di byte disponibili sul buffer seriale howmanybytesIn = howmanybytesIn - howmanybytesIn%(BURSTDATA*unit); //Faccio in modo che nella variabile ci sia un numero di byte tale da avere //tre interi per ogni unità byte[] inBuffer = new byte[howmanybytesIn]; port.readBytes(inBuffer); //I dati sono salvati in file diversi per ogni unità for(ii=0; ii <= howmanybytesIn - BURSTDATA ; ii = ii+ BURSTDATA) { for(jj=0;jj
92
if (jj<(BURSTDATA/2)) output1[(ii/BURSTDATA)%(unit)].print((int(inBuffer[ii+jj] << 8) | int(inBuffer[ii+jj+1])) + " "); // scrivo i primi 4 interi sul prino file txt else
output2[(ii/BURSTDATA)%(unit)].print((int(inBuffer[ii+jj]
<<
8)
|
int(inBuffer[ii+jj+1])) + " "); // scrivo gli interi rimanenti sul secondo file txt } output1[(ii/BURSTDATA)%(unit)].println(); output2[(ii/BURSTDATA)%(unit)].println(); } Count = Count + 1; if(time-time1==10000) Exit=true; } else { port.clear(); while(port.available()<1) { for (int p = 0; p < unit; p++) //Ripeto la sincronizzazione finchè non mi arriva qualcosa dalla seriale { SincronizeSerialArduino(); delay(500); } } InitDone = true; //Questo booleano mi indica l'effettiva sincronizzazione } } } else //Funzione di uscita (si attiva quando Exit è vero) { font = loadFont("TimesNewRomanPSMT-20.vlw"); textFont(font);
93
for(int a = 0; a < unit; a++) { output1[a].flush(); //Finisce di scrivere i file output1[a].close(); //Chiude e salva i file output2[a].flush(); //Finisce di scrivere i file output2[a].close(); //Chiude e salva i file println("File di salvataggio 1 chiuso correttamente"); println("File di salvataggio 2 chiuso correttamente"); delay(250); } println("I file di salvataggio contengono " + Count + " righe."); println("Uscita eseguita correttamente"); delay(1000); exit(); } } }
void keyPressed() { if(start) { Exit = true; /* Premendo un tasto della tastiera con la finestra aperta dal programma in primo piano si attiva la funzione di uscita e salvataggio file */ text("Funzione di uscita attivata, attendere la chiusura della finestra...", 10, Ytext); Ytext = Ytext + 30; } if(!start)
94
{ for (int a = 0; a < unit; a++) { output1[a] = createWriter("Dati primo accel. (" + name + ").txt"); output2[a] = createWriter("Dati secondo accel. (" + name + ").txt"); println("Dati primo accelerometro (" + name + ").txt creato"); println("Dati secondo accelerometro (" + name + ").txt creato"); } text("File di salvataggio creati, inizio acquisizione dati...", 10, Ytext); Ytext = Ytext + 30; start = true; } }
void mousePressed() { if(start) { text("I file di salvataggio contengono " + Count + " righe.", 10, Ytext); Ytext = Ytext + 30; } if(!start) { for (int a = 0; a < unit; a++) { output1[a] = createWriter("Dati primo accelerometro (" + name + ").txt"); output1[a] = createWriter("Dati secondo accelerometro (" + name + ").txt");
95
println("Dati primo accelerometro (" + name + ").txt creato"); println("Dati secondo accelerometro (" + name + ").txt creato"); } text("File di salvataggio creati, inizio acquisizione dati...", 10, Ytext); Ytext = Ytext + 30; start = true; } }
96
Allegato 2 Programma di filtraggio e condizionamento dei segnali %filtro statico dei segnali clc clear all close all N=8192;% parametro di conversione utilzzato dagli accelerometri BMA180 g=9.81;% accelerazione di gravità %-------------------------------------------------------------------------% LETTURA DATI DA FLIE TXT stringa = 'accelerazioni2.txt'; % legge file testo generato nell’ acquisizione dati Accel1= fopen (stringa); matrice= fscanf (Accel1,'%f',[4 inf ]); fclose (Accel1); acc1_X=matrice(1,:)/N; acc1_Y=matrice(2,:)/N; acc1_Z=matrice(3,:)/N; t=matrice (4,:); % il tempo di acquisizione è espresso in millisecondi deve essere convertito in secondi. t=t/1000; n_ril=size (matrice); temp= n_ril(:,2);
% CALCOLO DELLE ACCELERAZIONI MEDIE time=0:1:temp-1; %plot (time,acc1_X); %plot (time,acc1_Y); %plot (time,acc1_Z); acc_Xm=0; acc_Ym=0; acc_Zm=0; for i= 1:1:temp acc_Xm =acc_Xm + acc1_X(i); acc_Ym =acc_Ym + acc1_Y(i); acc_Zm =acc_Zm + acc1_Z(i); end acc_Xm = acc_Xm/(temp); acc_Ym = acc_Ym/(temp); acc_Zm = acc_Zm/(temp);
97
g1=(acc_Xm)^2+(acc_Ym)^2+(acc_Zm)^2;%1= (acc1_Xm)²+(acc1_Ym)²+(acc1_Zm)² %-------------------------------------------------------------------------% ACCELERAZIONI FILTRATE DALLA MEDIA acc1_Xf=acc1_X-acc_Xm ; acc1_Yf=acc1_Y-acc_Ym ; acc1_Zf=acc1_Z-acc_Zm ; % angolo medio accelerometro if acc_Xm >=0 alpha_m = acos(acc_Zm/(acc_Xm^2+acc_Zm^2)^0.5) else alpha_m = -acos(acc_Zm/(acc_Xm^2+acc_Zm^2)^0.5) end if acc_Ym>=0 beta_m =-acos((acc_Xm^2+acc_Zm^2)^0.5/(acc_Xm^2+acc_Ym^2+acc_Zm^2)^0.5) else beta_m =acos((acc_Xm^2+acc_Zm^2)^0.5/(acc_Xm^2+acc_Ym^2+acc_Zm^2)^0.5) end Nfig=1; figure (Nfig) Nfig=Nfig+1; subplot(3,1,1),plot(time,g*acc1_X),title('accelerazione x ( m/s²)'),xlabel('time'),ylabel('accelerazione x'); subplot(3,1,2),plot(time,g*acc1_Y),title('accelerazione x ( m/s²)'),xlabel('time'),ylabel('accelerazione y'); subplot(3,1,3),plot(time,g*acc1_Z),title('accelerazione x ( m/s²)'),xlabel('time'),ylabel('accelerazione z');
figure (Nfig) Nfig=Nfig+1; subplot(3,1,1),plot(time,g*acc1_Xf),title('accelerazione x filtrate ( m/s²)'),xlabel('time'),ylabel('accelerazione x'); subplot(3,1,2),plot(time,g*acc1_Yf),title('accelerazione x filtrate ( m/s²)'),xlabel('time'),ylabel('accelerazione y'); subplot(3,1,3),plot(time,g*acc1_Zf),title('accelerazione x filtrate ( m/s²)'),xlabel('time'),ylabel('accelerazione z');
%--------------------------------------------------------------------------
%MEDIA DELLE VELOCITà v_x0=0; v_y0=0; v_z0=0; for i= 1:1:temp if (i<2) v_x(i)=v_x0; v_y(i)=v_y0; v_z(i)=v_z0;
98
else dt(i)=(t(i)-t(i-1)); v_x(i)=v_x(i-1)+(acc1_Xf(i-1))*g*dt(i); v_y(i)=v_y(i-1)+(acc1_Yf(i-1))*g*dt(i); v_z(i)=v_z(i-1)+(acc1_Zf(i-1))*g*dt(i); end end v_xm=0; v_ym=0; v_zm=0; for i=1:1:temp v_xm=(v_xm+v_x(i)); v_ym=(v_ym+v_y(i)); v_zm=(v_zm+v_z(i)); end v_xm=v_xm/temp; v_ym=v_ym/temp; v_zm=v_zm/temp; %-------------------------------------------------------------------------% VELOCITà FILTRATE v_xf=(v_x-v_xm); v_yf=(v_y-v_ym); v_zf=(v_z-v_zm); figure (Nfig) Nfig=Nfig+1; subplot(3,1,1),plot(time,v_x),title('velocità x ( m/s )'),xlabel('time'),ylabel('velocità x'); subplot(3,1,2),plot(time,v_y),title('velocità y ( m/s )'),xlabel('time'),ylabel('velocità y'); subplot(3,1,3),plot(time,v_z),title('velocità z ( m/s )'),xlabel('time'),ylabel('velocità z'); figure (Nfig) Nfig=Nfig+1; subplot(3,1,1),plot(time,v_xf),title('velocità x filtrata ( m/s )'),xlabel('time'),ylabel('velocità x'); subplot(3,1,2),plot(time,v_yf),title('velocità y filtrata ( m/s )'),xlabel('time'),ylabel('velocità y'); subplot(3,1,3),plot(time,v_zf),title('velocità z filtrata ( m/s )'),xlabel('time'),ylabel('velocità z');
%-------------------------------------------------------------------------% MEDIA DEGLI SPOSTAMENTI x0=0; y0=0; z0=0; for i= 1:1:temp if (i<2) x(i)=x0; y(i)=x0; z(i)=x0; else
99
dt(i)=(t(i)-t(i-1)); x(i)=x(i-1)+(v_xf(i-1))*dt(i)+g*0.5*acc1_Xf(i-1)*dt(i); y(i)=y(i-1)+(v_yf(i-1))*dt(i)+g*0.5*acc1_Yf(i-1)*dt(i); z(i)=z(i-1)+(v_zf(i-1))*dt(i)+g*0.5*acc1_Zf(i-1)*dt(i); end end xm=0; ym=0; zm=0; for i= 1:1:temp xm=(xm+x(i)); ym=(ym+y(i)); zm=(zm+z(i)); end xm=xm/temp; ym=ym/temp; zm=zm/temp; %-------------------------------------------------------------------------% SPOSTAMENTI FILTRATI x_f= x-xm; y_f= y-ym; z_f= z-zm; figure (Nfig) Nfig=Nfig+1; subplot(3,1,1),plot(time,x),title('spostamento x ( m )'),xlabel('time'),ylabel('x'); subplot(3,1,2),plot(time,y),title('spostamento y ( m )'),xlabel('time'),ylabel('y'); subplot(3,1,3),plot(time,z),title('spostamento z ( m )'),xlabel('time'),ylabel('z'); figure (Nfig) Nfig=Nfig+1; subplot(3,1,1),plot(time,x_f),title('spostamento x filtrato ( m )'),xlabel('time'),ylabel('x'); subplot(3,1,2),plot(time,y_f),title('spostamento y filtrato ( m )'),xlabel('time'),ylabel('y'); subplot(3,1,3),plot(time,z_f),title('spostamento z filtrato ( m )'),xlabel('time'),ylabel('z'); %-------------------------------------------------------------------------% FILTRAGGIO DINAMICO DEI DATI %tabella conversione velocità macchina- frequenza di eccitazione %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % velocità macchina fequenza Hz % % 1 --------------------> 4,3 %
5
-------------------->
5,15
100
%
10
-------------------->
6,37
%
15
-------------------->
7,6
%
20
-------------------->
8,82
%
25
-------------------->
10,05
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
f=5.15; %Hz T=1/f; % periodo che caratterizza il segnale noto dai rilievi sperim. Tc= 4*T; N_Tc=(t(temp)-t(1))/Tc; T_c=0; if mod((t(temp)-t(1)),Tc)==0 K=1:1:floor(N_Tc) else K=1:1:floor(N_Tc)+1 end xc=floor(Tc/(t(2)-t(1))); %numero di misure su cui calcolo la media xc_agg=0; for k=1:length(K-1) acc1_Xm(k)=0; acc1_Ym(k)=0; acc1_Zm(k)=0; if k
figure (Nfig) Nfig=Nfig+1; subplot(3,1,1),plot(K,g*acc1_Xm),title('accelerazione x media ( m/s²)'),xlabel('numero di campionamenti'),ylabel('accelerazione x');
101
subplot(3,1,2),plot(K,g*acc1_Ym),title('accelerazione x media ( m/s²)'),xlabel('numero di campionamenti'),ylabel('accelerazione y'); subplot(3,1,3),plot(K,g*acc1_Zm),title('accelerazione x media ( m/s²)'),xlabel('numero di campionamenti'),ylabel('accelerazione z');
%-------------------------------------------------------------------------% MATRICE DI ROTAZIONE % ipotesi psi =0
for k= 1:1:length(K) if acc1_Xm(k)>=0 theta(k)= acos(acc1_Zm(k)/(acc1_Xm(k)^2+acc1_Zm(k)^2)^0.5); else theta(k)= - acos(acc1_Zm(k)/(acc1_Xm(k)^2+acc1_Zm(k)^2)^0.5); end if acc1_Ym(k)>=0 psi(k)=acos((acc1_Xm(k)^2+acc1_Zm(k)^2)^0.5/(acc1_Xm(k)^2+acc1_Ym(k)^2+acc1_Zm(k)^2)^0. 5); else psi(k)=+acos((acc1_Xm(k)^2+acc1_Zm(k)^2)^0.5/(acc1_Xm(k)^2+acc1_Ym(k)^2+acc1_Zm( k)^2)^0.5); end g2(k)= acc1_Zm(k)/(cos(theta(k))*cos(psi(k))); % verifica che la somma dei vettori è pari a g1 end figure (Nfig) Nfig=Nfig+1; plot (K, g*(a_g-g2)) ,title ('errore modello');
figure (Nfig) Nfig=Nfig+1;
subplot(2,1,1),plot(K,(360/(2*pi))*theta),title('angolo theta (°)'),xlabel('numero di campionamenti'),ylabel('theta'); subplot(2,1,2),plot(K,(360/(2*pi))*psi),title('angolo psi (°)'),xlabel('numero di campionamenti'),ylabel('psi');
%--------------------------------------------------------------------------
% SOLLECITAZIONI VERTICALI xc_agg=0; for k=1:length(K)
102
if k
figure (Nfig) Nfig=Nfig+1; plot(time,g*accf),title('accelerazioni verticali filtrate ( m/s²)'),xlabel('time'),ylabel('accelerazioni verticali'); figure (Nfig) Nfig=Nfig+1; plot(time,g*accf-g*acc1f) y=[accf;time]; fid=fopen('accelerazioni verticali sedile.txt','wt'); fprintf(fid,'%f %f \n',y); fclose(fid);
103
Allegato 3
Esempio di filtraggio e condizionamento
3.1 accelerometro sedile (speed 5)
104
105
3.2 accelerometro testa (speed 5)
106
107