Question on AB PLC

limsgp

Member
Join Date
Jul 2011
Location
Singapore
Posts
25
Say, the PLC program uses a State Machine design and an array of boolean bits to indicate what is the current "state", Is there a way to read off the array which bit is latched at any time?

In terms of implementation, a DINT bit array would be more efficient, however, the implementation of using boolean arrays is fixed and cannot change. The boolean array contains 128 elements to reflect 128 possible "states".

I have tried to create another routine (Report_Current_State) that would loop thru all 128 elements to detect which bit is latched and hence report the current "state" on the HMI. However, this method is not efficient and have serious bugs. I briefly explains as follows

1. The "Report_Current_State" would progress thru each element once once every scan. The PLC program would have transited thru a few "states" before the "Report_Current_State" even go thru all the 128 elements. The result is some "states" would go unreported.

For HMI display purpose, it is ok and not an issue. However, if I want to log a "State History" for debugging purposes, this becomes a very serious bug.

2. I tried to use the LBL and JMP instruction in the "Report_Current_State" routine to loop within the routine so that it will always report a valid state within one scan cycle of the main PLC program. However, this method results in a controller fault due to some timeout error as the scan doesn't complete within a specified duration.

Appreciate if anyone can offer some advise and/or solution. Thank you. I'm quite new to AB PLC and control logix programming.
 
On state machines I prefer bit overlays rather than boolean arrays, however your boolean array is fine. The same rung that sets a state bit also sets the state number.


STATE 1
ENABLE
LOGIC State.State1
--] [------------------( )----+MOV----------------+
|SOURCE 1 |
|DEST State.Number|
+-------------------+

STATE 2
ENABLE
LOGIC State.State2
--] [------------------( )----+MOV----------------+
|SOURCE 2 |
|DEST State.Number|
+-------------------+

STATE 3
ENABLE
LOGIC State.State3
--] [------------------( )----+MOV----------------+
|SOURCE 3 |
|DEST State.Number|
+-------------------+

 
Hi Alaric, Thank for your reply.

So, there is still no easy way to do what I wanted other than to add an additional instruction to each and every rung? Anyway thanks for your input :)
 
Last edited:
If it is a DINT, it would have been much simpler. Getting the bit position from a DINT is not difficult.. a Simple Log2 instruction would do it.

The problem is, it is a boolean array. I doubt COP works on boolean array. If there is any instrcution to map the boolean array into a DINT, this problem would not have been a problem.. Or maybe I missed out any instruction that can be used?
 
Ohh got caught again
Thanks for reminding me why I NEVER use BOOL[n] as a Tag Type

Only way around it that I know is to use UDT's as follows

MyBool_UDT
BitArrray BOOL[128]

MyDINT_UDT
Dint_Array DINT[4]

Both are the same size so you can COP from one to another

Or using a Brute force method in a subroutine or AOI
Mov 0 Step
XIC (MyBoolArray[1]) mov, 1, Step
XIC (MyBoolArray[2]) mov, 2, Step
...
 
That is exactly why I use bit overlays instead - however you apparently already have the program written.


Let me ask you a question: What is so hard about adding an instruction to write the state number in series with the state coil? Even if you have 128 them it should take less than half an hour to paste them in unless the logic is scattered all over the place. And its easy for anyone who looks at the program latter to understand.

Another option is a For/Next loop, A for/next loop is compact but it actually executes more instructions than if you use one of the other suggestions. A for/next also add a lot of program overhead.

Sample For/Next loop:
CLR I
LBL Q XIC BOOLARRAY MOV I STATE_NUMBER
XIO BOOLARRAY LES I 128 ADD I 1 I JMP Q

Michael's suggestion of a brute force method in a subroutine will actually execute faster than the For/Next loop. If you want to program a method like that really fast then do a forum search on my user name and EXCEL. Somewhere here I have a post on how MS Excel can be used for rapidly creating a large number of similar rungs of logic for AB PLC programs. You could build all 128 rungs in less than ten minutes.
 
Last edited:
Alas, if only a BOOL behaved like an integer.

RSLogix5K allocates a full 32 bit word to a boolean, even though it is just true or false. It will optimize arrays, but it still won't let you treat the array as a word. I'm not sure why the egg-heads didn't build such an obvious ability into the compiler. So multiple booleans have to be tediously copied to bits in integers first. Defining two equally sized UDTS simplifies the copy, but unless the program was set up that way to begin with then things get a bit more complicated.
 
Another option is a For/Next loop, A for/next loop is compact but it actually executes more instructions than if you use one of the other suggestions. A for/next also add a lot of program overhead.

Can't use for/next loop. using Ladder diagram.

Doing for/next in ladder is like using JMP and LBL instructions.. however, as mentioned in 1st post, it results in controller fault, timeout error.

Boolean array state machine is customer specification, cannot change.

Writing state numbers in series with state coil works, and if Micheal had not provided the method, it maybe the only way. However, I'll prefer lesser code and more "elegant" presentation if possible. It's more like personal choice/style.
 
Alas, if only a BOOL behaved like an integer.

Defining two equally sized UDTS simplifies the copy, but unless the program was set up that way to begin with then things get a bit more complicated.

Nice thing is the boolean array stae machine is in UDT to began with :)
 
Can't use for/next loop. using Ladder diagram.

Doing for/next in ladder is like using JMP and LBL instructions.. however, as mentioned in 1st post, it results in controller fault, timeout error.

If you are doing too much in the loop or looping too many times, you can trigger a watchdog or overlap. If you can 't spare a small chunk of scan time in this routine, then you are right, otherwise, there may have been an error in your loop construct...I have a L23E doing two conditional loops that repeat up to 120 times each, and they often happen during the same scan without much of a blip on scan time.

EDIT: I should clarify that I don't recommend looping in LAD either, but there are rare times when it's best.

Boolean array state machine is customer specification, cannot change.

You should at least advise them that their requirement is an impediment and a superior method exists. (Explain addressing bits within DINT arrays as being everything and more than B3:[x].)

Writing state numbers in series with state coil works, and if Micheal had not provided the method, it maybe the only way. However, I'll prefer lesser code and more "elegant" presentation if possible. It's more like personal choice/style.

Yes, remapping them is the quick fix, and that's what I would do too, since the design is already committed.
 

Similar Topics

HI i would like to know how to get a variable that will store the amount of times a program has been executed. The issue is I have 3 DBs for 1 FB...
Replies
2
Views
70
I've ready through the the previous posts, and we've worked with safety design for a long time. In the past, we worked with Pilz directly, and...
Replies
9
Views
554
Everyone, i am in the process of purchasing the Slc 500 version of software to support what we have and i have a question. Several of our...
Replies
9
Views
759
I know this can be done, but I can't get the router config right. My goal is to physically connect(using an ethernet cable) a device(PLC, RTU...
Replies
9
Views
1,016
Hello. Was just curious, if it is possible to load an image from an SD card on to a Compactlogix PLC that came straight out of the box brand new...
Replies
4
Views
544
Back
Top Bottom