Electrical & Software Control Systems for 
Safe Rides & Shows
(407) 290-2000

How to Simplify Ladder Logic

You can write better, simpler ladder logic by learning to recognize several common patterns within your rungs. Each of these patterns can be written in a shorter and simpler form that does the same thing. If you use the simpler forms your rungs will be easier to understand and change (which helps you write software that works the way you intend) and your programs will run faster and use less memory too.

Simplification Techniques

This document explains how to apply several simple laws taken from boolean algebra to ladder logic. You may remember the names of these laws from an old math class: Associative, Distributive, Communicative, Identity. Boolean algebra adds a few more: DeMorgan, Absorption, Tautology, and Contradiction. You won't have to remember the names of the laws - just learn to recognize their patterns and simplifications.

Extracting Duplicated Patterns

One simplification technique you will use very often is extracting patterns which appear more than once into a rung of their own. The pattern is then evaluated only once, and the result can be used in two or more rungs that follow without evaluating the same pattern again and again. This simplification is based on the associative law of boolean algebra.

When you use this simplification, it is important to remember that, unlike the electric circuit that it resembles, your ladder logic program is evaluated rung-by-rung, in order, from top to bottom. You should design your ladder program so that bits are always defined (right-side rung outputs) before they are referenced (left-side rung inputs). (As card inputs are defined prior to the start of the program, you need only worry about internal and output bits.) Following this rule will allow your program to react as quickly as possible (one scan) and avoid some rather devious program bugs.

The example below controls a motor which can run either up or down and must respond differently in Automatic mode than in Manual mode. The example avoids defining the automatic operation to focus on the extraction technique.

Extracting Duplicated Patterns - Original
In Manual mode, run the motor up while the [up] button is pressed.
In Auto mode, run the motor up while (TO BE DETERMINED)
Energize   Keyswitch in Keyswitch in Manual Up Manual Down   Run Motor in
EStop Relay   Manual Automatic Button Button   Up Direction
ESTOP_RELAY   MANU_KEYSW AUTO_KEYSW UP_BUT DOWN_BUT   RUN_MOTOR_UP
------[ ]------ + ------[ ]------ ------[/]------ ------[ ]------ ------[/]------ + ------( )------
  |         |  
  | Keyswitch in Keyswitch in To Be   |  
  | Manual Automatic Determined   |  
  | MANU_KEYSW AUTO_KEYSW TBD_UP   |  
  + ------[/]------ ------[ ]------ -----[TBD]----- --------------- +  
 
In Manual mode, run the motor down while the [down] button is pressed.
In Auto mode, run the motor down while (TO BE DETERMINED)
Energize   Keyswitch in Keyswitch in Manual Up Manual Down   Run Motor in
EStop Relay   Manual Automatic Button Button   Down Direction
ESTOP_RELAY   MANU_KEYSW AUTO_KEYSW UP_BUT DOWN_BUT   RUN_MOTOR_DOWN
------[ ]------ + ------[ ]------ ------[/]------ ------[/]------ ------[ ]------ + ------( )------
  |         |  
  | Keyswitch in Keyswitch in To Be   |  
  | Manual Automatic Determined   |  
  | MANU_KEYSW AUTO_KEYSW TBD_DOWN   |  
  + ------[/]------ ------[ ]------ -----[TBD]----- --------------- +  

Notice in the example above that two patterns involving the MANU_KEYSW and AUTO_KEYSW contacts are the same between the two rungs. These two patterns can be extracted out into two new rungs above the original rungs. We can name the two patterns MANU_MODE and AUTO_MODE and use them in these two rungs and elsewhere in the program.

Extracting Duplicated Patterns - Simpler
Determine if in Manual Mode
Keyswitch in   Keyswitch in     System in
Manual   Automatic     Manual Mode
MANU_KEYSW   AUTO_KEYSW     MANU_MODE
------[ ]------ - ------[/]------ --------------- --------------- - ------( )------
 
Determine if in Automatic Mode
Keyswitch in   Keyswitch in     System in
Manual   Automatic     Automatic Mode
MANU_KEYSW   AUTO_KEYSW     AUTO_MODE
------[/]------ - ------[ ]------ --------------- --------------- - ------( )------
 
In Manual mode, run the motor up while the [up] button is pressed.
In Auto mode, run the motor up while (TO BE DETERMINED)
Energize   System in Manual Up Manual Down   Run Motor in
EStop Relay   Manual Mode Button Button   Up Direction
ESTOP_RELAY   MANU_MODE UP_BUT DOWN_BUT   RUN_MOTOR_UP
------[ ]------ + ------[ ]------ ------[ ]------ ------[/]------ + ------( )------
  |       |  
  | System in To Be   |  
  | Automatic Determined   |  
  | AUTO_MODE TBD_UP   |  
  + ------[ ]------ -----[TBD]----- --------------- +  
 
