Skip to content

Commit 5f1f459

Browse files
authored
Merge pull request #5 from microbuilder/master
Updated lookup table to latest DS, added `read_reg`
2 parents a3be713 + e810fd9 commit 5f1f459

File tree

3 files changed

+54
-20
lines changed

3 files changed

+54
-20
lines changed

README.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,15 @@ Usage Example
6666
SENSOR = adafruit_mlx90393.MLX90393(I2C_BUS, gain=adafruit_mlx90393.GAIN_1X)
6767
6868
while True:
69-
MX, MY, MZ = SENSOR.read_data(delay=1.0, raw=False)
69+
MX, MY, MZ = SENSOR.read_data(raw=False)
7070
print("[{}]".format(time.monotonic()))
7171
print("X: {} uT".format(MX))
7272
print("Y: {} uT".format(MY))
7373
print("Z: {} uT".format(MZ))
7474
# Display the status field if an error occured, etc.
7575
if SENSOR.last_status > adafruit_mlx90393.STATUS_OK:
7676
SENSOR.display_status()
77+
time.sleep(1.0)
7778
7879
Contributing
7980
============

adafruit_mlx90393.py

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

122122

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

146-
def _transceive(self, payload, rxlen=0):
146+
147+
def _transceive(self, payload, rxlen=0, delay=0.01):
147148
"""
148149
Writes the specified 'payload' to the sensor
149150
Returns the results of the write attempt.
@@ -154,6 +155,9 @@ def _transceive(self, payload, rxlen=0):
154155
with self.i2c_device as i2c:
155156
i2c.write(payload)
156157

158+
# Insert a delay since we aren't using INTs for DRDY
159+
time.sleep(delay)
160+
157161
# Read the response (+1 to account for the mandatory status byte!)
158162
data = bytearray(rxlen+1)
159163
while True:
@@ -176,20 +180,23 @@ def _transceive(self, payload, rxlen=0):
176180
print("\t Status :", hex(data[0]))
177181
return data
178182

183+
179184
@property
180185
def last_status(self):
181186
"""
182187
Returns the last status byte received from the sensor.
183188
"""
184189
return self._status_last
185190

191+
186192
@property
187193
def gain(self):
188194
"""
189195
Gets the current gain setting for the device.
190196
"""
191197
return self._gain_current
192198

199+
193200
@gain.setter
194201
def gain(self, value):
195202
"""
@@ -200,10 +207,11 @@ def gain(self, value):
200207
if self._debug:
201208
print("\tSetting gain: {}".format(value))
202209
self._gain_current = value
203-
self._transceive(bytes([0x60,
210+
self._transceive(bytes([_CMD_WR,
204211
0x00,
205212
self._gain_current << _GAIN_SHIFT | _HALLCONF,
206-
0x00]))
213+
(_CMD_REG_CONF1 & 0x3F) << 2]))
214+
207215

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

233+
234+
def read_reg(self, reg):
235+
"""
236+
Gets the current value of the specified register.
237+
"""
238+
# Write 'value' to the specified register
239+
payload = bytes([_CMD_RR, reg << 2])
240+
with self.i2c_device as i2c:
241+
i2c.write(payload)
242+
243+
# Read the response (+1 to account for the mandatory status byte!)
244+
data = bytearray(3)
245+
with self.i2c_device as i2c:
246+
i2c.readinto(data)
247+
# Unpack data (status byte, big-endian 16-bit register value)
248+
self._status_last, val = struct.unpack(">Bh", data)
249+
if self._debug:
250+
print("\t[{}]".format(time.monotonic()))
251+
print("\t Writing :", [hex(b) for b in payload])
252+
print("\tResponse :", [hex(b) for b in data])
253+
print("\t Status :", hex(data[0]))
254+
return val
255+
256+
225257
def reset(self):
226258
"""
227259
Performs a software reset of the sensor.
@@ -232,25 +264,25 @@ def reset(self):
232264
_status_last = self._transceive(bytes([_CMD_RT]))
233265
return _status_last
234266

235-
def read_data(self, delay=0.0, raw=False):
267+
268+
def read_data(self, raw=False):
236269
"""
237270
Reads a single X/Y/Z sample from the magnetometer.
238271
"""
239272
# Set the device to single measurement mode
240273
self._transceive(bytes([_CMD_SM | _CMD_AXIS_ALL]))
241-
# Wait a bit
242-
time.sleep(delay)
243-
# Read 6 bytes back from 0x4E
274+
275+
# Read the 'XYZ' data as three signed 16-bit integers
244276
data = self._transceive(bytes([_CMD_RM | _CMD_AXIS_ALL]), 6)
245-
# Parse the data (status byte, 3 * signed 16-bit integers)
246277
self._status_last, m_x, m_y, m_z = struct.unpack(">Bhhh", data)
247278

248279
if raw:
249280
# Return the raw int values if requested
250281
return m_x, m_y, m_z
251282

252-
# Convert the units to uT based on gain and resolution
283+
# Convert the raw integer values to uT based on gain and resolution
253284
m_x *= _LSB_LOOKUP[self._gain_current][self._res_current][0]
254285
m_y *= _LSB_LOOKUP[self._gain_current][self._res_current][0]
255286
m_z *= _LSB_LOOKUP[self._gain_current][self._res_current][1]
287+
256288
return m_x, m_y, m_z

examples/adafruit_mlx90393_simpletest.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
SENSOR = adafruit_mlx90393.MLX90393(I2C_BUS, gain=adafruit_mlx90393.GAIN_1X)
99

1010
while True:
11-
MX, MY, MZ = SENSOR.read_data(delay=1.0, raw=False)
11+
MX, MY, MZ = SENSOR.read_data(raw=False)
1212
print("[{}]".format(time.monotonic()))
1313
print("X: {} uT".format(MX))
1414
print("Y: {} uT".format(MY))
1515
print("Z: {} uT".format(MZ))
1616
# Display the status field if an error occured, etc.
1717
if SENSOR.last_status > adafruit_mlx90393.STATUS_OK:
1818
SENSOR.display_status()
19+
time.sleep(1.0)

0 commit comments

Comments
 (0)