|
| 1 | +from micropython import const # NOQA |
| 2 | +import imu_sensor_framework # NOQA |
| 3 | + |
| 4 | + |
| 5 | +_VERSION_REG = const(0x0) |
| 6 | +_REVISION_REG = const(0x1) |
| 7 | + |
| 8 | +_TIME_REG = const(0x30) |
| 9 | +_TEMP_REG = const(0x33) |
| 10 | +_ACCEL_REG = const(0x35) |
| 11 | +_GYRO_REG = const(0x3B) |
| 12 | + |
| 13 | +_CONFIG2_REG = const(0x02) |
| 14 | +_CONFIG5_REG = const(0x05) |
| 15 | +_CONFIG6_REG = const(0x06) |
| 16 | +_CONFIG7_REG = const(0x07) |
| 17 | + |
| 18 | +_ACCEL_SETTING_REG = const(0x03) |
| 19 | +_GYRO_SETTING_REG = const(0x04) |
| 20 | +_ENABLE_REG = const(0x08) |
| 21 | + |
| 22 | +# STANDARD_GRAVITY = 9.80665 |
| 23 | + |
| 24 | + |
| 25 | +def _decode_settings(value): |
| 26 | + rnge = value >> 4 |
| 27 | + rate = value & 0xF |
| 28 | + |
| 29 | + return rnge, rate |
| 30 | + |
| 31 | + |
| 32 | +def _encode_setting(rnge, rate): |
| 33 | + return ((rnge & 0x7) << 4) | (rate & 0xF) |
| 34 | + |
| 35 | + |
| 36 | +ACCEL_RANGE_2 = const(0) # +/- 2g |
| 37 | +ACCEL_RANGE_4 = const(0x10) # +/- 4g |
| 38 | +ACCEL_RANGE_8 = const(0x20) # +/- 8g (default value) |
| 39 | +ACCEL_RANGE_16 = const(0x30) # +/- 16g |
| 40 | + |
| 41 | +GYRO_RANGE_16 = const(0) # +/- 16 deg/s |
| 42 | +GYRO_RANGE_32 = const(0x10) # +/- 32 deg/s |
| 43 | +GYRO_RANGE_64 = const(0x20) # +/- 64 deg/s |
| 44 | +GYRO_RANGE_128 = const(0x30) # +/- 128 deg/s |
| 45 | +GYRO_RANGE_256 = const(0x40) # +/- 256 deg/s (default value) |
| 46 | +GYRO_RANGE_512 = const(0x50) # +/- 512 deg/s |
| 47 | +GYRO_RANGE_1024 = const(0x60) # +/- 1024 deg/s |
| 48 | +GYRO_RANGE_2048 = const(0x70) # +/- 2048 deg/s |
| 49 | + |
| 50 | +ACCEL_RATE_8000_HZ = const(0) |
| 51 | +ACCEL_RATE_4000_HZ = const(1) |
| 52 | +ACCEL_RATE_2000_HZ = const(2) |
| 53 | +ACCEL_RATE_1000_HZ = const(3) |
| 54 | +ACCEL_RATE_500_HZ = const(4) |
| 55 | +ACCEL_RATE_250_HZ = const(5) |
| 56 | +ACCEL_RATE_125_HZ = const(6) # (default value) |
| 57 | +ACCEL_RATE_62_HZ = const(7) |
| 58 | +ACCEL_RATE_31_HZ = const(8) |
| 59 | +ACCEL_RATE_LP_128_HZ = const(12) |
| 60 | +ACCEL_RATE_LP_21_HZ = const(13) |
| 61 | +ACCEL_RATE_LP_11_HZ = const(14) |
| 62 | +ACCEL_RATE_LP_3_HZ = const(15) |
| 63 | + |
| 64 | + |
| 65 | +GYRO_RATE_8000_HZ = const(0) |
| 66 | +GYRO_RATE_4000_HZ = const(1) |
| 67 | +GYRO_RATE_2000_HZ = const(2) |
| 68 | +GYRO_RATE_1000_HZ = const(3) |
| 69 | +GYRO_RATE_500_HZ = const(4) |
| 70 | +GYRO_RATE_250_HZ = const(5) |
| 71 | +GYRO_RATE_125_HZ = const(6) # (default value) |
| 72 | +GYRO_RATE_62_HZ = const(7) |
| 73 | +GYRO_RATE_31_HZ = const(8) |
| 74 | + |
| 75 | +I2C_ADDR = 0x6B |
| 76 | +BITS = 8 |
| 77 | + |
| 78 | + |
| 79 | +class QMI8658C(imu_sensor_framework.IMUSensorFramework): |
| 80 | + |
| 81 | + def _read_reg(self, reg): |
| 82 | + self._device.read_mem(reg, self._rx_mv[:1]) |
| 83 | + return self._rx_buf[0] |
| 84 | + |
| 85 | + def _write_reg(self, reg, data): |
| 86 | + self._tx_buf[0] = data |
| 87 | + self._device.write_mem(reg, self._tx_mv[:1]) |
| 88 | + |
| 89 | + def __init__(self, device, delay_between_samples=100): |
| 90 | + |
| 91 | + super().__init__(device, 0.0, delay_between_samples) |
| 92 | + self._device = device |
| 93 | + self._tx_buf = bytearray(1) |
| 94 | + self._tx_mv = memoryview(self._tx_buf) |
| 95 | + self._rx_buf = bytearray(6) |
| 96 | + self._rx_mv = memoryview(self._rx_buf) |
| 97 | + |
| 98 | + if self._read_reg(_VERSION_REG) != 0x05: |
| 99 | + raise RuntimeError("Failed to find QMI8658C") |
| 100 | + |
| 101 | + self._accel_range = ACCEL_RANGE_8 |
| 102 | + self._accel_rate = ACCEL_RATE_125_HZ |
| 103 | + |
| 104 | + self._gyro_range = GYRO_RANGE_256 |
| 105 | + self._gyro_rate = GYRO_RATE_125_HZ |
| 106 | + |
| 107 | + self._write_reg(_CONFIG2_REG, 0x60) |
| 108 | + self._write_reg(_ACCEL_SETTING_REG, _encode_setting(ACCEL_RANGE_8, ACCEL_RATE_125_HZ)) |
| 109 | + self._write_reg(_GYRO_SETTING_REG, _encode_setting(GYRO_RANGE_256, GYRO_RATE_125_HZ)) |
| 110 | + |
| 111 | + self._write_reg(_CONFIG5_REG, 0x00) # No magnetometer |
| 112 | + self._write_reg(_CONFIG6_REG, 0x00) # Disables Gyroscope And Accelerometer Low-Pass Filter |
| 113 | + self._write_reg(_CONFIG7_REG, 0x00) # Disables Motion on Demand. |
| 114 | + self._write_reg(_ENABLE_REG, 0x03) # enable accel and gyro |
| 115 | + |
| 116 | + @property |
| 117 | + def accel_range(self): |
| 118 | + return self._accel_range |
| 119 | + |
| 120 | + @accel_range.setter |
| 121 | + def accel_range(self, value): |
| 122 | + self._accel_range = value |
| 123 | + self._write_reg(_ACCEL_SETTING_REG, _encode_setting(value, self._accel_rate)) |
| 124 | + |
| 125 | + @property |
| 126 | + def accel_rate(self): |
| 127 | + return self._accel_rate |
| 128 | + |
| 129 | + @accel_rate.setter |
| 130 | + def accel_rate(self, value): |
| 131 | + self._accel_rate = value |
| 132 | + self._write_reg(_ACCEL_SETTING_REG, _encode_setting(self._accel_range, value)) |
| 133 | + |
| 134 | + @property |
| 135 | + def gyro_range(self): |
| 136 | + return self._gyro_range |
| 137 | + |
| 138 | + @gyro_range.setter |
| 139 | + def gyro_range(self, value): |
| 140 | + self._gyro_range = value |
| 141 | + self._write_reg(_ACCEL_SETTING_REG, _encode_setting(value, self._gyro_rate)) |
| 142 | + |
| 143 | + @property |
| 144 | + def gyro_rate(self): |
| 145 | + return self._gyro_rate |
| 146 | + |
| 147 | + @gyro_rate.setter |
| 148 | + def gyro_rate(self, value): |
| 149 | + self._gyro_rate = value |
| 150 | + self._write_reg(_ACCEL_SETTING_REG, _encode_setting(self._gyro_range, value)) |
| 151 | + |
| 152 | + @property |
| 153 | + def timestamp(self) -> int: |
| 154 | + self._device.read_mem(_TIME_REG, self._rx_mv[:3]) |
| 155 | + return self._rx_buf[0] + (self._rx_buf[1] << 8) + (self._rx_buf[2] << 16) |
| 156 | + |
| 157 | + @property |
| 158 | + def temperature(self) -> float: |
| 159 | + """Chip temperature""" |
| 160 | + self._device.read_mem(_TEMP_REG, self._rx_mv[:2]) |
| 161 | + temp = self._rx_buf[0] / 256 + self._rx_buf[1] |
| 162 | + return temp |
| 163 | + |
| 164 | + def _get_accelerometer(self): |
| 165 | + self._device.read_mem(_ACCEL_REG, self._rx_mv[:6]) |
| 166 | + |
| 167 | + buf = self._rx_buf |
| 168 | + |
| 169 | + x = buf[0] << 8 | buf[1] |
| 170 | + y = buf[2] << 8 | buf[3] |
| 171 | + z = buf[4] << 8 | buf[5] |
| 172 | + |
| 173 | + return x, y, z |
| 174 | + |
| 175 | + def _get_gyrometer(self): |
| 176 | + self._device.read_mem(_GYRO_REG, self._rx_mv[:6]) |
| 177 | + buf = self._rx_buf |
| 178 | + |
| 179 | + x = buf[0] << 8 | buf[1] |
| 180 | + y = buf[2] << 8 | buf[3] |
| 181 | + z = buf[4] << 8 | buf[5] |
| 182 | + |
| 183 | + return x, y, z |
| 184 | + |
| 185 | + def _get_magnetometer(self): # NOQA |
| 186 | + return None |
0 commit comments