Skip to content
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

Updated lookup table to latest DS, added read_reg #5

Merged
merged 2 commits into from
Jan 21, 2019
Merged
Show file tree
Hide file tree
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
3 changes: 2 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,15 @@ Usage Example
SENSOR = adafruit_mlx90393.MLX90393(I2C_BUS, gain=adafruit_mlx90393.GAIN_1X)

while True:
MX, MY, MZ = SENSOR.read_data(delay=1.0, raw=False)
MX, MY, MZ = SENSOR.read_data(raw=False)
print("[{}]".format(time.monotonic()))
print("X: {} uT".format(MX))
print("Y: {} uT".format(MY))
print("Z: {} uT".format(MZ))
# Display the status field if an error occured, etc.
if SENSOR.last_status > adafruit_mlx90393.STATUS_OK:
SENSOR.display_status()
time.sleep(1.0)

Contributing
============
Expand Down
68 changes: 50 additions & 18 deletions adafruit_mlx90393.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,24 +99,24 @@
# The lookup table below allows you to convert raw sensor data to uT
# using the appropriate (gain/resolution-dependant) lsb-per-uT
# coefficient below. Note that the z axis has a different coefficient
# than the x and y axis.
# than the x and y axis. Assumes HALLCONF = 0x0C!
_LSB_LOOKUP = (
# 5x gain: res0(xy)(z), res1(xy)(z), res2(xy)(z), res3(xy)(z)
((0.805, 1.468), (1.610, 2.936), (3.220, 5.872), (6.440, 11.744)),
((0.751, 1.210), (1.502, 2.420), (3.004, 4.840), (6.009, 9.680)),
# 4x gain: res0(xy)(z), res1(xy)(z), res2(xy)(z), res3(xy)(z)
((0.644, 1.174), (1.288, 2.349), (2.576, 4.698), (5.152, 9.395)),
((0.601, 0.968), (1.202, 1.936), (2.403, 3.872), (4.840, 7.744)),
# 3x gain: res0(xy)(z), res1(xy)(z), res2(xy)(z), res3(xy)(z)
((0.483, 0.881), (0.966, 1.762), (1.932, 3.523), (3.864, 7.046)),
((0.451, 0.726), (0.901, 1.452), (1.803, 2.904), (3.605, 5.808)),
# 2.5x gain: res0(xy)(z), res1(xy)(z), res2(xy)(z), res3(xy)(z)
((0.403, 0.734), (0.805, 1.468), (1.610, 2.936), (3.220, 5.872)),
((0.376, 0.605), (0.751, 1.210), (1.502, 2.420), (3.004, 4.840)),
# 2x gain: res0(xy)(z), res1(xy)(z), res2(xy)(z), res3(xy)(z)
((0.322, 0.587), (0.644, 1.174), (1.288, 2.349), (2.576, 4.698)),
((0.300, 0.484), (0.601, 0.968), (1.202, 1.936), (2.403, 3.872)),
# 1.667x gain: res0(xy)(z), res1(xy)(z), res2(xy)(z), res3(xy)(z)
((0.268, 0.489), (0.537, 0.979), (1.073, 1.957), (2.147, 3.915)),
((0.250, 0.403), (0.501, 0.807), (1.001, 1.613), (2.003, 3.227)),
# 1.333x gain: res0(xy)(z), res1(xy)(z), res2(xy)(z), res3(xy)(z)
((0.215, 0.391), (0.429, 0.783), (0.859, 1.566), (1.717, 3.132)),
((0.200, 0.323), (0.401, 0.645), (0.801, 1.291), (1.602, 2.581)),
# 1x gain: res0(xy)(z), res1(xy)(z), res2(xy)(z), res3(xy)(z)
((0.161, 0.294), (0.322, 0.587), (0.644, 1.174), (1.288, 2.349))
((0.150, 0.242), (0.300, 0.484), (0.601, 0.968), (1.202, 1.936))
)


Expand All @@ -143,7 +143,8 @@ def __init__(self, i2c_bus, address=0x0C, gain=GAIN_1X, debug=False):
# Set gain to the supplied level
self.gain = self._gain_current

def _transceive(self, payload, rxlen=0):