In Manual mode, run the motor down while the [down] button is pressed.
In Auto mode, run the motor down while (TO BE DETERMINED)
Energize   System in Manual Up Manual Down   Run Motor in
EStop Relay   Manual Mode Button Button   Down Direction
ESTOP_RELAY   MANU_MODE UP_BUT DOWN_BUT   RUN_MOTOR_DOWN
------[ ]------ + ------[ ]------ ------[/]------ ------[ ]------ + ------( )------
  |       |  
  | System in To Be   |  
  | Automatic Mode Determined   |  
  | AUTO_MODE TBD_DOWN   |  
  + ------[ ]------ -----[TBD]----- --------------- +  

In this short example, the "simpler" code is actually slightly longer than the original - it uses two more instructions. However, this simplification is still desirable because it makes the program easier to understand. It is also clear than the MANU_MODE and AUTO_MODE results will be useful elsewhere in the program. Obviously, if the duplicated patterns had been larger or used branches, then the savings in speed and size could have been significant, in addition to improving the readability of the program.

Inverting Branched Rungs

Branches in rungs affect the complexity, size, and speed of ladder logic. A set of branches requires three or more instructions in addition to the contacts appearing on the branches. Each set of branches in a rung requires a branch-start and branch-end instruction, plus a next-branch instruction for every branch after the first. You can write faster, smaller, simpler programs by avoiding unnecessary branches.

Fortunately, it is possible to convert any rung from a "tall" rung which uses many branches to a "wide" rung using fewer branches by using DeMorgan's Law. To invert a rung, change all parallel branches (ORs) to series contacts (ANDs) and vice-versa, and invert all the contacts from N/O to N/C and vice-versa. Then use the output of the rung in the opposite sense from its original use.

In the example below, a motor must be disabled under any of several bad conditions. Put another way, the motor may only be enabled if all of several good conditions are satisfied. A Trouble Light indicates when the motor is disabled.

Inverting Branched Rungs - Original
Determine if Motor is Faulted
  3-phase     Motor is
  Monitor OK     Faulted
  3PHASE_OK     MTR_FAULTED
+ ------[/]------ + --------------- --------------- ------( )------
|   |  
| 240V Power |  
| Breaker ON |  
| 240_BRKR_ON |  
+ ------[/]------ +  
|   |  
| Motor Line |  
| Fuses are OK |  
| MTR_FUS_ON |  
+ ------[/]------ +  
|   |  
| Motor ON |  
| Response OK |  
| MTR_ON_RSP_OK |  
+ ------[/]------ +  
|   |  
| Motor OFF |  
| Response OK |  
| MTR_OFF_RSP_OK |  
+ ------[/]------ +  
 
Blink the Fault light if its faulted
  Motor is   Fast Blink   Motor
  Faulted   Util Bit   Fault Light
  MTR_FAULTED   FAST_BLINK   MTR_FLT_LIT
- ------[ ]------ - ------[ ]------ --------------- ------( )------
 
Run the Motor with Start/Stop buttons unless faulted
  Energize the   Motor Stop Motor is Energize the
  Motor Contactr   Button Faulted Motor Contactr
  MTR_CONTACTR   MTR_STOP_BUT MTR_FAULTED MTR_CONTACTR
+ ------[ ]------ + ------[ ]------ ------[/]------ ------( )------
|   |  
| Motor Start |  
| Button |  
| MTR_START_BUT |  
+ ------[ ]------ +  

Notice the large number of N/C "--[/]--" contacts and the multiply branched rung in the example above. These conditions should alert you to consider inverting a rung. The example below chooses to use "Motor is All OK" instead of "Motor is Faulted" and does the same job with 6 fewer instructions by converting branchs to series contacts..

Inverting Branched Rungs - Simpler
Determine if Motor is Faulted
3-phase 240V Power Motor Line Motor ON Motor OFF Motor is
Monitor OK Breaker ON Fuses are OK Response OK Response OK All OK
3PHASE_OK 240_BRKR_ON MTR_FUS_ON MTR_ON_RSP_OK MTR_OFF_RSP_OK MOTOR_ALL_OK
------[ ]------ ------[ ]------ ------[ ]------ ------[ ]------ ------[ ]------ ------( )------
 
Blink the Fault light if its faulted
  Motor is   Fast Blink   Motor
  All OK   Util Bit   Fault Light
  MTR_ALL_OK   FAST_BLINK   MTR_FLT_LIT
