I need a 100 KHz ADC sampling data rate for a pressure transducer (Analog pin), but my code keeps crashing. Everything goes well until I set performance_status = true. In that moment, Teensy 4.1 crashes and I cannot find the bug. I set all these variables as volatiles, if anyone wonders. I share the important parts of the code below.
Code:
// Transducer variables
const uint16_t transducer_max_pressure = 250;
const uint16_t transducer_min_value = 496;
const uint16_t transducer_max_value = 2482;
const float transducer_const = transducer_max_pressure / (transducer_max_value - transducer_min_value);
volatile uint32_t transducer_counter = 0;
volatile uint32_t transducer_freq = 0;
volatile uint16_t transducer_raw = 0;
volatile float transducer_avg = 0;
volatile float transducer_pressure = 0;
// SD
const uint32_t RB_size = 400 * 512;
const uint32_t file_size = 10 * 100000 * 600;
SdFs SDF;
FsFile file_pressure;
RingBuf<FsFile, RB_size> RB_pressure;
ADC *adc = new ADC();
void setup()
{
adc->adc0->setAveraging(8);
adc->adc0->setResolution(12); // set bits of resolution
adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::VERY_HIGH_SPEED); // change the conversion speed
adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::VERY_HIGH_SPEED); // change the sampling speed
transducer_set_high_speed(true);
SDF.begin(SdioConfig(FIFO_SDIO))
file_open();
}
bool file_open()
{
int i = 0;
String newName = i + file_data_name;
while (SDF.exists(newName.c_str())) newName = ++i + file_pressure_name;
if (!file_pressure.open(newName.c_str(), O_RDWR | O_CREAT))
{
send_order(15);
error_warning();
SD_ready = false;
return true;
}
file_pressure.println("Time, Chamber_Pressure, Raw_Transducer");
file_pressure.preAllocate(file_size);
RB_pressure.begin(&file_pressure);
}
void transducer_set_high_speed(bool enable)
{
adc->adc0->stopTimer();
adc->adc0->startSingleRead(PIN_TRANSDUCER); // call this to setup everything before the Timer starts, differential is also possible
adc->adc0->enableInterrupts(transducer_measure);
if (!enable)
{
adc->adc0->setAveraging(100); // set number of averages
adc->adc0->startTimer(10000); //frequency in Hz
}
else
{
adc->adc0->setAveraging(4); // set number of averages
adc->adc0->startTimer(1000000 / transducer_timer); //frequency in Hz
}
}
void transducer_measure()
{
// Read analog pin and change it to bars
transducer_raw = adc->adc0->readSingle();
transducer_pressure = transducer_raw * transducer_const - transducer_offset;
transducer_avg += transducer_pressure;
++transducer_counter;
++transducer_freq;
// Write in SD
if (performance_status) file_pressure_update();
}
void file_pressure_update()
{
if (!SD_ready) {return;}
// Transducer time (in s)
float transducer_time = micros() / 10000000. - last_reset_micros;
RB_pressure.print(transducer_time, 6);
RB_pressure.print(", ");
// Transducer measure already converted
RB_pressure.print(transducer_pressure);
RB_pressure.print(", ");
// Raw transducer data
RB_pressure.println(transducer_raw);
// Write it in the round buffer
if (RB_pressure.bytesUsed() >= 512 && !file_pressure.isBusy())
{
RB_pressure.writeOut(512);
}
}
Last edited: