
WireBiter665 (Customer) asked a question.
First let me start by saying that I haven't done any serious programming with PLCs for probably 20 years or more so I may seem a bit ignorant of the lingo.
I am working on a program to create a queue for receivers to call for material when they run low. These receivers all share a common pump which can only service one receiver at a time. I would prefer to use the First In First Out method to limit the chances of a receiver running out of material. The current program uses a Drum Sequencer to iterate through each receiver and if the current receiver needs material, the Sequencer is halted while that receiver is filled. With 16 receivers and a 1 minute fill time, this potentially could allow for a receiver to wait 15 minutes before being filled which most likely would result in bad product or stopping production until it catches up.
I did a test program that worked almost perfectly with the inputs setting the FIFO input tag with the receiver number specific to that receiver and pushing it into the array then popping it out to turn on the proper fill station for that receiver in the same order. The issue I can see happening, though, is when the system is initially turned on, multiple receivers may all need material. If I have more than one input on (using rising edge NO) only one of them will actually get pushed into the array and the others will never get pushed into the array because their respective inputs would remain on and the rising edge would never trigger again.
I thought I could put the FIFO into a "When Called Task" and call to it each time the scan comes upon a receiver requesting material. The basic idea there was the rising edge contact comes on, sets the input tag (We will call it RECEIVER) to the proper receiver number, then sets a bit on for the push (we will call it the PUSH bit), then calls the FIFO task which has a NO contact that closes when the PUSH bit is on to enable the push function. Then after the FIFO, the PUSH bit gets reset and the FIFO call returns to the next rung in the main ladder which looks at the next receiver. In my head, logically that should work. It doesn't.
What I get is RECEIVER gets set to the proper number for that receiver and the PUSH bit turns on (I'm assuming) but what actually gets pushed into the FIFO is a "0" instead of the number contained in RECEIVER. After this, no more elements are pushed into the FIFO even if I turn off all the inputs and turn them back on.
I should also state that there are NO rising edge contacts for each function rung of the FIFO and none of the others are triggered during this so no popping or clearing is occurring. It simply gets the one pushed element (number 0) and then nothing more. When I trigger the pop rung, the element pops out and the element count goes back to 0. Then I can push another one in, but it's just more of the same....no matter what RECEIVER is set to, I only get a 0 pushed into the FIFO.
I'm sure I'm missing something simple, but I just can't see it. Any help would be appreciated.
FWIW, if they allowed naming the FIFO array with a tag and the ability to reuse that tag in more than one FIFO instruction to push/pop/peek/clear that same array, it would be fantastic.
Is it possible to provide your project? Maybe one with the somewhat works and one where you are trying to call task?
Yes. Sorry. I am still figuring some stuff out.
This is without the call and it works fine except when more than one receiver calls for material within the same scan cycle which could happen when the system is powered up or turned on. It will only add the last receiver in line and the others will never get added until their inputs are turned off then back on and as long as it needs material, that won't happen without human interaction.
This is the main ladder with the call.
This is the called Task. In here I've tried the Push and Pop rungs as both NO Edge contacts with "Or Out Coils" from the main ladder and as you see here.
I've also tried using a sort of bitwise summation for the receivers that are calling for material:
Receiver 1 = 1
Receiver 2 = 2
Receiver 3 = 4
Receiver 4 = 8
and so on then just add them up in line on the rungs and do a For Loop to push them into the FIFO. I didn't go too far down this path because I figured the number of receivers it could handle would be limited and I have a system that needs almost 100 receivers and another with 50.
I have never done any programming with this series of PLC's so that part I can't be of any help. However I am familiar with vacuum loading systems for raw material. The typical system with have a set number of receivers it can service. There would be a bit to enable or disable a certain unit if its not needed. There would also be a number for each unit that tells it how many seconds to load that unit. (some are smaller capacity and only need a few seconds of load time) Some controls even allow selection of a pump number so more then one can be calling for material at the same time, provided they are using different pumps.
Part of what you describe above could pose a problem. If each unit requires a full minute of load time and your saying with 16 receivers, one would run out before the 15 minutes (assuming all need to be filled) That to me would indicate the system capacity is too low. Your later post indicates the system may have to handle 50 to 100 receivers. Without knowing the specifics of the project, that to me would tell me the system you are designing is under rated for capacity and would never keep up in production.
Mike
True. I'll explain further, then. The first system I'm tasked with is the 16 receiver, 1 pump system. The next system after that is 68 receivers with 4 pumps. The last system will be almost 100 receivers with 8 pumps. The only reason I mentioned the number of receivers being an issue is for using the bitwise method for adding into the queue. With even the 68 receivers, I'd need a 68 bit numerical tag available to hold all possible combinations and this PLC doesn't have that. Even though there are multiple pumps, I still need to use a FIFO type queue so one receiver isn't waiting too long to be filled via the drum sequencer method.
Using the Drum sequencer method, there are times when some bins run out of material. There is enough of a buffer so it isn't always an issue. It's rare, but it happens. My task from my boss is to eliminate that issue completely. Once it is shown to work in the 16 receiver system, we will move on to the larger systems.
You should probably look at using Arrays. I would suggest start by getting your inputs into a boolean array. You can do a cpd or you can Pack the input bits into a 32 bit integer.
Then Unpack them into a boolean array. This allows you to index to the boolean bits as well as associate other arrays with information about each receiver. For insatnce you can create an array that has the number for each boolean array . ( Boolen Array 1= #1, Boolean array 5 = #5, etc..) You could also associate a timer preset with each receiver so you could vary the time depending on the size of the receiver calling.
You can also then use For/Next loops to examine or copy data from other arrays that are associated with each element of the array. You can also then use the Shift Rotate array to call information out of an array similarly to how the FIFO works.
Unlike the FIFO instruction you can see the information in the array so in my opinion it is easier to work with.
I did look at using arrays but what started to develop in my mind was a lot more complicated than what you showed here so thank you for that. I will give this a go and see how it works.
Much appreciated.
I did come up with a solution using the FIFO instruction. What I've learned (and I could be wrong so don't quote me) is that a FIFO is only able to do one push and/or pop instruction per full scan cycle. A "For Loop" or a "Called Task" that tries to push or pop more than one element during a single scan cycle tends to not work as expected.
What I finally worked out is using a Drum Sequencer to push the elements into the FIFO and increment the Sequencer each cycle. First scan checks receiver 1. If it needs material it gets pushed into the FIFO. Second scan checks receiver 2 and so on. Since each scan is only microseconds vs seconds, the chances of receivers jumping the queue to delay others that need material are almost non-existent. Certainly not to the point of delaying a receiver long enough to run out of material if it actually called for the pump first. This method is also easily scalable for as many receivers/pumps as the system might have.