Hopper High/Low Priority Request Logic

The copy instruction in the 75% reset rung will remove the value when it reaches position 0. If Hopper_Array75[0] = hopper number and hopper full, then COP [1] to [0]. This removes the value (basically overwrites the value). I tested that. If hopper 1,2,3,4,5 & 6 enter the 75% array. We fill 1 first. If 4&5 go to 25% before 1 is filled, then 4&5 fills after 1 is filled. Once 4&5 complete, we go back and fill 2,3 &6. You are correct that 4 and 5 are still in the 75% Array. But they are overwritten as they reach position 0 because the hoppers are full. You could also debounce the Fill request if you believe that would be an issue. The Hopper Fill Request tag controls the hopper selection not the array tags.

Which leads one to believe that the same approach would work with an FFU. Don't worry about removing and realigning just unload the full as it reaches 0 until you find one that isn't.

But what do I know. I'm self-taught, and not a doctor. ;)
 
Last edited:
But they [4&5] are overwritten as they reach position 0 because the hoppers are full.
Agreed, IFF those hoppers are indeed full at that point.

But what if e.g. hopper 4 is no longer full when it reach position 0, in which case it would have another entry, at a higher-indexed position, in the 75% FIFO? In that case, I am pretty sure that the hopper 4 entry at position 0 would allow it to jump the queue to get filled before other 25-75%-full hoppers that entered that queue after hopper 4 was filled from 25% and before it went below 75% later.

But what do I know. I'm self-taught, and not a doctor. ;)

Heh, me too, and me not too (Chem. Eng., BS; cf. note (v) below).

And, for me, this is about what the code needs to do, and if it can handle every situation it might reasonably be expected to handle. And as I should have mentioned earlier, you wrote an excellent piece of code that should really give the OP a leg up (if they ever come back). But as you note it is not a finished product.

Again for me, this is definitely not about who is right, and I apologize if I gave any other impression. I am not one of the 10% (cf. here) who can write a piece of code that, to borrow a military axiom, "survives first contact" with the real world.
 
Little Red Hen

Untested. Fails. Works?

Basically identical [or so I thought] to @cwal61's excellent approach in concept, only using a loop and FFLs/FFUs instead of FALs (as @cwal16 noted, that should work), plus a "skip" array to ensure any hopper's 75% edge event is disabled when that hopper sees a later 25% edge event before the 75% event is serviced (filled).

Let me know if the comments do not clarify how the code works.Edit: fixed typos in PDF; nothing survives first contact ;)

Edit2: nor second contact; maybe OP should just go with @cwal61's code :ROFLMAO:.

Edit3 :-/

Edit4: Yay? I think the logic may need to forbear adding the currently-filling hopper to the FIFO-25% if that hopper detects a 25% level edge, as it's already filling, but that may be an unlikely case. I.e. why would the level drop while it is being filled?
 
Last edited:
Agreed, IFF those hoppers are indeed full at that point.

But what if e.g. hopper 4 is no longer full when it reach position 0, in which case it would have another entry, at a higher-indexed position, in the 75% FIFO? In that case, I am pretty sure that the hopper 4 entry at position 0 would allow it to jump the queue to get filled before other 25-75%-full hoppers that entered that queue after hopper 4 was filled from 25% and before it went below 75% later.

The copy instruction in the 75% reset rung will remove the value when it reaches position 0. If Hopper_Array75[0] = hopper number and hopper full, then COP [1] to [0]. This removes the value (basically overwrites the value). I tested that. If hopper 1,2,3,4,5 & 6 enter the 75% array. We fill 1 first. If 4&5 go to 25% before 1 is filled, then 4&5 fills after 1 is filled. Once 4&5 complete, we go back and fill 2,3 &6. You are correct that 4 and 5 are still in the 75% Array. But they are overwritten as they reach position 0 because the hoppers are full.

In the scenario shown above, if Hopper 4 dropped below 75% before reaching POS 0 it would be re-filled before hopper 6 but after 2&3. But it would not jump any 25% que. The 25% interlock bit prevents that. That's why the 25% interlock bit is set along with the FAL Array Entries and the 75% interlock bit is set at the end of subroutine.
Hopper Fill Request.PNG
Looking at it now the EQU instruction and the 25% interlock bit in this last rung are redundant and either one could be removed. As, some in this forum have pointed out. :rolleyes:

We could add a branch circuit in the 75% reset rung with a 25% fill memory bit to remove the entry at position 0 and reset the memory bit. That would maintain the entry order in which each 75% request became true. I can test that in the morning and remove the redundancy in the last rung :D and hopefully remember to fix the typo in rung 36.
 
But it would not jump any 25% que.


