Category Archives: PLC

PLC Programming Quickstart Guide : First 60 minutes of most PLC Programming Environments – Part 1

 

Most control engineers and PLC users are going to encounter several PLC platforms over a career span. Whether through jobs at different companies or through migration of control platforms, the need to adapt and learn new programming environment is an essential part of the job.  As I go through this process with a new platform, the following checklist was developed as a ‘quickstart guide’ when programming in a new PLC platform.

 

The good news is that most PLC programming platforms use a very similar set of features. The features are called using different names by different vendors. In many cases, even the layout of the program is similar. There is usually a directory on the left side of the screen, a message window at the bottom…etc.

 

So, this post will be Part 1 of a multi-part series about the key things to look out for in a new PLC programming environment. The way this will be set up is as follows:

 

  • Several programming platforms will be referenced in examples; SoMachine (CODESYS), SoMachine HVAC and Rockwell CCW. I’m very familiar with SoMachine and CODESYS, new to SoMachine HVAC and never used Rockwell Automation’s CCW before.

 

  • The intent would be to get proficient enough in a new environment to write simple to intermediate programs. We will save more advanced features for another discussion.

 

  1. I/O Declaration

 

The basic function of a PLC is to be able to accept inputs and control outputs. In most current PLC programming environments, the inputs and outputs are referred to in the logic using variable/tag names or pre-assigned terminal designations.

If a PLC program is to be looked upon as a story, the main characters would be the variables and the I/O. They are the subject.

 

So, the key questions when encountered with a new environment is:

Where are input and output variables or tag names assigned?

How are they called in the program- pre-assigned name or user-defined names?

 

Common approaches:

The I/O tags or their user assigned tag/symbol names are declared in one place and then available to be called throughout the program. They are essentially similar to global variables.

