Corrupted data structure after file open?

Status
Not open for further replies.

Talkiet

Well-known member
This is doing my head RIGHT IN...

I have a program which scans the I2C bus at setup and creates an array of the valid MLX90614 temp sensors so later on it only scans the ones that were detected at startup.

This worked great until I integrated some code which opens a couple of files on SDcard to log both the complete raw data, and the laptimes (also calculated by the program).

What's happening is that before opening either log file, the array is fine, and the code works great. After opening the first LOG file, the array is fine and the code works normally. after opening the second file however, the array is all stamped on and full of garbage.

This is the relevant snippet of code. All this does is open 2 files, and prints out the contents of the valid I2C array after the first and second file opens. The data below (26,27,28,42,43,44) is valid, the second set (69, 83, 46, 116, 120, 116) is garbage.

Code:
byte readsensors[64];
{snip}

      sprintf(filename, "%02u%02u%02u-%02u%02u%02u.txt", fix_data.dateTime.year, fix_data.dateTime.month, fix_data.dateTime.date, fix_data.dateTime.hours, fix_data.dateTime.minutes, fix_data.dateTime.seconds);
      if (logFile.open(filename, O_CREAT | O_WRITE | O_EXCL)) {
        logFile.println(F("Time;Distance;Lap;Brake;Throttle;Gear;RPM;KPH;KPHGPS;Heading;Roll;Pitch;Temp;Latitude;Longitude"));
        DEBUG_PORT.print(" Creating log file : ");
        DEBUG_PORT.println(filename);
      } else {
        initerror();
      }
      DEBUG_PORT.println("After LOG file opens");
      debugloop = 0;
      while (debugloop < nMLXdevices) {
        DEBUG_PORT.print(debugloop); DEBUG_PORT.print(" : "); DEBUG_PORT.println(readsensors[debugloop]);
        debugloop++;
      }

      sprintf(filename, "%02u%02u%02u-%02u%02u%02u-LAPTIMES.txt", fix_data.dateTime.year, fix_data.dateTime.month, fix_data.dateTime.date, fix_data.dateTime.hours, fix_data.dateTime.minutes, fix_data.dateTime.seconds);
      if (lapFile.open(filename, O_CREAT | O_WRITE | O_EXCL)) {
        lapFile.println(F("Lap;Time"));
        DEBUG_PORT.print(" Creating laptime file : ");
        DEBUG_PORT.println(filename);
      } else {
        initerror();
      }

      DEBUG_PORT.println("After LAP file opens");
      debugloop = 0;
      while (debugloop < nMLXdevices) {
        DEBUG_PORT.print(debugloop); DEBUG_PORT.print(" : "); DEBUG_PORT.println(readsensors[debugloop]);
        debugloop++;
      }

And this is the troubleshooting printout...

Code:
Laptimer started
Ruapuna : -435307000 : 1724808240 : -435304940 : 1724809940 : -436153118 : 1723706322 : 12.94
DunlopLoop : -436151360 : 1723713960 : -436152110 : 1723714710 : -436153118 : 1723706322 : 0.06
 Creating log file : 171231-042259.txt
After LOG file opens
0 : 26
1 : 27
2 : 28
3 : 42
4 : 43
5 : 44
 Creating laptime file : 171231-042259-LAPTIMES.txt
After LAP file opens
0 : 69
1 : 83
2 : 46
3 : 116
4 : 120
5 : 116
568009379.40,0.099,0,2,185.7,-43.x,172.y,52.10,7,4,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,26.11,25.23,24.17,0.00,33.79,33.91,27.25,0.00
568009379.60,0.232,0,1,0.0,-43.x,172.y,0.00,0,3,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,26.11,25.23,24.17,0.00,33.79,33.91,27.25,0.00

I'm using a Teensy 3.5 and I don't seem to be using anything like all the memory...
Code:
Sketch uses 68696 bytes (13%) of program storage space. Maximum is 524288 bytes.
Global variables use 10404 bytes (5%) of dynamic memory, leaving 186204 bytes for local variables. Maximum is 196608 bytes.

Using SdFat.h

It looks like something is stomping on memory - is there anything I can do to verify this or trace why the second file open is doing it (NOT the first!)

Cheers - Neil G
 
I cannot see that you close the logfile before opening the lapfile.
only ONE file can be open at any time, as Filesystem used global variables and structures.
use open/write(append)/close paradigma
 
Last edited:
Oh wow... It looked to me like the original software was working on a different platform (arduino M0) with 2 files open. It certainly created both files on the card. I didn't notice any issues until earlier today when I had some string processing go haywire (so I refactored the code to remove the string) and then the issue apparently moved onto the array I showed.

I'll disable the second file creation and writing and see if that stabilises things. It's a bit unfortunate as having 2 files open at once is pretty handy for this use but if it kills things then I'll have to think of a way around it.

Is there a reasonably straightforward way to accomplish this? Or am I stuck with interleaved open/close? I presume that is hideous from a performance and transaction point of view?


Cheers - N
 
Killing the second file creation has restored the expected functionality of the array. In fact due to a misplaced "if (writelapfile)" (by one line) the first time round it's this line doing it.

Code:
       sprintf(filename, "%02u%02u%02u-%02u%02u%02u-LAPTIMES.txt", fix_data.dateTime.year, fix_data.dateTime.month, fix_data.dateTime.date, fix_data.dateTime.hours, fix_data.dateTime.minutes, fix_data.dateTime.seconds);

I am a total Arduino Noob, but that's not actually opening the file is it?

For clarification, this solves the problem:

Code:
      if (writelapfile) {
        sprintf(filename, "%02u%02u%02u-%02u%02u%02u-LAPTIMES.txt", fix_data.dateTime.year, fix_data.dateTime.month, fix_data.dateTime.date, fix_data.dateTime.hours, fix_data.dateTime.minutes, fix_data.dateTime.seconds);
        if (lapFile.open(filename, O_CREAT | O_WRITE | O_EXCL)) {
          lapFile.println("Lap;Time");
          DEBUG_PORT.print(" Creating laptime file : ");
          DEBUG_PORT.println(filename);
        } else {
          initerror();
        }
      }

And this preserves the problem

Code:
      sprintf(filename, "%02u%02u%02u-%02u%02u%02u-LAPTIMES.txt", fix_data.dateTime.year, fix_data.dateTime.month, fix_data.dateTime.date, fix_data.dateTime.hours, fix_data.dateTime.minutes, fix_data.dateTime.seconds);
      if (writelapfile) {
        if (lapFile.open(filename, O_CREAT | O_WRITE | O_EXCL)) {
          lapFile.println("Lap;Time");
          DEBUG_PORT.print(" Creating laptime file : ");
          DEBUG_PORT.println(filename);
        } else {
          initerror();
        }
      }

I am off to read up on what that is, but is this possible it's something else?

Cheers - N
 
Odd. Changing the sprintf line in the LAPfile section to this:

Code:
      sprintf(filename, "%02u-LAPTIMES.txt", fix_data.dateTime.seconds);

Seems to be completely reliable (a few dozen trials with expected results vs 100% failure rate with the long line).

I guess I'll figure out a new way to name the files!

Cheers -N
 
I'm so embarrassed :) But I should close this loop. The code I was following didn't declare a large enough char for the laptime filename. I made that bigger and it seems to work now...

On to more interesting ways to fail :)

Cheers - N
 
Status
Not open for further replies.
Back
Top