Progetto #79 • Sensori e orientamento

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.

Difficoltà ★★☆☆☆ Facile
Tempo 30–45 minuti
Concetti Magnetometro • I2C • Heading

🧭 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:

Asse X
Misura una componente del campo magnetico sul piano orizzontale.
Asse Y
Misura la seconda componente del campo magnetico sul piano.
Asse Z
Misura la componente verticale del campo magnetico.
Heading
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
Concetto chiave: il magnetometro non indica direttamente “Nord”. Misura il campo magnetico sugli assi X, Y e Z; è Arduino a calcolare l’angolo utilizzando questi valori.

🎯 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

1× Arduino UNO o compatibile
1× modulo magnetometro HMC5883L
1× breadboard
Cavi jumper

🛒 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
Collegamento bussola HMC5883L ad Arduino UNO
Attenzione all’alimentazione: il chip HMC5883L utilizza tensioni basse. Alcune schedine breakout integrano regolatore di tensione e circuiti di adattamento e possono essere alimentate a 5 V, mentre altre no. Controlla sempre il modello esatto del modulo prima di collegare VCC.

📚 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.

Nota importante: esistono diverse librerie chiamate HMC5883L e le funzioni possono cambiare. Il codice seguente utilizza una libreria compatibile con initialize() e getHeading().

⚠️ 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.

HMC5883L
Utilizza librerie specifiche HMC5883L.
QMC5883L
Richiede una libreria e una gestione differenti.
Se Arduino non rileva il sensore anche se i collegamenti sono corretti, una delle prime verifiche da fare è capire quale chip sia realmente presente sul modulo.

💻 Codice Arduino completo

Progetto #79 — Bussola digitale HMC5883L
// ============================================
// 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.

Concetto chiave: senza correzione la bussola indica essenzialmente il Nord magnetico; applicando la declinazione possiamo avvicinare la lettura al Nord geografico.

🎯 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.

Per questa prima versione manteniamo il codice semplice. La calibrazione completa può diventare una variante avanzata del progetto.

🧲 Attenzione agli oggetti metallici

Una bussola elettronica può essere facilmente disturbata.

Tieni il sensore lontano da:

🔊 Altoparlanti
Contengono magneti permanenti.
⚙️ Motori
Generano importanti campi magnetici.
🧲 Magneti
Possono alterare completamente la misura.
🔩 Masse metalliche
Possono modificare il campo magnetico locale.
🔌 Cavi con molta corrente
Producono un campo magnetico.
🔋 Alimentatori
Possono introdurre disturbi.
Se provi la bussola accanto a un motore, un magnete o un altoparlante, le indicazioni possono diventare completamente errate anche se il programma funziona perfettamente.

🖥️ 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

Il sensore non viene rilevato
Controlla SDA, SCL, alimentazione e GND.
La libreria non compila
Esistono diverse librerie HMC5883L con API differenti.
La direzione è completamente errata
Il modulo potrebbe essere un QMC5883L anziché un vero HMC5883L.
Nord spostato di diversi gradi
Può essere necessaria la calibrazione e la correzione della declinazione.
Valori che cambiano vicino al PC
Componenti elettronici e parti metalliche possono disturbare il magnetometro.
Est e Ovest sembrano invertiti
Controlla l’orientamento fisico del modulo e l’ordine degli assi.

🔄 Varianti possibili

📟 Bussola con display OLED
Mostra angolo e punto cardinale senza utilizzare il computer.
🧭 Bussola grafica
Disegna una freccia che ruota verso Nord.
🤖 Robot orientabile
Arduino può mantenere il robot rivolto verso una determinata direzione.
🛰️ GPS + bussola
Combina posizione geografica e orientamento.
🎯 Bussola calibrata
Calcola automaticamente minimo, massimo e offset degli assi.
📡 Bussola con ESP32
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.