76
Technical support / Re:Creating a FIFO
« on: February 16, 2017, 02:38:14 PM »
Gary I really appreciate the quick turn around for your response on this subject.
I created a Custom Function (FIFO) that is called from the rising edge of relay 146
So when a message is created and stored into A$ the relay 146 is turned on
I then inserted your sample program into the Custom Function & removed your Call DequeueMsg
I then included # #Define Name Value
1 ENQ_Offset DM[1700] // DM1700 to DM1800 not used anywhere else
2 DEQ_Offset DM[1701]
3 FIFO_Cnt DM[1702]
4 FIFO_Size 15
5 FIFO_StartAddr 10
Also I changed your B$ to E$ as I was already using B$
When I run the simulator and Type in a message into A$ then I trigger Relay 147 nothing happens
I tried it many times and the value in FIFO_Cnt never changes
I see you use an Old Version of software and use ' for Rem Statements I found using the // makes the program easier to read. Can you please look over the program below & let me know where I went wrong.
Also when it is working how can I read the Stored Messages?
Actual program
// This function is used to store the latest 15 Fault Messages the the PLC has detected.
// This Custom Function was created with the expert help from GARRY DICKINSON
// 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 E$ 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 so we will discard the oldest to make room for the newest message.
// This action will overwrite the value of E$
ENDIF
SAVE_EEP$ A$,FIFO_StartAddr + ENQ_Offset // Write one entry into the FIFO
// Update the 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:
// Code:
// DequeueMsg - function to dequeue String data from the String FIFO
// On exit: E$ 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 E$
IF TestIO(MsgFifoEmpty)
// the FIFO is empty and there were no values to remove from the FIFO
// Just return a NULL String
//
E$ = ""
ELSE
// the FIFO was not empty, so return oldest message in E$]
E$ = 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
I created a Custom Function (FIFO) that is called from the rising edge of relay 146
So when a message is created and stored into A$ the relay 146 is turned on
I then inserted your sample program into the Custom Function & removed your Call DequeueMsg
I then included # #Define Name Value
1 ENQ_Offset DM[1700] // DM1700 to DM1800 not used anywhere else
2 DEQ_Offset DM[1701]
3 FIFO_Cnt DM[1702]
4 FIFO_Size 15
5 FIFO_StartAddr 10
Also I changed your B$ to E$ as I was already using B$
When I run the simulator and Type in a message into A$ then I trigger Relay 147 nothing happens
I tried it many times and the value in FIFO_Cnt never changes
I see you use an Old Version of software and use ' for Rem Statements I found using the // makes the program easier to read. Can you please look over the program below & let me know where I went wrong.
Also when it is working how can I read the Stored Messages?
Actual program
// This function is used to store the latest 15 Fault Messages the the PLC has detected.
// This Custom Function was created with the expert help from GARRY DICKINSON
// 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 E$ 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 so we will discard the oldest to make room for the newest message.
// This action will overwrite the value of E$
ENDIF
SAVE_EEP$ A$,FIFO_StartAddr + ENQ_Offset // Write one entry into the FIFO
// Update the 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:
// Code:
// DequeueMsg - function to dequeue String data from the String FIFO
// On exit: E$ 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 E$
IF TestIO(MsgFifoEmpty)
// the FIFO is empty and there were no values to remove from the FIFO
// Just return a NULL String
//
E$ = ""
ELSE
// the FIFO was not empty, so return oldest message in E$]
E$ = 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