Hopper High/Low Priority Request Logic

seat14

Lifetime Supporting Member
Join Date
Dec 2005
Location
Seattle
Posts
10
I have 10 Hoppers each with 2 level sensors; one is at the 75% full level and the other is at the 25% full level.
I need to fill hoppers that fall below the 25% level (High Priority) first, then any that fall below the 75% level (Normal Priority).
I’m thinking I need two ques one for High Priority and one for Low Priority. If the High Priority que is 0 look at the Low Priority que. If a hopper is filling and another goes to High Priority, it will need to be moved out of the low priority que into the high. But before the high priority can start filling the current hopper must finish filling.
I need help understanding how to set up the que. I had considered using two FFL Instructions, but that will not work since I have two priorities. And it will always look first at the low before the high priority. Once it went high I could not figure out how to remove it from the low priority FFL
Just in case it maters I am using a CompactLogix processor.
 
Don't make it hard. Way back in the 1980s the company I worked for implemented something similar. Higher priority tasks were assigned to a 16 bit word. Each high priority task was represented by a bit in the word. The same went for low priority tasks
Within the high priority tasks the lowest significant bit was of higher priority than the other high priority tasks. Something similar was done for the low priority tasks. You probably don't care about the small differences in priority. Once upon a time there were PLC instructions like Encode and Decode that would find the least signicant bit set and convert that to a number. The other command would is a number to set a particular bit. This made determing what task to run easy.

I agree the two FFL instructions might work just as well. I am not that familiar with the FFL instruction but I would use bits instead of a queue.
 
First of all you have not provided enough information for anybody to give the answer you want
FFL’s I am afraid they are heading you in the wrong direction.
A better choice would be to use 2 FIFO ‘s
I see this a lot, you and others need to understand the difference
A FFL is File Fill Load program that copies the value of the source word to every element of the file array based on the start index number and length to be filled. The important thing here is the FFL fills all the elements file array
The FIFO First In First Out works differently actually it is designed to work as a set
FIFO Load and FIFO Unload they must be used as a set ( I say that with a caveat ) because you can build your own so to speak and you don’t need to unload it the data will just fall off the stack
The FiFO Load loads the value of the source word into the word at index 0
And then copies the file element value up the file by 1 index
FIFO Unload looks at the index number then copies the value in the element at the index and copies it to the output word and subtracts 1 from the index
That just a short description look it up in the programmers manual for a better description

I would set 2 FIFO’s one for high priority fill, and one for low priority fill
Then fill using the first in hopper index when you fill it.
Then only look at the low priority fill if the high priority FIFO index is 0
You really should have 3 bin levels High , Middle and Low levels to do this program right but it can work with just 2.
Use the low level with the High priority FIFO and the high level for the low priority FIFO
I have used this method many times but each application has it’s own things to account for

Good Luck
 
@GaryS, I disagree. I know a high priority word of bits and a low priority word of bits is simple and effective. The problem is how does one duplicate the ENCODE and DECODE functions that were available long ago.

Back in the 1980s I was programming a HP1000 "mini computer" We would convert an int float to determine the higher bit set. We also and an efficient means of setting bits by the bit number. This was the basic part of "real time" operating system we had at that time.

Again, I have no idea what the FFL instruction does. I only know that once upon a time, Rockwell PLCs, maybe the SLC had an encode and decode instruction that would find the LSB or MSB and return an int or use an int to set or clear a bit in a word.

Shame on this forum for not having these basics all worked out and in a library somewhere. Otherwise everyone must re-invent the wheel. It should be easy to write a function to do what the encode and decode does using a Siemens PLC. Someone should write the equivalent using an AOI.

Also, I am still waiting to see someone use an alpha-beta-gamma AOI or Siemens function.

Way back in the dark ages I had a CP/M computer. CP/M was a popular OS before MS-DOS. Look it up. There was a CP/M users group that share MUCH more software that what is being shared today.
 
I'd approach it with two queues and two FFL/FFU arrangements as well. As you say, you service the high priority queue until it's empty, and then service the low priority queue.

