Technical Article

PLC Programming Commands: Boolean Functions and Bit Redistribution 

September 15, 2022 by Jon Peterson

Learn how to use the boolean bitwise functions AND, OR, XOR, and NOT in your PLC programming, as well as some instructions used to change the position of bits and bytes in your INTs and DINTs.

See our previous articles covering PLC programming commands:

Timers

One-Shots

Up and Down Counters

Math Instructions

Trigonometry Instructions

Comparison Instructions

Move and Copy Instructions

Arrays and Pointers

Storing Data Using Arrays


 

Anyone who has worked with PLCs for long has also likely been exposed to boolean math such as AND gates, NOT gates, and other functions. In this article, we will cover the boolean functions, as well as some instructions used to change the position of bits in INTs and DINTs.

The boolean instructions we will be working with are the AND, OR, XOR, and NOT. The bit redistribution instructions we will be working with, SWPB (Swap Byte) and BST (Bit Field Distribute), are more complex, however, with this added complexity comes some critical functionality akin to the MOV, COP, or CPS instructions

 

AND Instruction (Bitwise AND)

The AND function is one of the most widely known functions in the realm of boolean logic—if both inputs are true, the result is true. In the following examples, we will explore the AND instruction that Allen-Bradley controllers uses in the Studio 5000 platform, but the same principles apply to virtually every controller brand with bit manipulation abilities. 

Sometimes, the default view presents the instruction in a way that can be more difficult way to visualize. In Figure 1, you’ll see the result of an AND function if you were to just drop it into a program.

 

dropping AND function into program result

Figure 1. Result of dropping AND function into a program.

 

If someone asked me to describe what was going on in that instruction, I’d tell them, “Something… math-ish…” Trying to understand these instructions while in decimal mode is going to be terribly difficult. Fortunately, we can change this. Let’s go into our Tag Properties and change the Tag Style for these tags we’re using (refer to Figure 2). Switching these to Binary will help us out a lot.

 

switching Tag Style to Binary rather than decimal

Figure 2. By switching Tag Style to Binary, we’ll be better able to see the entire instruction.

 

Ok, with that done, let’s take a second look at the AND Instruction in Figure 3.

 

AND instruction entire function

Figure 3. AND instruction entire function.

 

Now that we can see the entire instruction in Figure 3, we can more easily determine what is happening here. The operation is something that an integer programming language would refer to as a ‘bitwise AND’ function. 

Each bit in the Source A data is compaired with the matching bit in Source B to create an AND function. The AND’ed result of each pair is then placed in the Destination tag. In the logic we created above, you can see we essentially created 32 AND gates because we used 2 DINTs (Double Integers).

 

OR Instruction (Bitwise OR)

In the AND instruction, we were able to turn an output bit on if both inputs were true. In the OR instruction, we turn the output on if either input is true. If the first bit of only Source A is on, the output turns on. If the first bit of only Source B is on, the output turns on. Lastly, if the first bit of both Source A and Source B are on, the output turns on. You can see in Figure 4 in the live program snapshot how the different combinations work.

 

different combinations in the OR instruction
Figure 4. A look at the different combinations in the OR instruction.

 

XOR Instruction (Bitwise XOR)

The XOR (Exclusive OR) instruction differs slightly from the OR in this way:

  • If both Sources A and B are off, the output goes false.

  • If Source A is on and Source B is off, the output goes true.

  • If Source A is off and Source B is on, the output goes true.

  • If Source A is on and Source B is on, the output goes FALSE.

The critical difference is that last one. In an XOR gate, it must be one or the other, not both together.

Depending on the inputs given, the instructions executes the XOR function and dumps the result into the Destination tag, as seen in Figure 5.

 

XOR function result in Destination tag

Figure 5. XOR function result in the Destination tag.

 

NOT Instruction (Bitwise NOT)

The NOT instruction is the easiest one we’ll address today. If the source bit is false, the output bit is true. If the source bit is true, the output bit is false. A NOT function simply inverts each bit of the Source data string. Remember when you’re using this kind of logic function to set your tag style to binary, it’ll help out a lot!

 

The NOT instruction simply inverts the Source signal.

Figure 6. The NOT instruction simply inverts the Source signal.

 

Swap Byte (SWPB) Instruction