Agreed, it could only jump the 75% queue . Sorry I was not clear, when I wrote
would allow it to jump the queue to get filled before other 25-75%-full hopper
I was referring not to 25-75% queues, but rather to hoppers with levels between 25% and 75% i.e. hoppers waiting in the 75% queue but not in the 25% queue, but now I can see that how I phrased it is unambiguous.

Actually, I think I found another problem with my logic (not sure if it is in @cwal61's): if hopper X is the hopper being filled at the time of the 25% low-level, does it make sense to add that hopper to the 25% queue? I think the answer is no, but my code would do it. Admittedly, that should not happen, as I would think the fill rate will always exceed any single hopper's pull rate, so once a hopper gets selected for filling from the 75% queue, which means it (or any other hoppers) dropped below the 25% level, it should then never reach 25% as long as that fill continues. The again, the fill rate is "inconstant," so who knows.

I was also thinking about my loops vs. @cwal61's brute force ("unwinding" the loops): the loops are nice in that they are


  • compact (80%+ fewer rungs to wade through), and
  • easier to read and understand the overall flow, and
  • less prone to copy-paste-tweak errors while programming.
However, once in operation, the ten separate rungs would almost certainly a provide far far far better visual aid, at least in RSLogix/Studio online mode, for diagnosing problems on any one hopper (failed sensors, etc.), and I think in many environments that would supersede any programming convenience. Although brute-forcing the loop data to display in an HMI could also be used for diagnostics, and RSLogix/Studio doesn't even come into it, plus it gives the operators and techs tools to diagnose the problem.


Anyway, it's the overall algorithm that is the main concern of this thread, and I think @cwal61's FIFO approach, with the tweaks he has applied, looks like it is up to the task.


Yall are doing a pretty good job doing this guys homework.
Yah, I'm waiting for the pharmacy to refill my prescription, and this is the result.
 
Yah, I'm waiting for the pharmacy to refill my prescription, and this is the result
Are you only below the 75% level or have you fallen below 25% and need to get bumped up the priority list?
I swear that my pharmacy (a chain, unnamed, but goes by three initials) generates an automatic refill when they think I've dropped below the 75% level.
 
Similar overall code structure with a different approach: instead of two fixed FIFOs with the location of the hopper indicating the priority and the time ordering of the level events, each hopper keeps a "timestamp" that expresses both the priority and the time ordering in such a way that a quick search of the hoppers' "timestamps" finds the hopper with the most negative "timestamp," and that hopper is the next one to fill.
 
Changes made to Version 4.
1. Corrected Typo in Rung 36
2. Added 25% Memory Bit to remove 75% entry if entry redrops below 75% before reaching Position 0 of the 75% array and realign request in next order of position.
3. Added Not Active to remove hopper from arrays if de-activated after an array entry.
4. Removed the redundant 25 interlock bit in the last rung.
 
Last edited:
Changes made to Version 4.
1. Corrected Typo in Rung 36
2. Added 25% Memory Bit to remove 75% entry if entry redrops below 75% before reaching Position 0 of the 75% array and realign request in next order of position.
3. Added Not Active to remove hopper from arrays if de-activated after an array entry.
4. Removed the redundant 25 interlock bit in the last rung.

Nice!


I am amazed how much code there is, for both yours and mine, for what seems like a simple task. It's the edge cases that getcha.
 
Nice!


I am amazed how much code there is, for both yours and mine, for what seems like a simple task. It's the edge cases that getcha.

Your right about that.

I reworked the program to use the FFL and FFU just because 👨🏻‍🏫 ........ :whistle: I wanted to see how it would work.
I had to modify the logic for the 25% full memory bit to remove the hopper from the 75% array at position 0. The true false transition of the FIFO instructions turned into PITA. But as always trial and error won the day! Other than that, it was pretty much the same. Still used Array[0] for the Fill Request and actually had to use the Unload of the FFU to help control the memory bit reset. So now they both work the same.
 
Version 5.
Using FIFO instructions and added logic to maintain order of entry of a 2nd 75% fill request after a 25% fill if needed. The last Version would capture a second 75% request if they occurred after a 25% fill cycle before clearing first request but would fill low to high hoppers numbers regardless of entry order. The additional logic corrected that scenario. Below shows example of what above is trying to explain.

Step1. All Hoppers Full
Step2. Hoppers 1 thru 7 drop below 75% level in sequential order.
Step3. Hoppers 3,4,5 drop below 25% during Hopper 1 fill cycle
Step4. Hopper1 Full.
Step5. Fill Hoppers 3,4,5 because of 25% High priority.
Step6. Fill Hopper 2
Step7. Hopper 4 then 3 drop below 75% level.
Step8. Hopper 2 Full.
Step9. Fill Hopper 6
Step10. Fill Hopper 7
Step11. Fill Hopper 4
Step12. Fill Hopper 3

Attached pdf and exported subroutine.
 

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,281
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,232
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,790
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,850
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,471
Back
Top Bottom