|
31 | 31 |
|
32 | 32 | * Author(s): Tony DiCola
|
33 | 33 | """
|
| 34 | +import ustruct |
| 35 | + |
34 | 36 | import adafruit_bus_device.i2c_device as i2c_device
|
35 | 37 |
|
36 | 38 |
|
|
73 | 75 | ACCEL_RANGE_8G = 0x02
|
74 | 76 |
|
75 | 77 |
|
| 78 | +def _twos_comp(val, bits): |
| 79 | + # Convert an unsigned integer in 2's compliment form of the specified bit |
| 80 | + # length to its signed integer value and return it. |
| 81 | + if val & (1 << (bits - 1)) != 0: |
| 82 | + return val - (1 << bits) |
| 83 | + else: |
| 84 | + return val |
| 85 | + |
| 86 | + |
76 | 87 | class FXOS8700:
|
77 | 88 |
|
78 | 89 | # Class-level buffer for reading and writing data with the sensor.
|
@@ -108,54 +119,49 @@ def __init__(self, i2c, address=_FXOS8700_ADDRESS,
|
108 | 119 |
|
109 | 120 | def _read_u8(self, address):
|
110 | 121 | # Read an 8-bit unsigned value from the specified 8-bit address.
|
111 |
| - with self._device: |
| 122 | + with self._device as i2c: |
112 | 123 | self._BUFFER[0] = address & 0xFF
|
113 |
| - self._device.write(self._BUFFER, end=1, stop=False) |
114 |
| - self._device.readinto(self._BUFFER, end=1) |
| 124 | + i2c.write(self._BUFFER, end=1, stop=False) |
| 125 | + i2c.readinto(self._BUFFER, end=1) |
115 | 126 | return self._BUFFER[0]
|
116 | 127 |
|
117 | 128 | def _write_u8(self, address, val):
|
118 | 129 | # Write an 8-bit unsigned value to the specified 8-bit address.
|
119 |
| - with self._device: |
| 130 | + with self._device as i2c: |
120 | 131 | self._BUFFER[0] = address & 0xFF
|
121 | 132 | self._BUFFER[1] = val & 0xFF
|
122 |
| - self._device.write(self._BUFFER, end=2) |
| 133 | + i2c.write(self._BUFFER, end=2) |
123 | 134 |
|
124 | 135 | def read_raw_accel_mag(self):
|
125 | 136 | """Read the raw accelerometer and magnetometer readings. Returns a
|
126 | 137 | 2-tuple of 3-tuples:
|
127 |
| - - Accelerometer X, Y, Z axis 14-bit unsigned raw values |
128 |
| - - Magnetometer X, Y, Z axis 16-bit unsigned raw values |
| 138 | + - Accelerometer X, Y, Z axis 14-bit signed raw values |
| 139 | + - Magnetometer X, Y, Z axis 16-bit signed raw values |
129 | 140 | If you want the acceleration or magnetometer values in friendly units
|
130 | 141 | consider using the accelerometer and magnetometer properties!
|
131 | 142 | """
|
132 |
| - # Read 13 bytes from the sensor. |
133 |
| - with self._device: |
134 |
| - self._BUFFER[0] = _FXOS8700_REGISTER_STATUS | 0x80 |
135 |
| - self._device.write(self._BUFFER, end=1, stop=False) |
136 |
| - self._device.readinto(self._BUFFER) |
137 |
| - # Parse out the accelerometer and magnetometer data. |
138 |
| - status = self._BUFFER[0] |
139 |
| - axhi = self._BUFFER[1] |
140 |
| - axlo = self._BUFFER[2] |
141 |
| - ayhi = self._BUFFER[3] |
142 |
| - aylo = self._BUFFER[4] |
143 |
| - azhi = self._BUFFER[5] |
144 |
| - azlo = self._BUFFER[6] |
145 |
| - mxhi = self._BUFFER[7] |
146 |
| - mxlo = self._BUFFER[8] |
147 |
| - myhi = self._BUFFER[9] |
148 |
| - mylo = self._BUFFER[10] |
149 |
| - mzhi = self._BUFFER[11] |
150 |
| - mzlo = self._BUFFER[12] |
151 |
| - # Shift values to create properly formed integers |
152 |
| - # Note, accel data is 14-bit and left-aligned, so we shift two bit right |
153 |
| - accel_raw_x = (((axhi << 8) | axlo) >> 2) & 0xFFFF |
154 |
| - accel_raw_y = (((ayhi << 8) | aylo) >> 2) & 0xFFFF |
155 |
| - accel_raw_z = (((azhi << 8) | azlo) >> 2) & 0xFFFF |
156 |
| - mag_raw_x = ((mxhi << 8) | mxlo) & 0xFFFF |
157 |
| - mag_raw_y = ((myhi << 8) | mylo) & 0xFFFF |
158 |
| - mag_raw_z = ((mzhi << 8) | mzlo) & 0xFFFF |
| 143 | + # Read accelerometer data from sensor. |
| 144 | + with self._device as i2c: |
| 145 | + self._BUFFER[0] = _FXOS8700_REGISTER_OUT_X_MSB |
| 146 | + i2c.write(self._BUFFER, end=1, stop=False) |
| 147 | + i2c.readinto(self._BUFFER, end=6) |
| 148 | + accel_raw_x = ustruct.unpack_from('>H', self._BUFFER[0:2])[0] |
| 149 | + accel_raw_y = ustruct.unpack_from('>H', self._BUFFER[2:4])[0] |
| 150 | + accel_raw_z = ustruct.unpack_from('>H', self._BUFFER[4:6])[0] |
| 151 | + # Convert accelerometer data to signed 14-bit value from 16-bit |
| 152 | + # left aligned 2's compliment value. |
| 153 | + accel_raw_x = _twos_comp(accel_raw_x >> 2, 14) |
| 154 | + accel_raw_y = _twos_comp(accel_raw_y >> 2, 14) |
| 155 | + accel_raw_z = _twos_comp(accel_raw_z >> 2, 14) |
| 156 | + # Read magnetometer data from sensor. No need to convert as this is |
| 157 | + # 16-bit signed data so struct parsing can handle it directly. |
| 158 | + with self._device as i2c: |
| 159 | + self._BUFFER[0] = _FXOS8700_REGISTER_MOUT_X_MSB |
| 160 | + i2c.write(self._BUFFER, end=1, stop=False) |
| 161 | + i2c.readinto(self._BUFFER, end=6) |
| 162 | + mag_raw_x = ustruct.unpack_from('>h', self._BUFFER[0:2])[0] |
| 163 | + mag_raw_y = ustruct.unpack_from('>h', self._BUFFER[2:4])[0] |
| 164 | + mag_raw_z = ustruct.unpack_from('>h', self._BUFFER[4:6])[0] |
159 | 165 | return ((accel_raw_x, accel_raw_y, accel_raw_z),
|
160 | 166 | (mag_raw_x, mag_raw_y, mag_raw_z))
|
161 | 167 |
|
|
0 commit comments