Skip to content

Add magnetometer offset calibrator example #25

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 9, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions examples/lis3mdl_calibrator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# SPDX-FileCopyrightText: 2023 Cedar Grove Maker Studios
# SPDX-License-Identifier: MIT

"""
'lis3mdl_calibrator.py' is a simple CircuitPython calibrator example for
the LIS3MDL magnetometer. The resultant offset values can be used to
compensate for 'hard iron' effects, static magnetic fields, or to orient
the sensor with the earth's magnetic field for use as a compass.

The calibrator measures the minimum and maximum values for each axis as
the sensor is moved. The values are captured over a fixed number of
samples. A middle-of-the-range calibration offset value is calculated
and reported after all samples are collected.

The sensor needs to be tumbled during the collection period in a manner
that exercises the entire range of each axis. A series of overlapping
figure-eight patterns is recommended.

This code was derived from the '9dof_calibration.py' Blinka code
authored by Melissa LeBlanc-Williams for the 'Adafruit SensorLab -
Magnetometer Calibration' learning guide (c)2020.
"""

import time
import board
import busio
from adafruit_lis3mdl import LIS3MDL

SAMPLE_SIZE = 2000

i2c = busio.I2C(board.SCL, board.SDA)
magnetometer = LIS3MDL(i2c)

while True:
print("=" * 40)
print("LIS3MDL MAGNETOMETER CALIBRATION")
print(" Tumble the sensor through a series of")
print(" overlapping figure-eight patterns")
print(f" for approximately {SAMPLE_SIZE/100:.0f} seconds \n")

print(" countdown to start:", end=" ")
for i in range(5, -1, -1):
print(i, end=" ")
time.sleep(1)
print("\n MOVE the sensor...")
print(" > progress <")
print(" ", end="")

# Initialize the min/max values
mag_x, mag_y, mag_z = magnetometer.magnetic
min_x = max_x = mag_x
min_y = max_y = mag_y
min_z = max_z = mag_z

for i in range(SAMPLE_SIZE):
# Capture the samples and show the progress
if not i % (SAMPLE_SIZE / 20):
print("*", end="")

mag_x, mag_y, mag_z = magnetometer.magnetic

min_x = min(min_x, mag_x)
min_y = min(min_y, mag_y)
min_z = min(min_z, mag_z)

max_x = max(max_x, mag_x)
max_y = max(max_y, mag_y)
max_z = max(max_z, mag_z)

time.sleep(0.01)

# Calculate the middle of the min/max range
offset_x = (max_x + min_x) / 2
offset_y = (max_y + min_y) / 2
offset_z = (max_z + min_z) / 2

print(
f"\n\n Final Calibration: X:{offset_x:6.2f} Y:{offset_y:6.2f} Z:{offset_z:6.2f} uT\n"
)

time.sleep(5)