Compact Logix Problem

celichi

Lifetime Supporting Member
Join Date
Apr 2008
Location
Greater Toronto Area
Posts
415
Hello Smart People,

I need to take 32 bits in a DINT, and transpose each bit to 32 DINTs.

If bit 00 = 1, then word 00 = 1
If bit 00 = 0, then word 00 = 0

If bit 01 = 1, then word 01 = 1
If bit 01 = 0, then word 01 = 0

.
.
.

and so on...

I want to avoid

XIC mov 1
XIO mov 0

I though about indirect pointer and loop or 1 pre scan, but wondering if there is a better path?

Thanks,
 
if you want to get fancy and the DINT's can be an array, you could make a loop with indirect addressing. Wouldn't be hard to do in ladder, but would look nice and neat in structured text. You are basically just doing XIC DINT.[INDEX] OTE ARRAY[INDEX].0
 
Last edited:
There's nothing inappropriate about brute force for a simple function like this. It's a very good opportunity to make use of the Add-On Instruction feature of ControlLogix.

Code:
If Source_DINT.0  Then Destination_DINT_Array[0] := 1 ; else Destination_DINT_Array[0] := 0 ; End_If ;
If Source_DINT.1  Then Destination_DINT_Array[1] := 1 ; else Destination_DINT_Array[1] := 0 ; End_If ;
If Source_DINT.2  Then Destination_DINT_Array[2] := 1 ; else Destination_DINT_Array[2] := 0 ; End_If ;
If Source_DINT.3  Then Destination_DINT_Array[3] := 1 ; else Destination_DINT_Array[3] := 0 ; End_If ;
If Source_DINT.4  Then Destination_DINT_Array[4] := 1 ; else Destination_DINT_Array[4] := 0 ; End_If ;
If Source_DINT.5  Then Destination_DINT_Array[5] := 1 ; else Destination_DINT_Array[5] := 0 ; End_If ;
If Source_DINT.6  Then Destination_DINT_Array[6] := 1 ; else Destination_DINT_Array[6] := 0 ; End_If ;
If Source_DINT.7  Then Destination_DINT_Array[7] := 1 ; else Destination_DINT_Array[7] := 0 ; End_If ;
If Source_DINT.8  Then Destination_DINT_Array[8] := 1 ; else Destination_DINT_Array[8] := 0 ; End_If ;
If Source_DINT.9  Then Destination_DINT_Array[9] := 1 ; else Destination_DINT_Array[9] := 0 ; End_If ;
If Source_DINT.10 Then Destination_DINT_Array[10] := 1 ; else Destination_DINT_Array[10] := 0 ; End_If ;
If Source_DINT.11 Then Destination_DINT_Array[11] := 1 ; else Destination_DINT_Array[11] := 0 ; End_If ;
If Source_DINT.12 Then Destination_DINT_Array[12] := 1 ; else Destination_DINT_Array[12] := 0 ; End_If ;
If Source_DINT.13 Then Destination_DINT_Array[13] := 1 ; else Destination_DINT_Array[13] := 0 ; End_If ;
If Source_DINT.14 Then Destination_DINT_Array[14] := 1 ; else Destination_DINT_Array[14] := 0 ; End_If ;
If Source_DINT.15 Then Destination_DINT_Array[15] := 1 ; else Destination_DINT_Array[15] := 0 ; End_If ;
If Source_DINT.16 Then Destination_DINT_Array[16] := 1 ; else Destination_DINT_Array[16] := 0 ; End_If ;
If Source_DINT.17 Then Destination_DINT_Array[17] := 1 ; else Destination_DINT_Array[17] := 0 ; End_If ;
If Source_DINT.18 Then Destination_DINT_Array[18] := 1 ; else Destination_DINT_Array[18] := 0 ; End_If ;
If Source_DINT.19 Then Destination_DINT_Array[19] := 1 ; else Destination_DINT_Array[19] := 0 ; End_If ;
If Source_DINT.20 Then Destination_DINT_Array[20] := 1 ; else Destination_DINT_Array[20] := 0 ; End_If ;
If Source_DINT.21 Then Destination_DINT_Array[21] := 1 ; else Destination_DINT_Array[21] := 0 ; End_If ;
If Source_DINT.22 Then Destination_DINT_Array[22] := 1 ; else Destination_DINT_Array[22] := 0 ; End_If ;
If Source_DINT.23 Then Destination_DINT_Array[23] := 1 ; else Destination_DINT_Array[23] := 0 ; End_If ;
If Source_DINT.24 Then Destination_DINT_Array[24] := 1 ; else Destination_DINT_Array[24] := 0 ; End_If ;
If Source_DINT.25 Then Destination_DINT_Array[25] := 1 ; else Destination_DINT_Array[25] := 0 ; End_If ;
If Source_DINT.26 Then Destination_DINT_Array[26] := 1 ; else Destination_DINT_Array[26] := 0 ; End_If ;
If Source_DINT.27 Then Destination_DINT_Array[27] := 1 ; else Destination_DINT_Array[27] := 0 ; End_If ;
If Source_DINT.28 Then Destination_DINT_Array[28] := 1 ; else Destination_DINT_Array[28] := 0 ; End_If ;
If Source_DINT.29 Then Destination_DINT_Array[29] := 1 ; else Destination_DINT_Array[29] := 0 ; End_If ;
If Source_DINT.30 Then Destination_DINT_Array[30] := 1 ; else Destination_DINT_Array[30] := 0 ; End_If ;
If Source_DINT.31 Then Destination_DINT_Array[31] := 1 ; else Destination_DINT_Array[31] := 0 ; End_If ;
 
