Openlog Fileopen error

I have openlog updated to v4.3. My config
115200,26,3,3,0,0,0,100,100
baud,escape,esc#,mode,verb,echo,ignoreRX,maxFilesize,maxFilenum

Issue faced:
when i have 100 MB file present which comes in next file to be logged after reset then it fails with error file open and blue LED blinks. I tried with 50 MB too same issue faced.

I have MCU connected over UART. I tried standalone logger too.

Please suggest what to do

Your config has mode=3, which is MODE_ROTATE…in that mode:

  • newLog() increments the file number every time a file fills up (not just on power-up), and when it passes your maxFilenum (100 in your config), it wraps back to file LOG00000.TXT.
  • appendFile() then opens that filename with O_CREAT | O_TRUNC | O_WRITE — it never checks size or existence first, it just tries to truncate-and-reuse whatever file already has that number.

So once you’ve rotated through 100 files and wrap back around to a slot that already holds a full 100MB file, the firmware tries to truncate that large file in place. I think that truncate/open call is what’s failing.

Why the “error file open” + blue LED is a bit misleading

There’s a quirk in the firmware itself:

case ERROR_FILE_OPEN:
  NewSerial.print(F("file.open"));
  blinkError(ERROR_SD_INIT);   // <-- should be blinkError(ERROR_FILE_OPEN)

ERROR_FILE_OPEN is supposed to blink 9 times, but it’s calling blinkError(ERROR_SD_INIT), which blinks 3 times. So the blink pattern you’re seeing (3 blinks, right?) makes it look like an “SD card failed to init” error, when it’s actually the file-open failure on rotation

Why the truncation itself is failing

Opening with O_TRUNC on an existing large file requires SdFat (this firmware is still on the old v1.1.4 SdFat library) to walk and free the entire existing cluster chain. This tends to break when:

  • that file wasn’t cleanly closed the last time it was written (e.g., a reset/power-loss happened mid-write to that same file number in a previous lap), leaving an inconsistent directory entry/cluster chain, or
  • the card has a lot of clusters to free (small allocation unit size relative to 50–100MB) and something in that chain is cross-linked or otherwise malformed :-/

Tests to do:

  1. Pull the card, manually delete the specific LOG#####.TXT that’s failing, put it back, and power up. If it then works fine, that confirms it’s the truncate-on-a-specific-file issue, not “large files in general.”
  2. Full-format the card (not quick format) with the SD Association formatter, then let OpenLog cleanly create a 100MB file from scratch (don’t interrupt it mid-write) and see if wraparound onto that file succeeds — this tells you whether it’s file corruption from an earlier abrupt reset vs. a genuine size limitation.
  3. Try a larger allocation unit size when formatting — fewer, bigger clusters means less work for the truncation

You can also just modify the firmware directly:

If you’re comfortable at this level, the cleanest fix is patching appendFile() for MODE_ROTATE to sd.remove(fileName) first, then open fresh with O_CREAT | O_WRITE, instead of relying on O_TRUNC. Remove-then-create tends to be more robust than in-place truncate for very large files on this library.

If this reproduces reliably, it’s worth filing on the sparkfun/OpenLog GitHub with steps to reproduce the problem — I didn’t find an existing issue for this specific rotate/truncate interaction.

Hi,
Thanks for the response. Apart from avoiding quick format, do i need to set allocation unit size. any recommended card type?

with the binary of v4.3 i get error
Serial port COM8 opened
112Error file.open112Error file.open112<112Error file.open112Error file.open112Error file.open112Error file.open

but when i flash code from Arduino IDE im not getting <
Serial port COM8 opened
11121211211211211211211212112

This happens when i have 100MB files 100 number (for empty card this is not see). Since 100 MB log takes time I generate txt with fixed data. Same issue seen with Open logger generated files of 100 MB. The cmd generated size files work if i reduce maxSize to 40 MB

I have tried below change. but still not getting < with 100 number 100 mb files in card. I also have a “file.txt” apart from config and 0 to 100 log files.
if (sd.exists(file_name)) {
sd.remove(file_name); }
if (!workingFile.open(file_name, O_CREAT | O_WRITE)) {
system_error(ERROR_FILE_OPEN); }

with remove too it fails at remove now. previously at open

Please check

I really like the Sandisk and Kingston ones we sell

