My setup is an esp32-wroom32 and an inexpensive digital accelerometer ADXL345: when the concept will work I'll scale to better accelerometers.
Nominally this accelerometer can measure at 3.2kHz and the esp32 i2c can read at 400kHz.
Unfortunately with the code I wrote I can't read faster than 1kHz and from my tests this limit comes from the esp32.
I'm wondering if it's a physical limit and I wrongly interpreted esp32 datasheet or my code is wrong.
This is my code:
Code: Select all
import time
from micropython import const
from machine import Pin, I2C
acquisition_time = 1 # [s]
sampling_rate = 3200 # [Hz]
n_exp_meas = floor(acquisition_time * ceil(sampling_rate))
acc_x = [0] * (n_exp_meas + 1)
acc_y = [0] * (n_exp_meas + 1)
acc_z = [0] * (n_exp_meas + 1)
i2c = I2C(1, freq=400000) # hardware i2c
i2c.writeto_mem(const(0x53), const(0x2C), b'\x0f') # set sampling rate to 3.2kHz
i2c.writeto_mem(const(0x53), const(0x2D), b'\x08') # set the device to measure mode
n_act_meas = 0
start = time.ticks_us()
while time.ticks_diff(time.ticks_us(), start) < acquisition_time * 1000000: # measure must last acquisition_time seconds
curr_time = time.ticks_us()
if time.ticks_diff(curr_time, start) < (n_act_meas * 1000000. / sampling_rate): # avoid repeated values if reading frequency is higher than sampling
continue
acc_x[n_act_meas], acc_y[n_act_meas], acc_z[n_act_meas] = get_xyz()
n_act_meas += 1
def get_xyz(self):
buff = i2c.readfrom_mem(self.address, self.regAddress, self.TO_READ)
x = (int(buff[1]) << 8) | buff[0]
y = (int(buff[3]) << 8) | buff[2]
z = (int(buff[5]) << 8) | buff[4]
if x > 32767:
x -= 65536
if y > 32767:
y -= 65536
if z > 32767:
z -= 65536
return x, y, z