When the filling system is idle, you do the following:
- If the high priority queue .POS > 0, FFU the high priority queue, and whichever hopper is unloaded from the queue (.UL) gets sent to the filling system to be filled
- If the high priority queue .POS = 0, then check the low priority queue. Same again, if the low priority queue .POS > 0, FFU the low priority queue, and whichever hopper is unloaded from the queue (.UL) gets sent to the filling system to be filled
- Otherwise, do nothing, and the filling system remains idle until the next scan cycle where it checks again

That covers getting things out of the queue. As far as putting them into the queue:
- As soon as a hopper falls below the 75% sensor, you FFL it into the low priority queue
- As soon as a hopper falls below the 25% sensor, you FFL it into the high priority queue

So if you have 10 hoppers, you'll end up with 10 FFL's and one FFU for the high priority queue, and the same again for the low priority queue. Of course, if your hoppers were in an array you could use a loop and some indirect addressing and have just one FFL for each queue, but let's not overcomplicate things if we don't have to.

The final question is how to handle a hopper that starts in the low priority queue, but then falls below 25% and needs to be moved to the high priority queue. I think, again, keep it simple. Extracting a value from the middle of a queue is possible, but unnecessarily complicated. Just leave it in both the high priority and the low priority queue. Each time you go to start a fill sequence, check if the sensor for that hopper is still uncovered. If so, great - fill it up. If not - well, obviously it already got filled via an entry in another queue, so just skip straight to "fill complete" and let the system check the queue for the next hopper.
 
There have been many posts on queing, even recently, other things to consider are what if a hopper goes into fault, need to move it out of the queue, I do agree with two shift registers or perhaps you could get away with 1, rather than bits use words, giving the possibility of 2 states plus obvious a 0 state i.e. removed from queue, so for example, hopper1 goes below 75%, put it in the queue as a "1", if a hopper goes below 25% or what ever, put it in the queue as a "2", itterate through the queue move any with a priority of "2" down the queue, should a hopper fail i.e. taken out of service then again itterate through the queue to remove it i.e. put a 0 in it.
So therefore you have a few operations to shift or remove the data, if there are "0" in the queue move "1" or "2" down the queue, if there is a "2" then move these down so these get priority, when a silo starts filling move a "0" into the end of the queue, the next scan will move the requests down the queue to populate the end of the queue.
It would be probably easier not to bother with FIFO, shift fumctions or FFL for 10 silos either do it long hand (start at position 10, work backwards) or indirect in a loop, TBH even if you do one operation each scan as far as the process goes time is not a real issue.

Here is a recent post on something similar

http://www.plctalk.net/qanda/showthread.php?t=129424
 
Shame on this forum for not having these basics all worked out and in a library somewhere. Otherwise everyone must re-invent the wheel. It should be easy to write a function to do what the encode and decode does using a Siemens PLC. Someone should write the equivalent using an AOI.

LOL. Sounds like a great retirement project, Peter. :ROFLMAO:
 
Thanks everyone, I'll go back and rethink the two FFL/FFU option.
the issue I had with that originally was how to get a low priority out of the list once it went high. I like the idea of just checking if it is full and if so go to the next one. The fill process could take several minutes. My apologies for not provided enough information. I obviously not as experienced at this. Again thanks everyone.
 
Shame on this forum for not having these basics all worked out and in a library somewhere. Otherwise everyone must re-invent the wheel. It should be easy to write a function to do what the encode and decode does using a Siemens PLC. Someone should write the equivalent using an AOI.

Let's not jump to conclusions. :D
 
@GaryS is, I think, confusing the FLL instruction, which is what fills an array of values with a single value, with the FFL instruction, which is FiFo-Load, and is usually paired with the FFU, FiFo-Unload.

I would not be bothered with a hopper being in both queues, because whichever causes it to be filled, if it is full when it is popped off the other queue, then it can be ignored until the next scan a few milliseconds later with no ill effect on the process.

I think the logic that will be most complex with be what ensures that any fill event, which has already started, will complete and not be interrupted by a subsequent higher-priority request.


Another approach would be to assign a "timestamp" (e.g. a UDINT counter that increments at ~1Hz; good for ~138 years) on each new fill request event, with the 10 hoppers' timestamps residing in two arrays, indexed by the hopper offset. if a timestamp for hopper N (e.g. low_timestamps[N] or high_timestamps[N]) is non-zero, then that is an active fill request. if a hopper gets a new high-priority request, then that could trigger clearing its existing low-priority request (MOV 0 low_timestamps[N]).