Yes, set it explicitly rather than trusting a default:

  • Format tool: use the official SD Association formatter, full format, not Windows quick format.
  • Allocation unit size: go bigger than the default the formatter picks for your card size — 32KB or 64KB. The reason this matters directly for your bug: the number of FAT cluster-chain entries that have to be walked/freed on truncate()/remove() scales with cluster count, not file size. A 100MB file at 4KB clusters is ~25,600 entries to process; at 32KB clusters it’s ~3,200 — roughly 8x less work for the exact operation that’s failing. This is very likely why 40MB works and 50/100MB don’t: you’re bumping into a time/entry-count threshold, not a hard size limit.
  • Filesystem: must be FAT16/FAT32 — this firmware is pinned to SdFat v1.1.4 (per the header comment), which does not understand exFAT.
  • Card type/size: stick to SDHC (4–32GB), not SDXC. Old SdFat versions have spotty SDXC support. For brand, industrial-grade cards (SanDisk Industrial, Kingston Industrial, etc.) are worth it here — consumer cards can have unpredictable latency spikes from background wear-leveling/garbage collection, and that’s exactly the kind of variability that would push a marginal-timing operation over the edge intermittently (which matches your “sometimes get <, sometimes don’t” behavior).

What your new logs are telling us

This part is more concerning than the original report:

112Error file.open112Error file.open112<112Error file.open...

1 and 2 are the boot-sequence prints from setup() (1 = serial up, 2 = SD initialized). Seeing 1, 2 repeat over and over — not just one Error file.open followed by the infinite blink loop — means the device is resetting itself repeatedly, not just sitting in blinkError(). blinkError() never returns, so under normal firmware behavior you’d only ever see one 112Error file.open and then silence except the LED. Repeated boot sequences mean something external is resetting OpenLog: most likely your host MCU is toggling the OpenLog reset line because it’s waiting for < and timing out, then retrying. Worth confirming — is your MCU’s init routine cycling the reset pin? If it is, that reset is landing mid-operation every time, which would also explain things getting progressively worse (a reset in the middle of a FAT truncate/free-chain operation can leave that specific file’s cluster chain in a worse, half-freed state than before).

Then with your own IDE-compiled build:

11121211211211211211211212112

No “Error file.open” text at all now — just repeated 1,1,2 with no error message ever printing. That’s a harder failure than a graceful open()/remove() returning false — it looks like a crash or reset happening before the code even reaches the point of printing the error, which is consistent with something like a stack overflow or brownout on the tight 2KB SRAM of the ATmega328 while it’s mid-walk through a large/fragmented cluster chain.

One thing to rule out here specifically: when you compiled from the Arduino IDE, did you pin SdFat to the exact same v1.1.4 referenced in the source comments? If Library Manager pulled a newer SdFat (2.x is a full rewrite with a different API/class structure), you could be running meaningfully different internals than the shipped v4.3 binary even though the .ino looks the same. That would explain why your build behaves worse than the precompiled binary rather than the same.

On your patch making it fail at remove() instead of open()

That’s actually useful diagnostic info: it tells me the bottleneck isn’t the O_TRUNC logic specifically, it’s the underlying cluster-chain deallocation itself, which both truncate() and remove() have to do. My earlier suggestion just moved where in that same expensive operation the reset lands.

Given the card has been rotating through the same 100 file slots repeatedly, it’s plausible free space has become fragmented over time — a “100MB” file’s clusters can end up scattered across the card after many rotate cycles, meaning the chain isn’t a handful of contiguous FAT entries but potentially thousands of scattered ones, each requiring effectively random-access reads on SPI (slow, no burst). That’s consistent with 40MB working, 50/100MB not.

Suggested next steps, in order of information value

  1. Disconnect the MCU reset line entirely and test standalone with a UART terminal, so nothing external can interrupt an in-progress operation. Give it real time (30+ seconds) before assuming it’s hung — see if it eventually completes or truly locks up.
  2. Pin SdFat to exactly v1.1.4 for your IDE build and recompile, to make it an apples-to-apples comparison with the shipped binary.
  3. Reformat the test card with a large allocation unit (32 or 64KB) and re-run your remove()-then-open() patch — if that resolves it, that confirms the cluster-count/fragmentation theory directly.
  4. If it’s still failing standalone with a fresh, non-fragmented card, that points away from fragmentation and more toward a hard timing/memory ceiling in v1.1.4’s chain-walking code on the 328’s limited RAM — at that point it becomes a firmware-level fix (possibly bounding how much work is done per loop() iteration, or moving to a newer SdFat with better large-file handling) rather than a format/config workaround.