- ------[/]------ - ------[ ]------ --------------- ------( )------
 
Run the Motor with Start/Stop buttons while ALL OK
  Energize the   Motor Stop Motor is Energize the
  Motor Contactr   Button All OK Motor Contactr
  MTR_CONTACTR   MTR_STOP_BUT MTR_ALL_OK MTR_CONTACTR
+ ------[ ]------ + ------[ ]------ ------[ ]------ ------( )------
|   |  
| Motor Start |  
| Button |  
| MTR_START_BUT |  
+ ------[ ]------ +  
 

Combining Common Contacts

Another way to cut down on your program's size and increase its scanning speed is to combine common contacts using the boolean distributive law. This technique may be useful if you see the same contact on two or more branches of the same group or on branchs of adjacent branch groups.

In the example below, the programmer has literally implemented a user interface specification which states: "the arm's ready light shall be ON if the pressure is High and the arm is at the upper limit switch, or if the pressure is Low and the arm is at the lower limit switch, or if the pressure is High and the foot switch is pressed." Note that the limit switches are normally closed and open when the arm is at each limit.

Combining Common Contacts - Original
 
Operator's "arm is ready" light
  High Pressure Upper Limit     Arm is Ready
  Switch (N/O) Switch (N/C)     Light
  HI_PRES_SW UPPER_LIM_SW     ARM_READY_LT
+ ------[ ]------ ------[/]------ + --------------- ------( )------
|     |    
| High Pressure Lower Limit |    
| Switch (N/O) Switch (N/C) |    
| HI_PRES_SW LOWER_LIM_SW |    
+ ------[/]------ ------[/]------ +    
|     |    
| High Pressure Operator's |    
| Switch (N/O) Foot Switch |    
| HI_PRES_SW OPER_FOOT_SW |    
+ ------[ ]------ ------[ ]------ +    

Notice that the non-inverted contact of the pressure switch appears in both the first and third branches. This is an opportunity to eliminate a contact. In the simplified version below, the first and third branches have been moved together (using the communicative law) and the two common pressure switch contacts have been combined into a single contact.

Combining Common Contacts - Simplified
 
Operator's "arm is ready" light
  High Pressure   Upper Limit         Arm is Ready
  Switch (N/O)   Switch (N/C)         Light
  HI_PRES_SW   UPPER_LIM_SW         ARM_READY_LT
+ ------[ ]------ + ------[/]------ + - + --------------- ------( )------
|   |   |   |    
|   | Operator's |   |    
|   | Foot Switch |   |    
|   | OPER_FOOT_SW |   |    
-   + ------[/]------ +   |    
|           |    
| High Pressure   Lower Limit     |    
| Switch (N/O)   Switch (N/C)     |    
| HI_PRES_SW   LOWER_LIM_SW     |    
+ ------[/]------   ------[/]------ - - +    

The rungs below give the basic patterns and simplifications for combining common contacts. X and Y are equal.

Distributive Law - Normal Form
  A   B   X
+ ------[ ]------ - ------[ ]------ + ------( )------
|       |  
| A   C |  
+ ------[ ]------ - ------[ ]------ +  
           
  A   B   Y
- ------[ ]------ + ------[ ]------ + ------( )------
    |   |  
    | C |  
    + ------[ ]------ +  

Here is the distributive law again, this time in its inverted form. X and Y are again equal.

Distributive Law - Inverted Form
  A       A   X
+ ------[ ]------ + - + ------[ ]------ + ------( )------
|   |   |   |  
| B |   | B |  
+ ------[ ]------ +   + ------[ ]------ +  
               
  A           Y
+ ------[ ]------ - - - --------------- + ------( )------
|           |  
| B       C |  
+ ------[ ]------ - - - ------[ ]------ +  

Absorbing Unnecessary Contacts

This simplification allows you absorb unnecessary contacts from branched rungs by using boolean algebra's law of absorption. You can find this pattern by looking for both a N/O and N/C contact of the same bit used on adjacent branches (or inside and outside a branch).

Consider the example below. This ladder segment compares the output to a motor starter (or contactor) to an input from the starter's aux contact. The aux contact input should always follow the output. If the aux contact is either stuck ON or stuck OFF (not following the output) for longer than the tolerance of a timer, then the fallen DoNe bit of the timer unlatches an OK bit to record the problem.

Absorbing Unnecessary Contacts - Original
 
If the motor is ON, then the AUX must be ON
If the motor is OFF, then skip (pass) the test
  Energize the Motor Starter   Motor Starter
  Motor Starter Aux Monitor   Aux Response 0
  MTR_STARTER MTR_AUX_MON   MTR_AUX_TOF0
