Hello,
I’ve bought some Xiao NRF52840 sense boards and trying to read IMU as fast as possible.
In the following piece of code, I can barely reach 700 Hz while I need 1kHz to perform a FFT on my computer.
How to speed it up ?
If I enable BLE, the rate drops to 70Hz
#include <LSM6DS3.h>
#include <Wire.h>
#define SAMPLING_RATE 1000 //Hz
// Declare IMU devices
LSM6DS3 myIMU(I2C_MODE, 0x6A);
float ax, ay, az;
float gx, gy, gz;
uint8_t readData = 0;
int numSamples = 0;
int samplesRead = numSamples;
void setup() {
Serial.begin(9600);
unsigned long startTime = millis();
while (!Serial && millis() - startTime < 1000);
// Toggle LEDs
pinMode(LED_RED, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_BLUE, OUTPUT);
digitalWrite(LED_RED, HIGH);
digitalWrite(LED_BLUE, HIGH);
digitalWrite(LED_GREEN, LOW);
// Initialize IMU
myIMU.settings.gyroEnabled = 0;
if (myIMU.begin() != 0) {
Serial.println("[FAILURE] Failed to start IMU.");
while (1);
}
Wire1.setClock(400000UL);
myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL2_G, 0x8C); //1.66kHz 2000dps
myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, 0x8A); //1.66kHz 4G
myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL7_G, 0x00);
myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL8_XL, 0x09);
Serial.println("[INFO] Ready.");
Serial.println("aX,aY,aZ,gX,gY,gZ");
}
void loop() {
// Collect samples
numSamples = SAMPLING_RATE * 5;
unsigned long startTime = micros();
unsigned long elapsedTime;
// Wait until IMU is ready
unsigned int timestamp = micros();
do {
myIMU.readRegister(&readData, LSM6DS3_ACC_GYRO_STATUS_REG); // 0,0,0,0,0,TDA,GDA,XLDA
} while ((readData & 0x07) != 0x07);
Serial.println("Ready to read samples");
// Read samples
uint8_t dataBuff[12];
unsigned long previousMicros = 0;
unsigned long delayTime = 1000000 / SAMPLING_RATE;
String data;
while (samplesRead < numSamples) {
unsigned long currentMicros = micros();
if (currentMicros - previousMicros < delayTime) continue;
previousMicros = currentMicros;
// Read raw data
myIMU.readRegisterRegion(dataBuff, LSM6DS3_ACC_GYRO_OUTX_L_G, 12);
//gx = myIMU.calcGyro((int16_t)dataBuff[0] | int16_t(dataBuff[1] << 8));
//gy = myIMU.calcGyro((int16_t)dataBuff[2] | int16_t(dataBuff[3] << 8));
//gz = myIMU.calcGyro((int16_t)dataBuff[4] | int16_t(dataBuff[5] << 8));
ax = myIMU.calcAccel((int16_t)dataBuff[6] | int16_t(dataBuff[7] << 8));
ay = myIMU.calcAccel((int16_t)dataBuff[8] | int16_t(dataBuff[9] << 8));
az = myIMU.calcAccel((int16_t)dataBuff[10] | int16_t(dataBuff[11] << 8));
// Format data
data = String(samplesRead)+","+ String(ax, 3)+","+String(ay, 3)+","+String(az, 3);
//data = data + ","+ String(_calcGyro(gX), 3)+","+String(_calcGyro(gY), 3)+","+String(_calcGyro(gZ), 3);
//Serial.println(data);
samplesRead++;
}
elapsedTime = micros() - startTime;
float frequency = (float)samplesRead / (elapsedTime / 1000000.0);
Serial.print("Frequency : ");
Serial.print(frequency);
Serial.println(" Hz");
// Reset counter
samplesRead = 0;
}