Example: Memory ring FiFo (FB_MemRingBuffer)

The complete source can be found here: MemRingBufferExample.zip

 

The following example illustrates a simple application of the function block. Data records with the same length should be buffered ( but not not mandatory). The data records have the following structure:

TYPE ST_DataSetEntry :
STRUCT
    bFlag : BOOL;
    nValue : BYTE;
    sMsg : STRING(20) := 'Unknown';
END_STRUCT
END_TYPE

Interface of function block FB_DataSetFifo:

The application specific function block used in the sample: FB_DataSetFifo uses internally the function block FB_MemRingBuffer. This function block simplifies the inserting/removing of data records. Furthermore the new function block supplies the current percental fill status of the buffer and an overwrite option.

If the intput bOverwrite is set and the buffer is full, the oldest entry will be removed from the buffer and overwritten by the newest one.

FUNCTION_BLOCK FB_DataSetFifo
VAR_INPUT
    bOverwrite : BOOL;
    in : ST_DataSetEntry;
END_VAR
VAR_OUTPUT
    bOk : BOOL;
    nCount : UDINT;
    nLoad : UDINT;
    out : ST_DataSetEntry;
END_VAR
VAR
    arrBuffer : ARRAY[0..MAX_BUFFER_SIZE] OF BYTE; (* Buffer memory used by FB_MemRingBuffer function block *)
    fbBuffer : FB_MemRingBuffer;
END_VAR
VAR CONSTANT
    MAX_BUFFER_SIZE : UDINT := 1000;
END_VAR

 

The main program::

A rising edge at bReset  deletes all buffer entries. If you set bAdd = TRUE a new data record will be written into the ring buffer file, and when bRemove =TRUE the oldest data record is removed.  With a rising edge at bGet  the oldest data record is read but not  removed.

PROGRAM MAIN
VAR
    fbFifo : FB_DataSetFifo := ( bOverwrite := TRUE );
    newEntry : ST_DataSetEntry;
    oldEntry : ST_DataSetEntry;
    bSuccess : BOOL;
    nCount : UDINT;
    nLoad : UDINT;

    bReset : BOOL := TRUE;
    bAdd : BOOL := TRUE;
    bGet : BOOL := TRUE;
    bRemove : BOOL := TRUE;
END_VAR
IF bReset THEN
bReset := FALSE;
    (* reset fifo (clear all entries) *)
    fbFifo.A_Reset( in := newEntry, bOk=>bSuccess, nCount=> nCount, nLoad => nLoad );
END_IF

IF bAdd THEN
    bAdd := FALSE;

    (* create new or modify data set entry *)
    newEntry.bFlag := NOT newEntry.bFlag;
    newEntry.nValue := newEntry.nValue + 1;
    newEntry.sMsg := BYTE_TO_STRING(newEntry.nValue);

    (* add new entry to the fifo *)
    fbFifo.A_Add( in := newEntry, bOk=>bSuccess, nCount=> nCount, nLoad => nLoad );
END_IF

IF bGet THEN
    bGet := FALSE;
    (* get (but not delete) oldest entry *)
    fbFifo.A_Get( out => oldEntry, bOk => bSuccess, nCount => nCount, nLoad => nLoad );
END_IF

IF bRemove THEN
    bRemove:= FALSE;
    (* remove oldest entry *)
    fbFifo.A_Remove( out => oldEntry, bOk => bSuccess, nCount => nCount, nLoad => nLoad );
END_IF