Structure of a program

wnkook

Member
Join Date
Oct 2003
Location
Akron, Ohio
Posts
18
Hello all,

I was wondering about the structure of a plc program.

I was taught to always to run in a sequence of events.
IE: I always latch a bit saying that the machine motion has been performed, this way I/O that is out of order do not happen.

I've taken this concept a step further in verifing that the step before has properly turned off (normally by checking the inputs), This way it's easier for a tech that is familar with the machine to see which input is either not working or always on, since the program stops mid cycle.

I've also noticed how this makes alarm generation a lot easier by just tossing a timer between internal memory steps.

So hoperfully you can see that I latch a bit after each step in my program and have an alarm for all of these steps when using a HMI.

Well here's my question is there anything I can do better, or is this way good enough?

Or are there a couple more things I can do to make my code more solid.

one other thing I do is I put a "/" in front of anything that is off when true. I picked that up from Computer programming.
 
I'm glad to see you're interested in taking things 'a step further'. There's always room for improvement... :nodi:

You may want to take a look at THIS THREAD. It started out as a 'naming' question, but we (or at least I) brought up the 'a step further' topic.

beerchug

-Eric
 
Excellent, if I understand you right.

If the PLC supports the decode instruction I would have use an integer to hold a state 0 to 15. The decode instruction would set one of 16 state bits at the beginning of the scan. When the state machine needs to go to the next state then one can just increment the state number. This method avoids race conditions.

It is possible to many state machines running at the same time.

