compensazione inclinazione HMC5883 per bussola

Ho realizzato con un hmc5883 e lcd16x2 una bussola per il puntamento della parabola motorizzata del camper ma in nessun modo sono riuscito a compensare il fatto che il sensore non sempre è in perfetta bolla, di conseguenza anche la lettura non è precisa al 100%.
Cosa devo modificare o aggiungere al codice?

#include <HMC5883L.h>


#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
#define Addr 0x1E               // 7-bit address of HMC5883 compass

void setup() {
 lcd.begin(16, 2);
 Wire.begin();
 Serial.begin(9600);


 // Set operating mode to continuous
 Wire.beginTransmission(Addr);
 Wire.write(byte(0x02));
 Wire.write(byte(0x00));
 Wire.endTransmission();
}

void loop() {
 int x, y, z, k;

 // Initiate communications with compass
 Wire.beginTransmission(Addr);
 Wire.write(byte(0x03));       // Send request to X MSB register
 Wire.endTransmission();


 Wire.requestFrom(Addr, 6);    // Request 6 bytes; 2 bytes per axis
 if (Wire.available() <= 6) {  // If 6 bytes available
   x = Wire.read() << 8 | Wire.read();
   z = Wire.read() << 8 | Wire.read();
   y = Wire.read() << 8 | Wire.read();
 }
 //Print out values of each axis
 Serial.print("x: ");
 Serial.print(x);
 Serial.print("  y: ");
 Serial.print(y);
 Serial.print("  z: ");
 Serial.println(z);
 lcd.setCursor(0, 0);
 lcd.print("    BUSSOLA");
 // Display the angle in LCD with respect to Nord
 float h = atan2(x, y) / 0.0174532925;
 if (h < 0) h += 360;
 h = 360 - h;
 lcd.setCursor(1, 1);
 k = int(h);
 lcd.print(k);
 lcd.print((char)223);

 if ( k > 337)
 {
   lcd.setCursor(6, 1); lcd.print("Nord"); lcd.setCursor(13, 0); lcd.print("-");lcd.print((char)126);
 }
 else
 {
   if (k > 23 && k <= 67)
   {
     lcd.setCursor(6, 1); lcd.print("Nord-Est");lcd.setCursor(13, 0); lcd.print((char)127);lcd.print("-");
   }
   else
   {
     if (k > 67 && k < 112)
     {
       lcd.setCursor(6, 1); lcd.print("Est");lcd.setCursor(13, 0); lcd.print((char)127);lcd.print("-");
     }
     else
     {
       if (k > 112 && k < 158)
       {
         lcd.setCursor(6, 1); lcd.print("Sud-Est");lcd.setCursor(13, 0); lcd.print((char)127);lcd.print("-");
       }
       else
       {
         if (k > 158 && k < 202)
         {
           lcd.setCursor(6, 1); lcd.print("Sud");lcd.setCursor(12, 0); lcd.print((char)127);lcd.print("-");lcd.print((char)126);
         }
         else
         {
           if (k > 202 && k < 248)
           {
             lcd.setCursor(6, 1); lcd.print("Sud-Ovest");lcd.setCursor(13, 0); lcd.print("-");lcd.print((char)126);
           }
           else
           {
             if (k > 248 && k < 293)
             {
               lcd.setCursor(6, 1); lcd.print("Ovest");lcd.setCursor(13, 0); lcd.print("-");lcd.print((char)126);
             }
             else
             {
               if (k > 293 && k < 337)
               {
                 lcd.setCursor(6, 1); lcd.print("Nord-Ovest");lcd.setCursor(13, 0); lcd.print("-");lcd.print((char)126);
               }
               else
               {
                 if (k <= 23)
                   lcd.setCursor(6, 1); lcd.print("Nord"); lcd.setCursor(13, 0); lcd.print((char)127);lcd.print("-");
               }
             }
           }
         }
       }
     }
   }
 }
 delay(200);
 lcd.clear();
}

Col solo magnetometro non vai da nessuna parte, se non è perfettamente in piano l'angolo letto è sempre errato anche di molti gradi.
Per compensare serve conoscere come è inclinato il magnetometro, ovvero ti serve anche una IMU da abbinare al magnetometro, la soluzione completa la trovi qui.

Ago99: prima che passi un mod a rimproverarti, per favore edita il post e racchiudi il codice nei tag "code" ... non solo perche' lo dice il regolamento, ma anche perche' postandolo direttamente come testo, alcune combinazioni di caratteri il forum li potrebbe trasformare in "faccine", rendendo il tutto poco comprensibile :wink:

Ho letto da qualche parte che l'asse z del hmc5883 serve proprio per compensare il non perfetto livellamento del sensore. Siccome è montato su un camper, di norma ma anche per comodita interna si cerca sempre di mettere a bolla il veicolo, quindi diciamo che in linea di massima la bolla perfetta puo variare i uno due gradi al massimo.
Altri consigli?

Ma che precisione serve?
Perché il nord magnetico non è esattamente a Nord, il Nord magnetico si muove e inoltre il campo non è perfettamente orizzontale. Poi si aggiungono le aree di anomalia magnetica, di solito le vulcaniche.

Ago99:
Ho letto da qualche parte che l'asse z del hmc5883 serve proprio per compensare il non perfetto livellamento del sensore.

Ma assolutamente no, il terzo asse serve per ottenere letture utili anche se il magnetometro è inclinato, se è solo due assi deve sempre essere perfettamente in bolla, si fa tramite un apposito calcolo che tiene conto della lettura su tutti e tre gli assi, però se non disponi dell'esatto angolo di inclinazione, grazie al quale e altri calcoli puoi compensare l'errore, è impossibile ottenere il reale nord magnetico.
Ovviamente tocca tenere conto anche della declinazione magnetica e delle zone con anomalie magnetiche come ti ha fatto correttamente notare zoomx.
Per il puntamento della parabola sul camper fai prima ad usare la bussola dello smartphone, però devi averne uno dotato di magnetometro, accelerometro e giroscopio, con l'apposita app che compensa l'inclinazione, oppure devi mettere prima esattamente in bolla lo smartphone.

In linea di massima quando sosto col camper cerco sempre di metterlo in bolla, anche per una vivibilita interna migliore, quindi il problema del magnetometro è risolto.
Questa estate ho testato la parabola, perfetta, anche dopo essermi spostato col camper, mi bastava riposizionare le coordinate del satellite che mi ero segnato e il decoder si agganciava in un lampo.