You are not registered yet. Please click here to register!


 
 
plc storereviewsdownloads
This board is for PLC Related Q&A ONLY. Please DON'T use it for advertising, etc.
 
Try our online PLC Simulator- FREE.  Click here now to try it.

---------->>>>>Get FREE PLC Programming Tips

New Here? Please read this important info!!!


Go Back   PLCS.net - Interactive Q & A > PLCS.net - Interactive Q & A > LIVE PLC Questions And Answers

PLC training tools sale

Reply
 
Thread Tools Display Modes
Old May 2nd, 2002, 07:58 PM   #1
New2PLCs
Guest
 
Posts: n/a
How to simulate a FOR..NEXT loop?

In a processor like the MicroLogix 1500 which does not have a built-in FOR..NEXT loop instruction (I've seen some web sites that indicate that some processors do have this instruction), how does one simulate this functionality? NOTE: I want to loop within a scan.

In the AB ML 1500 manual, I noticed in the section on shift registers it said something about using JMP, LBL and CTU to loop if you wanted to shift more than once per scan. But I couldn't figure out how to get those to work as a loop. I bet there's a way to get RSLogix to output the rungs of what I tried in ASCII so that I could post it, but explaining it might be easier. I just had a LBL on a line with a CTU and later, after the logic I wanted to loop, a JMP going back to the original label. To exit the loop, I examine the CTU done bit and jump to a label on the line after the other JMP instruction. Thanks,

-Don
  Reply With Quote
Old May 2nd, 2002, 08:09 PM   #2
Steve Bailey
Lifetime Supporting Member + Moderator
United States

Steve Bailey is online now
 
Steve Bailey's Avatar
 
Join Date: Apr 2002
Location: The boondocks of Western Massachusetts USA
Posts: 6,478
You put the label earlier in the ladder logic than the jump instruction. The reason you need the counter is to make sure that you have a way to exit the loop. Getting stuck in an endless loop could have disastrous consequences, since the I/O aren't getting updated while the program is looping.

It's been my experience that there are very few places where it's a good idea to loop within a PLC program. When you're accustomed to programming in other languages, you tend to try to program the PLC using the tools that you already know how to use. I'm confident that there are ways to accomplish what you want to do without looping. Remember, the PLC already loops back to the beginning of the program without you having to do anything.
  Reply With Quote
Old May 2nd, 2002, 08:19 PM   #3
Allen Nelson
Member
United States

Allen Nelson is offline
 
Join Date: Apr 2002
Location: West Chester, PA
Posts: 1,368
Use a LBL, and JMP backwards through the code. Initialize a "counter" before the LBL, and increment it through the JMP. Like this:


N7:0 IS THE I IN "FOR I=1 TO 20". SETTING THE COUNTER TO ZERO HERE MEANS THAT IT WILL START AT ONE ON THE NEXT RUNG.
+---- CLR -+
----------| N7:0 |
+----------+
<BR><BR>
INCREMENT THE COUNTER EACH PASS THROUGH THE FOR-NEXT LOOP.
Q:0 +-- ADD -+
--|LBL|--------| N7:0 |
| 1 |
| N7:0 |
+--------+
<BR><BR>
PUT WHATEVER CODE YOU WANT HERE. WITH INDIRECT ADDRESSING USE N7:0, OR SOME FUNCTION OF IT.
<BR><BR>
THE "NEXT" OF THE FOR-NEXT
+--- LES -+ Q:0
---| N7:0 |-----(JMP)
| 20 |
+---------+

__________________
  Reply With Quote
Old May 2nd, 2002, 08:36 PM   #4
Gerry
Guest
 
Posts: n/a
Note that the CTU won't increment except on a false-to-true transition. You will need to force this in your loop by resetting the counter's enable bit - most easily done with an unconditional OTU.
The ADD instruction, as shown in Allen's example, does not require a transition.
Conditioning the (looping) JMP with the LES comparison or XIO of a counter done bit saves using more JMP's and LBL's. The counter's accumulator can also be used for indirect addressing.
  Reply With Quote
Old May 2nd, 2002, 08:59 PM   #5
New2PLCs
Guest
 
Posts: n/a
Steve,

Read the thread entitled "Energy Management System". If you can show me how to program my final attack on the problem (in the last post from me) without looping, I will bow to you as PLC God. (If you can do it in any manner, you will rank as a minor deity in my book.)

Allen,

You know, I've was playing around with similar logic to do that without the JMP and LBL instructions, with each scan being on iteration in the loop. All I have to say to defend myself for not thinking of that on my own is "I'm a noobie!"

Gerry,

That's the missing ticket I needed for doing it with the LBL, JMP, and CTU instructions. I didn't see how to achieve the desired result in the way the AB manual mentioned. I guess it doesn't make much difference, but the way Allen suggested seems simpler to me and I'll probably use it. Thanks.

-Don
  Reply With Quote
Old May 2nd, 2002, 09:10 PM   #6
Peter Nachtwey
Member
United States

Peter Nachtwey is offline
 
Peter Nachtwey's Avatar
 
Join Date: Apr 2002
Location: Vancouver, WA, US
Posts: 6,673
Indirect or Indexed addressing

Quote:
Originally posted by Gerry
The counter's accumulator can also be used for indirect addressing.
Actually that is indexed addressing. In indirect addressing N7:0 would be initialized to the start of the array and the LES block should compare with the start of the array plus 20. In the above example, indirect addressing could only be used if the data or array start at 0.
  Reply With Quote
Old May 2nd, 2002, 09:24 PM   #7
Allen Nelson
Member
United States

Allen Nelson is offline
 
Join Date: Apr 2002
Location: West Chester, PA
Posts: 1,368
Don:

As Steve pointed out, unless you have to have each compressor evaluated every scan, you don't need the for-next loop. If you can stand a slight delay (up to 500 msec), then take my code, delete the LBL and JMP instructions, and move the CLR instruction to where the JMP is.

On the first scan, N7:0 will be zero, until it hits the ADD, and the logic will be scanned using n7:0=1. On the next PLC scan, N7;0 will be =2, and so forth, until it hits 20, at when it will go back to zero.

Another method of not doing the looping is to use subroutines. You could create LAD 4 for the processing of any (N7:0) compressor, and then pass a number to N7:0 just before the JSR, like this:

+--- MOV -+
---+---| 1 |
| | N7:0 |
| +---------+
|
| +--- JSR -+
+---| U:4 |
+---------+
<br><br>
+--- MOV -+
---+---| 2 |
| | N7:0 |
| +---------+
|
| +--- JSR -+
+---| U:4 |
+---------+
<br><br>
et cetera



Not as elegant, perhaps, but it works too. This technique works better than For-Next if there are specific compressors that you DON'T want evaluated - disable the rung, and you don't execute the subroutine (which means that any outputs that the subroutine has enabled, remain enabled - something to be VERY careful of).

One more possible solution to your problem: Just what is the consequence of exceeding the load limit? Will a breaker trip, or is it just the cost of electricity? My energy bills always go up in summer, because i've balance the cost of electricity with the cost of comfort. I'm not saying to be intentionally wasteful, but if that MaxLoad is set in stone, there will be days when even the VPs get "hot under the collar" (pun intended).

You know you've got a no-win situation (unless you're lucky and a 50% duty time is sufficient for each compressor to keep everyone cool). At the very least, put the MaxLoad in a register, rather than a hard-coded number, so that you can (if needed) expose it to an HMI, and adjust it up if things just get too miserable.
__________________
  Reply With Quote
Old May 2nd, 2002, 09:27 PM   #8
New2PLCs
Guest
 
Posts: n/a
Peter,

I'm not sure what you mean. What's the difference: you can initialize the counter's accumulator value just as you would N7:0, no? Would you mind explaining, please? Thanks,

-Don
  Reply With Quote
Old May 2nd, 2002, 09:35 PM   #9
Allen Nelson
Member
United States

Allen Nelson is offline
 
Join Date: Apr 2002
Location: West Chester, PA
Posts: 1,368
Re: Indirect or Indexed addressing

Quote:
Originally posted by Peter Nachtwey


Actually that is indexed addressing. In indirect addressing N7:0 would be initialized to the start of the array and the LES block should compare with the start of the array plus 20.
Indexed addressing manipulates S:24. To use indexed adressing, you would write N7:0, or the counter .ACC to S:24, and then reference any address with a '#' sign.

My example was "FOR i=1 to 20". If I had wanted, say 5 to 25, I would have done a MOV of 4 in the initialization rung, and a LES of 25.

Quote:
In the above example, indirect addressing could only be used if the data or array start at 0.
In my original example, the array actually starts at one, not zero, because the pointer is incremented from zero to one on the next rung, prior to it being used in any addressing scheme.
__________________
  Reply With Quote