Such a simple for/next loop would be ideal, but can't be used in ControlLogix because you can't use the Assignment operator with mixed data types (DINT and BOOL) like this.

The middle line of the for/next loop will fail to compile with a "BOOL tag not expected in expression" error.

The brute force if-then-else method takes more memory, but it compiles and functions correctly.
 
I could do an indirect rung, would take 32 scans to complete.

I am just doing brute force, at lease it will be easy to understand 3 months from now when someone is looking at it.

Thanks anyway.

I remember doing tasks like this in PLC5, which is why I couldn't figure this out in the logix PLCs
 
Sometimes dumb is best

Touche'.

But maybe belay the "lol" stuff. It's hard to not come off as snarky or insulting when you employ the text-message language of teenagers. Try "hey, have you considered this method ?".

One drawback of that method is if somebody inadvertently pokes a value greater than 1 into one of the Destination DINT elements; the value will change by 1, but won't automatically go back to 0 or 1 the next time the routine is executed.

The easy way to prevent such a malfunction by setting each sub-element to 0 before executing the assignment line.

Code:
For NDX := 0 to 31 Do;
Destination_DINT_Array[NDX] := 0 ;
Destination_DINT_Array[NDX].0 := Source_DINT.[NDX] ;
End_FOR ;

But when you do, there would be times in between the execution of those two lines during which other routines, interrupts, or communication requests could grab one or more of the DINT[x] elements while they are zero, and before the next line has gotten around to setting the correct value.

Even though those times are very short, it's possible for such an indeterminate condition to cause problems elsewhere in your application.
 
Last edited:
Several years ago I was looking to do a similar thing where I had set exactly one bit in a DINT to "1" and wanted to have a separate DINT to display which of the 32 bits was on. I asked the forum for advice and Ken Roach was the voice of reason that I needed to hear because sometime you just overthink things.

Yes, brute force - 32 rungs of ladder logic that examined each of the 32 bits. I made that into an Add-On Instruction that I have used in many projects since.

BTW - thanks again Ken!
 
Which application would you use this trick for? Are you capturing data somewhere and using the 32 DINTS to describe different conditions or something? Like are you capturing data from a barcode off a part, then using the DINTs to determine what part # ?
 
File Under: Just because you can, doesn't mean you should.

The problem is solvable with a FAL instruction as shown in attached. It took a few attempts.

The first (not shown) attempted to duplicate the structured text approach. However ladder expressions, unlike ST, do not allow BOOL operands.

The second tried to simply bit-shift the source and mask with the value 1. This should have worked, except the presence of the exponentiation operator (**) converts all operands to REALs, even though they are all DINTs, resulting in issues with rounding.

The third used a working array of 32 DINTs to hold the powers of 2, which mostly works except for the overflow error with 2**31. It also fails when the source DINT has bit #31 set, making it a negative number with issues on the shift-by-divide approach.

Finally, the fourth attempt handles all cases that I tested. And by the time it was done, illustrates why a "brute force" set of 32 XIC-OTL rungs (with a FLL clear) is probably the best choice for a ladder solution.

FAL BITS.jpg
 
Which application would you use this trick for? Are you capturing data somewhere and using the 32 DINTS to describe different conditions or something? Like are you capturing data from a barcode off a part, then using the DINTs to determine what part # ?

This is for data logging alarms, each alarm gets a full floating point because that is the only data type that is allowed.
 
File Under: Just because you can, doesn't mean you should.

The problem is solvable with a FAL instruction as shown in attached. It took a few attempts.

The first (not shown) attempted to duplicate the structured text approach. However ladder expressions, unlike ST, do not allow BOOL operands.

The second tried to simply bit-shift the source and mask with the value 1. This should have worked, except the presence of the exponentiation operator (**) converts all operands to REALs, even though they are all DINTs, resulting in issues with rounding.

The third used a working array of 32 DINTs to hold the powers of 2, which mostly works except for the overflow error with 2**31. It also fails when the source DINT has bit #31 set, making it a negative number with issues on the shift-by-divide approach.

Finally, the fourth attempt handles all cases that I tested. And by the time it was done, illustrates why a "brute force" set of 32 XIC-OTL rungs (with a FLL clear) is probably the best choice for a ladder solution.

Wow, I agree, brute force is sometimes the best method. Also, someone looking at brute force would get it right away.
 

Similar Topics

My company is involved with the installation (no programming or panel construction on our part) of a Compact GuardLogix PLC system with Point...
Replies
14
Views
5,606
Hi, I am using L30ERM as my controller and 1769-IF4XOF2 as my analog input module. and Rslogix5000 I applied voltage (0 to 5 V DC)on my input...
Replies
9
Views
4,349
I am having a problem with the max value when using a numeric input on the PVP 600. I created the numeric input and I am able to change the value...
Replies
10
Views
3,967
Hi I am Using a Panelview plus 700 with compactlogix 1768-L43 . In my pc i am getting all animations & values when i m testing but i cant get the...
Replies
0
Views
1,995
Hello, I have an HMI running an Intouch 9.5 application. It is communicating with a compact logix PLC via an external I/O server. The Intouch...
Replies
2
Views
2,839
Back
Top Bottom