FileStreamReaderLib is a file reader library for OMRON's NX/NJ series. The file reader within this library, FileStreamReader, continuously reads data from a file into a buffer passed as a parameter. It reads whenever the number of writable bytes in that buffer 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. FileStreamReader inherits this characteristic. It can also be flexibly combined with other programs that use RingBufferLib as their buffer.
The example below demonstrates reading a triplet of REAL values from a file. The buffer's capacity is smaller than the file size, ensuring that data is read from the file periodically according to the defined threshold.
IF P_First_Run THEN
DATA_FILE_PATH := '/points.bin';
POINTS_NUM := 2000;
READ_BUFFER_INTERVAL := 1;
END_IF;
IF P_First_Run THEN
// Setup the data buffer.
RingBuffer_init(Context:=iDataBufferContext,
Buffer:=iDataBuffer);
// Setup the reader.
FileStreamReader_configure(Context:=iFileReaderContext,
Activate:=TRUE,
Path:=DATA_FILE_PATH,
ReadThreshold:=(SizeOfAry(iDataBuffer) / 2));
// REAL * 3
POINTS_SIZE := 12;
END_IF;
CASE iState OF
// Generates points.
0:
iPointsGenerator.Path := DATA_FILE_PATH;
iPointsGenerator.Num := POINTS_NUM;
iPointsGenerator.Execute := TRUE;
Inc(iState);
1:
IF iPointsGenerator.Done OR iPointsGenerator.Error THEN
iPointsGenerator.Execute := FALSE;
Inc(iState);
END_IF;
// Start streaming points from the data file.
2:
iOk := TRUE;
iFileReader.Enable := TRUE;
Inc(iState);
3:
RingBuffer_read(Context:=iDataBufferContext,
Buffer:=iDataBuffer,
Out:=iBinPoints,
Size:=POINTS_SIZE,
ReadSize=>iBinPointsSize);
IF iBinPointsSize > 0 THEN
AryByteTo(In:=iBinPoints[0], Size:=iBinPointsSize, OutVal:=iPoints);
iReadPointX := iPoints[0];
iReadPointY := iPoints[1];
iReadPointZ := iPoints[2];
AryByteTo(In:=iGenePoints[iGenePointsHead], Size:=POINTS_SIZE, OutVal:=iPoints);
iGenePointX := iPoints[0];
iGenePointY := iPoints[1];
iGenePointZ := iPoints[2];
iGenePointsHead := iGenePointsHead + POINTS_SIZE;
iOk := iOk AND iReadPointX = iGenePointX;
iOk := iOk AND iReadPointY = iGenePointY;
iOk := iOk AND iReadPointZ = iGenePointZ;
iWaitTick := READ_BUFFER_INTERVAL;
Inc(iState);
ELSIF FileStreamReader_isEOF(Context:=iFileReaderContext) THEN
iState := iState + 2;
END_IF;
4:
Dec(iWaitTick);
IF iWaitTick < 1 THEN
Dec(iState);
END_IF;
// Finish streaming points.
5:
FileStreamReader_deactivate(Context:=iFileReaderContext);
iFileReader.Enable := FALSE;
Inc(iState);
END_CASE;
iPointsGenerator(GenerateData:=iGenePoints);
iFileReader(Context:=iFileReaderContext,
BufferContext:=iDataBufferContext,
Buffer:=iDataBuffer);
The functionality of FileStreamReader 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 (FileStreamReaderLib.slr
) by following these steps.
-
Reference
lib/RingBufferLib.slr
in your project. -
Reference
FileStreamReaderLib.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 (FileStreamReaderLib.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 that the generated data matches the data read from the file.
You can also run a functional check using the simulator. If running on the simulator, create the data file in the simulator's virtual SD card folder (C:\OMRON\Data\SimulatorData\CARD\Memory001).