Store sensor data in SD card
Antwort
15.10.18 07:20

Hello all,

at the moment i try to store sensor data which i get from the adc into a SD card. For this i looked in the DataLogger example and some other programms on the internet. The code i produced work fine.

I store the captured adc data in a char buffer and write it to the SD card. That works fine and is very fast.  But my problem is: in about 1% of the write operations the time to write the data is much more longer than normally. The normal time my function need to write about 19000 byte to the card is 250ms. But in this 1% of operations the function need more than 400ms. So i lose data because the other buffer is already full.

I googled a bit and find in a hint in a forum that says the SD card do some internal stuff and block the write access in this time.

Have anyone an idea how i could solve this problem? Maybe with a specail SD card initialization or something like this.

Thanks in advance and best regards

Christian

0 (0 Stimmen)
RE: Store sensor data in SD card
Antwort
15.10.18 15:06 als Antwort auf Christian Köhler.
Hello Christian,

First, I would like to welcome you to the XDK community.

The issue you described is not necessarily related to the SD Card.

Could you please go more into detail about how you implemented your application to write the ADC values to the SD card?

If you used the same task construct as in the Data Logger demo, I have a theory why you are getting an interference in 1% of all writing operations. This might be caused, because the Data Logger demo uses one task to sample sensor data and one task to write this data to the SD card, depending on the priorities of the task, these two might interfere during the 1% of the writing operations could also be the reason why you are having an exception in the writing interval.

Furthermore, it would be very helpful, if you could share more information about how you implemented your application and also about which parts you used from the Data Logger demo.

Please let me know if this was helpful and feel free to ask if you have further questions.

Kind regards,
Franjo
0 (0 Stimmen)
RE: Store sensor data in SD card
Antwort
16.10.18 07:08 als Antwort auf Franjo Stjepandic.

Hello Franjo,

thanks for the fast answer. I will try to explain my code:

First i create two tasks with the same priority. One to sample the adc data and the other to write the data in the file. I use the same buffer structure like the DataLogger example.

Buffer     pingBuffer = { 0 };
Buffer     pongBuffer = { 0 };
Buffer     *activeBuffer;
Buffer     *backBuffer;

I trigger the ADC with the PRS. In the ADC0_IRQHandler i write the captured data in the activeBuffer. After that i check in the ISR if the activeBuffer is full. In case the buffer is full, i switch the pointer.

    /* Reset the backbuffer */
    backBuffer->length = 0;
    backBuffer->data[0] = 0;

    /* Switch the two pointers from one buffer to the other */
    if (activeBuffer == &pingBuffer)
    {
        activeBuffer = &pongBuffer;
        backBuffer = &pingBuffer;
    }
    else
    {
        activeBuffer = &pingBuffer;
        backBuffer = &pongBuffer;
    }

    /* Reset the activeBuffer */
    activeBuffer->length = 0;
    activeBuffer->data[0] = 0;

Then i give a semaphore to the other task

xSemaphoreGiveFromISR(semaphoreHandle, &xHigherPriotityTaskWaken);

In the other task i wait for the semaphore and then start to write data to the SD card.

    for(;;){

        /* Wait here to get the full buffer from the ISR */
        xSemaphoreTake(semaphoreHandle, portMAX_DELAY);


        /* Write the second buffer to the csv file */
        if(RETCODE_SUCCESS != SDCard_Write(filename, backBuffer->data)){

            printf("Write Buffer data to SD card : Failed! \r\n");
        }

        /* Signals that the buffer is written to csv file completly */
        wrote_to_csv = 1U;
    }

With the wrote_to_csv flag i check in the ISR if the buffer is written completly to the SD card.

The function SDCard_Write writes the chracter buffer to the file with the following line.

fileSystemResult = f_write(&fileObject, data, strlen(data), &retBytes);

I think these are the most important parts of my code.

Thanks a lot in advance and best regards

Christian

0 (0 Stimmen)
RE: Store sensor data in SD card
Antwort
16.10.18 15:23 als Antwort auf Christian Köhler.
Hello Christian,

Thank you for providing further information on your application code.

In that regard for clarification, you are using one task to write data to the SD card and the second one would be the procedure you use in the interrupt service routine to sample the data from the ADC. Am I right so far?

Additionally, which additional module are you using to trigger via PRS the ADC? The timer module for an accurate sampling frequency?

Kind regards,
Franjo
0 (0 Stimmen)
RE: Store sensor data in SD card
Antwort
16.10.18 15:34 als Antwort auf Franjo Stjepandic.

Hello Franjo,

you are right. I am using one task to write the buffer data to the SD card and one task to capture ADC data with the ISR.

I am using the TIMER0 module to trigger the PRS channel 0 with timer overflow flag so the ISR get triggered. 

Best regards

Christian

0 (0 Stimmen)
RE: Store sensor data in SD card
Antwort
17.10.18 16:05 als Antwort auf Christian Köhler.
Hello Christian,

thank you for answering the questions.

I think I found the reason which causes your issue. For better understanding, I split up this process on a timeline:
 
  1. The timer starts the ADC over PRS in defined intervals.
  2. The ADC converts the analog sensor value
  3. The ADC ISR starts the SD card task by passing the semaphore
  4. The SD card task finishes and waits for the next semaphore
