micropython-mpu9250
micropython-mpu9250 copied to clipboard
gy91 mpu9255 and new ak8963
Using a gy-91 which contains a mpu9255 and a different model AK8963
Changed in AK8963.init
if 0x48 != self.whoami:
to
if self.whoami not in (0x48,0x5F):
in AK8963.magnetic (was getting the same y an z values, appears you can no longer read six bytes at a time but must read 2 bytes for each of hxl, hyl, hzl)
So changed
xyz = list(self._register_three_shorts(_HXL)
to
x = self._register_short(_HXL)
y = self._register_short(_HYL)
z = self._register_short(_HZL)
xyz=[x,y,z]
and in mpu6500.init
if 0x71 != self.whoami
to
if self.whoami not in (0x71,0x73)
Still working away trying to get this working ...
You mean this? Looks quite interesting board. Let me know how it goes.
Cant seem to get this to work properly .. when I plot all the graphs for calibration the data doesnt look correct. Heres the MPU-9255 register map
Sample output and the code follows
6.53933,-1.681542,-6.165654
-42.7859,-6.165654,-12.14447
-42.41222,-12.14447,-12.14447
-6.165654,-12.14447,-12.14447
-6.165654,-24.84945,-12.14447
-3.176246,-36.05973,-12.14447
-1.681542,-39.04914,-12.14447
6.913006,-41.2912,-15.13388
-37.55444,-39.04914,-12.14447
-30.82827,-24.47578,-12.14447
-36.43341,-6.165654,-12.14447
-37.74128,-5.231464,-15.13388
-42.41222,-46.89634,-12.14447
-42.7859,-46.89634,-12.14447
-0.560514,-42.22539,-12.14447
0.0,-36.43341,-12.33131
-45.77531,-30.08092,-12.14447
3.923598,17.74961,-12.14447
-42.7859,-25.59681,-6.165654
-42.7859,-27.09151,-6.165654
-42.22539,-27.09151,-6.165654
-43.90693,-30.26776,-6.165654
-43.53325,-30.08092,-6.165654
-1.681542,-30.08092,-6.165654
-3.176246,-30.82827,-6.165654
-3.176246,-30.08092,-6.165654
-3.176246,-34.9387,-6.165654
-1.681542,-30.08092,-6.165654
-3.176246,-30.08092,-6.165654
-3.176246,-36.43341,-6.165654
-6.165654,-37.55444,-6.165654
-6.165654,-40.73068,-6.165654
-6.165654,-42.7859,-6.165654
-6.165654,-0.186838,-12.14447
-6.165654,-1.681542,-6.165654
-6.165654,-6.165654,-6.165654
-12.14447,-6.165654,-6.165654
-12.14447,-12.89182,-6.165654
-12.14447,-12.14447,-6.165654
-6.165654,-12.14447,-12.14447
-6.165654,-12.14447,-12.14447
-6.165654,-24.1021,-12.14447
-3.176246,-30.08092,-12.14447
-3.176246,-30.08092,-12.14447
-0.186838,-30.08092,-12.14447
-1.681542,-30.08092,-12.14447
-45.40164,-39.04914,-12.14447
-43.72009,-39.04914,-12.14447
-37.55444,-43.53325,-12.14447
-37.55444,-45.96215,-6.165654
-37.55444,-43.90693,-12.14447
-30.08092,-42.22539,-12.14447
-30.08092,-0.560514,-12.14447
-30.82827,-45.40164,-12.14447
-27.09151,-0.93419,-6.165654
-12.14447,-0.93419,-6.165654
-12.14447,-0.93419,-6.165654
-12.14447,-0.93419,-12.14447
-12.14447,-1.681542,-12.14447
-12.14447,-0.560514,-12.14447
-6.165654,-46.52266,-12.14447
-3.176246,-46.52266,-6.165654
-1.681542,-42.7859,-12.14447
50.81994,-39.79649,-12.14447
53.062,-39.04914,-12.14447
55.11721,-33.81768,-202.7192
-30.08092,-30.08092,-250.5497
-34.9387,-24.47578,-11.02344
62.96441,-12.14447,-6.165654
-30.82827,-12.14447,-6.165654
-30.08092,-12.14447,-12.14447
-30.08092,-25.59681,-6.165654
-39.42282,-36.05973,-6.165654
48.39104,-41.2912,-6.165654
-13.63917,-1.681542,-6.165654
-12.14447,-0.93419,-6.165654
15.32072,-47.08318,-12.14447
7.47352,-44.84112,-12.14447
# Copyright (c) 2018-2019 Mika Tuupola
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copied of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# https://github.com/tuupola/micropython-mpu9250
# https://www.akm.com/akm/en/file/datasheet/AK8963C.pdf
"""
MicroPython I2C driver for AK8963 magnetometer
"""
__version__ = "0.2.1"
# pylint: disable=import-error
import ustruct
import utime
from machine import I2C, Pin
from micropython import const
# pylint: enable=import-error
_WIA = const(0x00)
_INFO = const(0x01)
_ST1 = const(0x02)
_HXL = const(0x03)
_HXH = const(0x04)
_HYL = const(0x05)
_HYH = const(0x06)
_HZL = const(0x07)
_HZH = const(0x08)
_ST2 = const(0x09)
_CNTL1 = const(0x0a)
_ASAX = const(0x10)
_ASAY = const(0x11)
_ASAZ = const(0x12)
_MODE_POWER_DOWN = 0b00000000
MODE_SINGLE_MEASURE = 0b00000001
MODE_CONTINOUS_MEASURE_1 = 0b00000010 # 8Hz
MODE_CONTINOUS_MEASURE_2 = 0b00000110 # 100Hz
MODE_EXTERNAL_TRIGGER_MEASURE = 0b00000100
_MODE_SELF_TEST = 0b00001000
_MODE_FUSE_ROM_ACCESS = 0b00001111
OUTPUT_14_BIT = 0b00000000
OUTPUT_16_BIT = 0b00010000
_SO_14BIT = 0.6 # μT per digit when 14bit mode
_SO_16BIT = 4912/32760 # μT per digit when 16bit mode
DRDY = 0b00000001
DOR = 0b00000010
HOFL = 0b00001000
class AK8963:
"""Class which provides interface to AK8963 magnetometer."""
def __init__(
self, i2c, address=0x0c,
mode=MODE_CONTINOUS_MEASURE_2, output=OUTPUT_16_BIT,
offset=(0, 0, 0), scale=(1, 1, 1)
):
self.i2c = i2c
self.address = address
self._offset = offset
self._scale = scale
self._raw_buf_x = bytearray(2)
self._raw_buf_y = bytearray(2)
self._raw_buf_z = bytearray(2)
self._raw_xyz = [0.0,0.0,0.0]
#if 0x48 != self.whoami:
whoami = self.whoami
if whoami not in (0x48,0x5F,0x7F):
raise RuntimeError("AK8963 not found in I2C bus - found 0x%02X." % whoami)
# Sensitivity adjustement values
self._register_char(_CNTL1, _MODE_FUSE_ROM_ACCESS)
asax = self._register_char(_ASAX)
asay = self._register_char(_ASAY)
asaz = self._register_char(_ASAZ)
self._register_char(_CNTL1, _MODE_POWER_DOWN)
# Should wait atleast 100us before next mode
self._adjustement = (
(0.5 * (asax - 128)) / 128 + 1,
(0.5 * (asay - 128)) / 128 + 1,
(0.5 * (asaz - 128)) / 128 + 1
)
utime.sleep_us(100)
# Power on
self._register_char(_CNTL1, (mode | output))
if output is OUTPUT_16_BIT:
self._so = _SO_16BIT
else:
self._so = _SO_14BIT
@property
def magnetic(self):
"""
X, Y, Z axis micro-Tesla (uT) as floats.
"""
while not self.data_is_ready:
utime.sleep_ms(10)
pass
self.i2c.readfrom_mem_into(self.address, _HXL, self._raw_buf_x)
self.i2c.readfrom_mem_into(self.address, _HYL, self._raw_buf_y)
self.i2c.readfrom_mem_into(self.address, _HZL, self._raw_buf_z)
if not self.magnetic_sensor_overflow:
self._raw_xyz[0] = self._read_int(self._raw_buf_x)
self._raw_xyz[1] = self._read_int(self._raw_buf_y)
self._raw_xyz[2] = self._read_int(self._raw_buf_z)
xyz=self._raw_xyz
#self._register_char(_ST2) # Enable updating readings again
# Apply factory axial sensitivy adjustements
xyz[0] *= self._adjustement[0]
xyz[1] *= self._adjustement[1]
xyz[2] *= self._adjustement[2]
# Apply output scale determined in constructor
so = self._so
xyz[0] *= so
xyz[1] *= so
xyz[2] *= so
# Apply hard iron ie. offset bias from calibration
xyz[0] -= self._offset[0]
xyz[1] -= self._offset[1]
xyz[2] -= self._offset[2]
# Apply soft iron ie. scale bias from calibration
xyz[0] *= self._scale[0]
xyz[1] *= self._scale[1]
xyz[2] *= self._scale[2]
return tuple(xyz)
@property
def adjustement(self):
return self._adjustement
@property
def whoami(self):
""" Value of the whoami register. """
return self._register_char(_WIA)
@property
def data_is_ready(self):
return bool(self._register_char(_ST1) & DRDY)
@property
def data_overrun(self):
return bool(self._register_char(_ST1) & DOR)
@property
def magnetic_sensor_overflow(self):
return bool(self._register_char(_ST2) & HOFL)
def calibrate(self, count=256, delay=200):
self._offset = (0, 0, 0)
self._scale = (1, 1, 1)
reading = self.magnetic
minx = maxx = reading[0]
miny = maxy = reading[1]
minz = maxz = reading[2]
while count:
utime.sleep_ms(delay)
reading = self.magnetic
minx = min(minx, reading[0])
maxx = max(maxx, reading[0])
miny = min(miny, reading[1])
maxy = max(maxy, reading[1])
minz = min(minz, reading[2])
maxz = max(maxz, reading[2])
count -= 1
# Hard iron correction
offset_x = (maxx + minx) / 2
offset_y = (maxy + miny) / 2
offset_z = (maxz + minz) / 2
self._offset = (offset_x, offset_y, offset_z)
# Soft iron correction
avg_delta_x = (maxx - minx) / 2
avg_delta_y = (maxy - miny) / 2
avg_delta_z = (maxz - minz) / 2
avg_delta = (avg_delta_x + avg_delta_y + avg_delta_z) / 3
scale_x = avg_delta / avg_delta_x
scale_y = avg_delta / avg_delta_y
scale_z = avg_delta / avg_delta_z
self._scale = (scale_x, scale_y, scale_z)
return self._offset, self._scale
def _read_int(self, buf=bytearray(2)):
value = (buf[1] <<8) + buf[0]
if (value >= 0x8000):
return -((65535 - value) + 1)
else:
return value
def _register_short(self, register, value=None, buf=bytearray(2)):
if value is None:
self.i2c.readfrom_mem_into(self.address, register, buf)
return ustruct.unpack("<h", buf)[0]
ustruct.pack_into("<h", buf, 0, value)
return self.i2c.writeto_mem(self.address, register, buf)
def _register_three_shorts(self, register, buf=bytearray(6)):
self.i2c.readfrom_mem_into(self.address, register, buf)
return ustruct.unpack("<hhh", buf)
def _register_char(self, register, value=None, buf=bytearray(1)):
if value is None:
self.i2c.readfrom_mem_into(self.address, register, buf)
return buf[0]
ustruct.pack_into("<b", buf, 0, value)
return self.i2c.writeto_mem(self.address, register, buf)
def __enter__(self):
return self
def __exit__(self, exception_type, exception_value, traceback):
pass
Getting better data using i2c = I2C(scl=Pin(21), sda=Pin(22), freq=100000)
. There appears to be an issue with the default freq on an ESP32 communicating with the GY-91. Might be a timing issues?
@hortovanyi Did you get this to work? I have been looking into using th GY-91 with a LoPy4. The LoPy is running µ-Python and getting the IMU to work has but me in some deep waters i have to admit, so I was looking for something to a library or driver for the GY-91
seems like a common issue.. https://hackaday.io/project/28491-quick-draw-motion-tracking/log/71828-a-spark-a-doh-a-surprise-and-data-sheets
working fine for me using MicroPython v1.13-186-g5a7027915 on 2020-11-25; ESP module with ESP8266
:
- code changed as @hortovanyi posted here
-
freq=100000
.
ℹ️ the gy-91
datasheet states 100 and 400khz as the only rates supported.
some seconds running:
acc (1.5275, -0.462081, 10.6111)
gyr (0.277387, 3.5177, -0.50388)
mag (10.4332, 20.6402, 1.39219)
tmp 31.0009
--
acc (-0.390255, 0.0766144, 9.69173)
gyr (0.0141225, 0.00106585, -0.0150551)
mag (12.232, 27.8824, 2.78437)
tmp 30.7134
--
acc (-0.301669, 0.0861912, 9.66539)
gyr (0.0222496, -0.0226493, -0.0159877)
mag (12.4119, 27.3392, 1.21816)
tmp 30.5217
--
acc (-0.332794, 0.100556, 9.742)
gyr (0.0209173, -0.0434334, -0.0190521)
mag (11.8723, 27.1582, 2.43633)
tmp 30.5217
--
acc (-0.28491, 0.0742202, 9.61511)
gyr (0.0182527, -0.013856, -0.0123905)
mag (13.3113, 26.434, 3.13242)
tmp 30.6654
--
acc (-0.299275, 0.083797, 9.72046)
gyr (0.0199847, -0.0110582, -0.0163874)
mag (13.3113, 26.0719, 3.13242)
tmp 30.5217
--
acc (-0.299275, 0.047884, 9.64145)
gyr (0.0225161, 0.0214502, -0.0151884)
mag (12.232, 26.434, 2.08828)
tmp 30.0904
--
Any luck with this?
I'm getting similar results, but it doesn't seem right (only the temp seems to be correct)
acce (-0.02154782, -0.02154782, 9.289502)
gyro (-0.05249311, 0.01985146, -0.02264931)
magn (-12.14364, -9.666079, 7.323508)
temp 27.6463
acce (-0.01197101, -0.06943185, 9.315839)
gyro (-0.05342574, 0.02251608, -0.01891884)
magn (-11.57441, -9.490331, 6.794097)
temp 27.79007
acce (-0.01197101, -0.05027823, 9.344569)
gyro (-0.05449158, 0.01998469, -0.02118377)
magn (-11.76415, -10.72056, 5.911747)
temp 27.6463
acce (-0.01197101, -0.02394202, 9.358934)
gyro (-0.05315928, 0.02451455, -0.02251608)
magn (-11.19492, -9.490331, 6.794097)
temp 27.79007
Cant seem to get this to work properly .. when I plot all the graphs for calibration the data doesnt look correct. Heres the MPU-9255 register map
Sample output and the code follows
6.53933,-1.681542,-6.165654 -42.7859,-6.165654,-12.14447 -42.41222,-12.14447,-12.14447 -6.165654,-12.14447,-12.14447 -6.165654,-24.84945,-12.14447 -3.176246,-36.05973,-12.14447 -1.681542,-39.04914,-12.14447 6.913006,-41.2912,-15.13388 -37.55444,-39.04914,-12.14447 -30.82827,-24.47578,-12.14447 -36.43341,-6.165654,-12.14447 -37.74128,-5.231464,-15.13388 -42.41222,-46.89634,-12.14447 -42.7859,-46.89634,-12.14447 -0.560514,-42.22539,-12.14447 0.0,-36.43341,-12.33131 -45.77531,-30.08092,-12.14447 3.923598,17.74961,-12.14447 -42.7859,-25.59681,-6.165654 -42.7859,-27.09151,-6.165654 -42.22539,-27.09151,-6.165654 -43.90693,-30.26776,-6.165654 -43.53325,-30.08092,-6.165654 -1.681542,-30.08092,-6.165654 -3.176246,-30.82827,-6.165654 -3.176246,-30.08092,-6.165654 -3.176246,-34.9387,-6.165654 -1.681542,-30.08092,-6.165654 -3.176246,-30.08092,-6.165654 -3.176246,-36.43341,-6.165654 -6.165654,-37.55444,-6.165654 -6.165654,-40.73068,-6.165654 -6.165654,-42.7859,-6.165654 -6.165654,-0.186838,-12.14447 -6.165654,-1.681542,-6.165654 -6.165654,-6.165654,-6.165654 -12.14447,-6.165654,-6.165654 -12.14447,-12.89182,-6.165654 -12.14447,-12.14447,-6.165654 -6.165654,-12.14447,-12.14447 -6.165654,-12.14447,-12.14447 -6.165654,-24.1021,-12.14447 -3.176246,-30.08092,-12.14447 -3.176246,-30.08092,-12.14447 -0.186838,-30.08092,-12.14447 -1.681542,-30.08092,-12.14447 -45.40164,-39.04914,-12.14447 -43.72009,-39.04914,-12.14447 -37.55444,-43.53325,-12.14447 -37.55444,-45.96215,-6.165654 -37.55444,-43.90693,-12.14447 -30.08092,-42.22539,-12.14447 -30.08092,-0.560514,-12.14447 -30.82827,-45.40164,-12.14447 -27.09151,-0.93419,-6.165654 -12.14447,-0.93419,-6.165654 -12.14447,-0.93419,-6.165654 -12.14447,-0.93419,-12.14447 -12.14447,-1.681542,-12.14447 -12.14447,-0.560514,-12.14447 -6.165654,-46.52266,-12.14447 -3.176246,-46.52266,-6.165654 -1.681542,-42.7859,-12.14447 50.81994,-39.79649,-12.14447 53.062,-39.04914,-12.14447 55.11721,-33.81768,-202.7192 -30.08092,-30.08092,-250.5497 -34.9387,-24.47578,-11.02344 62.96441,-12.14447,-6.165654 -30.82827,-12.14447,-6.165654 -30.08092,-12.14447,-12.14447 -30.08092,-25.59681,-6.165654 -39.42282,-36.05973,-6.165654 48.39104,-41.2912,-6.165654 -13.63917,-1.681542,-6.165654 -12.14447,-0.93419,-6.165654 15.32072,-47.08318,-12.14447 7.47352,-44.84112,-12.14447
# Copyright (c) 2018-2019 Mika Tuupola # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copied of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # https://github.com/tuupola/micropython-mpu9250 # https://www.akm.com/akm/en/file/datasheet/AK8963C.pdf """ MicroPython I2C driver for AK8963 magnetometer """ __version__ = "0.2.1" # pylint: disable=import-error import ustruct import utime from machine import I2C, Pin from micropython import const # pylint: enable=import-error _WIA = const(0x00) _INFO = const(0x01) _ST1 = const(0x02) _HXL = const(0x03) _HXH = const(0x04) _HYL = const(0x05) _HYH = const(0x06) _HZL = const(0x07) _HZH = const(0x08) _ST2 = const(0x09) _CNTL1 = const(0x0a) _ASAX = const(0x10) _ASAY = const(0x11) _ASAZ = const(0x12) _MODE_POWER_DOWN = 0b00000000 MODE_SINGLE_MEASURE = 0b00000001 MODE_CONTINOUS_MEASURE_1 = 0b00000010 # 8Hz MODE_CONTINOUS_MEASURE_2 = 0b00000110 # 100Hz MODE_EXTERNAL_TRIGGER_MEASURE = 0b00000100 _MODE_SELF_TEST = 0b00001000 _MODE_FUSE_ROM_ACCESS = 0b00001111 OUTPUT_14_BIT = 0b00000000 OUTPUT_16_BIT = 0b00010000 _SO_14BIT = 0.6 # μT per digit when 14bit mode _SO_16BIT = 4912/32760 # μT per digit when 16bit mode DRDY = 0b00000001 DOR = 0b00000010 HOFL = 0b00001000 class AK8963: """Class which provides interface to AK8963 magnetometer.""" def __init__( self, i2c, address=0x0c, mode=MODE_CONTINOUS_MEASURE_2, output=OUTPUT_16_BIT, offset=(0, 0, 0), scale=(1, 1, 1) ): self.i2c = i2c self.address = address self._offset = offset self._scale = scale self._raw_buf_x = bytearray(2) self._raw_buf_y = bytearray(2) self._raw_buf_z = bytearray(2) self._raw_xyz = [0.0,0.0,0.0] #if 0x48 != self.whoami: whoami = self.whoami if whoami not in (0x48,0x5F,0x7F): raise RuntimeError("AK8963 not found in I2C bus - found 0x%02X." % whoami) # Sensitivity adjustement values self._register_char(_CNTL1, _MODE_FUSE_ROM_ACCESS) asax = self._register_char(_ASAX) asay = self._register_char(_ASAY) asaz = self._register_char(_ASAZ) self._register_char(_CNTL1, _MODE_POWER_DOWN) # Should wait atleast 100us before next mode self._adjustement = ( (0.5 * (asax - 128)) / 128 + 1, (0.5 * (asay - 128)) / 128 + 1, (0.5 * (asaz - 128)) / 128 + 1 ) utime.sleep_us(100) # Power on self._register_char(_CNTL1, (mode | output)) if output is OUTPUT_16_BIT: self._so = _SO_16BIT else: self._so = _SO_14BIT @property def magnetic(self): """ X, Y, Z axis micro-Tesla (uT) as floats. """ while not self.data_is_ready: utime.sleep_ms(10) pass self.i2c.readfrom_mem_into(self.address, _HXL, self._raw_buf_x) self.i2c.readfrom_mem_into(self.address, _HYL, self._raw_buf_y) self.i2c.readfrom_mem_into(self.address, _HZL, self._raw_buf_z) if not self.magnetic_sensor_overflow: self._raw_xyz[0] = self._read_int(self._raw_buf_x) self._raw_xyz[1] = self._read_int(self._raw_buf_y) self._raw_xyz[2] = self._read_int(self._raw_buf_z) xyz=self._raw_xyz #self._register_char(_ST2) # Enable updating readings again # Apply factory axial sensitivy adjustements xyz[0] *= self._adjustement[0] xyz[1] *= self._adjustement[1] xyz[2] *= self._adjustement[2] # Apply output scale determined in constructor so = self._so xyz[0] *= so xyz[1] *= so xyz[2] *= so # Apply hard iron ie. offset bias from calibration xyz[0] -= self._offset[0] xyz[1] -= self._offset[1] xyz[2] -= self._offset[2] # Apply soft iron ie. scale bias from calibration xyz[0] *= self._scale[0] xyz[1] *= self._scale[1] xyz[2] *= self._scale[2] return tuple(xyz) @property def adjustement(self): return self._adjustement @property def whoami(self): """ Value of the whoami register. """ return self._register_char(_WIA) @property def data_is_ready(self): return bool(self._register_char(_ST1) & DRDY) @property def data_overrun(self): return bool(self._register_char(_ST1) & DOR) @property def magnetic_sensor_overflow(self): return bool(self._register_char(_ST2) & HOFL) def calibrate(self, count=256, delay=200): self._offset = (0, 0, 0) self._scale = (1, 1, 1) reading = self.magnetic minx = maxx = reading[0] miny = maxy = reading[1] minz = maxz = reading[2] while count: utime.sleep_ms(delay) reading = self.magnetic minx = min(minx, reading[0]) maxx = max(maxx, reading[0]) miny = min(miny, reading[1]) maxy = max(maxy, reading[1]) minz = min(minz, reading[2]) maxz = max(maxz, reading[2]) count -= 1 # Hard iron correction offset_x = (maxx + minx) / 2 offset_y = (maxy + miny) / 2 offset_z = (maxz + minz) / 2 self._offset = (offset_x, offset_y, offset_z) # Soft iron correction avg_delta_x = (maxx - minx) / 2 avg_delta_y = (maxy - miny) / 2 avg_delta_z = (maxz - minz) / 2 avg_delta = (avg_delta_x + avg_delta_y + avg_delta_z) / 3 scale_x = avg_delta / avg_delta_x scale_y = avg_delta / avg_delta_y scale_z = avg_delta / avg_delta_z self._scale = (scale_x, scale_y, scale_z) return self._offset, self._scale def _read_int(self, buf=bytearray(2)): value = (buf[1] <<8) + buf[0] if (value >= 0x8000): return -((65535 - value) + 1) else: return value def _register_short(self, register, value=None, buf=bytearray(2)): if value is None: self.i2c.readfrom_mem_into(self.address, register, buf) return ustruct.unpack("<h", buf)[0] ustruct.pack_into("<h", buf, 0, value) return self.i2c.writeto_mem(self.address, register, buf) def _register_three_shorts(self, register, buf=bytearray(6)): self.i2c.readfrom_mem_into(self.address, register, buf) return ustruct.unpack("<hhh", buf) def _register_char(self, register, value=None, buf=bytearray(1)): if value is None: self.i2c.readfrom_mem_into(self.address, register, buf) return buf[0] ustruct.pack_into("<b", buf, 0, value) return self.i2c.writeto_mem(self.address, register, buf) def __enter__(self): return self def __exit__(self, exception_type, exception_value, traceback): pass
Where did you change?I can use this code!