Need assistance creating a Queue function

TheWaterboy

Lifetime Supporting Member + Moderator
Join Date
May 2006
Location
-27.9679796,153.419016
Posts
1,927
The idea here is to provide for a brief rapid influx of message codes while preventing sequentially repeating the same message.
i.e. if two explosions occurred a second or two apart - only one audible announcement of an explosion will be required.
But if an Explosion and a Flood happened half a second (or 5, 10 seconds) apart, then announce them both, Explosion first , then Flood.
The plague of Locusts is not scheduled for another hour. It will be a single event that still needs to be announced.

Because the device being used is serial control it uses a ETH I/P gateway so there is a scan delay between command and response. So the logic here needs to wait for it.

I need to test the device for [BusyFlag] before allowing [PLAY] to be set or stack to be popped,
but Stack still needs to be able to push additional values should they arrive.

This process begs for a Pi or Arduino with CIP Ethernet but I dont know if that protocol even exists in that space and even if it did I just have the time to learn one of those now.

Some of this is this way because the HMS serial/IP Gateway requires it to be.
One example is that to actually send any character out or read anything back into the gateway serially you increment a seperate trigger byte.
The player itself is MUCH simpler and responds to single ASCII characters, but comm is serial so I gotta do this incrementation thing

I have the device working and can play messages through the PLC by toggling bits and moving values, but I cant get over this queueing hurdle.
Many of you use a FIFO queue far more than I so I hope I can get some example code I can grasp the required flow from.

DEFINES:

[IncomingCode] = 3 digit code used to choose the message to be played (Flood, Famine, Zombies etc)
[CheckForBusy] = random number sent to the Player asking for its status, It responds with a code that I filter into a bool called [BusyFlag]
[EvaluationTag] = Tag the [IncomingCode] is moved to for local processing, allowing [IncomingCode] to be cleared and then re-populated from elsewhere
STACK = FFL/FFU Pair to hold new codes that arrive while Player is busy - I have the FIFO pair working fine, it Pushes and Pops correctly. just cant visualize how to implement it here.
[BusyFlag] = Bit indicating the Player is busy doing something else (and it is not capable of queueing)
[PLAY] = Bit to tell the player to play the message code contained in [AnnunciatorInputTag]
[AnnunciatorInputTag] = The 3 Digit message code that is sent to the Player followed by [PLAY]
[ReadyFlag] = Opposite of [BusyFlag]

This below is only meant as a flow chart -I just couldn't come up with a better way to convey it
Code:
BEGIN PseudoCode

While [IncomingCode] > 0 'just a timer but shown here for sake of clarity
    Increment [CheckForBusy] integer every 5 seconds. 'Repeatedly check for Busy when a code comes in
End While

If     [IncomingCode] > 0
    Move  [IncomingCode] to [EvaluationTag]
    Clear [IncomingCode]
End If

If [ReadyFlag] is set then 'the result of incrementing [CheckForBusy]

    If [EvaluationTag] <> Previous Value OR > 20 seconds elapsed since last
      PUSH [EvaluationTag] to STACK
      Set [EvaluationTag] = 0

        While STACK.Pos > 0 'need to ensure the POP'd value is handled before popping another one
           POP STACK to [AnnunciatorInputTag] ' what do I use for this?

                        If [BusyFlag] = 0 'will this race against the first While Loop ?
                Latch [Play] Tag 'resulting in External device responding by setting [BusyFlag] Tag
                [BusyFlag] = 1 -> Unlatch [PLAY] tag
                End If
        End While
    End If
End If

END Pseudocode
 
are there a finite number of codes? make each one an index into an array of TOFs.

Code:
XIO tofarray[IncomingingCode].DN TOF tofarray[IncomingCode]

Done.
 
There are but more can be added if needed. I doubt there would be any more than a coulpe dozen.

But I'm not seeing how you response that makes all this work.

The comments I added are just additional questions about the flow. Are you talking about one of those?
 
But I'm not seeing how you response that makes all this work.

That code starts the TOF timer structure at offset IncomingCode of the tofarray (ARRAY[0..24] of type TIMER Structure).
  • if and only if that TOF timer is not already running,
  • and leaves it running if it is already running.
