Ffl ffu

Moosetracks

Member
Join Date
Apr 2016
Location
Missouri
Posts
35
I have used fifo's before, and I think I understand the general concept. However I am having trouble trying to create one that stores the information in an array where the newest information is at the beginning of the array, and the oldest is at the end. Is there a way to do this with a FFL / FFU pair?

This is what I want to end up with, but so far all my attempts have had them in the reverse order.

Array[1] = Newest
Array[100] = Oldest.

Thanks!
 
Sorry its a AB Contrologix L72. I looked a the lifo, but it unloads in the same order it goes in. It works until its full, but once its full and I use a LFU it takes the one from the newest position. At least that is what it did on mine. Is there a way to just shift everything down with a LFL and not have an LFU?
 
It looks like the FFL and LFL build the array in the same way (opposite what you want.) You may have to roll your own load/unload if the pattern of storage is that important.
 
The simplest way may be to use a COP instruction to shift the data in the order you want. You will need a dummy array to keep a copy of the values in as well.

If you don't need to keep track of the status bits like Done, Empty, and the Position of the array, then use a simple COPy instruction (or two).

EDIT: My little example is not tested, and the Length should probably be 99 in both COP instructions. Also, the trigger should be a oneshot or you fill up the array with NewData in a hurry.

FFL_upward.png
 
Last edited:
Thank you all for your replies. I had been looking at doing it via structured text or copy instructions, but was wondering if I was over complicating things.
 
Moosetracks,

Why are you not using Array[0], does this have special significance ? Anyway OkiePC has provided a workable solution, but I would use CPS instructions instead of COP.

On a [ONS] triggered rung...

CPS Array[1] Dummy[1] 99 CPS Dummy[1] Array[2] 99 MOV NewData Array[1].

Does the Newest to Oldest require that they are stored at indices 1 to 100, would it bother you if they were stored Oldest first, at Array[1] ? You can index into the Array with [100-Index] to retrieve values in Newest to Oldest order.

If you can suffer this, it makes the shifting simpler, and no Dummy buffer array is needed...

CPS Array[2] Array[1] 99 MOV NewData Array[100]
 
There is no significance in not using Array[0]. I was just using it to dump the old data in the FFU. My array is actually a UDT with a length of [500] so that makes for a lot of copy instructions.

We use the array to track widgets moving down the line and carry all their info in the UDT and shift the info down after so many encoder counts. I can use the data in reverse order, but its just one less thing to think about if its newest to oldest rather than oldest to newest.
 
There is no significance in not using Array[0]. I was just using it to dump the old data in the FFU. My array is actually a UDT with a length of [500] so that makes for a lot of copy instructions.

We use the array to track widgets moving down the line and carry all their info in the UDT and shift the info down after so many encoder counts. I can use the data in reverse order, but its just one less thing to think about if its newest to oldest rather than oldest to newest.

OK, your choice on the ordering.

If I were you I'd go for the COP or CPS solution, will execute faster than FIFO instructions, will use less memory (except for the buffer array), and much easier to program and understand.

And there's no extra COP instructions needed even if you are copying arrays of UDT tags, same code as if you are just copying DINT arrays.
 
Perhaps a little explanation is in order here
I wrote that up quick to post and I did forget to create the LBL loop my bad.
The new file shows it corrected. Sorry about that

First of all the ONS (One Shot) in the trigger rung
It’s just Housekeeping it insures that the file shift will only executes 1 time per trigger True. The trigger needs to reset or go false and true again to start the shift over. Otherwise it could go into runaway.

For this demo I have named the array File_Shift the number of elements is 500 (0-500) it can be anything you want any size you need

As for not using the File_Shift[0] if you look I load the Data (FS_Data) into File_shift[0] the base of the array with a True Trigger, at the same time I move 500 into FSIndex. To start the loop.

As long as FSIndex is > 0 the program will loop in Label FS_1 when FSIndex = 0 the rung will go False and the program will jump out of the loop and continue.

