Skip to content

Commit bfce0fa

Browse files
committed
Burst read IMU data registers
Burst reading speeds up data transmission a lot, up to 3x faster than reading single bytes when reading lots of registers (eg. reading 12 bytes at 400kHz should be almost 500us faster) Also best to minimize the amount of time spent hogging the I2C bus in case something else needs it
1 parent c036201 commit bfce0fa

1 file changed

Lines changed: 70 additions & 22 deletions

File tree

XRPLib/imu.py

Lines changed: 70 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ def _getreg(self, reg):
9696
self.i2c.readfrom_mem_into(self.addr, reg, self.rb)
9797
return self.rb[0]
9898

99+
def _getregs(self, reg, num_bytes):
100+
rx_buf = bytearray(num_bytes)
101+
self.i2c.readfrom_mem_into(self.addr, reg, rx_buf)
102+
return rx_buf
103+
99104
def _get2reg(self, reg):
100105
return self._getreg(reg) + self._getreg(reg+1) * 256
101106

@@ -161,38 +166,55 @@ def _set_if_inc(self, if_inc = True):
161166
self.reg_ctrl3_c_bits.IF_INC = if_inc
162167
self._setreg(LSM_REG_CTRL3_C, self.reg_ctrl3_c_byte)
163168

164-
def _mg(self, reg):
165-
return round(self._int16(self._get2reg(reg)) * LSM_MG_PER_LSB)
169+
def _raw_to_mg(self, raw):
170+
return self._int16((raw[1] << 8) | raw[0]) * LSM_MG_PER_LSB
166171

167-
def _mdps(self, reg):
168-
return round(self._int16(self._get2reg(reg)) * LSM_MDPS_PER_LSB)
172+
def _raw_to_mdps(self, raw):
173+
return self._int16((raw[1] << 8) | raw[0]) * LSM_MDPS_PER_LSB
169174

170175
def _get_gyro_x_rate(self):
171176
"""
172177
Individual axis read for the Gyroscope's X-axis, in mg
173178
"""
174-
return self._mdps(LSM_REG_OUTX_L_G) - self.gyro_offsets[0]
179+
# Burst read data registers
180+
raw_bytes = self._getregs(LSM_REG_OUTX_L_G, 2)
181+
182+
# Convert raw data to mdps
183+
return self._raw_to_mdps(raw_bytes[0:2]) - self.gyro_offsets[0]
175184

176185
def _get_gyro_y_rate(self):
177186
"""
178187
Individual axis read for the Gyroscope's Y-axis, in mg
179188
"""
180-
return self._mdps(LSM_REG_OUTY_L_G) - self.gyro_offsets[1]
189+
# Burst read data registers
190+
raw_bytes = self._getregs(LSM_REG_OUTY_L_G, 2)
191+
192+
# Convert raw data to mdps
193+
return self._raw_to_mdps(raw_bytes[0:2]) - self.gyro_offsets[1]
181194

182195
def _get_gyro_z_rate(self):
183196
"""
184197
Individual axis read for the Gyroscope's Z-axis, in mg
185198
"""
186-
return self._mdps(LSM_REG_OUTZ_L_G) - self.gyro_offsets[2]
199+
# Burst read data registers
200+
raw_bytes = self._getregs(LSM_REG_OUTZ_L_G, 2)
201+
202+
# Convert raw data to mdps
203+
return self._raw_to_mdps(raw_bytes[0:2]) - self.gyro_offsets[2]
187204

188205
def _get_gyro_rates(self):
189206
"""
190207
Retrieves the array of readings from the Gyroscope, in mdps
191208
The order of the values is x, y, z.
192209
"""
193-
self.irq_v[1][0] = self._get_gyro_x_rate()
194-
self.irq_v[1][1] = self._get_gyro_y_rate()
195-
self.irq_v[1][2] = self._get_gyro_z_rate()
210+
# Burst read data registers
211+
raw_bytes = self._getregs(LSM_REG_OUTX_L_G, 6)
212+
213+
# Convert raw data to mdps
214+
self.irq_v[1][0] = self._raw_to_mdps(raw_bytes[0:2]) - self.gyro_offsets[0]
215+
self.irq_v[1][1] = self._raw_to_mdps(raw_bytes[2:4]) - self.gyro_offsets[1]
216+
self.irq_v[1][2] = self._raw_to_mdps(raw_bytes[4:6]) - self.gyro_offsets[2]
217+
196218
return self.irq_v[1]
197219

