Il risultato deludente della precisione del modulo compass non mi ha dato pace per parecchio tempo.

Così ho voluto cercare di capire meglio questo problema e fare ulteriori tests.

 

Raccolta dati per elaborare una soluzione

Innanzitutto ho disegnato su un foglio delle righe in corrispondenza dei vari angoli. La posizione del Nord non è rilevante per questo test, ho voluto in ogni caso verificare se in qualche modo il mio cellulare era influenzato da qualche campo magnetico che non avevo considerato.

test angoli setup

 

Ho predisposto BigWheely parallelo ai rispettivi angoli che ho disegnato e ne ho rilevato i valori trasmessi.

Ho raccolto i dati in un foglio excel e fatto alcune considerazioni:

tabella funzione compass

 grafico funzione compass

 

Interpretazione dei dati raccolti

Innanzitutto, l'asse orizzontale mostra l'angolo REALE di posizionamento, mentre l'asse verticale indica il valore MISURATO.

La linea retta BLU denominata "Teorico" indica il comportamente ideale, ad ogni angolo reale corrisponde lo stesso angolo misurato.

Le curve VERDI e ROSSE sono molto simili tra loro, ho provato infatti a rilevare le identiche misurazioni ma assegnando alla funzione SetScale (libreria HMC5883L.h descritta in precedenza) valori differenti (prima 8.1 Ga e poi 1.3 Ga).
Il risultato, come si può notare dalla sovrapposizione delle curve, non cambia di molto.

 

Calcolo delle funzioni di compensazione

Ho aggiunto delle linee di tendenza in corrispondenza della curva ROSSA, e ho identificato una funzione di quinto grado che aderiva molto bene, ho dovuto scartare subito l'idea di integrare questa funzione in Arduino in quanto risolverla sarebbe stato un calcolo eccessivo (i numeri in gioco erano davvero molto grandi).
Ho quindi optato per utilizzare funzioni lineari e di suddividerle in segmenti più piccoli.

Calcolando i coefficienti k1, k2, k3 che determinano l'inclinazione e b1,b2,b3 (descritti erroneamente sempre con b) che influenzano lo spostamento verticale della retta, ne ho ricavato 3 funzioni F(x).
Da queste funzioni F1(x), F2(x), F3(x) ho potuto calcolare le rispettive funzioni inverse G1(x), G2(x), G3(x).

Si può notare come la curva risultante delle funzioni inverse G(x) rappresentata in AZZURRO seguono piuttosto bene la linea teorica.

 

Ho infine applicato queste funzioni in uno sketch su Arduino e ho provato ad effettuare di nuovo i rilevamenti.
Nelle immagini seguenti sono riportate le posizioni di BigWheely (sinistra), dei rispettivi angoli misurati (Campo Movement) e l'angolo rappresentato dopo le compensazioni appena descritte (campo Angle). 
NOTA: Il campo Movement mostra l'angolo moltiplicato per 10 (es: 3580 ==> 358.0 gradi)

 

 

 ANGOLO RIFERIMENTO: 0 GRADI  
 test angolo 0 misura angolo 0 
 ANGOLO RIFERIMENTO: 90 GRADI  
 test angolo 90  misura angolo 90
ANGOLO RIFERIMENTO: 180 GRADI  
test angolo 180 misura angolo 180
ANGOLO RIFERIMENTO: 270 GRADI  
test angolo 270 misura angolo 270

 

 

Generalmente le misurazioni si sono rilevate decisamente migliorate, in corrispondenza degli angoli dei punti cardinali (0; 90; 180; 270) sembra esserci una buona precisione.

 

Per concludere l'esperimento ho riapplicato l'identico test fatto in precedenza per constatare il comportamento durante la rotazione continua, ecco il video: