Skip to content

Commit 257871c

Browse files
committed
Fix to use proper unsigned int values.
1 parent 8c9a8fa commit 257871c

File tree

1 file changed

+33
-39
lines changed

1 file changed

+33
-39
lines changed

adafruit_lsm9ds1.py

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
* Author(s): Tony DiCola
3333
"""
3434
import time
35+
import ustruct
3536

3637
import adafruit_bus_device.i2c_device as i2c_device
3738
import adafruit_bus_device.spi_device as spi_device
@@ -112,6 +113,16 @@
112113
GYROSCALE_500DPS = (0b01 << 4) # +/- 500 degrees/s rotation
113114
GYROSCALE_2000DPS = (0b11 << 4) # +/- 2000 degrees/s rotation
114115

116+
117+
def _twos_comp(val, bits):
118+
# Convert an unsigned integer in 2's compliment form of the specified bit
119+
# length to its signed integer value and return it.
120+
if val & (1 << (bits - 1)) != 0:
121+
return val - (1 << bits)
122+
else:
123+
return val
124+
125+
115126
class LSM9DS1:
116127

117128
# Class-level buffer for reading and writing data with the sensor.
@@ -230,16 +241,9 @@ def read_accel_raw(self):
230241
# Read the accelerometer
231242
self._read_bytes(_XGTYPE, 0x80 | _LSM9DS1_REGISTER_OUT_X_L_XL, 6,
232243
self._BUFFER)
233-
xlo = self._BUFFER[0];
234-
xhi = self._BUFFER[1];
235-
ylo = self._BUFFER[2];
236-
yhi = self._BUFFER[3];
237-
zlo = self._BUFFER[4];
238-
zhi = self._BUFFER[5];
239-
# Shift values to create properly formed integer (low byte first)
240-
raw_x = ((xhi << 8) | xlo) & 0xFFFF
241-
raw_y = ((yhi << 8) | ylo) & 0xFFFF
242-
raw_z = ((zhi << 8) | zlo) & 0xFFFF
244+
raw_x = ustruct.unpack_from('<h', self._BUFFER[0:2])[0]
245+
raw_y = ustruct.unpack_from('<h', self._BUFFER[2:4])[0]
246+
raw_z = ustruct.unpack_from('<h', self._BUFFER[4:6])[0]
243247
return (raw_x, raw_y, raw_z)
244248

245249
@property
@@ -260,16 +264,9 @@ def read_mag_raw(self):
260264
# Read the magnetometer
261265
self._read_bytes(_MAGTYPE, 0x80 | _LSM9DS1_REGISTER_OUT_X_L_M, 6,
262266
self._BUFFER)
263-
xlo = self._BUFFER[0];
264-
xhi = self._BUFFER[1];
265-
ylo = self._BUFFER[2];
266-
yhi = self._BUFFER[3];
267-
zlo = self._BUFFER[4];
268-
zhi = self._BUFFER[5];
269-
# Shift values to create properly formed integer (low byte first)
270-
raw_x = ((xhi << 8) | xlo) & 0xFFFF
271-
raw_y = ((yhi << 8) | ylo) & 0xFFFF
272-
raw_z = ((zhi << 8) | zlo) & 0xFFFF
267+
raw_x = ustruct.unpack_from('<h', self._BUFFER[0:2])[0]
268+
raw_y = ustruct.unpack_from('<h', self._BUFFER[2:4])[0]
269+
raw_z = ustruct.unpack_from('<h', self._BUFFER[4:6])[0]
273270
return (raw_x, raw_y, raw_z)
274271

275272
@property
@@ -289,16 +286,9 @@ def read_gyro_raw(self):
289286
# Read the gyroscope
290287
self._read_bytes(_XGTYPE, 0x80 | _LSM9DS1_REGISTER_OUT_X_L_G, 6,
291288
self._BUFFER)
292-
xlo = self._BUFFER[0];
293-
xhi = self._BUFFER[1];
294-
ylo = self._BUFFER[2];
295-
yhi = self._BUFFER[3];
296-
zlo = self._BUFFER[4];
297-
zhi = self._BUFFER[5];
298-
# Shift values to create properly formed integer (low byte first)
299-
raw_x = ((xhi << 8) | xlo) & 0xFFFF
300-
raw_y = ((yhi << 8) | ylo) & 0xFFFF
301-
raw_z = ((zhi << 8) | zlo) & 0xFFFF
289+
raw_x = ustruct.unpack_from('<h', self._BUFFER[0:2])[0]
290+
raw_y = ustruct.unpack_from('<h', self._BUFFER[2:4])[0]
291+
raw_z = ustruct.unpack_from('<h', self._BUFFER[4:6])[0]
302292
return (raw_x, raw_y, raw_z)
303293

304294
@property
@@ -310,22 +300,26 @@ def gyroscope(self):
310300
return map(lambda x: x * self._gyro_dps_digit, raw)
311301

312302
def read_temp_raw(self):
313-
"""Read the raw temperature sensor value and return it as a 16-bit
314-
unsigned value. If you want the temperature in nice units you probably
303+
"""Read the raw temperature sensor value and return it as a 12-bit
304+
signed value. If you want the temperature in nice units you probably
315305
want to use the temperature property!
316306
"""
317307
# Read temp sensor
318308
self._read_bytes(_XGTYPE, 0x80 | _LSM9DS1_REGISTER_TEMP_OUT_L, 2,
319309
self._BUFFER)
320-
temp = (self._BUFFER[1] << 8) | self._BUFFER[0]
310+
temp = ((self._BUFFER[1] << 8) | self._BUFFER[0]) >> 4
311+
return _twos_comp(temp, 12)
312+
#print('Raw temp: {0} 0x{0:04X}'.format(temp))
321313
return temp
322314