+ ------[ ]------ ------[ ]------ + -----[TOF]-----
|     | 0.01 x 20
| Energize the   |  
| Motor Starter   |  
| MTR_STARTER   |  
+ ------[/]------ --------------- +  
 
Drop the OK bit if Motor is stuck OFF
  Motor Starter     Motor ON
  Resp. Timeout     Response is OK
  MTR_AUX_TOF0.DN     MTR_RESP0_OK
- ------[/]------ --------------- - ------(U)------
 
If the motor is ON, then skip (pass) the test
If the motor is OFF, then the AUX must be OFF
  Energize the     Motor Starter
  Motor Starter     Aux Response 1
  MTR_STARTER     MTR_AUX_TOF1
+ ------[ ]------ --------------- + -----[TOF]-----
|     | 0.01 x 20
| Energize the Motor Starter |  
| Motor Starter Aux Monitor |  
| MTR_STARTER MTR_AUX_MON |  
+ ------[/]------ ------[/]------ +  
 
Drop the OK bit if Motor is stuck ON
  Motor Starter     Motor OFF
  Resp. Timeout     Response is OK
  MTR_AUX_TOF1.DN     MTR_RESP1_OK
- ------[/]------ --------------- - ------(U)------
 

Notice on each of the branched rungs with a timer, that one of the MTR_STARTER contacts is unnecessary. The unnecessary contact is the one on a branch with the MTR_AUX_MON contact. It is unnecessary because the only contact on the other branch is its opposite. Consider this simple rung:

Law of Absorption - Normal Form
 
  A B   X
+ ------[ ]------ ------[ ]------ + ------( )------
|     |  
| A   |  
+ ------[/]------ --------------- +  
 
    B   Y
+ --------------- ------[ ]------ + ------( )------
|     |  
| A   |  
+ ------[/]------ --------------- +  
 

The results of X and Y for all combinations of A and B is given by this truth-table:

A B X Y
0 0 1 1
0 1 1 1
1 1 1 1
1 0 0 0

Notice that the results of X and Y are exactly the same for all possible combinations of A and B, dispite the missing A contact in the second rung. Clearly the first contact of A is unnecessary and can be "absorbed" into the the other contact of A.

Applying this simplification to our original example with the motor starter and aux contact input, we arrive at this ladder logic:

Absorbing Unnecessary Contacts - Simpler
 
If the motor is ON, then the AUX must be ON
If the motor is OFF, then skip (pass) the test
  Motor Starter     Motor Starter
  Aux Monitor     Aux Response 0
  MTR_AUX_MON     MTR_AUX_TOF0
+ ------[ ]------ + --------------- -----[TOF]-----
|   |   0.01 x 20
| Energize the |  
| Motor Starter |  
| MTR_STARTER |  
+ ------[/]------ +  
 
Drop the OK bit if Motor is stuck OFF
  Motor Starter     Motor ON
  Resp. Timeout     Response is OK
  MTR_AUX_TOF0.DN     MTR_RESP0_OK
- ------[/]------ - --------------- ------(U)------
 
If the motor is ON, then skip (pass) the test
If the motor is OFF, then the AUX must be OFF
  Energize the     Motor Starter
  Motor Starter     Aux Response 1
  MTR_STARTER     MTR_AUX_TOF1
+ ------[ ]------ + --------------- -----[TOF]-----
|   |   0.01 x 20
| Motor Starter |    
| Aux Monitor |    
| MTR_AUX_MON |    
+ ------[/]------ +    
 
Drop the OK bit if Motor is stuck ON
  Motor Starter     Motor OFF
  Resp. Timeout     Response is OK
  MTR_AUX_TOF1.DN     MTR_RESP1_OK
- ------[/]------ - --------------- ------(U)------
 

The law of absorption also works in its inverted form, where it applies to complementary contacts inside and outside of a branch. Here is the inverted form of the law of absorption. Note that the first contact of A (inside the branch) has no effect on the result because its opposite appears outside the branch.

Law of Absorption - Inverted Form
 
  A   A X
+ ------[ ]------ + ------[/]------ ------( )------
|   |  
| B |  
+ ------[ ]------ +  
 
  B   A Y
- ------[ ]------ - ------[/]------ ------( )------

The truth table for these two rungs is given below, showing that the results of X and Y are identical.

A B X Y
0 0 0 0
0 1 1 1
1 1 0 0
1 0 0 0

Eliminating Trivial Combinations

 

Condensing Identical Contacts


www.birket.com P.O. Box 610190, Ocoee, FL 34761-0190 fax (407) 654-2150