Skip to content

Commit

Permalink
Merge pull request #25 from CedarGroveStudios/main
Browse files Browse the repository at this point in the history
Add magnetometer offset calibrator example
  • Loading branch information
FoamyGuy authored Oct 9, 2023
2 parents 0d655cf + 6fed7c0 commit c6a93e3
Showing 1 changed file with 81 additions and 0 deletions.
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)

0 comments on commit c6a93e3

Please sign in to comment.