A daily-totals write to the SD card runs clean the first morning, then errors the next. The FILEOPEN instruction sits in error while .MediaInstalled and .MediaMounted are both on. Manual retriggers succeed sometimes, fault other times, and the FILEWRITE behind it faults independently. That signature is a scan-timing race inside the ladder, and every hardware fix you reach for will pass its own test and change nothing.
Try These First, Watch Them Fail
These are the moves everybody makes on a night shift with a data log that stopped writing. Run them if you want, but know what they prove.
| Quick fix | Why it gets tried | Why it fails here |
|---|---|---|
| Swap in a new SD card | Intermittent write faults look like flash wear | The new card errors the same way. The controller already reported the card present and the filesystem mounted before the instruction faulted. |
| Reformat the card | Assumed corrupt FAT or wrong allocation | A clean format changes nothing when the first open of the day fails. Formatting fixes mount failures, not post-mount instruction errors. |
| Update the PLC OS (2.9.9) | Assumed a firmware bug in the file subsystem | Symptom survives the update. The fault is in how the rungs are triggered, not in the executive. |
| Power down, reseat the card | Contact or mount problem | Restores nothing beyond the first write, which then repeats the same pattern. |
| Add RAM file instructions alongside the SD instructions | Keep data flowing while you debug | Works, and it masks the real fault. The RAM file writes every time precisely because it does not behave like the SD file. |
The tell is the manual retrigger. If hitting the instruction by hand sometimes opens the file and sometimes does not, with no change to the media, the variable is time, not hardware.
Why the SD Instruction Errors and the RAM Instruction Never Does
PLC scan time protects I/O control, so anything that can stall the scan is built as a multi-scan, asynchronous device instruction. File access on removable media and Modbus communications both fall in that class. The instruction is enabled, takes ownership of the operation, hands control back to the executive, and signals completion on a later scan through its OnSuccess and OnError outputs. It may finish in-line on the same scan, or it may take ten scans.
RAM file operations do not have that latency. The RAM file system is a memory-resident structure, so open, write and close all resolve inside a single scan. Three consecutive rungs driven by one trigger therefore work perfectly, which is exactly the habit that carries over and breaks on the SD card.
An SD card is a block device behind a FAT filesystem and a card controller that does its own erase-block management and wear leveling. Latency on any single operation ranges from immediate to hundreds of milliseconds, depending on what the card's internal housekeeping is doing when you knock. Fire FILEWRITE on the same scan as FILEOPEN and the write executes against a file handle that is not valid yet, so it errors. The faulted sequence then leaves the handle in an indeterminate or still-open state, so the next day's FILEOPEN errors against a handle already in use. That is the one-good-day-then-nothing pattern.
Note what the status bits actually tell you. .MediaInstalled reports card presence. .MediaMounted reports that the filesystem is mounted. Neither says a word about whether a file operation completed, so both reading healthy while the instruction errors is normal and expected in this failure mode.
Confirm It Before You Touch Hardware
- Open a Data View and add the structure members for each file instruction, plus
.MediaInstalledand.MediaMounted. Read the error code member from the instruction's own structure after a fault, not from a guess. - Force a single FILEOPEN by hand with the rest of the sequence disabled. Count scans until success or error asserts. Anything over one scan confirms the instruction is asynchronous in your application.
- Check the trigger topology. If FILEOPEN, FILEWRITE and FILECLOSE share one enable or one one-shot, you have the fault.
- After a faulted cycle, check whether the handle is still open. If a fresh FILEOPEN errors but a FILECLOSE first then FILEOPEN succeeds, the orphan handle is confirmed.
- Log scan time across the write window. A modest bump is normal; a stall is not, and points at a mount or media problem instead.
Two healthy media bits plus a retrigger that sometimes succeeds is enough. Stop testing cards.
Rebuild the Write as a Stage Sequence
The asynchronous device instructions carry stage transitions in their OnSuccess and OnError outputs for this reason. Use them. One stage per operation, no operation enabled until the previous one has reported.
PROGRAM WriteDailyTotals
SG S0 // entry - defensive close
FILECLOSE handle
OnSuccess JMP S1
OnError JMP S1 // nothing open is not a failure here
SG S1
FILEOPEN <file> append mode
OnSuccess JMP S2
OnError JMP S10
TMR stage_timeout --> JMP S10
SG S2
FILEWRITE buffer
OnSuccess JMP S3
OnError JMP S10
TMR stage_timeout --> JMP S10
SG S3
FILECLOSE handle
OnSuccess JMP S4
OnError JMP S10
TMR stage_timeout --> JMP S10
SG S4 // done - stamp time, reset trigger, clear busy
EXIT
SG S10 // error handler
FILECLOSE handle // release the handle either way
OnSuccess JMP S11
OnError JMP S11
SG S11
INC retry_count
retry_count < limit --> JMP S1
retry_count >= limit --> SET fault_alarm, EXIT
- Move each file instruction onto its own stage. Nothing else changes about the instruction parameters.
- Put a defensive FILECLOSE at the head of the sequence. Treat its error as a pass; an already-closed handle is the condition you want. This is the DOS file-routine discipline, and the SD path needs it even though the RAM path never did.
- Open in append mode if you are accumulating daily totals, not overwrite.
- Give every stage a timeout timer that jumps to the error handler. Without it, a card that never returns parks the sequence and you lose data silently.
- Add a sequence-busy bit and interlock the 06:00 trigger against it, so a repeat trigger cannot restart an in-flight sequence.
- Route the error handler through a FILECLOSE before any retry, then cap retries and raise an alarm the operator sees.
- Keep the RAM file write as a parallel mirror if you want a same-scan copy on the C-more, but do not treat it as the retained record.
Verify Before You Trust the Log
- Trigger one full cycle manually and watch the stage bits step S0 to S4. Any stage that lingers longer than its timeout tells you which operation the card is slow on.
- Power down, pull the card, read the file on a PC. Confirm the record count and that yesterday's rows are still there, which proves append mode.
- Run three consecutive scheduled cycles without intervention. One good write proves nothing here; the original failure appeared on day two.
- Force the error path. Remove the card and trigger the sequence. It must land in S10, close the handle, retry, and set the alarm rather than hang.
- Cycle RUN to PROGRAM to RUN, then transfer a small program change and trigger again. The sequence must start from S0 and clear any handle left from the mode change.
- Compare the SD file against the C-more display data and the 06:00 screenshot email for the same day. Three sources agreeing is your acceptance test.
Pitfalls That Bring It Back
- RAM file loss on download. The RAM file system is cleared by a program change or update. That is the reason for moving to SD in the first place, so never let the SD sequence quietly fail back to RAM-only logging.
- Repeat triggers. A one-shot that re-fires while the sequence is mid-flight restarts the open against a live handle. Interlock it.
- Hot card removal. Pulling a mounted card mid-write corrupts the FAT and takes the log with it. Power down or unmount first.
- Missing timeouts. A stage with no timer waits forever and produces no alarm. Data stops, nobody knows for a week.
- Card class. Consumer cards with aggressive internal housekeeping give the widest latency spread. Use an industrial-grade card and format it to the filesystem the hardware manual specifies before assuming logic is at fault again.
- The same mistake elsewhere. Modbus reads and writes are asynchronous for the same reason. Any place you fire two of them from one rung and assume the first finished, you have built the identical race.
Stop and open a ticket with AutomationDirect technical support if the sequence is properly staged, the handle is confirmed closed, both media bits are on with a known-good industrial card, and FILEOPEN still errors. Capture the instruction's error code from the structure member and the system error log before you call, because the first question will be which operation reported which code. If the card mounts on a PC but the controller cannot mount it, that is a media or filesystem problem, not ladder logic, and it belongs with support rather than another rewrite.
FAQ
Does the BRX RAM file system survive a program update?
No. The RAM file is erased on a program change or update to the PLC, which is why retained daily totals belong on the SD card. Keep the RAM file only as a same-scan mirror for display.
Can I put FILEOPEN, FILEWRITE and FILECLOSE on three consecutive rungs with one trigger?
Only for RAM files, which complete inside one scan. SD card file instructions are asynchronous and may take many scans, so the write executes against an invalid handle and errors.
Can a bad SD card cause intermittent FILEOPEN errors?
It can, but not this pattern. If .MediaInstalled and .MediaMounted are both on and a manual retrigger sometimes succeeds with no media change, the fault is a sequencing race.
Does updating the BRX OS to 2.9.9 fix SD file write faults?
No. The symptom persists after the update because the fault is program structure, not firmware. Restructure the write as a stage sequence with OnSuccess and OnError transitions.
Can I remove the SD card while the PLC is running?
Power down or unmount first. Pulling a mounted card during a write corrupts the FAT and can take the whole log file with it, which then looks like a fresh instruction fault on the next open.