323315
@property
324316
def temperature(self):
325317
"""Get the temperature of the sensor in degrees Celsius."""
326318
# This is just a guess since the starting point (21C here) isn't documented :(
319+
# See discussion from:
320+
# https://github.com/kriswiner/LSM9DS1/issues/3
327321
temp = self.read_temp_raw()
328-
temp = 21.0 + temp/8
322+
temp = 27.5 + temp/16
329323
return temp
330324

331325
def _read_u8(self, sensor_type, address):
@@ -335,7 +329,7 @@ def _read_u8(self, sensor_type, address):
335329
# MUST be implemented by subclasses!
336330
raise NotImplementedError()
337331

338-
def _read_bytes(self, sensor_type, address, count, buffer):
332+
def _read_bytes(self, sensor_type, address, count, buf):
339333
# Read a count number of bytes into buffer from the provided 8-bit
340334
# register address. The sensor_type boolean should be _MAGTYPE when
341335
# talking to the magnetometer, or _XGTYPE when talking to the accel or
@@ -368,15 +362,15 @@ def _read_u8(self, sensor_type, address):
368362
i2c.readinto(self._BUFFER, end=1)
369363
return self._BUFFER[0]
370364

371-
def _read_bytes(self, sensor_type, address, count, buffer):
365+
def _read_bytes(self, sensor_type, address, count, buf):
372366
if sensor_type == _MAGTYPE:
373367
device = self._mag_device
374368
else:
375369
device = self._xg_device
376370
with device as i2c:
377-
self._BUFFER[0] = address & 0xFF
378-
i2c.write(self._BUFFER, end=1, stop=False)
379-
i2c.readinto(self._BUFFER, end=count)
371+
buf[0] = address & 0xFF
372+
i2c.write(buf, end=1, stop=False)
373+
i2c.readinto(buf, end=count)
380374

381375
def _write_u8(self, sensor_type, address, val):
382376
if sensor_type == _MAGTYPE:

0 commit comments

Comments
 (0)