Then, when it is time to select the appropriate request, the only information of interest is the highest-priority, earliest timestamp (i.e. we do not need to sort the timestamps, only find the "first" one), which can be found very quickly (i.e. within a single scan without causing watchdog timer problems) with 20 brute-force instructions, or even less using a loop or two.
 
Last edited:
Also, in the FFL/FFU model, I would not try to remove a hopper's entry in the low-priority queue as that would be somewhat messy; it would probably be easier to disable such an entry (e.g. replace with hopper number -1) while leaving it in the queue, then write the code so disabled entries are ignored.

The code to locate low-priority entries matching high-priority entries could be simple:

  • there is no need to disable any low-priority entry for a hopper that is not in the next high-priority location e.g. fifo_high[0].
  • assumption: that fifo_high[0] should keep its value for many scans (e.g. until the fill it is requesting completes)
  • so the disable could be done by a simple rung that
    • only executes when the length of the fifo_low[0..9] FIFO is non-zero
    • increments an index itest by 1
    • assigns zero to itest when its incremented value is greater than or equal to the length of the fifo_low[0..9] FIFO (FIFO-control .LEN element)
    • does an EQU-compare of the value of one element fifo_low[itest] of the fifo_low[0..9] array against fifo_high[0]
    • and assigns fifo_low[itest] to -1 if the EQU evaluates to true
 
Without knowing the system, perhaps forget fifo's, how about just take the lowest value of the hoppers, latch it in to fill to x level. so for example you could set up a min level before a check is done i.e. 75%, loop though to find the one that has the lowest level, latch the fill mode to this hopper until a certain level is reached, you could be a little clever & if one goes below a critical level change to that, no need for complicated fifo's just lowest wins with a window of level fill. On initial i.e. all hoppers low level or empty, just take the first bin in the system based on how you program them in order.
 
I think everyone is over thinking this. If any vessel hits 25% it should enable a timer and become priority for that time (timer preset based on fill rate) and other vessels hold filling. When the time expires any vessel below 75% can resume filling.

Any vessel still timing can carry on as priority, so may need to consider a max number that can fill at the same time
 
I've been out on a job and just got back.
I see some people have comments about not having enough information.
If you can be more specific I will try and answer.
The hoppers get product from upstream at an inconstant rate, and the Hoppers get pulled from at different rates. If all hoppers are full then I will send a signal to stop upstream supply, but I am unable to stop conveyors between the infeed and hoppers, so this is why the full sensor is below the top of the hopper. I will have enough room to finish filling the current hopper. So I do not want to switch hoppers before it reaches a sensor.

I hope I am not confusing people even more.
 
If you can be more specific I will try and answer.



  • What are all of the inputs to the PLC?
  • What are all of the outputs from the PLC?
  • How does the infeed and conveyor system work?
    • Are there multiple conveyors (one per hopper) with the infeed system able to direct product to one conveyor at a time,
    • or is there one conveyor fed by the infeed system that can be moved or directed to fill one hopper at a time?
    • What are the inputs from (if any) and outputs to the infeed and conveyor system?
  • In the first post (#1), 75% was the Normal Priority level, below which filling might be initiated. In the last post (#14), there is also a Full Sensor, levels above which will initiate a stop to any current filling. Is the Full Sensor at the same level as the Normal Priority level, in which case start/stop would be on a knife edge that could be triggered by noise, or is there some hysteresis between those levels?
 

Similar Topics

Hey guys, I am looking at upgrading a machine from an old PCB controlled process with a membrane button control interface, to a PLC with a...
Replies
8
Views
2,276
I have a client that has burnt up their brake chopper resistors twice in the last few weeks with the drives idle but the disconnects on. The...
Replies
6
Views
2,226
Hi friends, I have a customer that is looking for some advice on upgrading the level system in their coal hopper. It is at a coal bagging plant...
Replies
14
Views
7,751
I'm installed a Powerflex 700 in place of a 1336F drive, but I'm still using the 1336F braking chopper with a same brake resistors. On the...
Replies
4
Views
4,784
Hello guys, Can someone please suggest me good alternative to this amplifier? Basically I need input signal 0-20 mA to amplify to 0-200mA (and...
Replies
5
Views
2,466
Back
Top Bottom