SdFat icon indicating copy to clipboard operation
SdFat copied to clipboard

Overrun while using ExFatLogger with ESP32

Open parthsjoshi2021 opened this issue 1 year ago • 1 comments

I am using the ExFatLogger example to record the accelerometer, gyroscope, and magnetometer data from MPU9250 to a 32 GB MicroSD card using ESP32. I am getting overruns when I try to test the sensor without logging. Please help me identify the mistake I might have made. I resolved the Guru Meditation Error using the approach suggested in https://github.com/greiman/SdFat/issues/423

This is the output that I get when I tried to test the sensor without logging: LOG_INTERVAL_USEC,500 rec#, AX, AY, AZ, GX, GY, GZ, MX, MY, MZ -1,31800,overuns -1,32016,overuns -1,31941,overuns -1,31852,overuns -1,31860,overuns -1,31865,overuns

I have reduced the SPI clock speed to 16 as follows: #define SPI_CLOCK SD_SCK_MHZ(16)

I have modified the logRecord and printRecord functions as follows:

void logRecord(data_t* data, uint16_t overrun) {
  mpu.update();
  if (overrun) {
    // Add one since this record has no adc data. Could add overrun field.
    overrun++;
    // data->adc[0] = 0X8000 | overrun;
    data->ax = 0X8000 | overrun;
  } else {
    // for (size_t i = 0; i < ADC_COUNT; i++) {
    //   data->adc[i] = analogRead(2); //analogRead(i);
    // }
    data->ax = mpu.getRawAccX();
    data->ay = mpu.getRawAccY();
    data->az = mpu.getRawAccZ();
    data->gx = mpu.getRawGyroX();
    data->gy = mpu.getRawGyroY();
    data->gz = mpu.getRawGyroZ();
    data->mx = mpu.getMagX();
    data->my = mpu.getMagY();
    data->mz = mpu.getMagZ();
  }
}
//------------------------------------------------------------------------------
void printRecord(Print* pr, data_t* data) {
  static uint32_t nr = 0;
  if (!data) {
    pr->print(F("LOG_INTERVAL_USEC,"));
    pr->println(LOG_INTERVAL_USEC);
    pr->print(F("rec#"));
    // for (size_t i = 0; i < ADC_COUNT; i++) {
    //   pr->print(F(",adc"));
    //   pr->print(i);
    // }
    pr->print(F(", AX, AY, AZ"));
    pr->print(F(", GX, GY, GZ"));
    pr->print(F(", MX, MY, MZ"));
    pr->println();
    nr = 0;
    return;
  }
  // if (data->adc[0] & 0X8000) {
  if (data->ax & 0X8000) {
    // uint16_t n = data->adc[0] & 0X7FFF;
    uint16_t n = data->ax & 0X7FFF;
    nr += n;
    pr->print(F("-1,"));
    pr->print(n);
    pr->println(F(",overuns"));
  } else {
    pr->print(nr++);
    // for (size_t i = 0; i < ADC_COUNT; i++) {
    //   pr->write(',');
    //   pr->print(data->adc[i]);
    // }
    pr->write(',');
    pr->print(data->ax);
    pr->write(',');
    pr->print(data->ay);
    pr->write(',');
    pr->print(data->az);
    pr->write(',');
    pr->print(data->gx);
    pr->write(',');
    pr->print(data->gy);
    pr->write(',');
    pr->print(data->gz);
    pr->write(',');
    pr->print(data->mx);
    pr->write(',');
    pr->print(data->my);
    pr->write(',');
    pr->print(data->mz);
    pr->println();
  }
}

I have modified ExFatLogger.h as follows:

// Avoid IDE problems by defining struct in septate .h file.
// Pad record so size is a power of two for best write performance.
#ifndef ExFatLogger_h
#define ExFatLogger_h
// const size_t ADC_COUNT = 1;
struct data_t {
  // uint16_t adc[ADC_COUNT];
  // unsigned long time;
  int16_t ax;
  int16_t ay;
  int16_t az;
  int16_t gx;
  int16_t gy;
  int16_t gz;
  float mx;
  float my;
  float mz;
};
#endif  // ExFatLogger_h

parthsjoshi2021 avatar Oct 17 '24 07:10 parthsjoshi2021

I suspect that using the high bit of ax for the overrun flag is causing the problem. I wrote this example many years ago and needed to save memory so it would run on a Uno.

I think the MPU9250 has 16-bit data so ax cannot be used for both the overrun count and data.

Modify logRecord() and printRecord() to use a separate member for the overrun count.

greiman avatar Oct 17 '24 14:10 greiman