BaroneRosso.it - Forum Modellismo

BaroneRosso.it - Forum Modellismo (https://www.baronerosso.it/forum/)
-   Circuiti Elettronici (https://www.baronerosso.it/forum/circuiti-elettronici/)
-   -   Arduino e sensori accelerometri (https://www.baronerosso.it/forum/circuiti-elettronici/377835-arduino-e-sensori-accelerometri.html)

Minestrone 15 novembre 18 16:37

Grazie a tutti delle preziose informazioni. Sto sbattendo la testa per la prima volta con questi sensori e sto cercando a fatica di capire. Oramai ho capito come lavorare sul registro dell'integrato e mi sento già un passo avanti. Purtroppo non riesco più a stare alzato fino a tardi come qualche anno fa e la mia attività modellistica ne sta risentendo.

Ora sto rifinendo il mio sketch che, al momento, fa uso di due soli assi dell'accelerometro. Devo inserire la calibrazione e registrare il valore nel registro dell'integrato. Per adesso non sto usando né DMP né librerie.

Per quanto riguarda il giroscopio, da quello che ho capito e da quello che sto osservando nelle mie prove, il problema è che l'accelerometro è molto rumoroso e il filtro complementare (o altri) mixano i valori del gyro e dell'accelerometro per ottenere un dato pulito. Devo ancora implementare la lettura e la determinazione dell'angolo con il gyro, fatto quello potrò scoprire se il filtro funziona.

Per adesso ho detto valori molto sporchi e variabili. Ho provato ad applicare un filtro passa basso con la libreria filter senza ottenerne nulla, probabilmente la frequenza di campionamento dell'integrato è troppo bassa. Sto facendo la media delle letture con calcolo della media ogni mezzo secondo ma i risultati sono ancora sporchissimi.

Inviato dal mio Mi A1 utilizzando Tapatalk

gawain 15 novembre 18 16:53

Citazione:

Originalmente inviato da ElNonino (Messaggio 5122840)
Non conosco direttamente la MPU in oggetto però per lavoro ho utilizzato accelerometri per leggere un'inclinazione sul piano, alcuni analogici altri con uscita digitale e DSP interni.

Per misurare un'inclinazione in regime statico come è la lettura dell'incidenza di ali, piani di coda o pale di elicottero basta un accelerometro, il giroscopio è inutile, il problema degli accelerometri analogici è che l'uscita non era lineare rispetto all'angolo d'inclinazione ma bensì ha un andamento sinusoidale che va compensato tramite algoritmi di fusione dei dati di almeno due assi e poi ulteriormente linearizzato con una tabella appositamente creata.

Uso un solo accelerometro analogico da oltre 10 anni per leggere l'inclinazione verticale dei pannelli FV installati in baita sul mio sistema di inseguimento solare senza alcun problema, utilizzo solo gli assi X ed Y in quanto l'asse Z è sempre parallelo al suolo e la velocità di rotazione è estremamente bassa quindi non ho necessità di effettuare ulteriori compensazioni.

Indipendentemente dal tipo di sensore usato è comunque necessario filtrare molto bene il segnale, sia attraverso reti RC passa basso + algoritmi digitali nel caso di analogico che filtri digitali + DSP in quelli puramente digitali, mi ricordo di aver disquisito di ciò sul Barone in un'altra discussione (forse in elicotteri o multirotori)

Comunque una soluzione semplicissima (ma non di soddisfazione) per realizzare un incidenziometro è quella di acquistare un inclinometro digitale e fissarlo su opportuni supporti, cosa che ho fatto io per le pale dei miei elicootteri RC.

Se servono info a disposizione.

:yeah:


la sensor fusion con il gyro serve per migliorare la risposta in frequenza... se la misura è lenta allora la soluzione diventa banale e basta filtrare potentemente con filtro IIR le componeti del vettore accelerazione

ElNonino 15 novembre 18 22:55

Citazione:

Originalmente inviato da gawain (Messaggio 5122850)
la sensor fusion con il gyro serve per migliorare la risposta in frequenza... se la misura è lenta allora la soluzione diventa banale e basta filtrare potentemente con filtro IIR le componeti del vettore accelerazione

Esatto, il gyro visto che la misura è statica non serve, non credo che misuri l'incidenza con il modello in volo :D, per filtrare decentemente potresti iniziare ad usare una media mobile a 16 o 32 campioni, darò un occhiata al datasheet della MPU.

:yeah:

Minestrone 16 novembre 18 01:01

Citazione:

Originalmente inviato da ElNonino (Messaggio 5122884)
Esatto, il gyro visto che la misura è statica non serve, non credo che misuri l'incidenza con il modello in volo :D, per filtrare decentemente potresti iniziare ad usare una media mobile a 16 o 32 campioni, darò un occhiata al datasheet della MPU.

:yeah:

Si ma infatti pensavo di implementare il filtro solo per pulire il segnale.
Comunque stasera ho fatto diverse prove. Il filtro passabasso non mi ha portato a nessun miglioramento significativo, ho provato diverse frequenze ma il risultato non cambiava molto; forse ho sbagliato qualcosa.
Facendo la media aritmetica dei campionamenti raccolti in un mezzo secondo il risultato si stabilizza molto anche se ci sono ancora oscillazioni alla seconda cifra decimale (se riuscissi ad avere una buona pulizia alla prima cifra decimale sarei parecchio contento).
Avevo scelto di fare una media del genere perchè ho pensato di fare il refresh del display ogni mezzo secondo.
Facendo una media in virgola mobile naturalmente il risultato migliora perchè perde gli scalini e gli sbalzi di una media aggiornata ogni 500millisecondi, però per poter ottenere un risultato decente ho usato degli array con 64 valori.
Dovendo calcolare la media mobile su 3 array con 64 valori credo proprio che non potrò usare un algoritmo grezzo, altrimenti occupo il processore con il solo calcolo della media.

Minestrone 16 novembre 18 07:31

Citazione:

Originalmente inviato da Minestrone (Messaggio 5122899)
Si ma infatti pensavo di implementare il filtro solo per pulire il segnale.
Comunque stasera ho fatto diverse prove. Il filtro passabasso non mi ha portato a nessun miglioramento significativo, ho provato diverse frequenze ma il risultato non cambiava molto; forse ho sbagliato qualcosa.
Facendo la media aritmetica dei campionamenti raccolti in un mezzo secondo il risultato si stabilizza molto anche se ci sono ancora oscillazioni alla seconda cifra decimale (se riuscissi ad avere una buona pulizia alla prima cifra decimale sarei parecchio contento).
Avevo scelto di fare una media del genere perchè ho pensato di fare il refresh del display ogni mezzo secondo.
Facendo una media in virgola mobile naturalmente il risultato migliora perchè perde gli scalini e gli sbalzi di una media aggiornata ogni 500millisecondi, però per poter ottenere un risultato decente ho usato degli array con 64 valori.
Dovendo calcolare la media mobile su 3 array con 64 valori credo proprio che non potrò usare un algoritmo grezzo, altrimenti occupo il processore con il solo calcolo della media.

In realtà però posso calcolare la media solo sul risultato finale, non sui dati iniziali. Meno calcoli.
Bah... Alla notte dovrei dormire, non calcolare le medie..

Inviato dal mio Mi A1 utilizzando Tapatalk

ElNonino 16 novembre 18 12:42

Ho dato un'occhiata al datasheet della MCU e mi pare che non abbia un filtro passa basso sull'accelerometro ma solo sul giroscopio, quindi necessita sicuramente filtrare il segnale nel microprocessore anche perchè questa MCU è indicata per giocattoli od applicazioni in cui non è richiesta molta precisione.

Quando fai le prove controlla che la MCU non abbia vibrazioni, sia ben fissata ed usa i canali X ed Y non lo Z; poi controlla con un break point quali sono i valori nei due array per vedere se ci sono picchi od anomalie.

La media mobile comporta solo pochissimi calcoli, in pratica una sottrazione, una somma ed un right shift quindi può essere chiamata spesso senza appesantire la CPU, un buon filtraggio lo puoi anche ottenere usando due medie mobili in cascata, comunque scordati di ottenere l'accuratezza di 1/100 di grado e sopratutto che con quella MCU sia affidabile nel tempo.

Verifica anche che non ci siano perdite di dati nella comunicazione I2C o SPI.

:yeah:

Minestrone 16 novembre 18 13:35

Citazione:

Originalmente inviato da ElNonino (Messaggio 5122936)
Ho dato un'occhiata al datasheet della MCU e mi pare che non abbia un filtro passa basso sull'accelerometro ma solo sul giroscopio, quindi necessita sicuramente filtrare il segnale nel microprocessore anche perchè questa MCU è indicata per giocattoli od applicazioni in cui non è richiesta molta precisione.

Quando fai le prove controlla che la MCU non abbia vibrazioni, sia ben fissata ed usa i canali X ed Y non lo Z; poi controlla con un break point quali sono i valori nei due array per vedere se ci sono picchi od anomalie.

La media mobile comporta solo pochissimi calcoli, in pratica una sottrazione, una somma ed un right shift quindi può essere chiamata spesso senza appesantire la CPU, un buon filtraggio lo puoi anche ottenere usando due medie mobili in cascata, comunque scordati di ottenere l'accuratezza di 1/100 di grado e sopratutto che con quella MCU sia affidabile nel tempo.

Verifica anche che non ci siano perdite di dati nella comunicazione I2C o SPI.

:yeah:

Mah , proverò a fare delle altre prove avvitando il sensore al tavolo ed alzando la frequenza di campionamento dell'integrato (mi sembra di ricordare che ci sia un valore di registro per impostare la frequenza).
Nelle prove che ho fatto non c'era NESSUNA differenza tra i valori filtrati e quelli non filtrati. Che frequenza di filtro mi consigli?

Per la precisione credo che un decimo di grado sia più che sufficiente, per l'affidabilità metterò un algoritmo di calibrazione da richiamare ogni tanto. Se poi funziona bene posso anche pensare di trasformare il tutto per un sensore più preciso.
Stasera devo mettere mano al minikosmo, che è più importante, domani vedo di andare avanti.

Intanto grazie dell'interessamento.

Inviato dal mio Mi A1 utilizzando Tapatalk

Minestrone 29 novembre 18 11:17

Sto andando avanti con il mio progettino ma ho un problemino con la gestione della media in virgola mobile. In pratica il risultato della media impiega parecchi secondi a stabilizzarsi ad ogni movimento del sensore. Non capisco perchè, sarà sicuramente una stupidata ma io non la vedo.
Se posso approfitto della vostra competenza e vi allego il codice del loop per cercare di capire cosa non va.
Considerate che la maggior parte del codice risiede nel void setup, compresa la parte della calibrazione che comprende la maggioranza delle righe di codice, ma non credo che quella interessi.
Vi posto il codice

note: tempodiciclo è impostato a 500millisecondi ( const int tempodiciclo=500; )
k è la dimensione dell'array per il calcolo della virgola mobile e vale 64 ( const int k=64; )


void loop(){
letturaMPU_0(); //funzione che riceve dati dal sensore MPU_0 e li memorizza nelle variabili
// MPU_0_AcX, MPU_0_AcY e MPU_0_GyZ (i primi due sono accelerazioni,
//l'ultimo e un dato di gyroscopio.)

sommadegMPU_0-=degMPU_0[i];
degMPU_0[i] = ((atan2(MPU_0_AcY, MPU_0_AcX )) * 180.0) / PI; //calcolo tramite accelerometro
sommadegMPU_0+=degMPU_0[i];
i++;
if (i==k) {i=0;}
tempodiciclo = millis()-startMillis;
startMillis = millis(); //reset timer
ciclorefresh+=tempodiciclo;
deggyroMPU_0=deggyroMPU_0+(((MPU_0_GyZ/131)*tempodiciclo)/1000);//calcolo tramite gyro
if(ciclorefresh >= lcdRefreshRate){
mediadegMPU_0 = sommadegMPU_0 / k ;
ciclorefresh=0;

} //fine if

#ifdef debug {stampadebug(); #endif} //se il debug è acceso chiama la funzione per la stampa
seriale dei valori

}




Ovviamente il valore dell'angolo calcolato tramite accelerometro cambia ogni 500 millisecondi sullo schermo del pc perchè così è impostato, però ad ogni movimento il valore impiega 4 o 5 secondi a raggiungere il valore reale.

il tempo di ciclo lo stampo a video per vedere quanto vale ed è attorno agli 83 millisecondi. Ho scoperto che il tempo di ciclo varia in funzione di come modifico la funzione stampadebug() , evidentemente la stampa a video di valori e stringhe tramite Serial.print() richiede molto tempo. Stampando un pochino di valori per avere un'idea di come varino le variabili sono arrivato ad avere tempi di ciclo sui 250ms.

ElNonino 29 novembre 18 17:46

Citazione:

Originalmente inviato da Minestrone (Messaggio 5124514)
Sto andando avanti con il mio progettino ma ho un problemino con la gestione della media in virgola mobile. In pratica il risultato della media impiega parecchi secondi a stabilizzarsi ad ogni movimento del sensore. Non capisco perchè, sarà sicuramente una stupidata ma io non la vedo.
Se posso approfitto della vostra competenza e vi allego il codice del loop per cercare di capire cosa non va.
Considerate che la maggior parte del codice risiede nel void setup, compresa la parte della calibrazione che comprende la maggioranza delle righe di codice, ma non credo che quella interessi.
Vi posto il codice

note: tempodiciclo è impostato a 500millisecondi ( const int tempodiciclo=500; )
k è la dimensione dell'array per il calcolo della virgola mobile e vale 64 ( const int k=64; )


void loop(){
letturaMPU_0(); //funzione che riceve dati dal sensore MPU_0 e li memorizza nelle variabili
// MPU_0_AcX, MPU_0_AcY e MPU_0_GyZ (i primi due sono accelerazioni,
//l'ultimo e un dato di gyroscopio.)

sommadegMPU_0-=degMPU_0[i];
degMPU_0[i] = ((atan2(MPU_0_AcY, MPU_0_AcX )) * 180.0) / PI; //calcolo tramite accelerometro
sommadegMPU_0+=degMPU_0[i];
i++;
if (i==k) {i=0;}
tempodiciclo = millis()-startMillis;
startMillis = millis(); //reset timer
ciclorefresh+=tempodiciclo;
deggyroMPU_0=deggyroMPU_0+(((MPU_0_GyZ/131)*tempodiciclo)/1000);//calcolo tramite gyro
if(ciclorefresh >= lcdRefreshRate){
mediadegMPU_0 = sommadegMPU_0 / k ;
ciclorefresh=0;

} //fine if

#ifdef debug {stampadebug(); #endif} //se il debug è acceso chiama la funzione per la stampa
seriale dei valori

}




Ovviamente il valore dell'angolo calcolato tramite accelerometro cambia ogni 500 millisecondi sullo schermo del pc perchè così è impostato, però ad ogni movimento il valore impiega 4 o 5 secondi a raggiungere il valore reale.

il tempo di ciclo lo stampo a video per vedere quanto vale ed è attorno agli 83 millisecondi. Ho scoperto che il tempo di ciclo varia in funzione di come modifico la funzione stampadebug() , evidentemente la stampa a video di valori e stringhe tramite Serial.print() richiede molto tempo. Stampando un pochino di valori per avere un'idea di come varino le variabili sono arrivato ad avere tempi di ciclo sui 250ms.

Stasera ti metto un pezzo di codice di come realizzo io i campionamenti e la media mobile.

:yeah:

Minestrone 29 novembre 18 17:55

Citazione:

Originalmente inviato da ElNonino (Messaggio 5124556)
Stasera ti metto un pezzo di codice di come realizzo io i campionamenti e la media mobile.

:yeah:

Molto gentile. Grazie.

Inviato dal mio Mi A1 utilizzando Tapatalk


Tutti gli orari sono GMT +2. Adesso sono le 09:28.

Basato su: vBulletin versione 3.8.11
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
E' vietata la riproduzione, anche solo in parte, di contenuti e grafica. Copyright 1998/2019 - K-Bits P.I. 09395831002