At least I think that is what it does; it may not, now that I think about it.

Somewhere else you can use each (or all) tofarray[...].DN bits to do something (sound a horn, etc.).
 
Its the integration between the elimination of duplicate stack entries and use of a FFL/FFU as a Surge Accumulator that I need the help with . Packaging lines must use something like that but all I have seen myself is shift registers for empty bottle detection. I need to track integers in a similar albeit far smaller fashion.
 
I suggest using arrays and not bothering with FFL/FFU/FIFO stuff; fiddling around with that is more trouble than it's worth. That one rung executes the bulk of the necessary logic (maybe).

Here is another approach, slightly more complicated, but it works; it uses the mean scan cycle as the "clock," and cycles through one of 32 "codes" per scan cycle; so if the continuous scan cycle is running at 1kHz, that "timer preset" of 1000 in the MOV on rung 0001 represents about 31s, and a timer resolution of about 32ms; you would need to "calibrate" you own scan cycle and "preset" for the time delay you want to use.

The incoming code could be cleared to 0 on every scan cycle since it is essentially a one-shot. Here it is not cleared until halfway through ([NXB LES ... CLR ...] branch on Rung 0001) so I could watch the behavior. The "incoming code" (N7:0) was assigned a value of 1 about 10s previous to this screenshot (N9:1 has counted down from 1000 to 675), then assigned a value of 2 (N9:2 has counted down from 1000 to 808), then assigned a value of 1 again, which did not restart the countdown of N9:1 because the N9:1 (Incoming Code "timer") had not counted down to zero.

I realize this approach may, at first blush, seem overly complex, but when I think about what will be necessary to do this with FFL/FFU/FIFOs, this will seem simple by comparison.
Untitled.png
 
I'm doing this in Logix5k (I thought I mentioned that but seems I didn't, apologies)
I'll have to digest that tomorrow, I see what it does but not how it helps... Fresh eyes tomorrow might help.
 
Here is yet another approach using FFU/FFL/FIFO; it's better than I thought it would be.

The timing is again notional to allow watching it run, and would need to be configured for the actual application, a preset of 100ms would be reasonable; this could also be put into a timed interrupt routine, which would eliminate the TON, but the FFU/FFL control structure /EU and /EN bits would need to be cleared to force the rising edge detection.

The way this is written, an IncomingCode value of zero is "No Code" i.e. B3:0/0 is not a useable bit. The conditional XIC B3:0/[N7.0] CLR N7:0 branch is necessary to avoid pushing any non-zero code value onto the FIFO more than once i.e. when that code's "alarm" is active.

Whether any of these are coded using Logix5k or 500, or in ST or Ladder, really doesn't matter, as it only changes the implementation details, not the algorithm.

Untitled.png
 
CCW, using ST and COP to implement the FIFO, because the triggering event (in this case an Selectable Timed Interrupt or STI) is a one-shot anyway.
  • The STI code:
    • N.B. many the statements here protect against an invalid incoming code; the meat of the algorithm comprises but a half-dozen statements.
03.png
  • The Global Data, shown live with three alarms active, and one (5, in fifo[0]) about to go inactive:
00.png
  • The STI configuration (Studio5k configuration will be different, of course, but functionally similar):
02.png
  • The local data:
01.png
 

Attachments

  • 01.png
    01.png
    93.7 KB · Views: 2

Similar Topics

Hi Group, I have a EZ-420 PLC and part of a program and I am trying to create a complete program for an E-Stop test bench. I have just...
Replies
9
Views
2,350
I am a complete newbie to this stuff and wanted to try this out and was looking for any information on how I can complete this by Wednesday...
Replies
19
Views
12,745
I'm having an issue with editing my Alarm settings within the Cimplicity workbench. I am attempting to change alarm sounds and settings dependent...
Replies
7
Views
4,330
I have a customer in Phoenix where we are starting up equipment. I will be out of town and cannot be there. The job has Siemens HMI, Siemens...
Replies
3
Views
2,010
Hello Guys, Well just a little back ground as to how the problem started. Last night our governors decided (somehow, we still don't know how yet)...
Replies
6
Views
1,633
Back
Top Bottom