Inside each loop I start at the top (500), copy File_Shift[(FSIndex – 1)] to File_Shift[FSIndex]
499 copy to 500 (Move the data up 1 element in the array)
499 is moved to 500, 498 in mover to 499 all the way down to 0 is moved to 1 with each loop.
FSIndex=(FSIndex – 1) loop to LBL FS_1
The UID and UIE are optional they just prevent the data in File_Shift from getting changed while the file shift loop is running.

This method used only 1 data array so you always know which array to use in the program.
Moves the data from the array base 0 up to the top one step per trigger.

While I cannot say I have actually used this in a ControlLogix PLC I have used this same block in a Micrologix PLC with good success just a smaller array size.

I think this has advantages over the FIFL and FIFU
No Unload is needed and the load is just a simple COP or MOV command
Data can be loaded or copied in or out at any point in the array again with just a simple COP or MOV command.
If you load at index 0 then the last data remains in 0 until over writhen on the next load
But if you load at index 1 or higher the data will be over writhen with the next lower index value.
This can also be used with multidimensional arrays Array[100,5]
You could load all 5 words of a step at the same time and shifted together on 1 trigger.

File Shift.jpg
 
Perhaps a little explanation is in order here
I wrote that up quick to post and I did forget to create the LBL loop my bad.
The new file shows it corrected. Sorry about that

I spotted that you had no looping structure, but deciding against posting on it....

1. As a general rule I don't like JMP/LBL combinations, it makes code position dependant, and can be hard to debug. Granted in your case the JMP is on the same rung as the LBL, so takes the sting out of it. Are you aware of the FOR instruction ?

2. You wouldn't need the UID and UIE rungs if you used the CPS instruction instead of the COP... the data-set would be guaranteed valid.

3. Your branches are not necessary, these are just extra instructions, extra memory, and extra scan time.

4. OkiePC solution would execute many many times faster, because it moves blocks of data very quickly... Your code moves 1 element at a time, then does some math, then loops back, etc. etc., very slow by comparison.
 
Your right I could have put everything on 1 single line in the Logix 5000 it a holdover from the PLC2's and 500 that would have made it a lot cleaner.
I am aware of the for loops use then all the time in VB the don't wok well in ladder.
as for the cops v cop command cops would not do you any good here it only works if you are copying multiple word of a file at a time in this case I am only copying 1 word at a time.
the UID and UTE are not necessary but they will help with data integrity.

and I agree the use of LBL and jump s should be used with care they can get you in trouble I have seen programs where they get in loop and never exit all other processes stop but the PLC Is still running
copying files would not excite any faster at least not by much because the processor will still only moves 1 word at a time that's why you use the COPS on file copies with less housekeeping and overhead it may even execute faster.
keep in mind anytime you move data you run the risk of contaminating it and the other example you are moving the data 3 times for each trigger with the above you only move it 1 time and then only 1 word at a time.
I just offer it as an alterative
 
Last edited:
I did not recognize the full simplicity and significance of OkiePC's solution. I originally thought I would have to add several more copy instructions for each element of the array. Now that I see it I really like it.

Can someone explain the significance of CPS vs COP in this application? I read tech note 50235 and it seems like you would only need to use CPS if the data was IO or produce consume related.
 
It all depends on if some other code running at a higher interrupt level will read the array. With COP, it could catch the process part way through. With CPS, it can't interrupt the execution of the copy.
 

Similar Topics

For those who may recall I had posted previously about the FSC instruction, and while I have a better understanding of how to use it I find myself...
Replies
1
Views
1,382
A couple of questions with RS500 FFL-FFU instruction set. 1-Does the stack load from the bottom or the top, My stack is #N7:50 with a length of...
Replies
7
Views
1,597
Hey guys, I came across one question about the FIFO, FFL & FFU instruction. I want to measure the wheel speed, so I use the RPM encoder as the...
Replies
8
Views
4,002
When executing a FFU to unload the oldest value the data in the file is shifted down and the position value is changed. Does this shifting take...
Replies
12
Views
3,387
Hello, I'm currently programming a MicroLogix 1400 in RSLogix Micro, and I'm trying to put data into FIFO queues. Would you know how to use the...
Replies
4
Views
5,084
Back
Top Bottom