Good practices in PLC programming.

Lukasz_Poland

Member
Join Date
Aug 2019
Location
Poland
Posts
28
Hello colleagues,
Some time ago I started my adventure with programming. With your help and the courses, things are starting to come together somehow. However, there are still questions along the way. Perhaps you could share some tips with me. For example, I recently read that signals from limit sensors should be done in the NC manner, etc.
Where can I look for such patterns, where can I learn about good programming practices?
Thank you for your help.
 
Actually the NC of limit switches depends on the function. Perhaps you want to make sure that if the sensor breaks or a wire is cut it will indicate, but this can be obtained with both types depending on the function.
 
Broken wire detection is a good thing, but it is not applicable in all situations. IMHO being a good programmer, requires you to know the process you are dealing with. In some cases NC is good. But others not so. It depends on the situation. My biggest complaint about new programmers is, lack of comments/documentation. Document everything. You never know, perhaps two years latter you have to trouble shoot something in a program you wrote. And you don't have a clue, because you did not document your logic.
 
... IMHO being a good programmer, requires you to know the process you are dealing with. ...
^^^This. This is a "good practice."

It is not unique to this industry, but it is important in this industry. If you cannot model the process, at least in your head ("open feed valve by 10% => tank level rises, or at least falls more slowly"), you'll have no clue how to control it.

Which is one possible reason why chemical engineers* tend gravitate to this industry.

* not to the exclusion of other engineers or other tech-minded folk, of course.
 
Talk to and listen to the operator!!!!Learn the process.
Simple to control motors go round and round, cylinders go in and out. When do they need to do it is what matters.

Don't use fancy programming. In several years that (1) PID loop that you pass 30 different parameters into because it looks cool will come back to kick you backside. The Temperature input is flaky and you can't see it because you are passing the info so fast.
 
Talk to and listen to the operator!!!!

I think the right advice is "Know what to talk about with the operator."... there are plenty of things for which the operator's opinion is downright dangerous and there's a reason control is taken from him.

As for advice:
- Assume nothing. Ask questions about the process BEFORE you start programming.
- Plan how your program will look like BEFORE you even create the blank project.
- Understand all the mechanisms and caveats of each to make modular code in the platform of choice.
- Write modular code. Key is to understand when to stop, don't pile on everything, but don't make functions for every little thing.
- Display correct information for the operator. If something is stuck because of X, don't just say something is stuck.
- Comment... even when it looks obvious, comment. Also worth using a keyword like your name in the comments so you can track them.
 
