FileStreamWriterLib is a file writer library for OMRON's NX/NJ series. The file writer (FileStreamWriter) in this library writes data to a file whenever the amount of data held in the buffer passed as a parameter exceeds a specified threshold. The buffer uses RingBufferLib. RingBufferLib is a ring buffer implementation for BYTE type arrays. The RingBufferLib implementation can be used in multi-tasking environments without locks, provided there's only one entity for reading and one for writing to the buffer. FileStreamWriter inherits this characteristic. It can also be flexibly combined with other programs that use RingBufferLib as their buffer.
The example below demonstrates combining FileStreamWriter with a simple Logger that uses RingBufferLib as its buffer, outputting logs to a file.
IF P_First_Run THEN
LOG_PATH := '/log_direct.txt';
LOGGING_INTERVAL := 1;
END_IF;
IF P_First_Run THEN
// Setup Logger.
Logger_init(Context:=iLoggerBufferContext,
Buffer:=iLoggerBuffer);
// Setup FileStreamWriter.
FileStreamWriter_configure(Context:=iContext,
Activate:=TRUE,
Path:=LOG_PATH,
FileOpenMode:=_eFOPEN_MODE#_WRITE_CREATE,
FlushThreshold:=(SizeOfAry(iLoggerBuffer) / 2),
FlushOnDeactivate:=TRUE);
iLogFileWriter.Enable := TRUE;
iWaitTick := LOGGING_INTERVAL;
END_IF;
// Logging at regular intervals.
Dec(iWaitTick);
IF iWaitTick < 1 THEN
iMsg := CONCAT('{"counter":', ULINT_TO_STRING(Get1usCnt()),
',"timestamp":"', DtToString(GetTime()),
'"}$L');
Logger_write(Context:=iLoggerBufferContext,
Buffer:=iLoggerBuffer,
Message:=iMsg);
iWaitTick := LOGGING_INTERVAL;
END_IF;
iLogFileWriter(Context:=iContext,
BufferContext:=iLoggerBufferContext,
Buffer:=iLoggerBuffer);
This program passes the Logger's buffer directly to FileStreamWriter as its buffer. This makes FileStreamWriter a consumer of the log data, consuming it as it's written.
You can also output logs to a file without consuming the log data. In the example below, FileStreamWriter has its own buffer, and it tracks writes to the Logger's buffer to output to a file.
IF P_First_Run THEN
LOG_PATH := '/log_tracking.txt';
LOGGING_INTERVAL := 1;
END_IF;
IF P_First_Run THEN
// Setup Logger.
Logger_init(Context:=iLoggerBufferContext,
Buffer:=iLoggerBuffer);
// Setup FileStreamWriter.
RingBuffer_init(Context:=iLogFileStreamBufferContext,
Buffer:=iLogFileStreamBuffer);
FileStreamWriter_configure(Context:=iLogFileStreamContext,
Activate:=TRUE,
Path:=LOG_PATH,
FileOpenMode:=_eFOPEN_MODE#_WRITE_CREATE,
FlushThreshold:=(SizeOfAry(iLogFileStreamBuffer) / 2),
FlushOnDeactivate:=TRUE);
iLogFileWriter.Enable := TRUE;
// Tracks Logger writes.
RingBuffer_createWriteTracker(Target:=iLoggerBufferContext,
Tracker=>iLoggerWrittenTracker);
iWaitTick := LOGGING_INTERVAL;
END_IF;
// Logging at regular intervals.
Dec(iWaitTick);
IF iWaitTick < 1 THEN
iMsg := CONCAT('{"counter":', ULINT_TO_STRING(Get1usCnt()),
',"timestamp":"', DtToString(GetTime()),
'"}$L');
Logger_write(Context:=iLoggerBufferContext,
Buffer:=iLoggerBuffer,
Message:=iMsg);
iWaitTick := LOGGING_INTERVAL;
END_IF;
// Gets the difference of the logger buffer into the log writer's write buffer.
RingBuffer_pullWrite(Context:=iLogFileStreamBufferContext,
Buffer:=iLogFileStreamBuffer,
Tracker:=iLoggerWrittenTracker,
Tracked:=iLoggerBufferContext,
TrackedBuffer:=iLoggerBuffer);
iLogFileWriter(Context:=iLogFileStreamContext,
BufferContext:=iLogFileStreamBufferContext,
Buffer:=iLogFileStreamBuffer);
The functionality of FileStreamWriter heavily relies on RingBufferLib, which aids in streaming data processing. However, RingBufferLib does not possess any special mechanisms to achieve such functionality. It is implemented solely using information required for the behavior of a ring buffer. Therefore, even if RingBufferLib were to become unusable, anyone could re-implement it.
The following environment is required to use this project.
Item | Requirement |
---|---|
Controller | NX or NJ |
Sysmac Studio | Latest recommended |
This project was developed in the following environment.
Item | Version |
---|---|
Controller | NX102-9000 Ver 1.64 |
Sysmac Studio | Ver.1.62 |
Use the library (FileStreamWriterLib.slr
) by following these steps.
-
Reference
lib/RingBufferLib.slr
in your project. -
Reference
FileStreamWriterLib.slr
in your project. -
Build the project and confirm there are no errors.
Both libraries use namespaces.
Ensure that there are no identifier conflicts with namespaces within your project.
The Sysmac project (FileStreamWriterLib.smc2
) includes an example program and can be used by following these steps.
-
Adjust the project configuration to match your operating environment.
Match the controller model. -
Run the program on the controller.
Transfer the program to the controller and start its execution.
Ensure the controller is ready to use an SD card. -
Check the output logs.
Confirm that output exists in the log files on the controller's SD card.
You can also test the operation in a simulator. When run in a simulator, the log files will be output to the simulator's virtual SD folder (C:\OMRON\Data\SimulatorData\CARD\Memory001).