Open simon88 opened 3 years ago
Having the same issue with a lsm6ds33 connected via i2c to an Adafruit Feather nRF52840 board maxing out at 208Hz rate.
A contributing factor to slowness is that Adafruit_LSM6DS::_read()
, which is called by Adafruit_LSM6DS::getEvent()
, will try to determine current range of acc and gyr each time it is called (!).
This is clearly not necessary and should be done only once efter e.g. reset(), and if the ranges are changed with Adafruit_LSM6DS::setAccellRange()
or Adafruit_LSM6DS::setGyroRange()
.
Yes you've right @anders-bogild this os clearly not necessary
a tested PR to add caching would be awesome!
In #31, I addressed this problem by buffering the ranges. This is a substantial performance gain, especially when reading the IMU with fast sample rates.
@simon88: try connecting the IMU per SPI and with a data ready-line on an interrupt. I could max an ISM330 out with 6.66kHz sample rate on an ESP32 feather. The bigger problem was to send this collected data over WIFI, as it generates about 300kB/s when using a timestamp and 6 float
, not calculating the other protocol overhead :wink:
Should this new PR change affect LSM6DSOX getEvent in the same way? I'm running an LSM6DSOX over i2c with a feather m0, and am being capped at around 313Hz - and was starting to get a bit confused as to why this was running so slow.
The code I am running is basically;
#include <Adafruit_LSM6DSOX.h>
Adafruit_LSM6DSOX sox;
File logfile;
int iterator = 1;
unsigned long timebefore;
unsigned long timeafter;
unsigned long duration;
unsigned long timeAtEvent;
volatile unsigned long timeAtReset = 0;
float freq;
void loop() {
sensors_event_t accel;
sensors_event_t gyro;
sensors_event_t temp;
noInterrupts();
timebefore = micros() - timeAtReset;
sox.getEvent(&accel, &gyro, &temp);
timeAtEvent = micros() - timeAtReset;
logfile.print(timeAtEvent); logfile.print(","); logfile.print(accel.acceleration.x); logfile.print(","); logfile.print(accel.acceleration.y); logfile.print(","); logfile.println(accel.acceleration.z);
timeafter = micros() - timeAtReset;
duration = timeafter-timebefore;
interrupts();
freq = 1000000/(duration);
if (iterator % 1001 == 0) {
logfile.flush();
Serial.println("Wrote to file");
Serial.print("Time spent reading last sensor value(microseconds): ");
Serial.println(duration);
Serial.print("Frequency: ");
Serial.println(freq);
Serial.print("Last reset at time: ");
Serial.println(timeAtReset);
iterator = 1;
} else { iterator++; }
It should get you an improvement, as it removes two additional reads of registers. If you want to test it, wait until @ladyada releases a new version or clone the repo locally to get the new code.
If you really want to read out the sensor fast, you have to connect it by SPI and with an interrupt on the DRDY-line to keep the latency low. I²C is maxed out at 400kHz, with SPI you can rise the datarate to 10MHz, which is 25x faster. In my first attempt I also connected the sensors by I²C, but I couldn't get much higher overall than about 50Hz with three different sensors on the same bus (ADS1115, ISM330 and LIS3MDL) and with many collisions and overruns, which negatively impacted latency and jitter. But that was before I removed the register reads for the range in both drivers (ISM330/LSM6DSOX and LIS3MDL), so YMMV.
Hi all, I'am working with an LSM6DSO32 and one SAMD21E18A. I've a personal board, so I use your library. But it's seem to be slow, I have a delay of 3ms for calling getEvent. I set my captor (accel and gyro) at 208Hz with LSM6DS_RATE_208_HZ mask in my setup function. After that I have a loop and I call getEvent when new data are availables like this
3ms seems to be long no? If I increase my data rate at 400Hz I can't getEvent beceause I have a minimum of 3ms in my loop just to read the register. So the maximum frequency of my loop is 333Hz....