Some of the terms used for these names include symbols (CODESYS), tags (often used in SCADA environments and aliases (alternate references to a I/O point in Rockwell controllers)

 

In SoMachine the input and output mapping can be addressed using either the address assigned to the terminal input( this is referred to as direct addressing) or a user-defined symbol name.

I/O declaration in SoMachine
I/O declaration in SoMachine

 

In CCW, I/O is addressable in code using either the pre-assigned name or an alias.

I/O Declaration in CCW
I/O Declaration in CCW

 

Between the pre-assigned name and the user-defined name, both are usable in this case. With the usage of the pre-assigned name in SoMachine, a pop-up usually occurs to advise the user to use symbolic addressing for ease of maintenance and modification.

 

 

  1. Variable declaration

 

Once the I/O is declared and accessible in the program, the next point of interest would be to figure out where and how variables are declared. Some variables can be pre-planned if we know the functions they will be plugged into. Others may be added on the fly.

 

The two main types of variables are the local and global variables. Local variables can be called from the POU that it is declared in. Global variables are accessible anywhere in the project.

 

Some environments allow for variables to be declared textually. Others require a tabular declaration with a pull down for the data type. The textual declaration may involve a little more typing, however, the benefit is that it is more flexible and supports copy and pasting variable names. For larger projects, variables can be created in a spreadsheet separately and then pasted into the PLC program project. The benefit of a separate variable creation is that variations of the variable name for SCADA purposes and also the generation of memory locations can be performed easily and quickly in a spreadsheet.

For textual declarations, observe the syntax used for various data types. Some key questions here are:

How are variables given an initial value?

How are persistent or retain variables created ( to keep values through power cycles)?

How are arrays declared?

 

Regarding the point about retain and persistent variables. In CODESYS, the retain variables holds a value through power cycles. Persistent variables hold a value through program downloads.

In SoMachine, retain variables are declared using the VAR_RETAIN header in the variable declaration section.

Declaring Retain Variables
Declaring Retain Variables in SoMachine

Variables to be kept through program downloads are declared in a separate object.

 

Persistent Variables to hold a value through program downloads
Persistent Variables to hold a value through program downloads

 

Next part will cover the program types or POU’s as referenced by the IEC 61131-3 standard…

Share

PLC Program Debugging Checklist: 5 Things to do to correct errors during PLC Program development

 

So, you’re programing in a PLC platform that is new to you. The functions, tools and syntax may be different from what you are used to. As you get acquainted with them, there are probably going to be errors showing up in the message list when a build or compile is performed. The following are 5 things to do to debug or correct these errors when developing a PLC program.

 

Checklist item 1: Compile as you go (don’t wait until the end) and check the messages

a. About compiling often: Nobel Prize winner Daniel Kahneman in his book ‘Thinking, Fast and Slow’ states a correlation between the ability to build expertise on a topic and the speed and quality of feedback during the process of learning. The inference of this in building PLC programs, specifically in an environment you are new to, is:

  • Compile or build the program often
  • Decipher the compile errors and messages accurately.

Some programs or programming environments are going to take longer to compile so this habit is dependent on the environment too.

b. The second part about deciphering the error message accurately is highly reliant on the environment itself. For instance, I am working in an IEC 61131-3 environment called SoMachine HVAC. The error message said ‘Token not found’ and pointed to an inexistent line number in the POU. After using Step 2 below, it turned out that one of the variables had a period/dot (.) in front of it which is acceptable in the CODESYS environment but not in the new environment. Removed the period/dot and the error message went away.

About checking the messages, observe if there are root cause messages that are effecting other error conditions. In CODESYS for instance, addressing the errors at the top of the error message list often results in the solving of multiple other errors that are lower in the list.

 

Checklist item 2: Check the help files and any example programs available

Some environments may have  a manual. Some may have a good Help section. On either one of those, browse through the contents of the manual and Help files. When a problem arises, it may come in handy.

Another good reference is an example program. Trying to figure out how a read operation is performed over a comms network? Or maybe just the usage of a simple CASE structure sequence? Having one good written up program helps and can serve as a ‘go to’ program. When starting in a new environment, ask the vendor for some example code and programs.

 

Checklist item 3: Test only the suspect function, in a separate POU.

 

The idea here is to test the function and its utilization method. If you are using the function wrongly then this step will pick that up. Break the function down to the arguments that are fed to it. Check if any one of the arguments are of incorrect type of using wrong syntax. The ideal case is if the compiler picks up the error and tells you what is wrong but that is not always the case.

 

Checklist item 4: Comment out sections of the program and check if the errors persists.

 

As is common in tackling any engineering feat, ‘divide and conquer’. Comment out sections of the code and perform compiles systematically. Start with the section you suspect to be the root cause and then expand from there.

 

A note about the psychology of debugging; sometimes it is easy to blame the problem on the programming environment or a vendor. You might be telling yourself ‘This programming environment is buggy’ or ‘It’s not user friendly’. Try to quash this, have some faith and be bullish about solving the problem. This has helped me tackle problems much quicker rather than going back and forth with tech support or giving up only to find a simple solution I had overlooked.

 

 

Checklist item 5: Build your go to resource list … and Google away

 

Document your findings somewhere. Preferably somewhere searchable. This step takes time but will save you time later. Also, when someone comes to you for help, you will have something to give them – which helps me since I work for a vendor.

As stated above, collect examples from the vendor.  I collect examples from colleagues, previous projects, development team…

Vendors may also have an online FAQ list, forum or wiki page. Get to know those resources.

Another resource maybe online forums like PLCTalk. For CODESYS, check out the CODESYS forum.

 

Hope this helps as a debug checklist. If there are any other methods out there, please add them to the comments section below. Given the thousands of hours controls engineers and PLC programmers spend debugging, there is probably a part 2 that needs to happen on this topic.

 

 

Share

CODESYS Arrays : What are they? How are they used?

 

A couple of previous posts covered sorting CODESYS arrays and using them with pointers. There was never a preface to the topic of arrays.  So, this is a stab at clarifying the definition and application of CODESYS arrays.

CodesysArrayVisual
Visual of an Array

 

What and why of arrays?

An array is an set of data. It could be a collection of numbers or a collection of custom data types. One analogy of arrays is a bucket with numbered containers in it., arranged from container 0 or 1 to container x. X being the length of the array.  Each container can store some data.

The purpose:

  • Collect and organize data of a certain type.
  • Data in an array can be called with a common namespace.
  • Makes it easier to sort data
  • Easier to do math on a set of data points

 

In the memory layout of a PLC, array elements are usually stored in contiguous ( back-to-back) memory locations. This has some benefits for retrieval when reading from another PLC, HMI or SCADA system.

 

How are they used?

The basic declaration of an array:

 

TestArray : ARRAY[1..5] of INT;

 

It also offers the option of initializing the element values in the declaration:

 

TestArray : ARRAY[1..5] of INT:= [5,3,2,5,2];

 

Array lengths can be defined using a variable in the declaration.  That is to  tie the array size to a variable name instead of a fixed number in the declaration.  NOTE: The variable has to be declared as a VAR CONSTANT and can not be altered in runtime. The value of the VAR CONSTANT variable needs to be declared and initialized with a constant value in the programming environment.  The IEC 61131-3 standard also makes reference to this point.  So, the feature of using a constant in the declaration of array length only serves to centralize the location of initial setup of parameters,  if required by the control program.

 

TestArray : ARRAY[1..UserDefinedVarLength] of INT:= [5,3,2,5,2];

 

VAR_CONSTANT

UserDefinedVarLength : INT:= 5;

END_VAR

 

The above as noted in the CODESYS environment:

CODESYS Array declaration

CODESYS Array declaration in the actual declaration window

 

CODESYS Arrays can be multi-dimensional. That is, they can have more than one attribute and form a matrix. Multi-dimensional arrays are declared as follows:

MotorData: ARRAY [ 1..2,1..5] OF REAL: [845, 822, 808, 795, 834, 30.2, 29.0, 28.5, 29.5, 30.2 ];

The above array will initialize as follows:

[1,1] :=  845;

[1,2] := 822;

[1,3] := 808;

[1,4 := 795;

[1,5] := 834;

[2,1] := 30.2;

[2,2] := 29.0;

[2,3] := 28.5;

[2,4] := 29.5;

[2,5] :=30.2;

An example application with a  visual representation of the multi-dimensional array above could be as follows:

MultidimensionalArray
An visual representation of the array example above

 

CODESYS Functions that can be used with Arrays:

There are a number of functions that can be used with arrays. Often times, for organizing and sorting data in arrays, pointers are used. Other than that, the following are some functions and their applications to arrays:

SizeOf

This function returns the number of bytes reserved for an area.  If an array is made up of INT datatypes, each element would take up 2 bytes. The total number of bytes would be number of elements times 2. For REAL datatypes it would be a multiplier of 4.

Checking the size of an array in bytes.
Checking the size of an array in bytes.

CheckBounds

This is added as an implicit check. It shows up as ‘ POU for Implicit Checks’ when Add Object is selected and check arrays during runtime to determine if any code is attempting to access array elements that are outside the declared range.

 

CODESYS ARRAYS
Implicit Check included in the CODESYS environment for array bounds checking

 

 

NOTE: Sum and arithmetic functions ( ADD, MUL, SUB…etc) usually accept INT, REAL’s and ANY_NUM type inputs. As such, feeding an array to the input of a math function will usually result in an error. Arrays have to be broken out to individual elements to be manipulated and used for number crunching.

To wrap up, a video on arrays in CODESYS from Kurt Braun’s YouTube channel

 

There are probably a number of functions related to arrays that folks out there use. If you know of one, please share in the comments section below.

Resources: Staying on the topics of arrays, the following articles are on the same topic:

CODESYS Array Sorting in PLC Programs

CODESYS Pointers and Dereferencing

If organizing and handling data in your PLC programs is important to you, check them out.

 

Share

Remote PLC Connection: Connecting to a SoMachine M241 PLC using InHand Networks IG601 Cellular Gateway and Device Touch

 

The ability to connect to a PLC remotely (or HMI) and to pull data, access webservers and download programs is increasingly a requirement on industrial automation projects. Remote data access and program maintenance saves travel time to sites and simplifies daily operations. Some of the PLC features that enable this are:

  • Webserver on PLC and HMI: Allows data monitoring and some updates to PLC configurations

 

  • WebVisualization: These are customizable user interface pages that are embedded in the PLC. WebVisu is the CODESYS term for these HTML5 pages. Some examples of their usage from YouTube are noted here.

 

  • PLC Programming software remote gateway support: This is the ability for a PLC programming software to connect to remote Ethernet based devices. This could be for program downloads or regular program viewing.

This article will cover the steps for remotely connecting from the SoMachine PLC programming software to a remote M241 PLC. The InHand Networks IG601 cellular gateway device is used as the intermediary. Other examples of intermediary gateway devices may include Netbiter by HMS and eWon ( also by HMS now I believe).

Over the last few years, the criteria I have laid out for these devices have included the means to use them without the manufacturer’s cloud- based connection service. Simultaneously, keeping the option to route more secure connections through the cloud service, only when required, is a plus.

 

The criteria for the gateway device:

 

  • Ability to setup port forwarding at the gateway device
  • Ability to use a VPN connection for secure PLC program downloads
  • Ability to support a static IP at the gateway device and allow for the above mentioned VPN connection at the same time.

The InHand Networks IG601 meets these criteria. Getting this set up can be accomplished with two sets of steps. The InHand steps and the SoMachine steps.

InHand Networks Steps:

 

  1. Connect to the InHand Device Cloud at http://g.inhandnetworks.com/. For initial setup, follow instructions per the Device Manager configuration video.

 

  1. Install Device Touch on the connecting PC. The installer is available in the Device Cloud portal. The next steps will assume proper setup of the Device Cloud and connection using Device Touch on the local PC. Instructions on Device Touch are available at the following link.

 

NOTE: While in the Device Cloud, be sure to set up a site, a device and the PLC. I forgot to add the ‘Controller’ once. It took some time and a call to InHand’s support team to figure it out.

InHandsite_Gateway_PLC
InHand Device Cloud

 

  1. Open Device Touch on your computer and connect with your Device Cloud account. Once connected to the cloud. Connect to the specific site/gateway but selecting it and clicking on the ON/OFF slider bar.
InHandDeviceTouch
Device Touch connection

SoMachine Steps

  1. In SoMachine, configure connectivity in the SoMachine gateway. The gateway is accessible by double clicking on the root of the controller directory in the device tree.
SoMachine Gateway setup for Remote PLC Connection
SoMachine Gateway

5. The connection method is set to IP address. In the example, the remote controller IP address was set to 10.0.0.100 with a subnet mask of 255.255.255.0

ConnectionMode
IP Address connection mode

    6.  Per step 3 above, if Device Touch is active and the Maintenance Channel is on/ready (screen cap below), go to the Online menu and select Login.

 

IP Address Remote PLC
IP Address Connection Mode

NOTE: The update key on the gateway will not result in the detection of the controller in the Gateway list. Entering the IP address and selecting ‘Login’ actually triggers the process if searching for the device and placing it in the available controllers list in the Gateway. The Update button in the Gateway may not find remote devices. As such, the remote PLC may not show up even if by clicking on the Update button.

 

 

  1. The gateway will scan the remote network via the Device Touch adapter. Once the controller has been found, it will show up on the controller list in the gateway with a REM icon next to it.
RemotePLCDetected
Remote PLC detected

Note: The standard warning message indicating the pending connection to a controller will pop up prior to an actual login. Entering Alt-F will proceed with the connection and potential remote download of a program. Clicking the Cancel button will abort the connection.

 

Troubleshooting tip:

Should the remote controller not be detected using the IP address connection method above, restart the SoMachine gateway as shown in the screen cap below. Subsequently repeat step 4 above.

RestartPLCGateway
Restart SoMachine Gateway

Should questions or comments arise, put it in the comments section below.

 

 

 

Share

CODESYS Visualization (and WebVisualization)

A CODESYS Visualization or Viz, is a way to embed a graphical interface into a PLC program. Interfacing with the PLC programs visually allows for quicker troubleshooting among other benefits. Further to that WebVisualizations publish a CODESYS visualization in HTML5. This enables user access to a PLC visualizations via a web browser.

Several examples of Visualizations and WebVisualizations exist online. Visualization and WebVisualization screens are created with drag and drop objects which are configured instead of coded. This simplifies screen development instead of having to build Java or HTML based objects for web accessible screens on the PLC.

The collection of YouTube based Visualizations highlighted below showcase the possibilities with the various screen objects across various applications – some industrial and some exemplar/illustrative.

The first example  is of an elevator application built in CODESYS. Credit to donkeykowng on creating this for a school project.

The next example is of an industrial mixing process with multiple tanks with levels updated dynamically. Credit to tweektweak23.

The next two credited to Kye-Hun Park .
Tetris . This visulization was built in SoMachine 4.1 which uses CODESYS 3.5
Snake game
 
Combination of  2D conveying and tank on a filling application.
CNC application courtesy of Martin van rijn
Another tank level application. Credit to Huseyin Gevrek
Material handling example with a couple of axis of a pick and place and a conveyor.
Credit to binyam .yo
More recent update of Codesys includes support for multi-touch. (from CoDeSysMotion YouTube page)
 A key benefit of a visualization is that it allows for parts of the PLC program to be graphically represented and viewed without the PLC programming software. This is given that the programmer or designer of the system designs and embed appropriate visualizations to represent the system. Being able to pull up a graphical representation of the system on a PC/tablet/phone browser allows for preliminary  troubleshooting without too many people having to have the programming software license . If the problem  is beyond wiring , mechanical or I/O issues , then someone with the programming software can be dispatched.

 

Share

Importance of Modbus Polarization Resistors

Modbus has been around for several decades and is widely implemented.  There are several elements of starting up a system with Modbus serial networks that usually get repeated. These include address, baud rate and parity. One element which does not get too much mention is the Modbus polarization resistors which can play a major role.

What does the polarization resistor do?

The detection margin requirement across the B and A signals is usually only about 200mV. With polarization resistors, the actual margin is ‘widened’ specifically when the signal drivers are not ‘driving’ thus allowing for better noise tolerance as well. This is especially true with networks that have variable speed/frequency drives  with high frequency switching being a large source of noise. The resistors are known as pull-up and pull-down resistors as they tie the B signal up to the 5V rail and the  A signal down to 0V.

On a recent startup, the PLC and HMI program was downloaded and the control program was being tested when the system started to act erratically. Closer observations revealed that the Modbus serial communications with the drive was sporadically dropping out, specifically when the drive was running the motor. All read values were becoming zeroes when this happened.

After trying several things, the polarization resistors solved the problem.

 

PolarizationResistorsThings to note about polarization resistors:

  1. Applied only once on each network. PLC’s may have this as an optional item in the Modbus port configuration. Slave devices usually do not have it though many manufacturers will advise on how to apply if when needed.
  2. The presence of polarization resistors could reduce the number of slaves that can be had on the network, specifically if a lower pull-up or pull-down resistance is used. This and many other important points about Modbus is covered in the specification at Modbus.org.
  3. What size resistors to use? The Modbus standard specification calls for resistance between 450 ohms and 650 ohms. Manufacturers usually have a guide. A good example to calculate it out is noted on page 11 of this document.

Polarization resistors are one factor to note in troubleshooting Modbus serial networks, others include proper grounding practices and proper usage of terminating resistors.

Share

PLC Programming Patterns- The Debounced Threshold/Limit

Patterns in PLC Programming: The threshold + timer function – Debounced Threshold

PLC programs are frequently made up of the same sets of functions or patterns of logic. These patterns perform commonly required control routines. Examples include threshold detection for alarm purposes, input/output mapping and scaling functions, to name a few. These combination of functions make up re-usable patterns or function sets that form the building blocks of a PLC program.

Repeated usage of some functions in a PLC programming environment holds true to the universal 80/20 rule ;20% of the functions available in a programming environment( such as timers and logic functions) would probably be used to build 80% of PLC programs.

The debounced alarm/threshold pattern is one of these commonly required PLC programming patterns. This pattern is probably better written in ladder diagram   (instead of any of the other 61131-3 languages), for two reasons:

  • Maintenance personnel will be able to view the status of the process/monitored variable, associated timer and output all in the same place
  • It can be programmed in 2 rungs of ladder compared to more than 10 lines of code.

The ladder diagram version could look something like this:

Alarm ACTIVE
DebouncedThreshold_LD_ALARMAutoManualReset

Note: An Auto/Manual Reset Provision is built into the Alarm Reset Timer rung.

Alarm NOT ACTIVE

DebouncedThreshold_LD

The following pattern is the debounce pattern for detecting limit breaches along with a timer, written in Structured Text for the CODESYS environment. As described above, the structured text version takes more space and possibly looks more intimidating specifically to someone who is used to the ladder environment.

CODESYS-LimitThresholdScreenCap

The plain text version of the structured text version is attached below:

PROGRAM DeBounced_Limit

VAR

irProcessValue : REAL; (*Process value scaled from analog input signal*)

rProcessLowLimit : REAL; (*User defined process value low limit alarm threshold*)

qxLowLimitAlarm : BOOL;(*Low limit alarm bit*)

LowLimitAlarmTimer : TON; (*Process value low limit alarm trigger debounce timer*)

LowLimitAlarmResetTimer : TON; (*Process value low limit alarm reset debounce timer*)

LowLimitDebounceT : TIME; (*Process value low limit alarm trigger debounce time*)

LowLimitResetDebounceT : TIME; (*Process value low limit alarm reset debounce time*)

xAutoReset : BOOL;(*User enabled alarm auto reset function*)

ixUserReset : BOOL;(*User triggered alarm reset function for manual reset*)

END_VAR

(*If value is lower than low limit, start timer, else reset timer*)

IF irProcessValue < rProcessLowLimit THEN

LowLimitAlarmTimer(in:=TRUE, PT:=LowLimitDebounceT);

ELSE

LowLimitAlarmTimer(in:=FALSE);

END_IF

(*If timer lapses, trigger alarm bit*)

IF LowLimitAlarmTimer.Q THEN

qxLowLimitAlarm:=TRUE;

END_IF

(*If value is higher than low limit, start alarm reset timer, else reset debounce timer*)

IF irProcessValue > rProcessLowLimit THEN

LowLimitAlarmResetTimer(in:=TRUE, PT:=LowLimitResetDebounceT);

ELSE

LowLimitAlarmResetTimer(in:=FALSE);

END_IF

(*If timer lapses, and system permits auto-reset, reset alarm bit*)

(*If the system does not permit auto-reset, add user invoked reset bit here*)

IF LowLimitAlarmResetTimer.Q AND (xAutoReset OR ixUserReset) THEN

qxLowLimitAlarm:=FALSE;

END_IF

Share

CODESYS Pointers and Dereferencing

Pointers and Arrays in CODESYS

The CODESYS language supports the usage of pointers which is essentially a variable that stores the location of another variable or data point instead of its value. The actual value of a variable that a pointer points to can be retrieved by dereferencing the pointer.

 

What could it be used for?

       1.Storing the location of the variable saves space specifically when pointing to large                 data points or structures.

  1. Pointers allow for sorting and re-arrangement of data sequences without actually changing the location of the original data points. To characterize in a diagram:

Pointers and Arrays Diagram

  1. Going down the path of object oriented programming in PLC’s/PAC’s, this supports abstraction by separating the usage, manipulation and parts of an object from the original object itself. This helps reduce the PLC code required to handle every scenario and also helps in situation where the original object can not be manipulated because its hardcoded to an input ( for example).

 

Example:

 

Let’s say the array of data on the left side of the diagram above is read (as inputs) from a set of 4 drives controlling 4 pumps. From top of the array to the bottom Array location 0 would be for Pump 1 , location 1 for Pump 2 …..location 4 for Pump 4.

 

If the data is each of the pumps runtime, the pointers to the runtime allow for it to be sorted and stored in the pointer of arrays without changing the order of the original array which is important, as the original array of runtime data may be hardcoded to the actual input or read values from the drives.

 

Secondly, when the decision is made to call a pump to run, the same mechanism of pointers and arrays and de-referencing can be used to point to the command word of each of the pumps on a communication bus.

The end result is the amount of code required in determining which of the pumps to run is reduced.

Pump Example Pointers and Arrays

What does the syntax look like in CODESYS?

To create a pointer:

The address operator or ADR is used.

Let’s say the variables are:

 

PROGRAM PLC_PRG

VAR

j: INT;

k:INT;

pointToJ: POINTER TO INT;

END_VAR

The pointer assignment would be:

 Pointer

in plain text:

pointToJ:=ADR( j);

Note: ADR is a CODESYS operator and not an operator prescribed in IEC61131-3.

 

To de-reference a pointer:

The ^ operator is used to de-reference pointers.

Example:

in plain text:

k:=pointToJ^;

This would yield the value of integer j.

SimulatedPointerDeReferencing

 

Share