198220
def _get_acc_gyro_rates(self):
@@ -201,8 +223,17 @@ def _get_acc_gyro_rates(self):
201223
The first row is the acceleration values, the second row is the gyro values.
202224
The order of the values is x, y, z.
203225
"""
204-
self.get_acc_rates()
205-
self._get_gyro_rates()
226+
# Burst read data registers
227+
raw_bytes = self._getregs(LSM_REG_OUTX_L_G, 12)
228+
229+
# Convert raw data to mg's and mdps
230+
self.irq_v[0][0] = self._raw_to_mg(raw_bytes[6:8]) - self.acc_offsets[0]
231+
self.irq_v[0][1] = self._raw_to_mg(raw_bytes[8:10]) - self.acc_offsets[1]
232+
self.irq_v[0][2] = self._raw_to_mg(raw_bytes[10:12]) - self.acc_offsets[2]
233+
self.irq_v[1][0] = self._raw_to_mdps(raw_bytes[0:2]) - self.gyro_offsets[0]
234+
self.irq_v[1][1] = self._raw_to_mdps(raw_bytes[2:4]) - self.gyro_offsets[1]
235+
self.irq_v[1][2] = self._raw_to_mdps(raw_bytes[4:6]) - self.gyro_offsets[2]
236+
206237
return self.irq_v
207238

208239
"""
@@ -214,30 +245,47 @@ def get_acc_x(self):
214245
:return: The current reading for the accelerometer's X-axis, in mg
215246
:rtype: int
216247
"""
217-
return self._mg(LSM_REG_OUTX_L_A) - self.acc_offsets[0]
248+
# Burst read data registers
249+
raw_bytes = self._getregs(LSM_REG_OUTX_L_A, 2)
250+
251+
# Convert raw data to mg's
252+
return self._raw_to_mdps(raw_bytes[0:2]) - self.gyro_offsets[0]
218253

219254
def get_acc_y(self):
220255
"""
221256
:return: The current reading for the accelerometer's Y-axis, in mg
222257
:rtype: int
223258
"""
224-
return self._mg(LSM_REG_OUTY_L_A) - self.acc_offsets[1]
259+
# Burst read data registers
260+
raw_bytes = self._getregs(LSM_REG_OUTY_L_A, 2)
261+
262+
# Convert raw data to mg's
263+
return self._raw_to_mdps(raw_bytes[0:2]) - self.gyro_offsets[1]
225264

226265
def get_acc_z(self):
227266
"""
228267
:return: The current reading for the accelerometer's Z-axis, in mg
229268
:rtype: int
230269
"""
231-
return self._mg(LSM_REG_OUTZ_L_A) - self.acc_offsets[2]
270+
# Burst read data registers
271+
raw_bytes = self._getregs(LSM_REG_OUTZ_L_A, 2)
272+
273+
# Convert raw data to mg's
274+
return self._raw_to_mdps(raw_bytes[0:2]) - self.gyro_offsets[2]
232275

233276
def get_acc_rates(self):
234277
"""
235278
:return: the list of readings from the Accelerometer, in mg. The order of the values is x, y, z.
236279
:rtype: list<int>
237280
"""
238-
self.irq_v[0][0] = self.get_acc_x()
239-
self.irq_v[0][1] = self.get_acc_y()
240-
self.irq_v[0][2] = self.get_acc_z()
281+
# Burst read data registers
282+
raw_bytes = self._getregs(LSM_REG_OUTX_L_A, 6)
283+
284+
# Convert raw data to mg's
285+
self.irq_v[0][0] = self._raw_to_mg(raw_bytes[0:2]) - self.acc_offsets[0]
286+
self.irq_v[0][1] = self._raw_to_mg(raw_bytes[2:4]) - self.acc_offsets[1]
287+
self.irq_v[0][2] = self._raw_to_mg(raw_bytes[4:6]) - self.acc_offsets[2]
288+
241289
return self.irq_v[0]
242290

243291
def get_pitch(self):
@@ -473,10 +521,10 @@ def _stop_timer(self):
473521

474522
def _update_imu_readings(self):
475523
# Called every tick through a callback timer
476-
477-
delta_pitch = self._get_gyro_x_rate() / 1000 / self.timer_frequency
478-
delta_roll = self._get_gyro_y_rate() / 1000 / self.timer_frequency
479-
delta_yaw = self._get_gyro_z_rate() / 1000 / self.timer_frequency
524+
self._get_gyro_rates()
525+
delta_pitch = self.irq_v[1][0] / 1000 / self.timer_frequency
526+
delta_roll = self.irq_v[1][1] / 1000 / self.timer_frequency
527+
delta_yaw = self.irq_v[1][2] / 1000 / self.timer_frequency
480528

481529
state = disable_irq()
482530
self.running_pitch += delta_pitch

0 commit comments

Comments
 (0)