You've gotten the most important advice so far:
• Document everything -- not the what but the why: Don't just say, "stop the motor when X happens"; I can read the code to see that that is happening. But why is X such an thing that the the pump should stop? That I don't know.
• Learn the process. Like they said, you can't control what you don't understand.
• Talk to the operators. What they need to do their jobs is not necessarily what you think they need. Operators tend to park on a single graphic where they can see the important stuff. Keep in mind that they might not know what is possible to do, and so may not ask for something they'd like.
• Keep in mind the guy who will inherit your work (which may be you, long after you've forgotten everything about it). Make it easy to follow and to troubleshoot.

More good practices:
• Bits are cheap; don't be afraid to add more, rather than making a single bit do too much, especially when things it does are similar, but not identical.
• On the other hand, don't overcomplicate your code either. If you have a rung that is merely a contact-to-coil { --| |------( ) }, you'd better have a good reason for the extra bit.
• Future proof as much as possible. Make array sizes bigger than you need them to be now. Because if the line is a success, they'll likely expand it. And it can be painful to increase memory allotment when you need it.
• Modularize your code. Device logic (valves, motors, input signals) can be little chunks of stand-along code. Each then can then be mapped to the physical I/O in simple I/O mapping logic (which would be lots contact-to-coil rungs that I warned against above; but with the justification that the internal logic uses the device objects, making it quick and easy to re-map the I/O should a card break). Similarly, your sequence logic can be split into "Actions" (mapping commands to the Device layer) and "Transitions" (what advances your sequence from one step/state to another).
• It's one thing to be able to program a sequencer to make things work the way they're intended when all goes right. Consider that as much as half your code could/should be dedicated to getting the system either back on track or to a safe landing when things go awry.
• Your GUI is as important as your control code. How you present what's happening is just as important as making everything work. If the operator doesn't know what's happening, they won't trust the system, and will likely not use it to it's full potential. Again this goes back to forming a partnership with the operators.

And last, but first:
• Make the system safe.
 
I dont remember which guru said it. They said 50/50 rule with code.
50% should be making the system run. The other 50% should be telling why it's not running.
I have a simple 30 bit sequencer ( 2 bits for errors) that keeps the previous steps on so you can see what step is next without looking everywhere. First rung of the sequencer program shows all the bits for that sequence. If you have to look at logic make it quick as possible.

I have seen very few machine that we couldn't break the sequences down into 30 steps. This sequence may start the next. They can see where and why the machine is doing something.


I did added a few steps to an existing machine. They had 300+ steps with MOV instructions that didn't follow any rhyme or reason that I could see. Rung 1 MOV 10 , rung 2 MOV 30, rung 22 MOV 78. It was fun spaghetti code.
 
COMMENTS. They can be the difference between looking at something for 30 seconds and looking at it for 30 minutes.
Modular Code. For one because it makes it easier to reuse small sections of logic for other applications if the need arises for another because if you break the puzzle down into smaller chunks it's easier to put together later.
Always plan for expansion, whether it's spare IO, spare sequence rungs/bits, or extra dimensions in arrays.
Plan for error recovery, every machine has failures and or breakdowns. Make sure that you leave the operator/maintenance a way to reset and start over.
Be descriptive, whether it's in your comments, your GUI, alarms etc. It doesn't have to be lengthy, but it should convey the necessary information.
 
comment.... rungs, bits, etc. For bits, I like to use the tag name to declare what the function is.....
Pump1MotorIsRunning
then decsription is
1=Pump is running
This gets rid of all ambiguity

I do the IO mapping routine as well. Great for changing cards and very simple to simulate
Debounce sensors, even with a 10ms debounce. Some inputs are more reliable than others (I have a simple AOI for on & off delay)

My code (usually ladder) uses step numbers. For any error in a step, I latch the error bit, then I move the Step number into StepError DINT, then jump to my error routine. This way, I can have the same functional error bit be used in multiple steps.
Example if you are using a camera to get images 3 times in a sequence. I would error for CameraResponseTimeOut in each step. Now my error routine would use StepError to distinguish which step
AND more importantly, I can easily find which step failed
 
A limit switch should be NC if it is normally not made.

The real rule to adhere to is:
Current flow required for operation.

If it's a limit switch that is normally engaged then the NO contact should be used.
If it's an overtravel limit that would never be made during normal operation then NC that one.
A low level float switch would be NO and held on if the liquid level was higher, whereas a high level float would be NC and open when the fluid reaches the limit level. Except if the high level float is to start a pump, then it would be NO and start the pump when current flows through it.

The sensor or switch must be passing current, no wires broken, or PLC inputs died, to run the applicable outputs.
 

Similar Topics

My employer has remote sites that that have recently been upgraded from relay control to plc control with a cell modem. The Wonderware DA Server...
Replies
0
Views
2,114
Hello, I'm working with some AD "CLICK" PLCs in a telemetry application. Each PLC is connected to a cellular (LTE) modem with a static IP...
Replies
3
Views
5,103
Hey everyone, I can't seem to find good instructions on how to connect/set up a brand new PLC. Thanks for the help.
Replies
6
Views
2,708
I started programming A-B MLX1000 PLCs when I was about 18. In 1993-4. I never had any formal training, but my boss at the time gave me a A-B...
Replies
1
Views
1,821
Just for a little backround.... I have been in the electrical field for 6yrs and have been involved with PLCs for the past year or so. I am now...
Replies
6
Views
5,036
Back
Top Bottom