Lorne - I've attached a PLC program to this message that demonstrates a simple FIFO mechanism for storing string messages in non-volatile memory.
I would suggest that you play with this program using the i-TRiLOGI simulator until you can understand how it works.
I use the #Define mechanism exhaustively to create readable names for variables. So the first thing that you need to do is open one of the custom functions and open the #Define table.
# #Define Name Value
1 ENQ_Offset DM[1]
2 DEQ_Offset DM[2]
3 FIFO_Cnt DM[3]
4 FIFO_Size 5
5 FIFO_StartAddr 1
You will note that use 3, 16-bit integer variables to manage the FIFO. ENQ_Offset is used when a message is added, enqueued, to determine where in non-volatile memory to write the data.
DEQ_Offset is used when a message is removed, dequeued, to determine where in non-volatile memory to retrieve the data.
FIFO_Cnt is the current number of message stored in the FIFO
The FIFO_Size define determines the FIFO size in the count of messages. For my test code, it is 5. Adjust as needed
FIFO_StartAddr is the starting address in non-volatile memory. For my test code the starting address is 1. Adjust as needed.
There are 2 RELAYs that you can use in both ladder logic and in custom functions to determine the current FIFO status:
[*]MsgFifoEmpty - set when FIFO is empty and holds no messages
[*]MsgFifoFull - set when the FIFO is full and if a new message is equeued then the oldest message in the FIFO will be lost
[/list]
This is the entire custom function to enqueue a string in the FIFO:
' EnqueueMsg - function to enqueue an array of 40 character messages into the Message FIFO
'
'
' On entry A$ holds the string to enqueue
' This FIFO uses the SAVE_EEP$ statement to store data in the non-volatile memory.
' The message length is limited to 40 characters
'
' On exit: The A$ will be written to the FIFO
' The FIFO_FULL and FIFO_EMPTY RELAYS may be affected.
' The DM[] variables ENQ_Offset, DEQ_Offset and FIFO_CNT may be updated.
' If the FIFO is full then the B$ variable will be written with
' the oldest message in the FIFO to make room for the new message
' If the FIFO is FULL, then discard oldest message in the FIFO
'
IF TestIO(MsgFifoFull)
' the FIFO is full, but Lorne is OK with overwriting old messages
' so we will discard the oldest to make room for the newest message.
' This action overwrite the value of B$
'
Call DequeueMsg
ENDIF
SAVE_EEP$ A$,FIFO_StartAddr + ENQ_Offset ' write one entry into the FIFO
' Update FIFO index, counter and flags
'
ENQ_Offset = (ENQ_Offset + 1) MOD FIFO_Size
FIFO_Cnt = FIFO_Cnt + 1
IF FIFO_Cnt = FIFO_Size
SetIO MsgFifoFull ' the FIFO is full and cannot accept more data
ENDIF
ClrIO MsgFifoEmpty ' FIFO cannot be empty
This is the entire custom function to enqueue a string in the FIFO:
' DequeueMsg - function to dequeue String data from the String FIFO
'
' On exit:
' B$ will hold the oldest string in the FIFO.
' The FIFO_FULL and FIFO_EMPTY RELAYS may be affected.
' The DM[] variables ENQ_Offset, DEQ_Offset and FIFO_CNT may be updated.
' Return message from FIFO in B$
'
IF TestIO(MsgFifoEmpty)
' the FIFO is empty and there were no values to remove from the FIFO
' Just return a NULL String
'
B$ = ""
ELSE
' the FIFO was not empty, so return oldest message in B$]
'
B$ = LOAD_EEP$(FIFO_StartAddr + DEQ_Offset)
' Update index, FIFO count and flags
'
DEQ_Offset = (DEQ_Offset + 1) MOD FIFO_Size
FIFO_Cnt = FIFO_Cnt - 1
IF FIFO_Cnt = 0
SetIO MsgFifoEmpty ' the FIFO is empty and there is no more data to remove
ENDIF
ClrIO MsgFifoFull ' FIFO cannot be full
ENDIF
This approach may seem like lot of work, but it actually takes very few lines of code and executes very rapidly. This is classic computer science done without the help of modern computer languages.
Best regards,
Gary D*ckinson