Dos and Don’ts of PLC Programming:  Flexible, Readable, Maintainable Code and Why It’s Important

Messy ladder logic programming is impossible to maintain

Production is down. Your client is losing $100k an hour and they’ve called you, probably just as you were sitting down for supper, to fix it as quickly as possible. Ever the devoted servant you put down your beer and fire up a VPN while looking at last minute flights. An hour later you’re staring at a new (to you) program, thousands of rungs of ladder logic in front of you, no tag descriptions, unclear naming conventions, code that’s been copy and pasted a hundred times, and the best part is it’s all in one, massive routine. “What in the world was this moron thinking?”

My apologies if that hits a little too close to home for some. The average PLC programmer is a smart person, don’t get me wrong. But programmers have a tendency to write code for themselves, for the now, the immediate solution. It’s easy to forget about the poor sap that has to maintain this in the future. If we’re not mindful, we may very well become the reason someone is shouting expletives at their screen. Here are some simple tips on how to not be that guy (or gal).

The Dos and Don’ts of PLC Programming

DON’T – Copy and paste repetitive logic
Let’s say you’ve got two coils you want to activate in sequence. A rung to turn on the first one, maybe a delay timer, and then a rung to turn the next one on. Aside from changing the tag name from “CoilOne” to “CoilTwo” the rungs are identical. We all have code like this because usually that’s all it is, just a couple rungs. But what happens when you’ve got 50 coils? Before you go hammering on Ctrl+V…

DO – Look for opportunities to reuse code
Loops are your friend. AOIs, subroutines, and even basic arrays can speed up development time, keep code cleaner, and make future maintenance easier. Logic change? You don’t have to paste 50 fixes, just one small change to your subroutine and you’re done. What? The client wants 50 coils to now be 100? If you did it right you should literally just have to change a tag, “Coil_Count” or whatever, from 50 to 100.

DON’T – Use indecipherable tag names with no labeling
“tmrdelay” – “Timer” and “delay” are redundant.  What’s this delay for? Are we using this to flash a light or wait a safe amount of time before lowering a heavy press?
“AB_XGI:I.Data[1]”, Obviously this is a data structure for some connected device but referencing it like this in your main routine is throwing away an opportunity for self-explanatory code.
“fireRobotMove”, Which robot? Which move?  Do I need a fire extinguisher?
These tag names aren’t useless, per se, but without context they don’t mean much.

DO – Use descriptive tag names
The name should say what the tag is for.  Care should also be taken with formatting.  Even “tmrDelay” or “tmr_delay” would be better. Nobody should have to guess at the word separation.
DO – Add descriptions to tags and rungs
A simple buffer routine or alias can turn “AB_XGI:I.Data[1]” into something more useful like “partXPos”. “tmrdelay” could become “tmrDrivesReady”.  Even better would be a description on the tag or rung that explains what it’s for.
Bonus DO – Use proper spelling. Ever tried to find all the tags dealing with position data and one of them is spelled “poistion”? Yeah…

DON’T – Neglect program structure
Nobody wants to sift through 200 rungs of a routine called “Main” that covers everything from I/O to process flow.

DO – Use routines and UDTs (or “structs” depending on manufacturer) to stay organized
Simply breaking code up into a few routines called “Camera”, “InputBuffer”, and “Faults” automatically makes things more readable. No sifting through 50 rungs of unrelated logic – if you need camera logic search the “Camera” routine.
Bonus DO – UDTs are incredibly useful. They let you group and name data, even in arrays.  For example, if you have a lot of position data coming back from your vision system you could keep it organized by creating a “Position” UDT with “X”, “Y”, and “Z” tags. “point1” with sub tags is far better than “point1X”, “point1Y”, and “point1Z”. Easier to rename, easier to cross reference, easier to stuff in an array and iterate through.

DON’T – Be optimistic
“This project will only take a few months”
“Client knows exactly what they want”
“Nobody will ever see this but me”
or my personal favorite:
“I’ll remember why I did that”

DO – Remember Murphy’s Law
“anything that can go wrong will go wrong”
This point is really to highlight the necessity of all the others. A positive attitude is rarely a bad thing but if nothing ever went wrong we probably wouldn’t have jobs. Things break, plans change, accidents happen.  Scalable, readable, maintainable code is Murphy’s mortal weakness.

You Can Do It!

The best thing we can do to prepare for an unknown future (in code at least, I’m not a life coach) is to be mindful of the above DOs. By using data structures, organization, consistent naming styles, and descriptive comments, we write code that is maintainable and flexible. This makes it easier for every single person who has to look at the project in the future.

Your client will thank you when they need to add a new push button. Your coworkers will thank you for having an easy to follow structure. But in my experience the person you help most is yourself. Because honestly, 50% of the time that I’m complaining about code, it’s my own.

DON’T – Just make it work.

DO – Take the time to do it right.  Work smart now to make work easier later.

About the Author

David is a driven problem solver with a background in PC application and web development. He thrives on challenging tasks and tight deadlines, generally preferring high-pressure projects and living out of a suitcase. When he’s not working 100 hour weeks he can usually be found in the gym or the local pool hall, almost certainly making new friends.

Leave a Reply