Just couldn't resist trying to develop a manager for the Queue with as few rungs as possible.
The following is only for managing the queue.
There are other concerns such as...
...how the sequence is actually started,
...how the sequence transitions from one motor to the next,
...what happens if a running motor is dropped out of the queue, etc.
Although a long description... this is only describing 2 Rungs (shown later).
M# = Motor #
Q# = Queue #
Last_Q# = Last Queue # used
Queue_(1 through 5) = 5 words holding Pump #s...
i.e. Queue_(1) = Pump-X, Queue_(2) = Pump-Y, etc.
Motor_(1 through 5) = 5 words holding Sequence #'s...
i.e. Motor_(1) = Queue-A, Motor_(2) = Queue-B, etc.
If "RESET", Zero-All
M# = 0
Q# = 0
Last_Q# = 0
Queue_(1 through 5) = 0
Motor_(1 through 5) = 0
RUNG-1: (Loading the Queue)
If input 1 just on... M# = "1"
If input 2 just on... M# = "2"
If input 3 just on... M# = "3"
If input 4 just on... M# = "4"
If input 5 just on... M# = "5"
INC Q# (Q# = Q# + 1)
INC Last_Q# (Last_Q# = Last_Q# + 1)
Copy M# to Queue_(Q#)
Copy Q# to Motor_(M#)
END OF RUNG-1:
If sequence = 3,1,2,5,4 then...
Sw# M# Q# Queue_(Q#) <= M# Motor_(M#) <= Q#
Initial 0 0 0
Sw-3 ON 3 3 1 Queue_(1) <= "3" Motor_(3) <= "1"
Sw-1 ON 1 1 2 Queue_(2) <= "1" Motor_(1) <= "2"
Sw-2 ON 2 2 3 Queue_(3) <= "2" Motor_(2) <= "3"
Sw-5 ON 5 5 4 Queue_(4) <= "5" Motor_(5) <= "4"
Sw-4 ON 4 4 5 Queue_(5) <= "4" Motor_(4) <= "5"
.
RUNG-2: (Unloading and Adjusting the Queue)
If input 1 just off... M# = "1"
If input 2 just off... M# = "2"
If input 3 just off... M# = "3"
If input 4 just off... M# = "4"
If input 5 just off... M# = "5"
Copy Motor_(M#) to Q#
If Q# < "2"... Copy Queue_(2) to Queue_(1)
If Q# < "3"... Copy Queue_(3) to Queue_(2)
If Q# < "4"... Copy Queue_(4) to Queue_(3)
If Q# < "5"... Copy Queue_(5) to Queue_(4)
Queue_(5) = "0"
DEC Last_Q#
Q# = Last_Q#
Motor_(M#) = 0
M# = 0
END OF RUNG-2:
If last entry was M# = 4 into Q# = 5 ...and then... Switch #2 goes OFF...M# = 2
Copy Motor_(M#) to Q#
Motor_(M#) = Motor_(2) = "3"... "3" is the Queue # for Motor-2
Copy "3" to Q#
Sw# M# Q# LQ# Q# <= Motor_(M#)
Initial 0 4 5 5
Sw-2 OFF 2 2 5 5 Q# <= Mtr_(2) <= "3"
2 2 3 5 If Q# < 2... Copy Queue_(2) to Queue_(1)
Q# is NOT < 2... so, no action here.
3 5 If Q# < 3... Copy Queue_(2) to Queue_(1)
Q# is NOT < 3... so, no action here.
3 5 If Q# < 4... Copy Queue_(3) to Queue_(2)
Q# IS < 4... Queue_(3) => Queue_(2)
3 5 If Q# < 5... Copy Queue_(4) to Queue_(3)
Q# IS < 5... Queue_(4) => Queue_(3)
3 5 ...and then... Queue_(5) = 0
3 5 ...and then... DEC Last_Q#
2 2 3 4 ...and then... Q# = Last_Q#
2 2 4 4 ...and then... Motor_(M#) = 0
2 2 4 4 ...and then... M# = 0
2 0 4 4
The next queue to be loaded is #5 (unless more queues are unloded).
Queue Adjustment...
Initial
Queue_(Q#) = M# Motor_(M#) = Q#
Queue_(1) = "3" Motor_(1) = "1"
Queue_(2) = "1" Motor_(2) = "3"
Queue_(3) = "2" Motor_(3) = "2"
Queue_(4) = "5" Motor_(4) = "5"
Queue_(5) = "4" Motor_(5) = "4"
Final
Queue_(Q#) = M# Motor_(M#) = Q#
Queue_(1) = "3" Motor_(1) = "1"
Queue_(2) = "1" Motor_(2) = "0"
Queue_(3) = "5" Motor_(3) = "2"
Queue_(4) = "4" Motor_(4) = "5"
Queue_(5) = "0" Motor_(5) = "4"
.
At this point, the only motor switch that can go ON is Motor Sw #2. If it goes ON then it will be logged into Queue_(5).
The following shows the two primary rungs which manage the queues...
RUNG-1:
SW-1 +--------+ +-----+ +---------+ +----------+ Dummy
---|/\|---+ M# = 1 +---+---+ INC +---+ INC +---+ COPY +----( )
+--------+ | | Q# | | Last_Q# | | M# to |
| +-----+ +---------+ |Queue_(Q#)|
| +----------+
SW-2 +--------+ |
---|/\|---+ M# = 2 +---+
+--------+ |
|
SW-3 +--------+ |
---|/\|---+ M# = 3 +---+
+--------+ |
|
SW-4 +--------+ |
---|/\|---+ M# = 4 +---+
+--------+ |
|
SW-5 +--------+ |
---|/\|---+ M# = 5 +---+
+--------+
RUNG-2:
ALWAYS
SW-1 +--------+ +----------+ +--------+ +----------+ OFF Dummy
---|\/|---+ M# = 1 +---+---+ COPY +---+--+ Q# < 2 +---+ COPY +---| |---+--( )
+--------+ | |Motor_(M#)| | +--------+ | QUEUE_(2)| |
| | to Q# | | | QUEUE_(1)| |
| +----------+ | +----------+ ALWAYS |
SW-2 +--------+ | | +--------+ +----------+ OFF |
---|\/|---+ M# = 2 +---+ +--+ Q# < 3 +---+ COPY +---| |---+
+--------+ | | +--------+ | QUEUE_(3)| |
| | | QUEUE_(2)| |
| | +----------+ ALWAYS |
SW-3 +--------+ | | +--------+ +----------+ OFF |
---|\/|---+ M# = 3 +---+ +--+ Q# < 4 +---+ COPY +---| |---+
+--------+ | | +--------+ | QUEUE_(4)| |
| | | QUEUE_(3)| |
| | +----------+ ALWAYS |
SW-4 +--------+ | | +--------+ +----------+ OFF |
---|\/|---+ M# = 4 +---+ +--+ Q# < 5 +---+ COPY +---| |---+
+--------+ | | +--------+ | QUEUE_(5)| |
| | | QUEUE_(4)| |
| | +----------+ ALWAYS |
SW-5 +--------+ | | +-----------+ +--------+ OFF |
---|\/|---+ M# = 5 +---+ +--+ Queue_(5) +--+ DEC +---| |---+
+--------+ | | = "0" | |Last_Q# | |
| +-----------+ +--------+ |
| |
| +-------+ +----------+ +------+ |
+--+ Q# = +--+Motor_(M#)+--+ M# = +-+
|Last_Q#| | = "0" | | "0" |
+-------+ +----------+ +------+
.
Rung-1 Loading:
Any switch going ON causes the particular switch# to be assigned to the Motor# (M#).
The Queue# is Incremented.
The Last Queue (Last_Q#) used is Incremented. (this is used for unloading)
The Motor# (M#) is copied to the current Queue# QUEUE_(Q#)
Rung-2 Unloading:
Any switch going OFF causes the particular switch# to be assigned to the Motor# (M#).
The Q# where the particular motor# is stored (in Motor_(M#)) is copied to Q#.
The Queue is adjusted according to Q#.
Whether or not one Queue is copied to another depends on the value of Q#.
In all cases, Queue_(5) will be set to "0".
In all cases, the Last_Q# will be decremented.
In all cases, the current Q# will then be set to equal the Last_Q#.
In all cases, the Queue # in the affected Motor queue will be set to "0"... it is out of the queue.
In all cases, the current M# is set to "0".
For those PLCs that bail-out at the first opportunity...
...the "ALWAYS OFF" bit ensures that all of the branches are executed before the rung is exited.