Old May 2nd, 2002, 10:48 PM   #10
Peter Nachtwey
Member
United States

Peter Nachtwey is offline
 
Peter Nachtwey's Avatar
 
Join Date: Apr 2002
Location: Vancouver, WA, US
Posts: 6,673
Indirect or Indexed Addressing

Allen, I usually put my code before the increment so the arrays can begin at 0. Incrementing before the code does start the array at 1.

New2PLC. I dread explaining this. Let's say there is an array of compressor runtimes for four compressors at N7:101 to N7:104.

To sum the run times using indexed addressing:

clr N7:0 INDEX
clr N7:1 SUM = 0
lbl q:0 mov N7:0 S:24 LOAD INDEX INTO S:24 INDEX REGISTER
add #N7:101,N7:1,N7:1 SUM = SUM + ARRAY[INDEX]
add N7:0 1 N7:0 INDEX = INDEX + 1
les N7:0 20 JMP Q:0 IF INDEX < 20 THEN REPEAT

Notice the # in front of the N7:0. That means that S:24 is added to N7:101 to form the effective address

To sum the run times using indirect addressing:

mov 101 N7:0 POINTER = 101
clr N7:1 SUM = 0
lbl q:0 add N7:[0],N7:1,N7:1 SUM = SUM + [POINTER]
add N7:0 1 N7:0 POINTER = POINTER + 1
les N7:0 105 JMP Q:0 IF POINTER < 101

Notice the [ ] around the 0 in N7:[0] this means N7:0 contains the address or register number of the register you really want to access.
  Reply With Quote
Old May 3rd, 2002, 08:01 AM   #11
Tom Jenkins
Lifetime Supporting Member
United States

Tom Jenkins is offline
 
Tom Jenkins's Avatar
 
Join Date: Apr 2002
Location: Milwaukee, WI
Posts: 5,878
I agree with Steve and Allen. It is generally NOT necessary or a even good idea to use a for-next loop in ladder logic. Unlike high level languages, the very structure of ladder logic is desigend for evaluating repetitive logic, making for-next loops redundant. Besides, it is much easier to troubleshoot successive rungs evaluated once per scan than to troubleshoot the logic in a for-next loop where intermediate results are undoubtedly not accessible.

And, as many regulars here know, I firmly believe that good prgramming, by definition, must be easy to troubleshoot!
  Reply With Quote
Old May 3rd, 2002, 08:56 AM   #12
New2PLCs
Guest
 
Posts: n/a
Peter,

I'm sorry, I should have made it clear that I know the difference between indexed and indirect addressing. Your first post still doesn't make sense (to me.) In his example Allen shows the structure of a loop and mentions using indirect addressing. Then, Gerry showed how to do it the way I originally asked about, using a counter, and says you can use the counter accumulator for the same type of indirect addressing functionality. Then you say it's really indexed addressing. Sorry to be so thick, but I don't see what you meant.

-Don
  Reply With Quote
Old May 3rd, 2002, 07:57 PM   #13
Gerry
Guest
 
Posts: n/a
Don,
I think you've got a handle on the problem and know how to do what you want. This may have been a rare mis-fire on Peter's part.