The process repeats over and over.

I assume, the delay differences you want to get rid of occurring due to a short delay within the ISR while checking the buffer. This delay is stacking up and causing the other SD card task to get delayed too. Then a secondary ISR is triggered due to a started new timer period and delaying the task too. Please note ISRs are no operating tasks and have higher priority (5) compared to the lower priority (4).

As such, I recommend excluding the buffer checking from the ISR to ensure that the executed ISRs do not delay to ensure that the following executes in time and is not interrupted by a following ISR.

Please let me know if this was helpful and feel free to ask if you have further questions.

Kind regards,
Franjo
0 (0 Stimmen)
RE: Store sensor data in SD card
Antwort
18.10.18 08:22 als Antwort auf Franjo Stjepandic.

Hello Franjo,

first of all thank you very much for your help!

In my earlier versions of this programm i checked and switched the buffer in the SD card task before writing the backBuffer to file. But i had the same issues like now. The intention to do the buffer switching in the ISR was to ensure that the buffers are switched before the next adc value is captured.

To find out which is the reason for the delays, i tried some "time measurements" earlier.

For that i implemented code like this :

Clock_getTimeMillis(&start);

//Buffer switchting operation or write to file function

Clock_getTimeMillis(&end);

printf("Time  %lu\n",end-start);

The results of this (i dont know how believable the function works) shows the time to switch the buffer always 0 milli seconds. So i thought that process should be very fast. 

On the other hand the time to write the data to the SD card had values between 75 ms and up to 400 ms. In the runs with the long write time the function didnt finished writing the buffer to file before the next buffer was full.

In 99% of the runs the write time takes about 75ms to 100ms. And in 1% of the runs the write time increases up to 400ms.

At the moment my programm works well with sampling rates up to 2kHz. But with higher sampling rates the write function doesn't seem to be fast enough sometimes.

I really appreciate your help so far!

Best regards,

Christian

0 (0 Stimmen)
RE: Store sensor data in SD card
Antwort
18.10.18 17:21 als Antwort auf Christian Köhler.
Hello Christian,

Thank you for providing further information. The clock you are using is normally influenced on the temperature drift and has also a jitter of about 1-2%.

For your use case, I assume it should be sufficient to make a first analysis about the time behavior. But since you mentioned, that 99% of the operations are running as expected with a variability of 25ms, I assume that here the accumulation of the time takes account and is causing the 1% writing operation to fail.

Unfortunately, I do not see an easy approach to fix that, since you would need to make advanced analysis in the time behavior of the SD card task and the executed ISR, to see how much time is accumulated and when its effect does preciously come into account.

For that, you could, for example, make longtime tests and save the time differences between the tasks into a log file and then calculate the accumulated time.

Since you are sending that data over USB to XDK-Workbench console, a python script might come handy to collect the data over the serial COM port and then log into a log file.

Please let me know if this was helpful and feel free to ask if you have further questions.

Kind regards,
Franjo
0 (0 Stimmen)
RE: Store sensor data in SD card
Antwort
19.10.18 07:23 als Antwort auf Franjo Stjepandic.

Hello Franjo,

Thank you very much for your effort.

I will try a few ideas i still have and maybe one of them will work.

If i find a solution i am going to update this threat.

Best regards,

Christian

0 (0 Stimmen)
RE: Store sensor data in SD card
Antwort
19.10.18 14:05 als Antwort auf Christian Köhler.
Dear Christian,

I am always glad to help.

I hope that you find an appropriate solution for your issue and I am looking forward to seeing it when you share it with the XDK community.

Please feel free to ask if you have any kind of further concern or questions.

Kind regards,
Franjo
0 (0 Stimmen)
RE: Store sensor data in SD card
Antwort
17.11.18 18:03 als Antwort auf Franjo Stjepandic.

Hello Franjo and Community,

i solved the problem!

It was actually a problem of the SD Card. I bought an industrial grade micro SD Card and used it with my program. Now i am able to sample and store sensor data up to 10 kHz without any error or data loss. I was really suprised that the industrial grade SD card makes such a big difference.

Meanwhile i faced a new problem. toring data with the new SD card worked well until the .csv file got to large. If the file reached a certain size (about 75 MB), the write operation took to long.

I solved that problem by checking the file size after any write operation. If the file sized got bigger than a defined value i create a new file and write in that one.

With this combination i was able to capture and store sensor data with 10 kHz sampling rate about nine hours without any data loss.

Thanks again for your help and your hints.

Best regards,

Christian

0 (0 Stimmen)
RE: Store sensor data in SD card
Antwort
19.11.18 14:17 als Antwort auf Christian Köhler.
Hello Chris,

thank you a lot for the informational update on your case and especially the solution regarding the .csv file length.

I'm glad you found a clean way to solve this. I really like your solution by implementing a function, which checks the current file size and creates a new file, if the size oversteps a certain length.

Also it is good to know that a casual SD card with the XDK can result into the writing issue you described earlier, and also that this specific issue can be solved by upgrading to an industrial SD card.

If you have any questions in the future, feel free to ask.

Kind regards,
Franjo
0 (0 Stimmen)