Now let’s change gears and look at ways to move bits from one part of a piece of data to another. Sometimes you need to move portions of data around. The SWPB instruction gives you four different movements you can choose from—they are called Order Modes and are selectable inside the instruction via a drop-down menu. For DINTs, you can choose REVERSE, HIGH/LOW, and WORD; if you put in an INT, you get the same result, no matter what you pick as an Order Mode.

To bring some clarity on how these movements take place, let's look at the letter system attached to INTs and DINTs. It is important to remember that when you look at INTs and DINTs inside Allen-Bradley instructions, they are read from right to left. The first bit is on the far right. The first 8 bits are designated as the letter A, the next set of 8 bits are designated B. If you are working with an INT, you only have 16 bits and are limited to the A and B letters only. If you are using a DINT, you will have the first set of 8 (A), the second set (B), a third set designated C, and the last set of 8 designated D. 

Let me try and express this in written form below:

 

INT

Byte A

Byte B

1111_1111

1111_1111

 

DINT

Byte A

Byte B

Byte C

Byte D

1111_1111 

 1111_1111 

 1111_1111 

 1111_1111

 

If you’re moving an INT (Integer), there are only 16 bits and the SWPB instruction gives you only one option no matter what you pick. The 8 bits left of center are swapped with the 8 bits to the right of center.

This expression would be demonstrated in letter form below:

AB => BA

Now let’s look at it in logical form in Figure 7. Remember this is for INTs, no matter what you pick for an Order Mode, it will always do the same thing.

 

moving an INT gives the same output, regardless of Order Mode

Figure 7. When moving an INT, it will give the same output, regardless of Order Mode.

 

Now let’s move on to DINTs. There are three different ways for you to be able to shift bits around in these. If you recall above, a standard layout for a DINT is ABCD. If we choose the REVERSE option, we would take the ABCD and rearrange the bits to form DCBA. This is shown in Figure 8. Our data in Section A of the Source is moved to Section B. The other sections would follow suit according to the Order Mode letter layout.

 

Data from Section A of the Source is moved to Section B

Figure 8. Data from Section A of the Source is moved to Section B.

 

Now for the WORD Order Mode, ABCD becomes CDAB. This is because a WORD is considered as 16 bits, so AB constitutes the first 16 bits, and this is swapped with CD, which is the second set of 16 bits.

In the logic in Figure 9, you can see our 8 bits in position D started on the right and ended up becoming placed in the second position from the left. All other data will be moved according to the WORD Order Mode.

 

8 bits move to second position from left

Figure 9. The 8 bits are placed in the second position from the left.

 

The last type of move that we deal with in the SWPB instruction is the HIGH/LOW. In this one, we start with ABCD and end up with BADC. Instead of flipping the whole thing around, this time we just reverse the order of A and B then reverse the order of C and D. You can see in the logic in Figure 10 how our Data in position D has simply swapped over one spot to the third position. All other data would move according to the HIGH/LOW Order Mode letter layout. 

 

Data in position D swapped to the third position

Figure 10. Data in position D swapped to the third position.

 

Bit Field Distribute (BTD) Instruction

Alright, I hope your brain isn’t too confused yet! We’re now on the last instruction in this article. The BTD function. This function can take any number of consecutive bits from a Source integer and place them into an arbitrary spot in a Destination integer.

We identify a Source DINT or INT and a starting point. In my logic, I used bit position 0 as my start point. We then give it a destination DINT or INT to place our data into as well a Destination Bit to serve as a starting point for where we are dropping in the data. Lastly, we give it the length—the number of bits to transfer starting from the source bit position.

In Figure 11, we can see I told my PLC to take 8 bits, starting in the BTDSource DINT Position 0, and drop them into the BTDDest DINT, starting at position 8. It executed exactly as we told it to. You can customize this to fit whatever needs you have.

 

8 bits moved from position 0 to position 8 using the BTD instruction

Figure 11. 8 bits moved from position 0 to position 8 using the BTD instruction.

 

Boolean and Bits

Now that we’ve walked through boolean and bit redistribution instructions, hopefully you have a better understanding of what they are and how to use them in your programming. Take your time familiarizing yourself with these PLC programming commands, and be sure to check out our related PLC programming content!
 

Featured image adapted and used courtesy of ABB

 

If you enjoyed this article, check out the rest of the PLC programming article sequence:

Timers

One-Shots

Up and Down Counters

Math Instructions

Trigonometry Instructions

Comparison Instructions

Move and Copy Instructions

Arrays and Pointers

Storing Data Using Arrays