A digital compass is one of the most useful additions to any navigation or robotics project. Whether you are building an autonomous drone, a GPS tracker, a robot that needs to face north, or a hiking gadget, knowing magnetic heading is fundamental. The HMC5883L is a 3-axis magnetometer IC from Honeywell that measures magnetic field strength along X, Y, and Z axes — allowing you to compute the compass heading to within ±1–2 degrees when properly calibrated.
In this guide, you will learn how the HMC5883L works, how to connect it to an Arduino over I2C, how to write the firmware from scratch, and critically — how to perform hard-iron and soft-iron calibration to get accurate heading in real-world environments full of magnetic interference.
What Is the HMC5883L Magnetometer?
The HMC5883L is a surface-mount, multi-chip module designed for low-field magnetic sensing. It uses Honeywell’s anisotropic magnetoresistance (AMR) technology — thin film permalloy elements whose electrical resistance changes proportionally to the applied magnetic field. This gives the HMC5883L outstanding sensitivity: it can detect magnetic fields as weak as 0.73 milliGauss (mG) at its highest sensitivity setting.
Key specifications:
- Axes: 3 (X, Y, Z)
- Range: ±0.88 to ±8.1 Gauss (8 selectable)
- Resolution: 5 milli-Gauss at ±1.3 Ga range
- Output rate: 0.75 to 75 Hz
- Interface: I2C (address 0x1E)
- Supply voltage: 2.16–3.6V (logic tolerant of 5V when using GY-273 module)
- Current consumption: 100μA typical in continuous mode
The HMC5883L is most commonly found on the GY-273 breakout board, which adds a 3.3V regulator and level shifters, making it compatible with 5V Arduino systems.
How Magnetometers Measure Direction
Earth’s magnetic field is a vector — it has both magnitude and direction. At any point on Earth’s surface, the horizontal component of this field points roughly toward magnetic north (with regional declination variation). The HMC5883L measures the field’s X and Y components (horizontal plane) and Z component (vertical).
When the sensor is level (flat), the heading angle from magnetic north is simply:
heading = atan2(Y_measurement, X_measurement) in radians heading_degrees = heading × (180 / π)
The Earth’s total field strength is approximately 25–65 μTesla depending on location. In India, it ranges from about 35–50 μTesla. The HMC5883L’s sensitivity is more than adequate for compass use.
HMC5883L vs QMC5883L: What Is the Difference?
Many GY-273 modules sold today use the QMC5883L chip from QST Corporation, not the original Honeywell HMC5883L. They are pin-compatible but have different I2C addresses and register maps:
| Feature | HMC5883L | QMC5883L |
|---|---|---|
| I2C Address | 0x1E | 0x0D |
| Identification Register | 0x48 at reg 0x0A | 0xFF at reg 0x0D |
| Library | Adafruit_HMC5883_U | QMC5883LCompass |
| Availability | Less common (discontinued) | Very common in current modules |
To detect which chip you have, run an I2C scanner sketch. If the address is 0x1E → HMC5883L. If 0x0D → QMC5883L. The code approach is nearly identical but use the matching library.
Components Required
- GY-273 HMC5883L or QMC5883L module
- Arduino Uno / Nano
- 4.7kΩ pull-up resistors x 2 (for SDA and SCL, usually not needed if module has them)
- Jumper wires
- Optional: MPU-6050 IMU module (for tilt-compensated compass)
- Optional: 0.96″ OLED I2C display for heading readout
Wiring HMC5883L to Arduino
| GY-273 Pin | Arduino Pin | Notes |
|---|---|---|
| VCC | 5V (or 3.3V) | GY-273 has onboard 3.3V regulator |
| GND | GND | Common ground |
| SCL | A5 (SCL) | I2C clock line |
| SDA | A4 (SDA) | I2C data line |
| DRDY | Not required | Data-ready interrupt (optional) |
On Arduino Uno, I2C uses pins A4 (SDA) and A5 (SCL). On Arduino Nano, same pins. On Arduino Mega, use pins 20 (SDA) and 21 (SCL). The GY-273 module typically includes 4.7kΩ pull-up resistors on SDA and SCL, so no external resistors are needed.
Basic Arduino Code: Reading Raw Magnetic Data
Install the Adafruit HMC5883 Unified library via Library Manager (search “HMC5883”). For QMC5883L, install “QMC5883LCompass” library instead.
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>
// Assign a unique ID to the sensor
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);
void setup() {
Serial.begin(9600);
if (!mag.begin()) {
Serial.println("HMC5883L not detected. Check wiring!");
while (1);
}
sensor_t sensor;
mag.getSensor(&sensor);
Serial.println("HMC5883L Magnetometer Ready");
}
void loop() {
sensors_event_t event;
mag.getEvent(&event);
Serial.print("X: "); Serial.print(event.magnetic.x);
Serial.print(" uT Y: "); Serial.print(event.magnetic.y);
Serial.print(" uT Z: "); Serial.print(event.magnetic.z);
Serial.println(" uT");
delay(500);
}
Calculating Compass Heading
Once you have raw X and Y magnetic field values, computing heading is straightforward. The key is handling the atan2 output range (-π to +π) and converting to a 0–360 degree compass bearing:
// After reading event.magnetic.x and event.magnetic.y:
// Apply hard-iron offset corrections (from calibration)
float x_corrected = event.magnetic.x - x_offset;
float y_corrected = event.magnetic.y - y_offset;
// Calculate heading
float heading = atan2(y_corrected, x_corrected);
// Add magnetic declination for your location
// Mumbai, India declination: approximately -0.77 degrees (negative = west)
float declinationAngle = -0.013; // in radians (-0.77 degrees)
heading += declinationAngle;
// Correct for negative values
if (heading < 0) heading += 2 * PI;
if (heading > 2 * PI) heading -= 2 * PI;
// Convert to degrees
float headingDegrees = heading * 180.0 / PI;
Serial.print("Heading: ");
Serial.print(headingDegrees, 1);
Serial.println("°");
The declination angle corrects for the difference between magnetic north (what the compass points to) and true geographic north. Without this correction, navigation calculations based on map bearings will have small but systematic errors.
Magnetometer Calibration (Hard Iron + Soft Iron)
Uncalibrated magnetometers give terrible results. The raw data is distorted by two types of errors:
Hard-Iron Distortion
Caused by permanent magnets and ferromagnetic material near the sensor (speaker magnets, motor magnets, iron chassis parts). Creates a constant offset added to every measurement. This shifts the center of the circular measurement locus away from the origin.
Fix: Collect magnetic field data while slowly rotating the sensor through all directions (a complete figure-8 or sphere). Find the min and max values for each axis. The hard-iron offset is the midpoint:
x_offset = (x_max + x_min) / 2 y_offset = (y_max + y_min) / 2 z_offset = (z_max + z_min) / 2
Soft-Iron Distortion
Caused by magnetically permeable materials (soft iron, steel) that distort the shape of the magnetic field. Turns the circular measurement locus into an ellipse. Requires a 3×3 matrix correction — more complex to compute but the “Magneto” PC tool can compute it from your calibration data automatically.
Quick Calibration Sketch
// Calibration: rotate sensor in all directions for 30 seconds
// Record min/max for each axis
float xMin = 9999, xMax = -9999;
float yMin = 9999, yMax = -9999;
void loop() {
sensors_event_t event;
mag.getEvent(&event);
if (event.magnetic.x < xMin) xMin = event.magnetic.x;
if (event.magnetic.x > xMax) xMax = event.magnetic.x;
if (event.magnetic.y < yMin) yMin = event.magnetic.y;
if (event.magnetic.y > yMax) yMax = event.magnetic.y;
Serial.print("xMin:"); Serial.print(xMin);
Serial.print(" xMax:"); Serial.print(xMax);
Serial.print(" | offset X:"); Serial.print((xMax+xMin)/2);
Serial.print(" Y:"); Serial.println((yMax+yMin)/2);
delay(100);
}
Tilt Compensation with Accelerometer
If the sensor is not perfectly level — which is always the case in a moving robot or vehicle — the heading calculation degrades. A 5-degree tilt can cause 10–15 degree heading error. Tilt compensation uses accelerometer data (from an MPU-6050 or similar IMU) to correct for this.
The tilt-compensated heading equations:
// roll and pitch from accelerometer (in radians) float roll = atan2(ay, az); float pitch = atan2(-ax, sqrt(ay*ay + az*az)); // Tilt-compensated magnetic components float Xh = Bx*cos(pitch) + Bz*sin(pitch); float Yh = Bx*sin(roll)*sin(pitch) + By*cos(roll) - Bz*sin(roll)*cos(pitch); // Tilt-compensated heading float heading = atan2(Yh, Xh);
Magnetic Declination for India
Magnetic declination varies across India. Use the NOAA World Magnetic Model calculator (ngdc.noaa.gov/geomag) for your exact location. Some approximate values for major Indian cities:
| City | Declination (2025) | In Radians |
|---|---|---|
| Mumbai | −0.77° W | −0.0134 |
| Delhi | −0.25° W | −0.0044 |
| Bengaluru | −0.92° W | −0.0161 |
| Chennai | −0.89° W | −0.0155 |
Recommended Sensors from Zbotic
BMP280 Barometric Pressure and Altitude Sensor
Pair with HMC5883L for a complete navigation sensor suite — altitude from BMP280 + heading from magnetometer gives you a 4-axis positioning system.
GY-BME280 Precision Altimeter and Atmospheric Sensor
Temperature, humidity, and pressure in one module — the perfect companion for a navigation device using HMC5883L compass data.
Benewake AD2-S-X3 Automotive-Grade LiDAR
Fuse LiDAR 3D obstacle detection with HMC5883L compass heading for a fully autonomous navigation stack — the combination used in advanced robotics platforms.
Frequently Asked Questions
Q: Why does my compass reading drift even when stationary?
Drift can come from several sources: electrical noise from nearby components (especially switching regulators and motor drivers), thermal effects on the AMR sensor, or insufficient averaging. Try increasing the oversampling rate (set config register for 8-sample average) and add a low-pass filter in software: filteredHeading = 0.9 * filteredHeading + 0.1 * rawHeading.
Q: Can I use HMC5883L on a drone or near motors?
Motor magnets and ESC switching noise are the biggest enemies of magnetometers on drones. Mount the compass on a mast as far from motors as possible (typically 10–15cm). Add ferrite bead filters on power supply lines to the magnetometer. Enable the built-in 8-sample averaging mode. Many drone flight controllers use compass calibration routines specifically because of motor interference.
Q: What is the difference between magnetic north and true north?
Magnetic north is where compass needles point — the location of Earth’s magnetic pole, which moves slightly each year. True (geographic) north is the Earth’s rotational axis — the north pole on maps. The angle between them at your location is the magnetic declination. For most of India, this difference is less than 1 degree, making it negligible for most projects, but important for precision navigation.
Q: My I2C scanner finds nothing at 0x1E or 0x0D. What is wrong?
Check your wiring carefully — SDA and SCL are often swapped by beginners. Verify that VCC is 3.3V or 5V (not floating). Check for solder bridges on the GY-273 module. Try adding external 4.7kΩ pull-up resistors from SDA and SCL to 3.3V. If still not found, the module may be faulty — test with another I2C device first.
Q: How do I combine HMC5883L data with GPS for navigation?
GPS gives position (latitude/longitude) but cannot determine which direction you are facing when stationary. The magnetometer fills this gap. In navigation code, use the compass heading to determine which way to steer toward the next GPS waypoint. The desired bearing from current GPS position to waypoint is computed with the Haversine formula, and the steering correction is the difference between desired bearing and compass heading.
Q: Is HMC5883L good enough for a professional compass application?
For hobbyist and educational projects, yes. For professional marine or aviation compasses, you need certified sensors with far higher specifications. The HMC5883L achieves ±1–2 degree accuracy after calibration — sufficient for robotics, drones, and hiking gadgets, but not for regulatory compliance in vessels or aircraft.
Find all the sensors, modules, and components you need for navigation and robotics at Zbotic. Fast shipping across India with quality-tested products.
Add comment