Hi Everyone,
I am trying to record data from ADC to a SD card every 500ms using nrf52832. I am following the fatfs example. Before I had a problem whereby every approximately 10s I would lose a few samples from the ADC as shown by the figure below. I thought the problem was due to the SD card write latency as every 10s I observed an increase in current that usually lasted for around a few hundred milliseconds. After reading around I found that instead of opening and closing the file everytime I wanted to record data onto the SD card I should use f_sync() and this somehow fixed the problem.
But then I still observe this regular increase in write duration, so I was wondering if this is caused by the SD card write latency or is it due to software bugs. And how does the fatfs module handle this (ie when calling f_write) if it's due to SD write latency.
Thanks for the help. Bryan
White lines showing loss of ADC samples x-axis = sample number y-axis = voltage in uV
Significant increase in write duration for the fifth peak
White lines showing loss of ADC samples x-axis = sample number y-axis = voltage in uV
Update: I tested with another SD card and the problem with the missing samples came back. So f_sync did not solve the problem.
Update: 13/11/17
Code For writing to the SD card added.
In Main
while(1)
{
if( sampling_done == true)
{
sdWrite(data);
}
power_manage();
}
In SAADC callback
void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{
if(p_event->type == NRF_DRV_SAADC_EVT_DONE)
{
ret_code_t err_code;
err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, NUM_OF_CHANNELS);
APP_ERROR_CHECK(err_code);
int16_t temp[4]={0};
int8_t notification[8]={0};
temp[0] = ADC_result_conversion(p_event->data.done.p_buffer[0]);
temp[1] = ADC_result_conversion(p_event->data.done.p_buffer[1]);
temp[2] = ADC_result_conversion(p_event->data.done.p_buffer[2]);
temp[3] = ADC_result_conversion(p_event->data.done.p_buffer[3]);
NRF_LOG_INFO("ADC event number: %d\r\n", (int)event_cnt);
NRF_LOG_INFO("CH1: %d.%02d \r\n", NRF_LOG_FLOAT(temp[0]));
NRF_LOG_INFO("CH2: %d.%02d \r\n", NRF_LOG_FLOAT(temp[1]));
NRF_LOG_INFO("CH3: %d.%02d \r\n", NRF_LOG_FLOAT(temp[2]));
NRF_LOG_INFO("CH4: %d.%02d \r\n", NRF_LOG_FLOAT(temp[3]));
NRF_LOG_INFO("\n");
NRF_LOG_FLUSH();
memcpy( &data[0]+NUM_OF_CHANNELS*event_cnt, &temp[0], NUM_OF_CHANNELS*2);
memcpy( ¬ification[0], &temp[0] , NUM_OF_CHANNELS*2);
event_cnt++;
if( event_cnt >= MAX_NUM_SAMPLES)
{
//sdWrite(data);
sampling_done = true;
event_cnt = 0;
}
ble_cus_custom_value_update(&m_cus, notification);
sample_cnt++;
}
}
In sdWrite function
static void sdWrite(int16_t data[])
{
FRESULT ff_result;
uint32_t bytes_written;
char buffer[3000] = {0};
int n=0;
int counter=0;
while(counter < MAX_NUM_SAMPLES)
{
n += sprintf(&buffer[n], "%d %d %d %d\r\n", data[NUM_OF_CHANNELS*counter], data[NUM_OF_CHANNELS*counter+1], data[NUM_OF_CHANNELS*counter+2], data[NUM_OF_CHANNELS*counter+3]); //format the data to ASCII
counter++;
}
ff_result = f_write(&file, buffer , n , (UINT *) &bytes_written);
if (ff_result != FR_OK)
{
NRF_LOG_INFO("Write failed\r\n.");
}
else
{
//NRF_LOG_INFO("%d bytes written.\r\n", bytes_written);
}
NRF_LOG_FLUSH();
f_sync(&file);
}