Sequential Status Display...

Eric Nelson

Lifetime Supporting Member + Moderator
Join Date
Apr 2002
Location
Randolph, NJ
Posts
4,346
Anybody have an elegant solution for the following?...

Keeping it as simple as possible. Hopefully, I won't get too confusing! :rolleyes:

Let's say you're monitoring a low level condition of 4 infeed tracks. Any of these may be "low" at any time. You want to display the status of the tracks sequentially, yet only when they are "low"

For example, when tracks 2 and 3 are low, the display will read:
"Track 2 Low"
pause
"Track 3 Low"
pause
"Track 2 Low"
pause
"Track 3 Low"
and so on...

But then track 4 goes low as well, so we now display:
"Track 2 Low"
pause
"Track 3 Low"
pause
"Track 4 Low"
pause
"Track 2 Low"
pause
"Track 3 Low"
pause
"Track 4 Low"
and so on...

Now ONLY track 1 is low, so the display will be static with:
"Track 1 Low"

Get it?... I've done things like this by using a bunch of timers and LOTS of branches, but I KNOW there must be a simpler way! It's a piece of cake with 2 items, but the more items you add increases the mess exponentially!

Anyone?...Bueller?...Anyone?......Terry?

-Eric
 
Eric

Can the proc. you're using support asci to the display ?
If it can then what i've seen is all info sent from 1 register in plc.
just cycle the info to that register on a time basis.

Or are the errors programmed in the display and linked to bits in the plc?
 
Last edited:
If it were me, I wouldn't scroll, but put in a message for every possible combination--1 low, or 1 and 2 low, or 1, 2, and 3 low, etc. Then I'd set 0 to four LS bits in a word, one for each of the low conveyors. Then examine this word for value and display the appropriate message--depending on the value. A 1 would mean 1 is low. A 3 would meadn 1 and 2 low. a 4 means 3 is low. A 5 means 1 and 3 low, etc.--all the way to 15 for 1,2,3,4 low.

If the messages are "canned" and called by a message number, binary or otherwise, it makes it real easy to assign the message numbers from 0-15, via the same word.
 
Eric,

I'm trying to do a simular thing right now with alarms too, and am not quite successful :( What I have done is built up an alarm word with different alarm bit, causing a value to be given to the alarm word for each alarm condition. Now, this value in the alarm word indexes a list of alarm text strings which are displayed on an operator screen. No, I cannot just use the alarm bit and use the HMI's alarm functionality for certain reasons. My problem is when I have more than one alarm at a time, now, my alarm word can display a false alarm text.

EX:

Alarm 1 = Value 1 in alarm word = Alarm Text : Shutter didn't Close
Alarm 2 = Value 2 in alarm word = Alarm Text : Standardize Failed


Now, If I say get both alarms, the value of my alarm word is 3, and the alarm text for value 3 might be "Grid Alarm", so, "grid alarm" is displayed on the screen instead of the 2 alarms I want.

I have tried using a sequencer, and continually scrolling through any alarm condition that might exist, which works, but lets say Alarm 1 is active and Alarm 10 is active, there is a huge gap in the messages displayed, not a good think.

Any idea's how to do this? All the alarms are mutually exclusive.
I am also looking to have the active alarms displayed, one after the other.

I think Eric, this is simular to your problem, I hope im not mistaken.

I tried to post my ladder logic, but it didnt show up how I wanted it, I'll try again if anyone want to see how I'm trying to implement it.

Andrew Evenson
 
Sounds like a job for a FIFO.

Each track has its own chunk of code for managing its message. If it is LOW, the chunk looks through the FIFO. If it's number isn't listed, it loads the FIFO.

Meanwhile, the message handler has independant code. It performs the unload, by a simple timer, and displays the message correstponing to the number that it just unloaded.

Case A: Single track (2) low: On event, the 2 get's loaded. Since FIFO is not not empty, Message handler unloads FIFO, and displays Message 2 ("Track 2 Low"), and starts timer. While timer is running, Track 2's code sees that there is no '2' in the FIFO (having been unloaded), and so loads one. (On next scan, it finds the previous '2', and so doesn't load another.
Eventually timer times out, FIFO unloads the single '2', and the message is repeated. (To the operator, the message will be continuous).
Case B: Two tracks (1 & 4) low. Both load the FIFO. '1' got there first, then '4'. Message handler unloads the '1', and starts the timer. Track 1 code reloads '1'. Track 4 code is satisfied. After timer, '4' unloads, and Track 4 code reloads he '4'.

Et cetera.

That's my first pass at it. Hopefully Terry can improve on it (like how to handle it if there is a number in the FIFO, and the Low condition drops out. Remove from the middle (that gets ugly), or have the message handler do a double check on the validity of the message (OK, but not 'elegant')
 
I like John's solution best.
I've done similar things.
Whenever I jump to a subroutine I light up a bit for that subroutine.
When all bits are off the value of the word is zero, and display reads "Everything is ok".
When bit one is on, the value of the word is 1, and the dispay reads "Manual Ram Down".
Good Luck
 
Andrew,

I display alarms similar to how you are describing it. Basically what I do is set up all my alarms in sequencial registers say 100-109. So say for instance register 100 is an alarm for a door open. If the door is open there will be a non-zero number placed in the register. This number corresponds to the screen number or message number I want to display. If the door is closed a zero is placed in the register. In order for the PLC to know there is an alarm present you use a search instruction to search registers 100-109 for a non-zero value. If a non-zero is found in any of the registers a coil is turned on. This alarm coil activates four rungs of code.

The first rung is a array that moves the value found in registers 100-109 into a temporary register depending on the pointer value. The pointer value is also 0-9. If the pointer is 0 it is reading register 100 if it is 5 it is reading register 105.

The second run looks at the value of this temporary register. If it is greater than zero the register contains an alarm. The value of that register is then placed in the message display register which in turn displays it on your OIT. At this point a timer starts after say 3 seconds the pointer is incremented by 1.

This is where the third rung comes into play. If the value found in the alarm registers 100-109 is zero you have a rung that increments the pointer until a nonzero is found. Rung 2 increments it if a non zero is found, rung 3 increments it if a zero is found.

The final rung, rung 4 resets the pointer back to zero. So if the pointer register is larger than 9 it writes a zero to the pointer and the process starts over.

I hope you can understand what I am saying here I'm not very good at explaining things. Let me know if you have any questions and I will do my best to explain it. All of this is programmed in a GE Fanuc 90-30 so depending on the PLC you are using you may or may not have similar functions.
 
glaverty,

Thanks you very much for your post. It is the right idea I was looking for!! Actually, I have figured out a way to do what you are doing in the PLC I'm using. I think it will work just fine..Just have to do a little reading on a specific instruction I havent used before. Its a bit shift instruction that cycles through a word, and looks to see if a bit is set, if one is set it outputs the corresponding word value. From that word value, I can use your timer idea, and use the value to index through a table of alarm messages. I dont know if my expliantion is correct on the function of the instruction, but I hope you understand where I'm going.

Thanks,

Andrew
 
I understand what you are saying, it is more or less the same concept of looking for a non-zero number in a register. However it is done the end results the same.
 
Thanks for the responses so far. John's idea makes sense to me right off the bat since it's so simple. Now that I think about it, I've approached other things this way, but I never thought about using this method for THIS application.

It seems most of you understand what I'm trying to accomplish, so it doesn't look like I need to re-explain anything right now. Later tonight I'll have more time to read (and re-read) Alan's FIFO idea... This sounds promising. I also have to run glaverty's idea through my head when it (my HEAD, that is!) is clearer.

Hopefully, Terry will find time to do one of his full-blown detailed descriptions with all the pictures and diagrams that we all enjoy! :D

I'll be back,

-Eric
 
I'm Back...

OK, I've finally found time to really look at the responses...<hr>
John,
<blockquote>Sorry, but I'm not liking your solution as much. I just would rather not have a message like:

"Track 1 AND 2 AND 3 AND 4 are Low" (or something similar)

Plus I would wind up needing 16 messages to display the status of just 4 tracks :eek: (if you includes an "All Tracks OK" message) ;)</blockquote><hr>
Andrew,
<blockquote>You are fighting with the same things I've dealt with. I create alarms the same way as you (setting bits in a word), but I treat them differently. With alarms, I usually don't need to DISPLAY more than one at a time (even if there are several). All I do is give them priorities (1-15), and use the ENCODE instruction to determine the highest bit that is set. This is the one that gets displayed. When that alarm condition is remedied, any others that exist will be displayed based on their priority.

This is how I handle alarms when using a graphic display that can associate messages with word values. I have a different method when I use text-based (canned message) displays. I can elaborate on that if you like.</blockquote><hr>
Allen,
<blockquote>Sorry 'bout the misspelling of you name in my previous post... I guess I was thinking Alan "CASE"? :oops:

As far as using a FIFO for this... I'm not that familiar with 'em, but from what little I know, I agree that this "looks" like a place to use one. You just store the events and display them. Sounds simple, but I too am concerned about how to remove an event that's no longer valid from the stack... Terry where are you? banghead</blockquote><hr>
glaverty,
<blockquote>I'm STILL running your idea through my head, but you've got me thinking about another idea! Perhaps a ROTATE instruction would work here? ROTATE is just like a BIT SHIFT, except you don't lose the bit that gets shifted out... It goes back into the front of the accumulator. Using 2 of these might work. Use one to store the event, and the other to store the matching message number. Imagine them "rotating" together, any looking at one bit at a time. If the bit is ON, trigger the matching message and start a timer. When the timer expires, "rotate" them once. If the bit is OFF, immediately rotate them once (without the time delay). This should "blow through" any bits that are OFF at the current scan time (i.e. FAST!). With this method, I still have access to the individual bits (and I know where they are). They aren't "out of reach" in the FIFO accumulator.

One problem though. Other PLCs I use have this instruction, but on this project, I'm using a ML1500, and there is no ROTATE instruction! :mad:

Any quick ideas how to accomplish this with only BIT SHIFT instructions?</blockquote><hr>
<blockquote>Oh well, let me get busy seeing if this will work while we await the "Why Didn't I Think of That" solution that Terry will undoubtedly come up with :D</blockquote>
Many thanks to everyone!

-Eric
 
You haven't mentioned a brand name, however, if you're using A-B, there is an instruction that will do most of the work for you. The FBC (file bit compare) will check 'any' number of contiguous bits in memory (i.e. can work across word boundaries) against another group of reference bits. When a mismatch is found, an index number is returned. You can use the instruction's FD (found) status bit to control a timer delaying scanning past the 'found' bit and the index number to trigger the appropriate canned message.

If you don't have a FBC to help, you could increment your way through contiguous bits using indirect addressing. Set your timer off when you find a bit on and use your index word to select the canned message.

Either method will handle a variable amount of bits without additional logic.
 
Yeah Gerry, this instruction sounded GREAT! I just finished DROOLING over it, only to find out that the MicroLogix don't support it! mddr

Thanks anyway! :)

-Eric
 
Thought about it some more. Here's the code (I tried it on a simulated Micor 1000, and it works:


LANE 1 - CHECK THE FIFO FOR THE EXISTANCE OF A '1', AND IF NOT FOUND, LOAD IT IN THE LAST FIFO POSITION.
LANE 1 FIFO POSN #1 FIFO POSN #2 FIFO POSN #3 FIFO POSN #4 USE INDEXED ADDRESSING
IS LOW +--- NEQ -+ +--- NEQ -+ +--- NEQ -+ +--- NEQ -+ +--- MOV -+
----| |----| N7:51 |---| N7:52 |---| N7:53 |---| N7:54 |---+---| N7:60 |
| 1 | | 1 | | 1 | | 1 | | | S:24 |
+---------+ +---------+ +---------+ +---------+ | +---------+
|
| INDEXED TO
| LOAD POSITION
| +--- MOV -+
+----| 1 |
| | #N7:50 |
| +---------+
|
| FIFO LOAD
| POINTER
| +--- ADD -+
+----| N7:60 |
| 1 |
| N7:60 |
+---------+

DUPLICATE THE ABOVE RUNG FOR EACH LANE. SUBSTITUTE '2' FOR THE '1' IN ALL THE 'EQU AND MOV INSTRUCTIONS.

MESSAGE DISPLAY TIMER - CONTROL HOW LONG THE MESSAGE IN N7:50 WILL BE DISPLAYED.
SELF-RESETING WHEN NEXT MESSAGE COMES IN.
CURRENT MESSAGE
MESSAGE TIMER
+--- NEQ -+ T4:10/DN +--- TON -+
---| N7:50 |-----|/|------| T4:10 |
| 0 | | 5 SEC |
+---------+ +---------+

FIFO UNLOAD - UNLOAD THE FIFO WHEN
A) THE MESSAGE IS "NULL", BUT THE POINTER ISN'T AT ZERO (ERROR CONTROL)
B) THE MESSAGE TIMER IS DONE, OR
C) IF THE CURRENT MESSAGE IS NO LONGER VALID (CONDITION CLEARED WHILE MESSAGE WAS IN THE STACK)
THE FIFO IS CONTROLLED BY COPYING THE STACK DOWN UPON ITSELF, OVERWRITING THE PREVIOUS VALUE WITH THE NEXT.
DECREMENT THE POINTER BY ONE TO KEEP IT POINTING TO THE NEXT EMPTY SPACE.
CURRENT FIFO LOAD
MESSAGE POINTER
+--- EQU -| +--- NEQ -+ +---- COP -+
---+---| N7:50 |---| N7:60 |---+---+---| # N7:51 |
| | 0 | | 0 | | | | # N7:50 |
| +---------+ +---------+ | | | 5 |
| | | +----------+
| MESSAGE TIMER | | FIFO LOAD POINTER
| T4:10/DN | | +---- SUB -+
+------| |----------------------+ +---| N60:0 |
| CURRENT | | 1 |
| LANE 1 MESSAGE | | N60:0 |
| IS LOW +--- EQU -+ | +----------+
+----| |-----| N7:50 |--------+
| | 1 | |
| +---------+ |
| LANE 2 |
| IS LOW +--- EQU -+ |
+----| |-----| 2 ----+
| |
CONTINUE DOWN




This is pretty brute-force code for 4 lanes. If it got expanded to 20 lanes, you'd want to put some of the repetative logic <br>(like the check for the existance of a message) into a for-next loop and index through things,

But this should do the trick. (Thanks for the diversion - this documentation stuff has been really getting me down. <br>It felt good to code again, even if it was only for 6 rungs).
 
Code

Here is the code I was describing before, obviously your functions will not be the same but it might give you a better idea about what I was talking about.

comb1.jpg
 

Similar Topics

Hi there, We have a system at a water treatment plant where large raw water tanks feed into the plant that's all on the same level. At high tank...
Replies
18
Views
3,639
Hi, I started off my career in PLC programming doing water/wastewater on AB around 20 years ago, but then moved overseas a few years later and...
Replies
57
Views
11,862
It appears to me that Logix is improperly executing sheets of an AOI in sequential scans instead of the same scan as the main program. To test...
Replies
4
Views
1,655
Hi, is it possible to read the name of the steps in an S7 Graph sequencer? In the parameterinterface there is, for example the parameter #S_NO...
Replies
21
Views
7,091
Hi All, is there a way to incorporate SFC with HMI in some way, in order to represent missing conditions for next step. Something similiar...
Replies
0
Views
961
Back
Top Bottom