Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LSM6DSO32 getEvent seems to be slow #22

Open
simon88 opened this issue Jul 30, 2021 · 7 comments
Open

LSM6DSO32 getEvent seems to be slow #22

simon88 opened this issue Jul 30, 2021 · 7 comments

Comments

@simon88
Copy link

simon88 commented Jul 30, 2021

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

if(dso32.accelerationAvailable() == 1 && dso32.gyroscopeAvailable() == 1){
      SerialUSB.println(millis()));
      dso32.getEvent(&accel_dso, &gyro_dso, &temp_dso); //here I have 3ms
      SerialUSB.println(millis()));
     ..... other lines  ......
}

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....

@anders-bogild
Copy link

anders-bogild commented Dec 3, 2021

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 (!).

void Adafruit_LSM6DS::_read(void) {
// get raw readings
Adafruit_BusIO_Register data_reg = Adafruit_BusIO_Register(
i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, LSM6DS_OUT_TEMP_L, 14);
uint8_t buffer[14];
data_reg.read(buffer, 14);
rawTemp = buffer[1] << 8 | buffer[0];
temperature = (rawTemp / temperature_sensitivity) + 25.0;
rawGyroX = buffer[3] << 8 | buffer[2];
rawGyroY = buffer[5] << 8 | buffer[4];
rawGyroZ = buffer[7] << 8 | buffer[6];
rawAccX = buffer[9] << 8 | buffer[8];
rawAccY = buffer[11] << 8 | buffer[10];
rawAccZ = buffer[13] << 8 | buffer[12];
lsm6ds_gyro_range_t gyro_range = getGyroRange();
float gyro_scale = 1; // range is in milli-dps per bit!
if (gyro_range == ISM330DHCX_GYRO_RANGE_4000_DPS)
gyro_scale = 140.0;
if (gyro_range == LSM6DS_GYRO_RANGE_2000_DPS)
gyro_scale = 70.0;
if (gyro_range == LSM6DS_GYRO_RANGE_1000_DPS)
gyro_scale = 35.0;
if (gyro_range == LSM6DS_GYRO_RANGE_500_DPS)
gyro_scale = 17.50;
if (gyro_range == LSM6DS_GYRO_RANGE_250_DPS)
gyro_scale = 8.75;
if (gyro_range == LSM6DS_GYRO_RANGE_125_DPS)
gyro_scale = 4.375;
gyroX = rawGyroX * gyro_scale * SENSORS_DPS_TO_RADS / 1000.0;
gyroY = rawGyroY * gyro_scale * SENSORS_DPS_TO_RADS / 1000.0;
gyroZ = rawGyroZ * gyro_scale * SENSORS_DPS_TO_RADS / 1000.0;
lsm6ds_accel_range_t accel_range = getAccelRange();
float accel_scale = 1; // range is in milli-g per bit!
if (accel_range == LSM6DS_ACCEL_RANGE_16_G)
accel_scale = 0.488;
if (accel_range == LSM6DS_ACCEL_RANGE_8_G)
accel_scale = 0.244;
if (accel_range == LSM6DS_ACCEL_RANGE_4_G)
accel_scale = 0.122;
if (accel_range == LSM6DS_ACCEL_RANGE_2_G)
accel_scale = 0.061;
accX = rawAccX * accel_scale * SENSORS_GRAVITY_STANDARD / 1000;
accY = rawAccY * accel_scale * SENSORS_GRAVITY_STANDARD / 1000;
accZ = rawAccZ * accel_scale * SENSORS_GRAVITY_STANDARD / 1000;
}

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().

@simon88
Copy link
Author

simon88 commented Dec 3, 2021

Yes you've right @anders-bogild this os clearly not necessary

@ladyada
Copy link
Member

ladyada commented Dec 7, 2021

a tested PR to add caching would be awesome!

@eringerli
Copy link
Contributor

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.

@eringerli
Copy link
Contributor

eringerli commented Apr 18, 2022

@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 😉

@steffensol
Copy link

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++; }

@eringerli
Copy link
Contributor

eringerli commented Apr 22, 2022 via email

eringerli added a commit to eringerli/Adafruit_LSM6DS that referenced this issue May 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants