Power_Broker
Well-known member
I have a T4.1 and I'm trying to do ~100Hz data logging to an SD card via the built-in slot. Even when running the T4.1 overclocked, I have inconsistent logging rates. Most of the logging is at 100Hz, but sometimes I get lags of up to 0.125 seconds! These lags are not evenly spaced through time. Even more odd, I also sometimes have a log rate of over 100Hz (not sure how that's even possible due to how I have my code setup).
The big question is: what is causing these timing issues (especially the lags) and what can I do to mitigate them? I understand that writing to a larger buffer (i.e. 512 bytes or so) might help, but I'm not writing much data per loop and 100Hz isn't that high of a sample rate. I don't think the SD interface should be struggling so much at 100Hz (IMO).
Below is my code:
Also, here is the plot showing loop latency:
The big question is: what is causing these timing issues (especially the lags) and what can I do to mitigate them? I understand that writing to a larger buffer (i.e. 512 bytes or so) might help, but I'm not writing much data per loop and 100Hz isn't that high of a sample rate. I don't think the SD interface should be struggling so much at 100Hz (IMO).
Below is my code:
Code:
#include "Adafruit_LSM6DS33.h"
#include "Adafruit_LIS3MDL.h"
#include "SdFat.h"
#include "navduino.h"
#include "attitude.h"
#include "FireTimer.h"
#ifdef SDCARD_SS_PIN
const uint8_t SD_CS_PIN = SDCARD_SS_PIN;
#endif // SDCARD_SS_PIN
#define SPI_CLOCK SD_SCK_MHZ(50)
#define SD_CONFIG SdioConfig(FIFO_SDIO)
Adafruit_LSM6DS33 lsm6ds33;
sensors_event_t accel;
sensors_event_t gyro;
sensors_event_t temp;
Adafruit_LIS3MDL lis3mdl;
sensors_event_t mag;
compFilt ahrs;
FireTimer msTimer;
SdFs sd;
FsFile logFile;
char field[20] = { '\0' };
char buff[200] = { '\0' };
float gyro_x_bias = -0.045967611;
float gyro_y_bias = 0.092546083;
float gyro_z_bias = 0.0813977905;
void setup()
{
Serial.begin(115200);
if (!lsm6ds33.begin_I2C(0b1101011))
{
Serial.println("Failed to find LSM6DS33 chip");
while (1);
}
lsm6ds33.setAccelRange(LSM6DS_ACCEL_RANGE_4_G);
lsm6ds33.setGyroRange(LSM6DS_GYRO_RANGE_500_DPS);
lsm6ds33.setAccelDataRate(LSM6DS_RATE_104_HZ);
lsm6ds33.setGyroDataRate(LSM6DS_RATE_104_HZ);
if (! lis3mdl.begin_I2C(0b0011110))
{
Serial.println("Failed to find LIS3MDL chip");
while (1);
}
lis3mdl.setPerformanceMode(LIS3MDL_MEDIUMMODE);
lis3mdl.setOperationMode(LIS3MDL_CONTINUOUSMODE);
lis3mdl.setDataRate(LIS3MDL_DATARATE_155_HZ);
lis3mdl.setRange(LIS3MDL_RANGE_4_GAUSS);
msTimer.begin(10);
if (!sd.begin(SD_CONFIG))
{
Serial.println("SD initialization failed");
while (1);
}
logFile.open("cal_data.csv", FILE_WRITE);
sprintf(buff,
"%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
"epoch_us",
"ax_g",
"ay_g",
"az_g",
"gx_rps",
"gy_rps",
"gz_rps",
"mx_nT",
"my_nT",
"mz_nT",
"roll_deg",
"pitch_deg",
"yaw_deg");
logFile.write(buff, strlen(buff));
logFile.close();
}
void loop()
{
if(msTimer.fire())
{
long ts = micros();
lsm6ds33.getEvent(&accel, &gyro, &temp);
lis3mdl.getEvent(&mag);
float ax = accel.acceleration.x;
float ay = accel.acceleration.y;
float az = accel.acceleration.z;
float gx = (gyro.gyro.x + gyro_x_bias) * 180 / M_PI;
float gy = (gyro.gyro.y + gyro_y_bias) * 180 / M_PI;
float gz = (gyro.gyro.z + gyro_z_bias) * 180 / M_PI;
float mx = mag.magnetic.x;
float my = mag.magnetic.y;
float mz = mag.magnetic.z;
ahrs.updateIMU(ax, ay, az, gx, gy, gz, -1, 0, 0, 0);
gx *= (M_PI / 180);
gy *= (M_PI / 180);
gz *= (M_PI / 180);
char ts_str[20];
char ax_str[20];
char ay_str[20];
char az_str[20];
char gx_str[20];
char gy_str[20];
char gz_str[20];
char mx_str[20];
char my_str[20];
char mz_str[20];
char roll_str[20];
char pitch_str[20];
char yaw_str[20];
dtostrf(ts, 1, 9, ts_str);
dtostrf(ax, 1, 9, ax_str);
dtostrf(ay, 1, 9, ay_str);
dtostrf(az, 1, 9, az_str);
dtostrf(gx, 1, 9, gx_str);
dtostrf(gy, 1, 9, gy_str);
dtostrf(gz, 1, 9, gz_str);
dtostrf(mx, 1, 9, mx_str);
dtostrf(my, 1, 9, my_str);
dtostrf(mz, 1, 9, mz_str);
dtostrf(ahrs.getRoll(), 1, 9, roll_str);
dtostrf(ahrs.getPitch(), 1, 9, pitch_str);
dtostrf(ahrs.getYaw(), 1, 9, yaw_str);
sprintf(buff,
"%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
ts_str,
ax_str,
ay_str,
az_str,
gx_str,
gy_str,
gz_str,
mx_str,
my_str,
mz_str,
roll_str,
pitch_str,
yaw_str);
logFile.open("cal_data.csv", FILE_WRITE);
logFile.write(buff, strlen(buff));
logFile.close();
}
}
Also, here is the plot showing loop latency: