Skip to content

Commit c6a93e3

Browse files
authored
Merge pull request #25 from CedarGroveStudios/main
Add magnetometer offset calibrator example
2 parents 0d655cf + 6fed7c0 commit c6a93e3

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

examples/lis3mdl_calibrator.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# SPDX-FileCopyrightText: 2023 Cedar Grove Maker Studios
2+
# SPDX-License-Identifier: MIT
3+
4+
"""
5+
'lis3mdl_calibrator.py' is a simple CircuitPython calibrator example for
6+
the LIS3MDL magnetometer. The resultant offset values can be used to
7+
compensate for 'hard iron' effects, static magnetic fields, or to orient
8+
the sensor with the earth's magnetic field for use as a compass.
9+
10+
The calibrator measures the minimum and maximum values for each axis as
11+
the sensor is moved. The values are captured over a fixed number of
12+
samples. A middle-of-the-range calibration offset value is calculated
13+
and reported after all samples are collected.
14+
15+
The sensor needs to be tumbled during the collection period in a manner
16+
that exercises the entire range of each axis. A series of overlapping
17+
figure-eight patterns is recommended.
18+
19+
This code was derived from the '9dof_calibration.py' Blinka code
20+
authored by Melissa LeBlanc-Williams for the 'Adafruit SensorLab -
21+
Magnetometer Calibration' learning guide (c)2020.
22+
"""
23+
24+
import time
25+
import board
26+
import busio
27+
from adafruit_lis3mdl import LIS3MDL
28+
29+
SAMPLE_SIZE = 2000
30+
31+
i2c = busio.I2C(board.SCL, board.SDA)
32+
magnetometer = LIS3MDL(i2c)
33+
34+
while True:
35+
print("=" * 40)
36+
print("LIS3MDL MAGNETOMETER CALIBRATION")
37+
print(" Tumble the sensor through a series of")
38+
print(" overlapping figure-eight patterns")
39+
print(f" for approximately {SAMPLE_SIZE/100:.0f} seconds \n")
40+
41+
print(" countdown to start:", end=" ")
42+
for i in range(5, -1, -1):
43+
print(i, end=" ")
44+
time.sleep(1)
45+
print("\n MOVE the sensor...")
46+
print(" > progress <")
47+
print(" ", end="")
48+
49+
# Initialize the min/max values
50+
mag_x, mag_y, mag_z = magnetometer.magnetic
51+
min_x = max_x = mag_x
52+
min_y = max_y = mag_y
53+
min_z = max_z = mag_z
54+
55+
for i in range(SAMPLE_SIZE):
56+
# Capture the samples and show the progress
57+
if not i % (SAMPLE_SIZE / 20):
58+
print("*", end="")
59+
60+
mag_x, mag_y, mag_z = magnetometer.magnetic
61+
62+
min_x = min(min_x, mag_x)
63+
min_y = min(min_y, mag_y)
64+
min_z = min(min_z, mag_z)
65+
66+
max_x = max(max_x, mag_x)
67+
max_y = max(max_y, mag_y)
68+
max_z = max(max_z, mag_z)
69+
70+
time.sleep(0.01)
71+
72+
# Calculate the middle of the min/max range
73+
offset_x = (max_x + min_x) / 2
74+
offset_y = (max_y + min_y) / 2
75+
offset_z = (max_z + min_z) / 2
76+
77+
print(
78+
f"\n\n Final Calibration: X:{offset_x:6.2f} Y:{offset_y:6.2f} Z:{offset_z:6.2f} uT\n"
79+
)
80+
81+
time.sleep(5)

0 commit comments

Comments
 (0)