I also would have a time out value for each state exce[t the stopped or error states. If the state times, out it can flash a message on the HMI and perhaps enter the stopped or error state. This occurs when a condition is not met to get to the next state in time. This make the system self diagnosing.

Finally, you must make the state machine flexible enough handle common error conditions. This means that the abilty to back up a state or two is often required for error recovery. This sure beats having to clear off the whole line to restart at state 0. Some one told me a long time ago that the difference between a good and great control system is the ability to recover from errors quickly.
 
wnkook,

I certainly agree with the idea of programming in a "forward fashion". It is more natural to read forward in a listing to follow the process, plus there are other benefits, at least from a programmers' point of view.

The alternate method, to which you inferred, is what I call "Advance to the Rear". The idea behind the "Advance to the Rear" scheme is to ensure that down-line portions of the process are ready to accept material/input from up-line portions of the process. That is a good thing... however...

The programmer has to mentally synchronize actual material flow forward through the physical process while moving in reverse through the logical process.

That is, if you want to "see" material flowing through the program, you have to start at the end of the program and work your way back to the top... well, almost. The programmer has to remember to "finish the scan" before "Advancing to the Rear" to the next (previous) rung.

For example, if the program is currently processing material with Rung-50, at Station-6, and Rung-50 produces a signal for the next physical station, Station-7 (Rung-49 being the logical location associated with Station-7), then the programmer must "finish the scan", which might or might not involve changes in the status of other conditions, and then proceed, from the top of the ladder, to Rung-49, which, again, might or might not involve changes in the status of other conditions. Rung-49 then reacts to the flag from Rung-50 plus any other changes in conditions that have occurred.

The problem, of course, is that it becomes too tedious to go through the mental exercise of "finishing the scan" and re-running the scan into ladder. PLC's are great for doing tedious work... we are not.

The programmer will simply tend to move his eyes up one rung to the previous rung. However, having done so, the programmer will have ignored any and all other rungs that might have an influence on that rung. Upon examining the rung, the programmer will then have to "seek" the status for each condition.

On the other hand, if Station-7 is covered in the next rung, Rung-51, then the programmer can simply move down to that rung, carrying status with him knowing that all of the current status is, in fact, current. If there has been any change in the status of any condition, it occurred in Rung-50.

That's not to say that, with respect to the conditions examined in Rung-51, several conditions haven't changed since the last time Rung-51 was examined... but, all conditions are as they were upon entry into this particular ladder scan plus any changes that have been carried forward through the previous 50 rungs.

This means, when the programmer moves from Rung-50 to Rung-51, he has all of the latest status in-hand.

Any Alarm information that was developed in the previous scan is available immediately to all stations in the current scan.

Now, it might seem that it would be better to have Alarm information available to the previous station immediately... within the same scan. But then, that would mean developing the program using the "Advance to the Rear" method, which would, of course, precipitate the problems described above.

Demand-Side vs. Supply-Side

Too often, programs are written in a "Supply-Side" fashion. That is, an up-line station in the process shoves material down the throat of a down-line station in the process and says... "Here. Hope you can handle it!" While the down-line station is choking on the previous material, the up-line station continues to say "Here. Hope you can handle it!"

The "Demand-Side" method "CALLS" for material to be passed down-line. That is, a down-line station in the process has to explicitly "Call" for material from the previous station in the process. The down-line station "calls" only when it is ready to receive and handle material. If it's not ready, then a "call-flag" is not posted. If a particular station is not "calling" for material, then the previous station "holds" any material that it might have.

If properly co-ordinated, this method can produce a "controlled crash stop" when problems develop down-line. That is, when an up-line station "sees" that there is a problem down-line, the up-line station can perform a "controlled crash stop" into a "known good restart situation" - at least, with respect to the particular station. This precludes "clearing the system for restart". Certainly the station that has the jam, fault, whatever, has to be cleared, or fixed... but the rest of the system comes to an orderly stop which allows for an immediate restart as soon as the problem is resolved.

As far as providing information that identifies "point of failure"...
I'm a proponent for using "English" (or whatever your chosen language) to initiate, track and report on the current status, in each step, of each module, in the process. That includes explicit timed failures.

If an action hasn't occurred, as expected, when expected, then explicitly identify that particular problem.

For example, If "Run Motor-1" & NOT "Motor-1 AUX" for 2-Seconds, then latch "Motor-1 Faulted" until "Reset" or "Auto OFF" or whatever.

If a fault occurs, disable the system, in the appropriate manner, but maintain AUTO so as to allow viewing of all current alarms. Then at Auto OFF, reset all alarms. That will at least give operators or maintenance will have the opportunity to view the particular fault before they clear the problem area.

I generally use dedicated relay bits for tracking the various stages of a sub-process and the particular alarms associated with the process.

That is, I can certainly indicate the particular action the PLC is trying to perform at this location. If there is a problem, and if I can rationalize the cause of a particular problem then, I indicate that particular cause.

For example, Too Soon, Too Late, Not Loaded, Still Loaded, Not ON, Not OFF, etc.

IF there is enough input information for the PLC then, anything that I can rationalize, as a viewer of the process, can be rationalized by the processor.

After all, "we", as real observers, with our inherent input capability, can SEE everything... the PLC, however, might not be able to "SEE" everything. If there are not enough sensors to give POSITIVE indications to the PLC then, the least that can be done is, work with the idea of "I (the processor), based on previous activities, think such-n-such should have happened by now".

At the very least, you can make the PLC think what should be happening!
 
Very briefly I would like to add weight to the excellent ideas above...thanks guys for these very interesting posts.

My conntribution is:

1. Always break code into "functionally" isolated objects.

2. Always validate inputs where possible.

3. And most usefully...make the alarming an integral part of the logic...not an afterthought as is so often the case.


In my experience, getting the logic to do what the spec asks for is easy. Getting it to intelligently handle and message all the possible errors and unspec'ed states is where the real work begins...and makes the difference between a machine that functions ok if the operator treats is just right...and an easy to use, robust system that gives intelligent diagnostics in the face of whatever is thrown at it.
 
To Peter's suggestion of a timeout for each step of the sequence, I would add a minimum time as well.

Consider a pneumatic cylinder. Spending too much time between fully retracted and fully extended could be an indication of a misadjusted end-of-travel switch, low air pressure, burned out solenoid coil or PLC output circuit among other things. Spending too little time could also indicate a malfunction like a misadjusted end-of-travel switch or the absense of the load that the cylinder is supposed to push.
 
Or better still ...how about a simple common subroutine that "learns" the mean and standdeviation times of the cyclinder actions, and alarms anything outside of say 2 sigma. Not hard to do if you get the datastructures and routines organised.

Oftentime this kind of diagnostic tool will pick up progressive mechanical failures and can alert operators/maintenance folk to a fault before it actually stops production....very cool.
 
Absolutely, Philip!... :cool:

Too many programmers consider a job 'finished' once it's functional. There are just so many features you can easily 'build in' to your programs that it seems foolish to settle for "It works... I'm done".

In my eyes, I'm never really "done" with a program. Although, at some point I have to settle on what's enough, or the machine would never ship... :rolleyes:

There's always SOMETHING you can do to make it better!... :nodi:

I actually did something along the lines of your 'learning' idea a few years ago. I explained it briefly in THIS POST if you're interested.

beerchug

-Eric
 
The PLC is not a good place to do standard deviations.

PhilipW said:
Or better still ...how about a simple common subroutine that "learns" the mean and standdeviation times of the cyclinder actions, and alarms anything outside of say 2 sigma. Not hard to do if you get the datastructures and routines organised.

I think any statistical processing should be done on a PC, not a PLC. Calculating the standard deviation is very time consuming it would also consume lots of memory.
 
Yes and no Peter...it depends on the processor you are using.

My prefered PLC is ControlLogix. It has several forms of statistical function.

In ladder there are single instructions that will derive the Average and Standard Deviation for an array of data.

In function block other instructions derive Moving Average and STD for an analog variable.

Using up lots of memory isn't an issue as it is easy in CLX to create a User Defined Datastructure to suit the task, and then pass multiple instances of it to a single common subroutine.

Gobbling up lots of scantime is even less of an issue as it is only necessary to run the diagnostic on an event basis, once after each cylinder activation.

All up it is more desirable to do the function in a PC...but it is not unreasonable to do it in a PLC processor that can handle it.
 
plc code

Here is some code that I wrote for case palletizer while I was with kodak. Its pretty basic and there are not type of interlocks, It was the early works of the program. Later I went back and created more interlocks etc It is a great way to program called state logic but with a little twist enjoy and I would like some of the pros on here to point out the weaknesses to this type of programming
thanks
Dallas
also it is rslogix 500 version 6.00
email me at [email protected] I just noticed that I cannot post attachments
 
I can apreciate good code because I have seen alot of bad code. I have debugged German code that latched and unlatched each individual state, with multiple latches and unlatches in mulitple subroutines acting on the same bit or worse an output and on multiple pieces of equipment(habits are hard to break), try finding a bug when everybit and thier brothers bit is also accessing that bit, next try adding to the code.
The identity of each bit and that in which controls the bit should be concise.
In sequencing a machine I have adopted an easy to use method we have termed RTO logic. In the A/B world a bit or state would start a Retentive timer giving you some key bits which would assist in control: the .EN bit - shows rung is true, .TT bit - allows time for the rung to be true. "WHILE"(good for dwells watchdogs), .DN - this would finish that sequence and trigger the next sequence, .ACC - this register allows for timed features(LIM,GRT,LES) as the rung sequence progresses(again watchdogs,
limit times,ect.), .PRE timer preset- this determines the time the rung will be true before triggering the next sequence( I like this because I can run the sequences in slow motion while I am doing debug and when the control is doing what I want I can reduce the .PRE register and run the step at normal time. When all the steps are .DN(done) and the sequence is complete a RST resets all the RTOs and awaits the next operator PB(pushbutton).
------------------------------------------------------------
I seldom can put a name to a style of programming and I apreciate those that can. Would like to hear from you guys.
-------------------------------------------------------------

"In a throw away society even the bottom feeders can flourish"
"I have only one regrett, that I have only one life to give to my company"
 

Similar Topics

Hello all, Just to give you an idea of my background, I'm new to the PLC world with a background in IT and currently pursuing my MSEE. I have...
Replies
3
Views
730
OK, (some of) you guys know by now that I'm not a PLC programmer, so I'm not really familiar with how a well-structured PLC program is typically...
Replies
2
Views
1,466
Program structure - s7-1200 MODBUS RTU Master with multiple slaves & multiple registe I'm having problem to make a appropriate structure of my...
Replies
7
Views
11,228
Hello, I am creating a PLC program for a fresh water pump station which will be based on downstream and upstream pressures. There will be several...
Replies
5
Views
2,100
hi guys I have recently completed a basic S7 course and have started creating my own little programs/solutions to small problems using stl. So...
Replies
1
Views
1,219
Back
Top Bottom