Discuss your PLC and automation problems for Allen Bradley, GE, Omron, Mitsubishi, Modicon, Panel Views, RS View, ABB, Adept Robots, Cognex etc. You can also submit and download sample PLC code.

If our forums and knowledge base still hasn't got your PLC operational, we recommend contacting PDF Supply and Electric for PLC repair and replacement parts.

Email to friend
Multiple emails allowed. Separate with commas

Confirmation code image

Type the characters in the image above exactly as you see them

Programming in List on a Mitsubishi PLC - Part 1

- by Jim Rowell - 2003/10/19 (Download Instead? Part 1 and Part 2) 
This is a tutorial written for 2 sets of people. First its intended for those just starting out who have at least learned how to use the basics of their editing software in order to enter a simple program. They should already understand the basic concepts such as x0 is an input, y0 is an output. It's also intended for advanced users of Ladder who are curious about List. Hopefully it's not too difficult for the former or too simplistic for the latter. I'm not an experienced tutorial writer, so apologies in advance!  ;)

You're bound to have a better grasp of PLC coding and the best ways to approach problems if you understand how the PLC reads and executes your code.


First of all, despite the fact that the PLC was designed as a direct replacement for relays, its logic is actually quite different. Relays are 100% parallel logic. Every single part of a relay control system operates simultaneously. If you were to draw several rungs on a relay diagram and put one coil on each line with no contacts on any of the lines, every relay would energize at the same time when power was applied. If you add contacts to each line and the contacts on a line change at some time, the coil on that line is instantly affected. This makes relay logic blindingly fast by nature (its only the relay's mechanical limitations that make it slow) but it's often a source of trouble. There can be a race effect where different logic states occur if this relay closes faster than that relay this time but not the next time. On the other hand, the PLC is sequential in operation. One thing happens at a time. In happens in the order you dictate and its the same order every time. In fact, the entire PLC program doesn't exist as far as the PLC itself is concerned. Only the single piece of code that it happens to be examining at any one time matters.

Here's how it works:

First the PLC's operating system examines the state of all of the external wiring inputs. It records this data to an area of memory called the "input image". This image or record of the inputs is what will be used for input reference while executing your code. The real inputs are not used. The PLC then looks at your code starting at the beginning and progresses through it. The PLC only keeps track of a single logic result as it's reading your code. This result will be equal to 1 (true) or 0 (false). There are complications to this such as when the operating system must read ahead during complex logic or when certain things require stacked results but its true for the most part. As it reads your code, it will update any changes to the outputs by writing to an area of memory called the "output image" rather than the actual outputs themselves. When it reaches the end of your code, it then turns the real outputs on or off by copying the output image memory to the actual output registers. This start to finish cycle is called a "scan" and repeats endlessly over and over. In summary, the inputs are read once as a group, then your code is executed and then the outputs are updated as a group. Without this cycle method, inputs changing midway during your program could cause strange results and you couldn't change your mind about outputs before finally turning them on or off for real. With the scan method, we have an almost imaginary world inside the program where we can do what we want with no interference or consequences. It's only at the end of each scan that we have to worry about reality.


This is at the heart of the PLC's operation. You need to know this.

There are other ways of looking at PLC logic that perhaps are more intuitive than the pure Boolean method but you still must understand it and have it in your arsenal of tools if you are going to have more than a basic ability with PLC's. Unfortunately, this is a scary subject to the uninitiated but stand fast! It's really not that hard to grasp. Just remember, it's the basis of all things digital. Even good old relays are digital devices that lend themselves well to Boolean logic.

Boolean logic uses 2 states to represent things. Something can be on (equal to 1) or it can be off (equal to 0).

We perform what are known as "logical" operations in Boolean. Things like "logical AND" and "logical OR" (I'll use uppercase to denote a logical operation).

logical AND means "if both things equal 1 then the answer is 1"

or in other words:

 0 AND 0 = 0
 0 AND 1 = 0
 1 AND 0 = 0
 1 AND 1 = 1

Logical OR means "if either thing equals 1 then the answer is 1"

or in other words:

 0 OR 0 = 0
 0 OR 1 = 1
 1 OR 0 = 1
 1 OR 1 = 1

Logical NOT (also called "invert") means "invert the item, make it the opposite, the current value is NOT what I want"

or in other words:

 NOT 0 = 1
 NOT 1 = 0

You perform a logical NOT on something when you know you want the opposite result.

So now if we said given that X=1 and Y=1, you'd know that X AND Y = 1 and also that X OR Y = 1

or given that X=0 and Y=1, you'd know that X AND Y = 0 but X OR Y = 1.

Or, to get tricky, given that X=0 and Y=1, you'd know that NOT X AND Y = 1 but X OR NOT Y = 0

You should read and re-read this until you understand it. It's important.

When something is equal to 1 we say that the result is "true". When something is equal to 0 we say that the result is "false".

In proper Boolean, there is a defined order for performing operations just like in math where multiplication is performed before addition. In Boolean, AND operations are performed before any OR operations. In fact, the short form method of writing Boolean uses the times symbols "x" or "*" to represent AND while the plus sign "+" is used for OR. (eg. 1+0=1 is the same as writing 1 OR 0 =1). The "times" symbol expresses the fact that AND has precedence over OR. You don't have to worry about this in the PLC. It simply performs the operations in the order they are presented. Just be aware that it's a deviation from what goes on outside of the PLC arena.


To program the PLC we have several options in the way of languages. The two common ones are Ladder and Instruction List. There are many tutorials that discuss Ladder so we'll stick with the one most near and dear to my heart: "Instruction List". List is a "mnemonic" or text-based language. It's exactly like the Assembler languages used to program microprocessors in their native language. A native language is one that the processor directly understands. You type a "mnemonic" which is simply an abbreviation consisting of a few letters to represent a command, and the editing software on the PC sends the corresponding code number to the PLC. There are no interpretations or changes made other than the fact that you type in letters and symbols and the PLC reads numbers. When working with a PLC, you are not really programming the processor. There is a high-level operating system on-board that is programmed to "be" a PLC but the net affect to you as a programmer is identical to working directly with a processor. In other words, you are about to become an Assembler programmer! Pretty exciting, right?  ;)

Mitsubishi uses mostly obvious mnemonics such as LD to mean "load the accumulator", AND to mean "AND", OR to mean "OR" and OUT to mean "send the result to the output image". These and the following may seem like gibberish to you at first but plough through it. There is a bit of a learning curve and then the sun breaks through the clouds!

LDI (Load Inverted; more commonly thought of as Load Not) means "perform a NOT operation on the following value, then load the accumulator with the result".

AND means "perform an AND operation".

ANI (And Not) means "perform a NOT operation on the following value, then do an AND"

  eg. given that X1=1 and Y1=0,    X1 ANI Y1 =1 because although Y1 contains a zero, it is first inverted to a 1. The AND operation is performed as 1 AND 1 which = 1.

ORI (Or Not) means "perform a NOT operation on the following value, then do an OR

 eg. given that X1=0 and Y1=0, X1 ORI Y1 =1 because although both contain zeros, Y1 has first been inverted to a 1. The OR operation is performed as 0 OR 1 which = 1.


People generally think of the PLC as being more complex in its method of reading lines than it really is. They picture it reading an entire Ladder rung like they would and then making a decision at the end as to whether or not to turn on the output. It actually never makes a decision when performing basic logic such as AND, ANI, OR, ORI. It just keeps track of the current state of affairs in a reserved memory location known as the Accumulator or just "A" for short. This is an old, tried and true processor method that the PLC's operating system emulates.


If we were to write some standard English control logic as such:

                if x1 is on and x2 is on or y1 is on and y2 is off then turn on y10 else turn y10 off.

and then rewrote the same thing for the PLC it would look like the code below. The comments show how the PLC executes it.

LD          x1            ;the PLC "loads" the Accumulator (A) with the value of x1 (ie. the value of x1 is moved into A).
AND      x2            ;the PLC performs A AND x2. The result is placed in A.
OR         y1           ;the PLC performs A OR y1. The result is placed in A.
ANI         y2           ;the PLC performs A AND NOT y2. Result is placed in A.
OUT      y10         ;the PLC "outputs" the value of A into the output image memory location reserved for y10.

As you can see, no decisions were made. The PLC didn't even turn the output on or off. It just moved the result to the output image when it was told to! Later, at the end of the scan, the entire output image will be copied to the real output registers. If there ends up being a 1 in a register, the associated output will magically turn on. If it contains a zero, it will turn off. The turning on, turning off part is done by the hardware. The operating system has nothing to do with it.

The PLC doesn't even perform the operations in the proper order according to the rules of Boolean logic. It simply AND's and OR's things as presented.

This is how the PLC with a simple and comparatively slow processor can scream through your code at such speed. Its efficient and only concerned with simplicity.

When we start a new "series" or collection of statements in List or begin a new rung in Ladder, what we are really doing is telling the PLC that we want to start over and it should not use any previous results. In other words, we want it to "Load the accumulator" with the first value rather than perform an operation with the old value from the previous line. Loading the accumulator with the new value overwrites whatever was already there.


Okay, so now lets back up and start simple:

You want a motor to come on but only if you turn on a selector switch. So you connect a switch to x0 on the PLC and you connect the motor's contactor coil to y0.

Now what? First we name the inputs and outputs. Never, ever, ever, use the raw I/O names in a program. Its fine for describing things to your friends in snippets of code about how to do something... but don't use x0, y0, etc in a real program. It's hard to read, it's hard to debug and it's hard to change. Okay, so we'll call x0 "switch" and y0 "motor". Right?

Here's how your program will look:

                LD          SWITCH
                OUT      MOTOR

That was pretty easy, no? To make it easy to read, instead of thinking "LD", think "IF" and instead of OUT, think "then" or "turn on".
In your head it becomes:

                if              switch
                then        motor

What if you want the motor to shut off if it gets too hot? Oops, that's right, we have overload contacts we have to monitor. So lets put them into x1 and call them "overload". Typically, we want the motor to only turn on if the overload contacts are closed. Same as the switch. So now we have:

                LD          SWITCH
                AND      OVERLOAD
               OUT      MOTOR

Now someone adds a special sensor on the machine and tells you the motor must turn off if the sensor turns on.

                LD          SWITCH
                AND      OVERLOAD
                ANI         SENSOR
                OUT      MOTOR

So now in English, this would read...

If switch (was that supposed to be open or closed?) and we have an overload... no, wait! If we don't have an overload... and the sensor is not on (not open or not closed?)... hmmm.... this is getting confusing!!

We've only got 4 lines of code and already its unclear exactly what we are trying to do. Time for some more RULES!


Name your inputs and outputs according to what they do when they are "active". That's an important word. Forget "open" and "closed" for a minute. Think "active" and "inactive". Every item has a purpose or you wouldn't be connecting it in the first place. You must always name an item according to its purpose. It will be "active" when its fufilling its intended purpose. The purpose of the switch we used was to turn on the motor or make it run. We should have called it something like "RUN". Even better would be to call it "RUN'SEL" (for Run Selector). Notice I used 2 words separated by an apostrophe. We are only allowed a single word but often two or three make the purpose clearer. The apostrophe is a good way of cheating your 1 word into several. The more traditional underscore also works but it's easy for your eye to miss it and a tired and worn printer will often drop it. Now you know the following about RUN'SEL:

If the real switch in the field is active then our input called RUN'SEL is active (x0=on),and its

name tells you what the intended result should be (RUN).

It doesn't matter how that was achieved in the field ie. normally-open or normally-closed contacts. An input is only active if you have a live electrical signal coming to it.

Now, how about our overload contacts. Their purpose in life is to detect overloads. They become "active" when an overload occurs. So they can properly be called "Overload" contacts. Since we have decided to use normally-closed contacts from the overloads, we have a problem. The signal into the PLC will be OFF (inactive) when the overloads are active. In other words, the input should be named "NO'OVERLOAD" because when the input is active, the overload contacts are inactive and there is no overload.

A better method is to use a slash in front of the name which is read as "NOT". This is just my personal idea, stolen from Boolean, but it works really well. The slash tells you that the input is inverted (inactive when the input is on). So "OVERLOAD" is read as "not overload". The field device is called "Overload" but the input on the PLC is called /OVERLOAD. When you see the slash, it tells you the field device is using normally-closed contacts. Otherwise, everything is from normally-open contacts. Beautiful, no?

Let's see where we are now (the comments show how YOU would read it):

                LD          RUN'SEL             ;"if run'sel"
                AND      /OVERLOAD      ;"and not overload"
                OUT      MOTOR               ;"out motor"

That's better. We need a name for the sensor. Let's say that when its active, it's telling us that the machine is busy and the motor must remain off. Let's call it BUSY.

                LD          RUN'SEL             ;"if run'sel"
                AND      /OVERLOAD      ;
"and not overload"
                ANI         BUSY                    ;
"and not busy
               OUT      MOTOR               ;
"out motor"

In English: If the run selector switch is on and there is no overload and the machine is not busy then turn on the motor.

You can see how important the names are when reading List. They are everything. Another benefit of the "slash" is when you have a line like "LDI  /OVERLOAD", you can cancel out the 2 "NOTS" in your head and it makes more sense. Instead of saying "If-not not-overload", its just "If overload". It means the same thing!


I suspect this is the area where most people give up. They don't understand how combinations of OR and AND are seen by the PLC. And it can soon become very confusing to read. Complex Boolean is actually more clearly displayed in Ladder format than it is in List. But List can manage it, and Ladder is not very useful for displaying non-Boolean operations such as math and the higher functions. So the challenge is to make your List readable when doing Boolean so that you can take advantage of the rest.

First thing to remember is that the PLC completes each statement as it reads them. It doesn't read the entire collection of lines at one go. For those familiar with Ladder, its like saying that the PLC reads one contact and adds it to its sum in the Accumulator, forgets that the contact exists and goes on to the next contact. It doesn't read the entire rung at once. If it encounters an AND, its the same as if you have a contact in series with everything that came before. If it encounters an OR, it's like a contact in parallel with everything that came before. On a Ladder diagram, the AND is always in series with the ENTIRE rung. The OR is always in parallel with the ENTIRE rung (in other words, its a new line that starts back at the left rail). That being the case, how the heck can we do anything?!

There are a couple of methods for telling the PLC to hang on to a result for later use. Just like on your calculator where you have the Memory feature. On your calculator you might add some figures together, place the result into the Memory, do some multiplying with new figures and then finally add the result to what you previously put in the Memory. We can do the same thing on the PLC in several different ways.

Write out a series of statements such as follows:

                LD          RUN'SEL
                AND      /OVERLOAD
                ANI         BUSY

Don't complete the series by using an OUT statement. Now start a new series:

                LD          HIGH'SEL            ;high-speed selector switch

The PLC knows you are not done with the first series because you haven't "used" the result yet in an output type of statement. When it encounters the new LD statement, it puts the old result into a temporary storage area called a stack. It knows you will need it later.

Now carry on:

               LD          HIGH'SEL            ;high-speed selector switch
               OR         LOW'TEMP        ;low temperature sensor

That last command was "AND BLOCK". It means pull the old value from storage and then AND it with the current value in the Accumulator. In other words, "I want the old series (the old block of code) to be true AND I want the new series (new block of code) to be true before performing any outputs. You could also have used ORB. It means "If the old series is true OR if the new series is true then..."). Now, you follow with whatever output code you wish. Let's put it all together:

                LD          RUN'SEL
               AND      /OVERLOAD
                ANI         BUSY
                LD          HIGH'SEL
                OR         LOW'TEMP
                OUT      MOTOR

In English: If the run selector switch is active and we have no overload and the machine is not busy...  if the high selector switch is active or the low temp sensor is active... if both of those series of things are true then turn on the motor.

Make sure you use a blank line to separate the two series. It keeps things readable.

When you have seriously twisted logic to express, and even the handy ANB, ORB won't manage it, there is an all-powerful stand-by at your disposal. Its called MPS for "Memory Point Store". It's exactly like the one on your calculator. No different. You should avoid it like the plague in most cases because it can lead to code that's difficult to read. There are times, however, when it's exactly what the doctor ordered. Usually, it's better if you repeat sections of code or store your own result with its own descriptive name rather than using MPS.


That's all for Part 1. We'll try out some more examples and look at some more advanced topics in Part 2.