def _transceive(self, payload, rxlen=0, delay=0.01):
"""
Writes the specified 'payload' to the sensor
Returns the results of the write attempt.
Expand All @@ -154,6 +155,9 @@ def _transceive(self, payload, rxlen=0):
with self.i2c_device as i2c:
i2c.write(payload)

# Insert a delay since we aren't using INTs for DRDY
time.sleep(delay)

# Read the response (+1 to account for the mandatory status byte!)
data = bytearray(rxlen+1)
while True:
Expand All @@ -176,20 +180,23 @@ def _transceive(self, payload, rxlen=0):
print("\t Status :", hex(data[0]))
return data


@property
def last_status(self):
"""
Returns the last status byte received from the sensor.
"""
return self._status_last


@property
def gain(self):
"""
Gets the current gain setting for the device.
"""
return self._gain_current


@gain.setter
def gain(self, value):
"""
Expand All @@ -200,10 +207,11 @@ def gain(self, value):
if self._debug:
print("\tSetting gain: {}".format(value))
self._gain_current = value
self._transceive(bytes([0x60,
self._transceive(bytes([_CMD_WR,
0x00,
self._gain_current << _GAIN_SHIFT | _HALLCONF,
0x00]))
(_CMD_REG_CONF1 & 0x3F) << 2]))


def display_status(self):
"""
Expand All @@ -222,6 +230,30 @@ def display_status(self):
print("Reset status :", (self._status_last & (1 << 2)) > 0)
print("Response bytes available :", avail)


def read_reg(self, reg):
"""
Gets the current value of the specified register.
"""
# Write 'value' to the specified register
payload = bytes([_CMD_RR, reg << 2])
with self.i2c_device as i2c:
i2c.write(payload)

# Read the response (+1 to account for the mandatory status byte!)
data = bytearray(3)
with self.i2c_device as i2c:
i2c.readinto(data)
# Unpack data (status byte, big-endian 16-bit register value)
self._status_last, val = struct.unpack(">Bh", data)
if self._debug:
print("\t[{}]".format(time.monotonic()))
print("\t Writing :", [hex(b) for b in payload])
print("\tResponse :", [hex(b) for b in data])
print("\t Status :", hex(data[0]))
return val


def reset(self):
"""
Performs a software reset of the sensor.
Expand All @@ -232,25 +264,25 @@ def reset(self):
_status_last = self._transceive(bytes([_CMD_RT]))
return _status_last

def read_data(self, delay=0.0, raw=False):

def read_data(self, raw=False):
"""
Reads a single X/Y/Z sample from the magnetometer.
"""
# Set the device to single measurement mode
self._transceive(bytes([_CMD_SM | _CMD_AXIS_ALL]))
# Wait a bit
time.sleep(delay)
# Read 6 bytes back from 0x4E

# Read the 'XYZ' data as three signed 16-bit integers
data = self._transceive(bytes([_CMD_RM | _CMD_AXIS_ALL]), 6)
# Parse the data (status byte, 3 * signed 16-bit integers)
self._status_last, m_x, m_y, m_z = struct.unpack(">Bhhh", data)

if raw:
# Return the raw int values if requested
return m_x, m_y, m_z

# Convert the units to uT based on gain and resolution
# Convert the raw integer values to uT based on gain and resolution
m_x *= _LSB_LOOKUP[self._gain_current][self._res_current][0]
m_y *= _LSB_LOOKUP[self._gain_current][self._res_current][0]
m_z *= _LSB_LOOKUP[self._gain_current][self._res_current][1]

return m_x, m_y, m_z
3 changes: 2 additions & 1 deletion examples/adafruit_mlx90393_simpletest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
SENSOR = adafruit_mlx90393.MLX90393(I2C_BUS, gain=adafruit_mlx90393.GAIN_1X)

while True:
MX, MY, MZ = SENSOR.read_data(delay=1.0, raw=False)
MX, MY, MZ = SENSOR.read_data(raw=False)
print("[{}]".format(time.monotonic()))
print("X: {} uT".format(MX))
print("Y: {} uT".format(MY))
print("Z: {} uT".format(MZ))
# Display the status field if an error occured, etc.
if SENSOR.last_status > adafruit_mlx90393.STATUS_OK:
SENSOR.display_status()
time.sleep(1.0)