Bussola digitale con Arduino e HMC5883L
Costruiamo una bussola elettronica capace di misurare il campo magnetico terrestre, calcolare l’orientamento da 0° a 360° e indicare automaticamente il punto cardinale.
🧭 Introduzione
In questo progetto realizzeremo una bussola digitale con Arduino e sensore magnetometro HMC5883L.
Una bussola tradizionale utilizza un ago magnetizzato che si orienta rispetto al campo magnetico terrestre. Con Arduino possiamo ottenere lo stesso principio utilizzando un magnetometro elettronico.
Il sensore misura l’intensità del campo magnetico lungo tre assi:
Misura una componente del campo magnetico sul piano orizzontale.
Misura la seconda componente del campo magnetico sul piano.
Misura la componente verticale del campo magnetico.
Dai valori X e Y possiamo ricavare l’orientamento da 0° a 360°.
Il progetto mostrerà sul monitor seriale sia l’angolo della bussola sia la direzione:
- Nord
- Nord-Est
- Est
- Sud-Est
- Sud
- Sud-Ovest
- Ovest
- Nord-Ovest
🎯 Cosa imparerai
- come funziona un magnetometro digitale;
- come collegare un sensore HMC5883L ad Arduino;
- come comunicare tramite I2C;
- come leggere il campo magnetico sugli assi X, Y e Z;
- come utilizzare la funzione atan2();
- come ottenere un angolo compreso tra 0° e 360°;
- come convertire l’angolo in un punto cardinale;
- cos’è la declinazione magnetica;
- perché una bussola elettronica deve essere calibrata.
🧰 Materiale necessario
🛒 Non hai ancora i componenti?
Un kit Arduino per principianti contiene molti dei componenti necessari per realizzare questo e numerosi altri progetti.
Kit Arduino consigliato → Link di affiliazione Amazon: in qualità di Affiliato Amazon ricevo un guadagno dagli acquisti idonei, senza alcun costo aggiuntivo per te.📘 Vuoi imparare Arduino passo dopo passo?
Scopri i miei libri → Link di affiliazione Amazon: in qualità di Affiliato Amazon ricevo un guadagno dagli acquisti idonei, senza alcun costo aggiuntivo per te.🔌 Schema di collegamento
Il sensore HMC5883L comunica con Arduino attraverso il bus I2C.
| HMC5883L | Arduino UNO |
|---|---|
| VCC | 3,3 V oppure tensione prevista dal modulo |
| GND | GND |
| SDA | A4 |
| SCL | A5 |
📚 Librerie necessarie
Per il progetto utilizzeremo:
- Wire
- HMC5883L
La libreria Wire è già inclusa nell’IDE Arduino.
Per installare la libreria del magnetometro apri:
Sketch
→ Include Library
→ Manage Libraries
e cerca una libreria compatibile con il sensore HMC5883L.
⚠️ HMC5883L o QMC5883L?
Prima di scrivere il programma è utile conoscere un piccolo problema molto comune.
Molti moduli venduti online come HMC5883L possono montare in realtà un magnetometro differente, spesso appartenente alla famiglia QMC5883.
I due sensori non sono completamente compatibili a livello software.
Utilizza librerie specifiche HMC5883L.
Richiede una libreria e una gestione differenti.
💻 Codice Arduino completo
// ============================================
// Progetto #79
// Bussola digitale con HMC5883L
//
// Mostra:
// - angolo da 0° a 360°
// - punto cardinale
// ============================================
#include <Wire.h>
#include <HMC5883L.h>
#include <math.h>
HMC5883L compass;
// Declination angle.
//
// Impostare qui la declinazione magnetica
// della propria località in radianti.
//
// Per il primo test può essere lasciata a 0.
float declinationAngle = 0.0;
void setup() {
Serial.begin(9600);
Wire.begin();
// Inizializza il magnetometro
compass.initialize();
Serial.println("Bussola digitale HMC5883L");
Serial.println("-------------------------");
}
void loop() {
int16_t x;
int16_t y;
int16_t z;
// Legge il campo magnetico
compass.getHeading(&x, &y, &z);
// Calcola l'angolo
float heading = atan2((float)y, (float)x);
// Correzione della declinazione magnetica
heading += declinationAngle;
// Normalizza tra 0 e 2*PI
if (heading < 0) {
heading += 2 * PI;
}
if (heading >= 2 * PI) {
heading -= 2 * PI;
}
// Conversione da radianti a gradi
float gradi = heading * 180.0 / PI;
Serial.print("Angolo: ");
Serial.print(gradi, 1);
Serial.print("°");
Serial.print(" | Direzione: ");
// Determina uno degli 8 punti cardinali
if (gradi >= 337.5 || gradi < 22.5) {
Serial.println("NORD");
}
else if (gradi < 67.5) {
Serial.println("NORD-EST");
}
else if (gradi < 112.5) {
Serial.println("EST");
}
else if (gradi < 157.5) {
Serial.println("SUD-EST");
}
else if (gradi < 202.5) {
Serial.println("SUD");
}
else if (gradi < 247.5) {
Serial.println("SUD-OVEST");
}
else if (gradi < 292.5) {
Serial.println("OVEST");
}
else {
Serial.println("NORD-OVEST");
}
delay(300);
}
⚙️ Come funziona il programma
Il primo passaggio consiste nel leggere il campo magnetico misurato dal sensore.
compass.getHeading(&x, &y, &z);
Otteniamo tre valori:
- X
- Y
- Z
Per determinare la direzione sul piano utilizziamo principalmente X e Y.
📐 Calcolo dell’angolo
La parte fondamentale della bussola è:
float heading = atan2((float)y, (float)x);
La funzione atan2() permette di ricavare l’angolo utilizzando le due componenti del campo magnetico.
Il risultato viene inizialmente espresso in radianti.
Per trasformarlo in gradi utilizziamo:
float gradi = heading * 180.0 / PI;
Otteniamo quindi un valore compreso tra:
0° → Nord
90° → Est
180° → Sud
270° → Ovest
360° → Nord
🧭 I punti cardinali
Per rendere la bussola più leggibile dividiamo i 360° in otto settori.
| Intervallo indicativo | Direzione |
|---|---|
| 337,5° – 22,5° | Nord |
| 22,5° – 67,5° | Nord-Est |
| 67,5° – 112,5° | Est |
| 112,5° – 157,5° | Sud-Est |
| 157,5° – 202,5° | Sud |
| 202,5° – 247,5° | Sud-Ovest |
| 247,5° – 292,5° | Ovest |
| 292,5° – 337,5° | Nord-Ovest |
🌍 Nord magnetico e Nord geografico
Una bussola magnetica non punta direttamente verso il Nord geografico.
Il magnetometro segue il campo magnetico terrestre e quindi indica il Nord magnetico.
Tra Nord magnetico e Nord geografico esiste una differenza chiamata:
declinazione magnetica
Il suo valore cambia in base alla posizione geografica e può cambiare lentamente nel tempo.
Nel programma abbiamo previsto questa correzione:
float declinationAngle = 0.0;
Per un semplice esperimento può essere lasciata a zero. Per una bussola più precisa bisogna inserire la declinazione della propria zona.
🎯 Calibrazione della bussola
I magnetometri sono molto sensibili ai campi magnetici presenti nell’ambiente.
Una lettura grezza può quindi avere errori anche abbastanza evidenti.
Per questo una vera bussola digitale deve essere calibrata.
Una procedura molto semplice consiste nel ruotare lentamente il sensore in tutte le direzioni e registrare i valori minimi e massimi degli assi X e Y.
Da questi valori possiamo calcolare gli offset:
offsetX = (maxX + minX) / 2
offsetY = (maxY + minY) / 2
Gli offset possono quindi essere sottratti alle misure:
xCorretto = x - offsetX;
yCorretto = y - offsetY;
e utilizzare i valori corretti per calcolare l’heading.
🧲 Attenzione agli oggetti metallici
Una bussola elettronica può essere facilmente disturbata.
Tieni il sensore lontano da:
Contengono magneti permanenti.
Generano importanti campi magnetici.
Possono alterare completamente la misura.
Possono modificare il campo magnetico locale.
Producono un campo magnetico.
Possono introdurre disturbi.
🖥️ Risultato nel monitor seriale
Apri il monitor seriale dell’IDE Arduino impostando:
9600 baud
Ruotando lentamente il sensore potresti vedere valori simili a questi:
Angolo: 2.8° | Direzione: NORD
Angolo: 44.7° | Direzione: NORD-EST
Angolo: 91.2° | Direzione: EST
Angolo: 179.4° | Direzione: SUD
Angolo: 271.6° | Direzione: OVEST
L’angolo cambia continuamente mentre ruotiamo il modulo.
⚠️ Errori comuni
Controlla SDA, SCL, alimentazione e GND.
Esistono diverse librerie HMC5883L con API differenti.
Il modulo potrebbe essere un QMC5883L anziché un vero HMC5883L.
Può essere necessaria la calibrazione e la correzione della declinazione.
Componenti elettronici e parti metalliche possono disturbare il magnetometro.
Controlla l’orientamento fisico del modulo e l’ordine degli assi.
🔄 Varianti possibili
Mostra angolo e punto cardinale senza utilizzare il computer.
Disegna una freccia che ruota verso Nord.
Arduino può mantenere il robot rivolto verso una determinata direzione.
Combina posizione geografica e orientamento.
Calcola automaticamente minimo, massimo e offset degli assi.
Invia direzione e angolo a smartphone tramite Wi-Fi o Bluetooth.
🚀 Variante: bussola con display OLED
Una delle evoluzioni più interessanti consiste nell’aggiungere un piccolo display OLED.
Potremmo mostrare:
Direzione: NE
Angolo: 43.6°
Oppure creare una vera bussola grafica con una freccia che ruota sul display.
In questo modo Arduino diventerebbe un dispositivo completamente autonomo e non sarebbe più necessario utilizzare il monitor seriale.
🤖 Utilizzare la bussola su un robot
Il magnetometro può diventare particolarmente interessante nei progetti di robotica.
Arduino può confrontare l’angolo desiderato con quello misurato dalla bussola.
Per esempio:
Direzione desiderata = 90°
Direzione misurata = 72°
Il robot può ruotare fino a raggiungere circa:
90° → EST
Questo principio può essere utilizzato per realizzare sistemi di orientamento e navigazione.
🧠 Cosa impari con questo progetto
- come funziona una bussola digitale;
- cos’è un magnetometro;
- come misurare il campo magnetico terrestre;
- come utilizzare X, Y e Z;
- come comunicare attraverso I2C;
- come utilizzare atan2();
- come convertire radianti in gradi;
- come normalizzare un angolo tra 0° e 360°;
- come ricavare i punti cardinali;
- cos’è la declinazione magnetica;
- perché è importante calibrare un magnetometro.
✅ Cosa devi ricordare
- l’HMC5883L è un magnetometro a tre assi;
- misura il campo magnetico lungo X, Y e Z;
- Arduino comunica con il sensore tramite I2C;
- sull’Arduino UNO SDA corrisponde ad A4;
- SCL corrisponde ad A5;
- atan2(Y, X) permette di calcolare l’heading;
- l’heading viene convertito in un valore tra 0° e 360°;
- 0° corrisponde indicativamente al Nord;
- 90° all’Est;
- 180° al Sud;
- 270° all’Ovest;
- la declinazione magnetica permette di correggere la differenza tra Nord magnetico e geografico;
- la calibrazione migliora notevolmente la precisione;
- motori, magneti e masse metalliche possono falsare la lettura.

