Hello everyone, I currently have a problem that I hope you can help me with in my project.
Materials:
6 x IMU
1 x Muxtiplexer
1 x Rasp pi Zer0
I am trying to read data from an Adafruit TDK InvenSense ICM-20948 9-DoF IMU sensor, currently I am doing very well when reading data from a single chip.
But here is the problem:
I want to read data from 6 ICM-20948, then I have them connected to an Adafruit TCA9548A 1-to-8 I2C Multiplexer Breakout to work through the I2C protocol.
I have a 6Hz sample rate reading the accelerometer, gyroscope and magnetometer, any idea how I can improve my sample rate?
I currently use the must-have code for:
- Load modules
- Prepare the connection
- Read data
I have tried with:
Maximum i2c speed at 400 Kb/s. reference
Reference
https://www.raspberrypi-spy.co.uk/2018/ ... bus-speed/
Adafruit TDK InvenSense ICM-20948 and Adafruit TCA9548A Multiplexer sample rate problems
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- vakkerlivet
- Posts: 4
- Joined: Fri Sep 23, 2022 11:34 am
- adafruit_support_carter
- Posts: 29056
- Joined: Tue Nov 29, 2016 2:45 pm
Re: Adafruit TDK InvenSense ICM-20948 and Adafruit TCA9548A Multiplexer sample rate problems
Can you share your full code listing? Or a short example that demonstrates the issue.
- vakkerlivet
- Posts: 4
- Joined: Fri Sep 23, 2022 11:34 am
Re: Adafruit TDK InvenSense ICM-20948 and Adafruit TCA9548A Multiplexer sample rate problems
Hello, of course.adafruit_support_carter wrote: ↑Fri Sep 23, 2022 5:02 pm Can you share your full code listing? Or a short example that demonstrates the issue.
This is my code with which I load the modules, read the sensor data and save it in a log.
The code runs for 30 seconds with the lines below.
Code: Select all
from threading import Thread
import logging
import board
import time
from adafruit_icm20x import ICM20948
import adafruit_tca9548a
i2c = board.I2C()
tca = adafruit_tca9548a.TCA9548A(i2c)
imu1 = ICM20948(tca[0], 0x68)
imu2 = ICM20948(tca[0], 0x69)
imu3 = ICM20948(tca[2], 0x68)
imu4 = ICM20948(tca[2], 0x69)
imu5 = ICM20948(tca[3], 0x68)
imu6 = ICM20948(tca[3], 0x69)
imu1.gyro_data_rate_divisor = 0
imu2.gyro_data_rate_divisor = 0
imu3.gyro_data_rate_divisor = 0
imu4.gyro_data_rate_divisor = 0
imu5.gyro_data_rate_divisor = 0
imu6.gyro_data_rate_divisor = 0
imu1.accelerometer_data_rate_divisor = 0
imu2.accelerometer_data_rate_divisor = 0
imu3.accelerometer_data_rate_divisor = 0
imu4.accelerometer_data_rate_divisor = 0
imu5.accelerometer_data_rate_divisor = 0
imu6.accelerometer_data_rate_divisor = 0
imu1.accelerometer_range = 0
imu2.accelerometer_range = 0
imu3.accelerometer_range = 0
imu4.accelerometer_range = 0
imu5.accelerometer_range = 0
imu6.accelerometer_range = 0
imu1.gyro_range = 0
imu2.gyro_range = 0
imu3.gyro_range = 0
imu4.gyro_range = 0
imu5.gyro_range = 0
imu6.gyro_range = 0
LOG = 'logfile0.log'
logging.basicConfig(filename=LOG, filemode="a+",level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S', format='%(asctime)s.%(msecs)03d %(message)s',)
console = logging.StreamHandler()
console.setLevel(100)
logging.getLogger("").addHandler(console)
input('start...')
def some_task():
while True:
logging.info(str(imu2.gyro) + str(imu2.acceleration) + str(imu1.gyro) + str(imu1.acceleration) + str(imu3.gyro) + str(imu4.gyro) + str(imu5.gyro) + str(imu6.gyro))
if __name__ == '__main__':
t = Thread(target=some_task)
t.daemon= True
t.start()
time.sleep(30)
378 samples / 30 seconds = 12.6Hz.
I would like to improve the sample rate.
- adafruit_support_carter
- Posts: 29056
- Joined: Tue Nov 29, 2016 2:45 pm
Re: Adafruit TDK InvenSense ICM-20948 and Adafruit TCA9548A Multiplexer sample rate problems
Try buffering the data and then writing it to the file after the acquisition is complete. Having the formatted string conversions and file writes in the acquisition loop could be slowing things down.
- vakkerlivet
- Posts: 4
- Joined: Fri Sep 23, 2022 11:34 am
Re: Adafruit TDK InvenSense ICM-20948 and Adafruit TCA9548A Multiplexer sample rate problems
Even if I remove the part where I write the data to a file, the result is the same.adafruit_support_carter wrote: ↑Mon Sep 26, 2022 12:02 pm Try buffering the data and then writing it to the file after the acquisition is complete. Having the formatted string conversions and file writes in the acquisition loop could be slowing things down.
For example, I already tried to print the results directly in the console at the end of the script and count line by line manually the number of samples and the result is still the same.
Do you think I should try to program directly on the microcontroller?
- adafruit_support_carter
- Posts: 29056
- Joined: Tue Nov 29, 2016 2:45 pm
Re: Adafruit TDK InvenSense ICM-20948 and Adafruit TCA9548A Multiplexer sample rate problems
Try this basic rate test:
Code: Select all
import time
import board
from adafruit_icm20x import ICM20948
import adafruit_tca9548a
i2c = board.I2C()
tca = adafruit_tca9548a.TCA9548A(i2c)
imu1 = ICM20948(tca[0], 0x68)
imu1.gyro_data_rate_divisor = 0
imu1.accelerometer_data_rate_divisor = 0
imu1.accelerometer_range = 0
imu1.gyro_range = 0
print("Reading...")
start_time = time.time()
for _ in range(1000):
reading = imu1.gyro
end_time = time.time()
print("Took 1000 readings in {} seconds.".format(end_time - start_time))
- vakkerlivet
- Posts: 4
- Joined: Fri Sep 23, 2022 11:34 am
Re: Adafruit TDK InvenSense ICM-20948 and Adafruit TCA9548A Multiplexer sample rate problems
The first output is reading data from the gyroscope, I also attach the output with the same code, but reading data from the accelerometer.adafruit_support_carter wrote: ↑Tue Sep 27, 2022 2:01 pm Try this basic rate test:Code: Select all
import time import board from adafruit_icm20x import ICM20948 import adafruit_tca9548a i2c = board.I2C() tca = adafruit_tca9548a.TCA9548A(i2c) imu1 = ICM20948(tca[0], 0x68) imu1.gyro_data_rate_divisor = 0 imu1.accelerometer_data_rate_divisor = 0 imu1.accelerometer_range = 0 imu1.gyro_range = 0 print("Reading...") start_time = time.time() for _ in range(1000): reading = imu1.gyro end_time = time.time() print("Took 1000 readings in {} seconds.".format(end_time - start_time))
I think the problem arises from the natural phase lag that exists between the gyroscope and the accelerometer, then when trying to read 6 IMUs the delay increases in a non-linear way. All this despite having the minimum necessary code.
This will be a problem because of the number of IMUs connected (which seems strange to me, as there must be systems with many more...).
I want to mention that I have done these tests on a Jetson Nano 2GB, to rule out the processor speed problem.
- adafruit_support_carter
- Posts: 29056
- Joined: Tue Nov 29, 2016 2:45 pm
Re: Adafruit TDK InvenSense ICM-20948 and Adafruit TCA9548A Multiplexer sample rate problems
There are several sleeps in the CircuitPython driver:
https://github.com/adafruit/Adafruit_Ci ... 0x.py#L270
Not sure the reasoning for that nor to what extent it's required by the sensor.
In general, reading things "fast" will be tricky. Using Python on a Pi will be some of that. The way the driver is written is another contributor. But also at some point the basic speed of I2C will limit things.
https://github.com/adafruit/Adafruit_Ci ... 0x.py#L270
Not sure the reasoning for that nor to what extent it's required by the sensor.
In general, reading things "fast" will be tricky. Using Python on a Pi will be some of that. The way the driver is written is another contributor. But also at some point the basic speed of I2C will limit things.
Please be positive and constructive with your questions and comments.