99
99
# The lookup table below allows you to convert raw sensor data to uT
100
100
# using the appropriate (gain/resolution-dependant) lsb-per-uT
101
101
# 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!
103
103
_LSB_LOOKUP = (
104
104
# 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 )),
106
106
# 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 )),
108
108
# 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 )),
110
110
# 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 )),
112
112
# 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 )),
114
114
# 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 )),
116
116
# 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 )),
118
118
# 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 ))
120
120
)
121
121
122
122
@@ -143,7 +143,8 @@ def __init__(self, i2c_bus, address=0x0C, gain=GAIN_1X, debug=False):
143
143
# Set gain to the supplied level
144
144
self .gain = self ._gain_current
145
145
146
- def _transceive (self , payload , rxlen = 0 ):
146
+
147
+ def _transceive (self , payload , rxlen = 0 , delay = 0.01 ):
147
148
"""
148
149
Writes the specified 'payload' to the sensor
149
150
Returns the results of the write attempt.
@@ -154,6 +155,9 @@ def _transceive(self, payload, rxlen=0):
154
155
with self .i2c_device as i2c :
155
156
i2c .write (payload )
156
157
158
+ # Insert a delay since we aren't using INTs for DRDY
159
+ time .sleep (delay )
160
+
157
161
# Read the response (+1 to account for the mandatory status byte!)
158
162
data = bytearray (rxlen + 1 )
159
163
while True :
@@ -176,20 +180,23 @@ def _transceive(self, payload, rxlen=0):
176
180
print ("\t Status :" , hex (data [0 ]))
177
181
return data
178
182
183
+
179
184
@property
180
185
def last_status (self ):
181
186
"""
182
187
Returns the last status byte received from the sensor.
183
188
"""
184
189
return self ._status_last
185
190
191
+
186
192
@property
187
193
def gain (self ):
188
194
"""
189
195
Gets the current gain setting for the device.
190
196
"""
191
197
return self ._gain_current
192
198
199
+
193
200
@gain .setter
194
201
def gain (self , value ):
195
202
"""
@@ -200,10 +207,11 @@ def gain(self, value):
200
207
if self ._debug :
201
208
print ("\t Setting gain: {}" .format (value ))
202
209
self ._gain_current = value
203
- self ._transceive (bytes ([0x60 ,
210
+ self ._transceive (bytes ([_CMD_WR ,
204
211
0x00 ,
205
212
self ._gain_current << _GAIN_SHIFT | _HALLCONF ,
206
- 0x00 ]))
213
+ (_CMD_REG_CONF1 & 0x3F ) << 2 ]))
214
+
207
215
208
216
def display_status (self ):
209
217
"""
@@ -222,6 +230,30 @@ def display_status(self):
222
230
print ("Reset status :" , (self ._status_last & (1 << 2 )) > 0 )
223
231
print ("Response bytes available :" , avail )
224
232
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 ("\t Response :" , [hex (b ) for b in data ])
253
+ print ("\t Status :" , hex (data [0 ]))
254
+ return val
255
+
256
+
225
257
def reset (self ):
226
258
"""
227
259
Performs a software reset of the sensor.
@@ -232,25 +264,25 @@ def reset(self):
232
264
_status_last = self ._transceive (bytes ([_CMD_RT ]))
233
265
return _status_last
234
266
235
- def read_data (self , delay = 0.0 , raw = False ):
267
+
268
+ def read_data (self , raw = False ):
236
269
"""
237
270
Reads a single X/Y/Z sample from the magnetometer.
238
271
"""
239
272
# Set the device to single measurement mode
240
273
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
244
276
data = self ._transceive (bytes ([_CMD_RM | _CMD_AXIS_ALL ]), 6 )
245
- # Parse the data (status byte, 3 * signed 16-bit integers)
246
277
self ._status_last , m_x , m_y , m_z = struct .unpack (">Bhhh" , data )
247
278
248
279
if raw :
249
280
# Return the raw int values if requested
250
281
return m_x , m_y , m_z
251
282
252
- # Convert the units to uT based on gain and resolution
283
+ # Convert the raw integer values to uT based on gain and resolution
253
284
m_x *= _LSB_LOOKUP [self ._gain_current ][self ._res_current ][0 ]
254
285
m_y *= _LSB_LOOKUP [self ._gain_current ][self ._res_current ][0 ]
255
286
m_z *= _LSB_LOOKUP [self ._gain_current ][self ._res_current ][1 ]
287
+
256
288
return m_x , m_y , m_z
0 commit comments