Question for fat16lib


First of all thank you for your great SD card library. I just have a question regarding my code. I have made a program that reads a CSV text file line by line, parses the data then sends it to an external DAC. I am using your getline example as the basis of the code. The code runs successfully, but I can see there is a disturbance in my output, I should have nice clear sinusoidal waveforms, but there seems to be flat spots on each of them. Please see the picture below. The flat spots for each of the three waveforms happen at the same time, from what I gather this could be a moment in time where an internal buffer from the library gets updated. Is there a way around this? Is it possible to read from the card directly one line at a time instead of storing 512 bytes in a buffer? Basically I need to have a nice clear sinusoidal signal as an output.

My code is below, the CSV text file contains HEX values like so [ F12C, BBBB, BA32 ], each line is parsed and the ASCII hex is converted to actual hex, then outputted to the DAC vis SPI.

void showWaveform(char waveTEST[] ) {

  // open test file
  SdFile rdfile(WaveTEST, O_READ);

  // check for open error
  if (!rdfile.isOpen()) {
    Serial.println("error opening file");

  // read lines from the file
  while ((n = rdfile.fgets(line, sizeof(line))) > 0) {
    if (line[n - 1] == '\n') {

    strcpy(line1, strtok(line , ","));
    strcpy(line2, strtok(NULL, ","));
    strcpy(line3 , strtok(NULL, " "));

   one=strtol(line1, NULL, 16);//converts to binary hex
   two=strtol(line2, NULL, 16);
   three=strtol(line3, NULL, 16);




My output waveform is shown below, any help would be much appreciated.

Is there a way around this?


Is it possible to read from the card directly one line at a time instead of storing 512 bytes in a buffer?

Make each record 512 bytes long. One read == one record. Wasteful, but at least each record will take the same amount of time to read.

I havent used a circular buffer before, could that help in this situation?

I havent used a circular buffer before, could that help in this situation?

How? The SD library uses a buffer. How will your using another buffer, circular, rectangular, or square, help the fact that the SD library returns data from the buffer most of the time (quickly), and actually reading data from the card only when the buffer does not contain enough data to satisfy the request (which takes a lot longer)?

Ok thanks for the input PaulS, I will look into something else.

This is a classic, to me anyways, example of a hard real-time system. Timing is tight and when you violate timing, catastrophe (sort of) happens.

Okay, so you're underflowing a buffer -- now what? You have two choices: speed up how fast you get the data, or slow down how fast you consume the data, and period of your loop ends up being the time it takes to do the thing that takes the longer time. And because in this case the "smoothness" of the output is a direct function of the period of the loop, every iteration of the loop must take the same amount of time. Put another way, the quickest thing the loop does (writing to the DAC) must be padded out to equal the time it takes to do the longest thing (refilling the buffer), making this whole smoothness thing really, really slow.

If smoothness is the goal, then yeah, you're fine at this point. But I'm assuming speed and smoothness are required, so you must somehow do both at once: read from the buffer and write to the DAC at the same time. This is where multi-threading comes in, but it's something as far as I understand, isn't something vanilla-Arduino supports.

Sorry if I misunderstood the original problem... it's a slow day at work, but this post reminded me of when I took RTOS in school and my simple mind was totally blown.

Yes Pizzle, I think I may need to look into another microcontroller with a RTOS. :sob: