Flashing Output On and Off

Ron:

What's so scary about that? I do it all the time. I set up a subroutine called SIM, which I conditionally enable as the very first line in the code.

It's full of all sorts of "wacko" logic like:

MOTOR MOTOR
AUX CONTACT
O:0/1 I:1/0
------| |--------------( )


VALVE VALVE IS
OPEN LS
O:0/1 I:1/1
--+---| |------------( )
|
| VALVE VALVE IS
| CLOSED LS
| O:0/1 I:1/2
+---|/|------------( )



So while the shop is wiring the rack and I/O modules, I'm debugging the PLC / HMI / SCADA, with the processor sitting in a spare rack.

By the time the PLC is in the field, and trying to actually operate machinery, I've run a hundred batches, and I know the program is at least 50% bug-free (Ma Nature & Mr. Murphy are always good for a few wrinkles).

When I want to (have the time to), I'll put timer delays on driving all my inputs and then the system really looks real. This makes FAT a breeze.
"What happens if the valve fails to open?" - Just increase the delay timer to 32767, and watch.

<hr>

Thanks for the object lesson on why NOT to use the ALWAYS bits. I'm not sure I'll abandon my ways (too lazy to add two instructions). The guy must have been a knucklehead indeed not to notice that the coil he just inserted was already annotated and said "ALWAYS OFF"

I'm trying to figure out what THREE errors are in the AFI description.
This input instruction disables its rung when inserted in the condition side of the rung. Use for debugging programs and for temporarily deactivating a rung that will be needed later. Program an AFI as the first input in the rung. © 1997 Rockwell Software Inc.

"Disables its rung" are two - if used on a branch, it only disables the branch, not the rung. Plus, I would quibble about the use of the word "Disable" An OTE will still get evaluated, and the bit RESET on an AFI'ed rung.

What do you have for the other?
  • "when inserted in the condition side of the rung" - implies that it could be inserted on the result side of the rung - it can't.
  • "Program an AFI as the first input in the rung." - it can go anywhere (except as a coil). On a branch is one handy place.
  • "and for temporarily deactivating a rung that will be needed later" - this could be interpreted as the AFI (or some other instruction) can reactivate the rung later (which of course, only modifying the program can).
 
Oh, come on, Allen. Remember that I said that the BEGINNERS may find it scary. I knew I wasn’t go to scare guys like you. But I have seen some beginners get all “freaked out” when they see a “green” contact (which they THINK means TRUE) but in actuality it’s false - as per the LAMP rung example. Then they often think that an OTE “is an output”. You and I, of course, know that an OTE is actually “an instruction” to the processor which (when executed true) tells the processor to go write a “1” into a particular bit. Conversely, when the OTE is executed false, it tells the processor to go write a “0” into the bit. Some beginners think its “freaky” to “control” an input bit the way I did in the BUT-to-DUMMY rung. I’ve actually had quite a few bet me that it can’t even be programmed in the first place. You and I (and a lot of others) do it for debugging purposes all the time with no loss of sleep what-so-ever.

As for the “knucklehead” who made the typographical error – just how he went about making this obvious mistake is far beyond me – I never got any closer than 60 miles to the scene of the crime. My best guess as for how he missed the documentation: Maybe he was a “heads-down, one-finger” typist like many maintenance workers out there in the real-world. I’ve watched some of these guys peck away for an eternity before they ever look up at the screen to see what’s going on up there. I can identify. When I went to high-school, only girls learned how to type. Now typing is called “keyboarding” and it’s a socially acceptable skill even for macho dudes like us.

And everybody - we have a winner! Allen got all three errors for the AFI in record time.

For the beginners:

(1) The AFI does not DISABLE its rung – the rung still executes – but the logic (after the AFI) will always be false. In other words, if you program an AFI to “disable” a rung which controls an OTE, then that OTE will still be placing a “0” in its bit every time the rung gets scanned. (As per Allen). The biggest problem occurs when you use the AFI to “disable” an OTE rung and then program and test a new rung with an alternate method of control. Bad news. The first rung has NOT been disabled – it’s still writing “0” to the bit. Which will (among other things) unseal and/or unlatch any “in-cycle” bits which have the same address. I had a very frustrated customer fight this particular effect for several hours – he had read the “book” and accepted its word as fact.

(2) The AFI does not DEACTIVATE its rung. It doesn’t “deactivate” for the same reasons as given in “disables” above. And obviously I’m not as generous as Allen. When I count ERRORS – I count ERRORS. And personally I don’t think that Allen is “quibbling” at all about the use of the words in the help file’s description. The book uses the word “disables” - and the book uses the word “deactivating” - and those two words are not correct descriptions of what the AFI actually does. It doesn’t “disable” and it doesn’t “deactivate” – it just executes as a false condition. Period.

(3) You don’t have to “PROGRAM AN AFI AS THE FIRST INPUT IN THE RUNG” the way the “book” says. Actually, you can place it anywhere you would place any other input condition.

Now my personal opinion is this: The guy who originally wrote this description (and incidentally, it’s been around for years) was probably a “junior” engineer who got assigned to “write the book” after the “real engineers” where finished with the software development project. This guy was probably very familiar with the REM or REMARK statements used in most programming languages. So maybe he thought that the AFI works just like an REM or a REMARK statement. Now you could say that an REM statement does DISABLE its line of code. And you could also say that an REM statement does DEACTIVATE its line of code. And you could also say that an REM should be programmed “AS THE FIRST THING ON A LINE OF CODE”. (And yes, all of these are subject to interpretation if you really want to get picky). But the fact remains, the AFI does NOT do what the “book” says it does.

Hopefully someday this little tidbit of knowledge may help make someone’s programming career a little less traumatic. If so, then I’m happy to have been a very small part of the educational process. My work here is done.
 
Last edited:
First let me state that I do not have the ability/knowledge to debate this with any of you.

I am wondering what "book" this came from?

In the past when I had to work with 6200 and plc5 the AFI wouldnt work unless it was the first instruction in the rung...cant remember all the details but not even sure you could place it anywhere but at the beginning. In those days I/we used the AFI ALOT, the system was designed in house by company engineers...note none were an EE. The project was an ongoing process full of glitches/problems that I had to deal with on a day to day basis. I learned about histograms because of it tho.

NOW for the description...I have no idea (never thought about it really) how an AFI works BUT my experience tells me that if its ALWAYS FALSE then to make the rung ALWAYS FALSE it has to scan it to disable/deactivate it, HOW else would the instruction work ..ie the ladder know if it wasnt scanned. I guess that was too early in my days with plc's, took the instruction for granted that it would always "prevent" that rung from every being true. Too my knowledge it always did just as it was meant too.

Maybe its more of a semantics thing...maybe more of an I DONT KNOW thing. IT was stated as an Always False insruction to be used to prevent/disable/deactivate the rung from being true/active...I dont know of a case that it didnt do as stated.

Of course I am naive and lacking in experience.
 
Necro-thread alert!

I used to like the "always off" bit idea too - until ... some knucklehead made a typographical error ... [and] he turned the [always off] bit ON with his ladder logic.

Based on that sobering experience, I think from now on (when forced to do without AFI and unconditional branches) I personally will use XIC and XIO in series for all of my "GUARANTEED OFF" conditions - and XIC and XIO in parallel for all of my "GUARANTEED ON" conditions. ...



Necro-thread alert.


Stumbled onto this great thread today.

An alternative suggestion: test alluz on and off at the end of the program i.e.


Code:
                 ZERO
---[LBL Q:0]--+---] [---+---[JMP Q:0]---
              |         |
              |   ONE   |
              +---]/[---+
This puts a canary in the coal mine so at least this particular future mistake is discovered ASAP. That said, it has the same fundamental weakness but to a lesser degree e.g. if one rung latches ZERO then a later rung unlatches it.
 
This old thread was all about flashing an output on and off.

Here's how I do mine, simple and straightforward.

The rung with the counter is located in a periodic task (or STI if PLC5/SLC500). The other rung posted is in my continuous task, and although the bits are aliased to the counter accumulator bits, that's only to provide a nice name for them. They could be direct addressed, with Symbols and comments.

Depending on the configuration of the periodic task or STI, I can choose whichever bits from the counter accumulator gives me the flash rates I want. Since I'm aliasing to bits 0 and 3 of the counter accumulator, the "slow" flasher runs at an eighth the speed of the "fast" flasher.

Just 2 instructions to generate my flash rates, and I could address numerous accumulator bits, each successive bit would be half the rate of the previous one.

And if the periodic task has a high priority, you get very accurate timing, which may not be needed for lamp flashing, but there may be other applications that might need the accuracy

2021-01-20_190928.jpg 2021-01-20_191007.jpg 2021-01-20_191907.jpg
 
Hmm, interesting. It seems to be counting scans.


But could that not be done in one instruction: [ADD dint_bits 1 dint_bits]?


What keeps the counter accumulator from overflowing?
 
Hmm, interesting. It seems to be counting scans.


But could that not be done in one instruction: [ADD dint_bits 1 dint_bits]?


What keeps the counter accumulator from overflowing?

Yep, it's counting scans, but of a periodic nature (periodic task).

Yep, it could be done with an ADD instruction, and it will most likely be even "cheaper" because you won't need a counter (less memory), and you won't need to OTU the counter's .CU bit (less memory, and less code to execute). Well spotted...

The "count", however it is derived, will definitely overflow, but you can ignore any overflow conditions, it will continue to count regardless of any "Control" flags or processor arithmetic flags....

A destination (whether that's a DINT or a counter's accumulator) will continue to increment, ad infinitum, even if the destination "overflows" into negative numbers, it'll still be going in the positive direction when it "flips" from 2,147,483,647 to -2,147,483,648, and the next "count" will be -2,147,483,647, which is one more than -2,147,483,648

Same goes for an ADD, the destination is always cyclic, so that all 32 bits of a DINT are pure binary....
 
Overflow doesn't cause a minor or major fault then?


No, neither. It's up to the programmer to deal with any arithmetic status flags hoisted by any instruction that can modify them. Easily ignored, by doing nothing with the information.
 
Last edited:

Similar Topics

Hello everyone, I am having issues with an output module connected to my 5069-L306ER PLC. The modules I have connected are a 5069-IA16 in slot 1...
Replies
1
Views
643
When trying to troubleshoot a machine at my factory, I was checking out the PLC and on one of the output cards there were a bunch of flashing...
Replies
4
Views
2,111
Hello there, Sorry I am quite new to this... thank you for taking the time to answer my thread. I have a small problem trying to get an output...
Replies
23
Views
5,053
Hi everyone, I have an output module that is blinking outputs 6 and 7 even when I take the wires out from the terminals. I thought it was the...
Replies
6
Views
4,893
Im trying to flash an output (50/50 duty cycle, .5 sec on/off.) I thought a TON/TOFF setup, but I cant get the logic down right. Is there an...
Replies
7
Views
18,129
Back
Top Bottom