From 62f1412641c442b1936427583723187ecf62f9c8 Mon Sep 17 00:00:00 2001 From: FoamyGuy Date: Sat, 8 Feb 2020 12:06:19 -0600 Subject: [PATCH 1/5] adding compass example --- examples/lis2mdl_compass.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 examples/lis2mdl_compass.py diff --git a/examples/lis2mdl_compass.py b/examples/lis2mdl_compass.py new file mode 100644 index 0000000..6baf648 --- /dev/null +++ b/examples/lis2mdl_compass.py @@ -0,0 +1,26 @@ +""" Display compass heading data five times per second """ +import time +from math import atan2, degrees +import board +import busio +import adafruit_lis2mdl + +i2c = busio.I2C(board.SCL, board.SDA) +sensor = adafruit_lis2mdl.LIS2MDL(i2c) + + +def vector_2_degrees(x, y): + angle = degrees(atan2(y, x)) + if angle < 0: + angle += 360 + return angle + + +def get_heading(_sensor): + magnet_x, magnet_y, _ = _sensor.magnetic + return vector_2_degrees(magnet_x, magnet_y) + + +while True: + print("heading: {:.2f} degrees".format(get_heading(sensor))) + time.sleep(0.2) From 1f6bf6b3fe8a0a1e78d82eb0eea402f2c0ca7062 Mon Sep 17 00:00:00 2001 From: FoamyGuy Date: Fri, 3 Apr 2020 19:22:19 -0500 Subject: [PATCH 2/5] adding calibration script for compass example and update compass to use calibration values. --- examples/lis2mdl_calibrate.py | 35 +++++++++++++++++++++++++++++++ examples/lis2mdl_compass.py | 39 +++++++++++++++++++++++------------ 2 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 examples/lis2mdl_calibrate.py diff --git a/examples/lis2mdl_calibrate.py b/examples/lis2mdl_calibrate.py new file mode 100644 index 0000000..050da9a --- /dev/null +++ b/examples/lis2mdl_calibrate.py @@ -0,0 +1,35 @@ +""" Calibrate the magnetometer and print out the hard-iron calibrations """ + +import time +import board +import busio +import adafruit_lis2mdl + +i2c = busio.I2C(board.SCL, board.SDA) +magnetometer = adafruit_lis2mdl.LIS2MDL(i2c) + +# calibration for magnetometer X (min, max), Y and Z +hardiron_calibration = [[1000, -1000], [1000, -1000], [1000, -1000]] + +def calibrate(): + start_time = time.monotonic() + + # Update the high and low extremes + while time.monotonic() - start_time < 10.0: + magval = magnetometer.magnetic + print('Calibrating - X:{0:10.2f}, Y:{1:10.2f}, Z:{2:10.2f} uT'.format(*magval)) + for i, axis in enumerate(magval): + hardiron_calibration[i][0] = min(hardiron_calibration[i][0], axis) + hardiron_calibration[i][1] = max(hardiron_calibration[i][1], axis) + print("Calibration complete:") + print("hardiron_calibration =", hardiron_calibration) + +print("Prepare to calibrate! Twist the magnetometer around in 3D in...") +print("3...") +time.sleep(1) +print("2...") +time.sleep(1) +print("1...") +time.sleep(1) + +calibrate() diff --git a/examples/lis2mdl_compass.py b/examples/lis2mdl_compass.py index 6baf648..76cbc7e 100644 --- a/examples/lis2mdl_compass.py +++ b/examples/lis2mdl_compass.py @@ -1,6 +1,7 @@ -""" Display compass heading data five times per second """ +""" Display compass heading data from a calibrated magnetometer """ + import time -from math import atan2, degrees +import math import board import busio import adafruit_lis2mdl @@ -8,19 +9,31 @@ i2c = busio.I2C(board.SCL, board.SDA) sensor = adafruit_lis2mdl.LIS2MDL(i2c) +# You will need the calibration values from your magnetometer calibration +# these values are in uT and are in X, Y, Z order (min and max values) +hardiron_calibration = [[-61.4879, 34.4782], [-43.6714, 53.5662], [-40.7337, 52.4554]] -def vector_2_degrees(x, y): - angle = degrees(atan2(y, x)) - if angle < 0: - angle += 360 - return angle +# This will take the magnetometer values, adjust them with the calibraitons +# and return a new array with the XYZ values ranging from -100 to 100 +def normalize(magvals): + ret = [0, 0, 0] + for i, axis in enumerate(magvals): + minv, maxv = hardiron_calibration[i] + axis = min(max(minv, axis), maxv) # keep within min/max calibration + ret[i] =(axis - minv) * 200 / (maxv - minv) + -100 + return ret -def get_heading(_sensor): - magnet_x, magnet_y, _ = _sensor.magnetic - return vector_2_degrees(magnet_x, magnet_y) +while True: + magvals = sensor.magnetic + normvals = normalize(magvals) + print("magnetometer: %s -> %s" % (magvals, normvals)) + # we will only use X and Y for the compass calculations, so hold it level! + compass_heading = int(math.atan2(normvals[1], normvals[0]) * 180.0 / math.pi) + # compass_heading is between -180 and +180 since atan2 returns -pi to +pi + # this translates it to be between 0 and 360 + compass_heading += 180 -while True: - print("heading: {:.2f} degrees".format(get_heading(sensor))) - time.sleep(0.2) + print("Heading:", compass_heading) + time.sleep(0.1) \ No newline at end of file From c63d24500da281fc29e0716b2336b92f48e627eb Mon Sep 17 00:00:00 2001 From: FoamyGuy Date: Fri, 3 Apr 2020 19:49:45 -0500 Subject: [PATCH 3/5] fix pylint issues --- examples/lis2mdl_calibrate.py | 2 ++ examples/lis2mdl_compass.py | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/lis2mdl_calibrate.py b/examples/lis2mdl_calibrate.py index 050da9a..791223f 100644 --- a/examples/lis2mdl_calibrate.py +++ b/examples/lis2mdl_calibrate.py @@ -11,6 +11,7 @@ # calibration for magnetometer X (min, max), Y and Z hardiron_calibration = [[1000, -1000], [1000, -1000], [1000, -1000]] + def calibrate(): start_time = time.monotonic() @@ -24,6 +25,7 @@ def calibrate(): print("Calibration complete:") print("hardiron_calibration =", hardiron_calibration) + print("Prepare to calibrate! Twist the magnetometer around in 3D in...") print("3...") time.sleep(1) diff --git a/examples/lis2mdl_compass.py b/examples/lis2mdl_compass.py index 76cbc7e..dcfe1fa 100644 --- a/examples/lis2mdl_compass.py +++ b/examples/lis2mdl_compass.py @@ -13,11 +13,12 @@ # these values are in uT and are in X, Y, Z order (min and max values) hardiron_calibration = [[-61.4879, 34.4782], [-43.6714, 53.5662], [-40.7337, 52.4554]] + # This will take the magnetometer values, adjust them with the calibraitons # and return a new array with the XYZ values ranging from -100 to 100 -def normalize(magvals): +def normalize(_magvals): ret = [0, 0, 0] - for i, axis in enumerate(magvals): + for i, axis in enumerate(_magvals): minv, maxv = hardiron_calibration[i] axis = min(max(minv, axis), maxv) # keep within min/max calibration ret[i] =(axis - minv) * 200 / (maxv - minv) + -100 @@ -36,4 +37,4 @@ def normalize(magvals): compass_heading += 180 print("Heading:", compass_heading) - time.sleep(0.1) \ No newline at end of file + time.sleep(0.1) From 563d8587cc0bf1ff1a817f381d5872f668d13412 Mon Sep 17 00:00:00 2001 From: FoamyGuy Date: Fri, 3 Apr 2020 19:55:08 -0500 Subject: [PATCH 4/5] run black on compass and calibrate --- examples/lis2mdl_calibrate.py | 2 +- examples/lis2mdl_compass.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/lis2mdl_calibrate.py b/examples/lis2mdl_calibrate.py index 791223f..9fab73d 100644 --- a/examples/lis2mdl_calibrate.py +++ b/examples/lis2mdl_calibrate.py @@ -18,7 +18,7 @@ def calibrate(): # Update the high and low extremes while time.monotonic() - start_time < 10.0: magval = magnetometer.magnetic - print('Calibrating - X:{0:10.2f}, Y:{1:10.2f}, Z:{2:10.2f} uT'.format(*magval)) + print("Calibrating - X:{0:10.2f}, Y:{1:10.2f}, Z:{2:10.2f} uT".format(*magval)) for i, axis in enumerate(magval): hardiron_calibration[i][0] = min(hardiron_calibration[i][0], axis) hardiron_calibration[i][1] = max(hardiron_calibration[i][1], axis) diff --git a/examples/lis2mdl_compass.py b/examples/lis2mdl_compass.py index dcfe1fa..62fd716 100644 --- a/examples/lis2mdl_compass.py +++ b/examples/lis2mdl_compass.py @@ -21,7 +21,7 @@ def normalize(_magvals): for i, axis in enumerate(_magvals): minv, maxv = hardiron_calibration[i] axis = min(max(minv, axis), maxv) # keep within min/max calibration - ret[i] =(axis - minv) * 200 / (maxv - minv) + -100 + ret[i] = (axis - minv) * 200 / (maxv - minv) + -100 return ret From d23fc6ecefee4479d844e13203c13f48ff7c56ad Mon Sep 17 00:00:00 2001 From: FoamyGuy Date: Sun, 19 Apr 2020 09:48:18 -0500 Subject: [PATCH 5/5] adding explanation of how to use the calibration script --- examples/lis2mdl_compass.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/examples/lis2mdl_compass.py b/examples/lis2mdl_compass.py index 62fd716..b2b9da8 100644 --- a/examples/lis2mdl_compass.py +++ b/examples/lis2mdl_compass.py @@ -10,11 +10,23 @@ sensor = adafruit_lis2mdl.LIS2MDL(i2c) # You will need the calibration values from your magnetometer calibration -# these values are in uT and are in X, Y, Z order (min and max values) +# these values are in uT and are in X, Y, Z order (min and max values). +# +# To get these values run the lis2mdl_calibrate.py script on your device. +# Twist the device around in 3D space while it calibrates. It will print +# some calibration values like these: +# ... +# Calibrating - X: -46.62, Y: -22.33, Z: -16.94 uT +# ... +# Calibration complete: +# hardiron_calibration = [[-63.5487, 33.0313], [-40.5145, 53.8293], [-43.7153, 55.5101]] +# +# You need t copy your own value for hardiron_calibration from the output and paste it +# into this script here: hardiron_calibration = [[-61.4879, 34.4782], [-43.6714, 53.5662], [-40.7337, 52.4554]] -# This will take the magnetometer values, adjust them with the calibraitons +# This will take the magnetometer values, adjust them with the calibrations # and return a new array with the XYZ values ranging from -100 to 100 def normalize(_magvals): ret = [0, 0, 0]