As for the concept of 'dumbing down' your programs to supposedly make them easier to understand or troubleshoot, I am strongly opposed. Following this maxim, one would avoid not only loops, but indirect and indexed addressing, subroutines, etc. for fear of confusing the unwashed masses. And without the tools, one would avoid many potential applications. Rather akin to burning books. It is arrogant to assume that electricians are incapable of learning anything new or that they are not even interested. Besides, getting equivalent functionality to a 'banned' technique will more than likely be 'long-winded' and bug-prone and genuinely difficult.
  Reply With Quote
Old May 3rd, 2002, 09:05 PM   #14
Peter Nachtwey
Member
United States

Peter Nachtwey is offline
 
Peter Nachtwey's Avatar
 
Join Date: Apr 2002
Location: Vancouver, WA, US
Posts: 6,673
New2PLC,
When I saw N7:0 set to 0 I assumed ( oops ) that Gerry really meant indexed as opposed to indirect address. Setting N7:0 allows one to access arrays or data using indirect addressing starting at 0 or 1 depending on whether the index is pre incremented or post incremented. I always start arrays at 0 and post-increment pointers or indexes because this is often more efficient than starting arrays at 1 in many cases where the array is a power of 2 long. In my narrow thinking, didn't consider the other options such as starting the array at 1 and pre-incrementing like Allen does. Oops again.
  Reply With Quote
Old May 3rd, 2002, 10:17 PM   #15
ganutenator
Member
United States

ganutenator is offline
 
ganutenator's Avatar
 
Join Date: May 2002
Location: akron, ohio
Posts: 1,032
so For/Nxt loops are bad now?

I too believe and try my hardest to make programs easy to follow. I can't tell you how many times I have reduced multiple confusing rungs using redundant contacts down to 1 or two rungs of logic. It has been my experience however, that just using coils and contacts DOES NOT necesarily make a program easier to understand. IN FACT if I come across a FOR/NXT routine that is written correctly, I find it much easier to comprehend. Why, because a For/Nxt routine has boundaries. You can easily determine what the programmer was trying to accomplish by writing that section of code. The hardest part of reading programs written by others is not in figuring out how a rung of logic works, but trying to figure out WHY or WHAT the programmer was trying to accomplish by writing it. (Which is why I can't emphasize enough... that you should write comments explaining what you were trying to accomplish when writing a particular section of logic, rather then trying to explain that a false to true transition of B3/0 latches coil B3/30 and loads N7:0 into the FIFO stack N7:[N8:0] where N8:0 is the pointer into the indexed array. If I want to understand how an instruction works, I'll look it up in a book. TELL ME WHAT YOU WERE TRYING TO ACCOMPLISH!!!

Excuse me, I was just venting there for a second. Probably all of the Heinekens. But seriously, you will find that a section written with a FOR/NXT loop may appear difficult at first, but you will come to long for them after trying to decipher a program that is badley written with all XIO XIC OTE instructions where 80% of the contacts or coils will never come in to play.

One example of a good use for For/Nxt loops is to replace the god awful AB file intstructions like the FAL, FSC, and FBC that only operate every other scan. A For/Nxt loop is awesome for this. And since I am venting..... What in the hell was Rockwell smoking when they created the average (AVE) instruction.
  Reply With Quote
Reply
Jump to Live PLC Question and Answer Forum

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Topics
Thread Thread Starter Forum Replies Last Post
Loop Performance Package kumar123 LIVE PLC Questions And Answers 1 September 8th, 2004 08:37 AM
Sensor Averaging for PID loop Hutchman LIVE PLC Questions And Answers 5 June 4th, 2004 08:01 AM
Sensor Averaging for PID loop Hutchman LIVE PLC Questions And Answers 1 May 27th, 2004 04:35 AM
PID Loop (DL06 PLC) phasor LIVE PLC Questions And Answers 2 May 7th, 2004 02:01 PM
Pid Loop Rslogix Peter Honey-Jones LIVE PLC Questions And Answers 1 October 9th, 2002 01:24 PM


All times are GMT -5. The time now is 01:25 PM.


.