Jump to content
C_R_PLC

Fully self taught and looking for some advice/critique on my program.

Recommended Posts

For a little backstory I work for a small business that basically hired me to be their official tinkerer, they need it learned I learn it. So in my endeavors I had to learn PLC programming to make the program for a water recycling system for a laundromat. This was mostly done through YouTube and trial and error, which has led to me making programs that work for my purposes but I'm curious if I've developed any weird tendencies or bad habits in my little educational bubble.

The project I'm adding here is part of the program and I think shows most of the things that I'm concerned I came up with "unique" solutions to, namely my use of set/reset and timers. If anyone could take a look and see what they think I am open to any and all critique.

Thank you very much for your time,

-Chris

Don't mind some of my labeling, I wasn't sure what the technical name was so I used some very literal descriptions.

SaS_Sensors_Alarms_Revised.vlp

Share this post


Link to post
Share on other sites

The most glaring thing to me is placing multiple logic threads in a a single ladder rung (Password Entry routine rungs 1, 2, & 5). DO NOT DO THAT! It may work, but it is extremely poor practice and will often not perform as expected. You will not run out of ladder rungs, so break all logic into simple components, one per rung.

One other thing is ALWAYS use a positive transition contact for HMI calls. Although the one time you used a direct contact, it appears to me that it will only be on for a single PLC cycle, so it's okay in this case.

I didn't dive into the logic itself, but nothing jumped out at me when I reviewed it.

In general, when I write a program I only have two things in the Main Routine - Power-Ups then subroutine calls. Everything else is handled in subroutines.

I'll try to take a look in more detail later.

Share this post


Link to post
Share on other sites

By the way, I should have also mentioned that, for a self-taught newbie, your program was far better than I'm used to seeing from beginners - certainly better than the first stuff I did (which makes me cringe when I look back at it :)).

Share this post


Link to post
Share on other sites

A bold move, Chris.  "Here's my code - tell me everything I'm doing wrong".  Truly a sign of humility, which is rare these days.

In addition to what Flex says-

Don't rename "Main".  It's now confusing as to which subroutine is the caller for all the others.

I didn't see any network comments.  I know it takes time, but it's good practice to describe what you are doing as you do it.  When you go back and look at the program a year from now you'll be wondering what in the world you were thinking.

You've made good use of subroutines to separate functionality.  A+.

Try to avoid vertical lines connecting coils to function blocks.  The Lizard Brain wants to see a continuous straight line for a logical statement.

I personally like to put all the outputs in one subroutine (in order) and call them with MBs from other subroutines.  Makes troubleshooting easier.

I also like to make a subroutine called "Display Control".  Put all your display calls and any logic that is display oriented (like the password stuff) in there.  Once again, easier troubleshooting.

I didn't see you make any use of the "Links and Jumps" tab on any of the displays.  Considering you're calling the same display from three different displays, you may have done this on purpose.  But also consider the power of Unitronics to move some of the logic out of the ladder and into the displays.  This will reduce ladder code clutter for non-logical things like basic display calls.  

This is not horrible code.  Your rungs are relatively small and concise, which is good.

 

Keep practicing.  

Joe T.

 

 

Share this post


Link to post
Share on other sites
On 8/6/2018 at 5:14 PM, Flex727 said:

The most glaring thing to me is placing multiple logic threads in a a single ladder rung (Password Entry routine rungs 1, 2, & 5). DO NOT DO THAT! It may work, but it is extremely poor practice and will often not perform as expected. You will not run out of ladder rungs, so break all logic into simple components, one per rung.

One other thing is ALWAYS use a positive transition contact for HMI calls. Although the one time you used a direct contact, it appears to me that it will only be on for a single PLC cycle, so it's okay in this case.

I didn't dive into the logic itself, but nothing jumped out at me when I reviewed it.

In general, when I write a program I only have two things in the Main Routine - Power-Ups then subroutine calls. Everything else is handled in subroutines.

I'll try to take a look in more detail later.

Thank you so much for responding, sorry my own response was so slow. The job site I'm working at doesn't have very good internet and it just totally slipped my mind. Definitely will fix the multiple logic threads and the Main Routine parts, this program is the culmination of a few months of a lot of trial and error so the fresh eyes definitely helps.

On 8/6/2018 at 5:18 PM, Flex727 said:

By the way, I should have also mentioned that, for a self-taught newbie, your program was far better than I'm used to seeing from beginners - certainly better than the first stuff I did (which makes me cringe when I look back at it :)).

Hah well thank you very much, I can't imagine you'd look so fondly at my first few months of struggle but it's good to know that some of the things I noticed and learned from proved to be going in the right direction.

On 8/7/2018 at 11:48 PM, Joe Tauser said:

A bold move, Chris.  "Here's my code - tell me everything I'm doing wrong".  Truly a sign of humility, which is rare these days.

In addition to what Flex says-

Don't rename "Main".  It's now confusing as to which subroutine is the caller for all the others.

I didn't see any network comments.  I know it takes time, but it's good practice to describe what you are doing as you do it.  When you go back and look at the program a year from now you'll be wondering what in the world you were thinking.

You've made good use of subroutines to separate functionality.  A+.

Try to avoid vertical lines connecting coils to function blocks.  The Lizard Brain wants to see a continuous straight line for a logical statement.

I personally like to put all the outputs in one subroutine (in order) and call them with MBs from other subroutines.  Makes troubleshooting easier.

I also like to make a subroutine called "Display Control".  Put all your display calls and any logic that is display oriented (like the password stuff) in there.  Once again, easier troubleshooting.

I didn't see you make any use of the "Links and Jumps" tab on any of the displays.  Considering you're calling the same display from three different displays, you may have done this on purpose.  But also consider the power of Unitronics to move some of the logic out of the ladder and into the displays.  This will reduce ladder code clutter for non-logical things like basic display calls.  

This is not horrible code.  Your rungs are relatively small and concise, which is good.

As I said with Flex thank you very much for the response. Sorry for being late on my own side.

The renaming Main thing and network comments definitely makes sense to me,  I think that may have stemmed from me knowing I'd be the only one to ever look at it but it makes total sense that it's just as much there for me as anyone else reading it. I've definitely had times where even after a week or so of having to do other things I came back and had to basically relearn what I'd written. I hadn't even considered the Output idea, I think up till now where I'm a little bit more comfortable with everything I really needed to see the whole logic string together but moving forward I will definitely transition towards a more usable/troubleshooting friendly approach. Would you say the Display Control subroutine is similar to what I did with the Password Entry subroutine? Or should mine be split up more?

Could you elaborate on the vertical line statement? You're referring to Rung 6 vs Rung 8 in the attached picture? I think mainly I'm just making sure I'm understanding what you mean by function block.

As for the Links and Jumps I knew they existed but hadn't delved into using them at all, I'll definitely look into how to use those because I do like the idea of getting rid of some of that clutter. Things like that are kind of what prompted me to ask this because some parts of the code just seemed extra cluttered compared to others especially around like looping timer setups and things of that nature.  The Set Reset method I used was discovered kind of by accident but I'll link an older program I made that was basically the PLC version of a laundry machine cycle that really gave me a headache trying to figure out. It's all in Subroutine 4 and honestly I'm not even sure if it works because I haven't gotten to test it yet, but it shows off the timer issue I was concerned about in the initial post really well I think.

Thank you very much for the kind words, I think "this is not horrible code" is just about as good as I could ask for in all honesty so I'm happy to hear that.

TEST.PNG

DoD Full Program V2.vlp

Share this post


Link to post
Share on other sites
On 8/6/2018 at 5:14 PM, Flex727 said:

The most glaring thing to me is placing multiple logic threads in a a single ladder rung (Password Entry routine rungs 1, 2, & 5). DO NOT DO THAT! It may work, but it is extremely poor practice and will often not perform as expected. You will not run out of ladder rungs, so break all logic into simple components, one per rung.

Just as a follow up question would the attached picture count as placing multiple logic threads in a single ladder rung? And if it is what is the harm in something like this? I only ask because to me it looks neat this way but if there is a more behind the curtain reason not to do it then obviously that overrides looking nice lol

TEST.PNG

Share this post


Link to post
Share on other sites

Yes, that would count as multiple logic threads in a single ladder rung.  It will often work but it is extremely poor programming practice. Remember that what the PLC executes is compiled code, not ladder logic. The compiler may not compile code like that exactly in the way you expect. You can be certain what to expect when the logic is in separate rungs.

Share this post


Link to post
Share on other sites
6 minutes ago, Flex727 said:

Yes, that would count as multiple logic threads in a single ladder rung.  It will often work but it is extremely poor programming practice. Remember that what the PLC executes is compiled code, not ladder logic. The compiler may not compile code like that exactly in the way you expect. You can be certain what to expect when the logic is in separate rungs.

Ahh okay that's exactly what I meant by behind the curtain, I had no idea about the differences between compiled code and ladder logic. Will definitely fix those wherever I see them. I always feel weird asking for explanatory questions like that because I know it can come off as like disregarding the advice, definitely not how I meant it.

Share this post


Link to post
Share on other sites

I also sometimes (but rarely) like to combine multiple pieces of very simple logic together, as you are doing above. Here is the way I do it:

image.png.17a1b7014b12363f022339e7bb3ba87f.png

This will compile as you would expect, but this is purely an organizational thing for easier readability to the programmer.

Share this post


Link to post
Share on other sites

Ahh okay I see, I'll try and avoid doing that until I understand more how it affects the compilation process. But that logic is also much more straightforward than the storing that I was doing in mine so I could see why that is able to be combined as opposed to mine.

In that example what is the purpose of SB 1? Wouldn't just a line from the left rail be enough to always have that powered? 

Share this post


Link to post
Share on other sites
6 minutes ago, C_R_PLC said:

Wouldn't just a line from the left rail be enough to always have that powered? 

Yes, but I don't have a deep enough understanding of the compiler to know the result. With SB 1 there, I know exactly what the compiler will do. Like I said, your expression will most likely work perfectly, it's just poor practice since more complex expressions can get you in trouble. Placing a line there instead of SB 1 will also most certainly work perfectly - I just consider that also to be poor practice, though others may not agree.

By the way, even a technically legal logic thread can get you in trouble with order of execution. You should always break the logic up into the smallest pieces as practical to place in separate rungs.

Share this post


Link to post
Share on other sites

I understand, thanks for taking the time to explain it. That whole notion of the compiler not necessarily doing what you expect it to never even crossed my mind. I just had the basic understanding that it read left to right and up to down, but even that's not really the compiler aspect of it.

Share this post


Link to post
Share on other sites

I love this thread--very good example of what the forum is all about :)

Chris, if you haven't come across it, you may want to check out the Help topic Program Sequencing.

Also,  right-clicking the left-hand rail will open a menu that offers a view option called 'power flow'. This shows little arrows in the direction of flow--which is a handy thing as well/

PS.jpg

pf.jpg

 

4236A6B4-B5AC-493C-9E71-D458B9A09263.SNAG

Share this post


Link to post
Share on other sites
On 8/19/2018 at 12:35 AM, Cara Bereck Levy said:

I love this thread--very good example of what the forum is all about :)

Chris, if you haven't come across it, you may want to check out the Help topic Program Sequencing.

Also,  right-clicking the left-hand rail will open a menu that offers a view option called 'power flow'. This shows little arrows in the direction of flow--which is a handy thing as well.

Thank you very much, definitely very handy tools. I was in the process of trying to wrap my head around the links/jumps sections.

This has very much been a good example of the more I learn the more I know I don't know lol

Share this post


Link to post
Share on other sites
On 8/16/2018 at 9:47 AM, C_R_PLC said:

I understand, thanks for taking the time to explain it. That whole notion of the compiler not necessarily doing what you expect it to never even crossed my mind. I just had the basic understanding that it read left to right and up to down, but even that's not really the compiler aspect of it.

Ask around and you will find that there are multiple ways of coding a valid solution.  You will also run into designers who express the opinion that to not do it their way constitutes at least poor if not "extremely poor" programming .  The more extreme the response, the more questionable the advice.

Your rung 9 example above will work just fine but looks wonky.  I blame that on the software.  A rung should have only a single connection to the left-hand rail, and the software should not allow more that.  For that matter, it should allow only a single connection to the right-hand rail.

Regarding the need for SB 1 on rung 26 in Flex727's example above, I would say that is is unnecessary.  If it turns out that without it the resulting logic does not perform as intended, that is a serious flaw in the software suite and if not addressed by Unitronics would cause me to look elsewhere for my PLC solutions.  I am confident that that is not necessary.

Share this post


Link to post
Share on other sites
2 hours ago, Dan Blake said:

Ask around and you will find that there are multiple ways of coding a valid solution.  You will also run into designers who express the opinion that to not do it their way constitutes at least poor if not "extremely poor" programming .  The more extreme the response, the more questionable the advice.

Aren't you doing just that?

 

3 hours ago, Dan Blake said:

Your rung 9 example above will work just fine but looks wonky.  I blame that on the software.  A rung should have only a single connection to the left-hand rail, and the software should not allow more that.  For that matter, it should allow only a single connection to the right-hand rail.

Regarding the need for SB 1 on rung 26 in Flex727's example above, I would say that is is unnecessary.  If it turns out that without it the resulting logic does not perform as intended, that is a serious flaw in the software suite and if not addressed by Unitronics would cause me to look elsewhere for my PLC solutions.  I am confident that that is not necessary.

So on one hand you are saying there should only be a single connection to the LH rail allowed by the software, yet when Flex does this the most practical way you complain about it????  And you also say rung 9 will work just fine, going against your advice?  Flex sugggested separating the rungs out but also offered alternatives.

Discussion is welcomed on the forum, but nitpicking using conflicting statements within a post is not very helpful to anyone.

cheers, Aus

Share this post


Link to post
Share on other sites
19 hours ago, Dan Blake said:

A rung should have only a single connection to the left-hand rail, and the software should not allow more that.

 

8 hours ago, Isakovic said:

I always touch left rail two times when doing OR for two bits.

People seem confused about this issue. A single ladder rung can have multiple connections to the left rail, or multiple connections to the right rail (VisiLogic, unlike some other programming software allows a virtual connection to the right rail), but not BOTH, unless there is a  point of contact between them, or a vertical connecting line that connects them together. The problem in rung 9 (far above), is that you have 5 independent logic threads in a single ladder rung. A single ladder rung should contain only a single logic thread, which may or may not have multiple connections to either the left or right rail.

Share this post


Link to post
Share on other sites

==> dB: Ask around and you will find that there are multiple ways of coding a valid solution.  You will also run into designers who express the opinion that to not do it their way constitutes at least poor if not "extremely poor" programming .  The more extreme the response, the more questionable the advice.

=> Ausman: Aren't you doing just that?

No, I am not.  I said that there are multiple valid solutions to a problem.  At this point I made no comment about anyone's specific code.

==> dB: Your rung 9 example above will work just fine but looks wonky.  I blame that on the software.  A rung should have only a single connection to the left-hand rail, and the software should not allow more that.  For that matter, it should allow only a single connection to the right-hand rail.

  1. I said C_R_PLC's code is a valid, if unorthodox, solution.
  2. I expressed my opinion that his style is not good practice and indeed should not be allowed by the software.
  3. I agreed with Flex727's solution to rewrite the rung using a single connection point with the LH rail.

==> dB: Regarding the need for SB 1 on rung 26 in Flex727's example above, I would say that is is unnecessary.  If it turns out that without it the resulting logic does not perform as intended, that is a serious flaw in the software suite and if not addressed by Unitronics would cause me to look elsewhere for my PLC solutions.  I am confident that that is not necessary.

=> Ausman: So on one hand you are saying there should only be a single connection to the LH rail allowed by the software, yet when Flex does this the most practical way you complain about it????  And you also say rung 9 will work just fine, going against your advice?  Flex sugggested separating the rungs out but also offered alternatives.

=> Ausman: Discussion is welcomed on the forum, but nitpicking using conflicting statements within a post is not very helpful to anyone.

  1. Your welcome is appreciated, but realize that meaningful discussion necessarily involves diverse opinions.
  2. I wasn't nitpicking anything.  I said contact SB 1 was unnecessary; I did not say it was wrong.  This is called discussion.
  3. I suggested a different, IMO better, way to code rung 9.  How is it going against my advice to acknowledge that the original method would work?  I am not afraid to say that someone else's style would work.
  4. Yes, Flex offered an alternative solution., and I commented on it.  More discussion.
  5. As explained above, there is no conflict in my original post.

By the way, I checked with seven different PLC programming suites I have used in the past, Unitronics being the latest one.  Three of them would allow a rung to make multiple connections to the left or right rail.  Four of them would allow only a single contact point.  I guess you know my preference.  ?

Share this post


Link to post
Share on other sites

Dan- 

You are really going to be freaked out when you realize Unitronics allows multiple coil stacking and curvy logic joints-

image.png.b2e8434821663daaaf70b6b5c0b419e7.png

 

If your primary focus has been the various flavors of RSLogix, I totally understand your irritation with the Unitronics way.    After I originally read your post I considered the packages I've also programmed- AB SLC500 + uLogix, PLC 5, RSLogix 5000, Omron, Mitsubishi, Idec, Siemens, and the Modicon x84 series.  As you state, it seems to be a toss-up as to rung-starting methodology. 

None of them were especially difficult to figure out with the exception of Omron, with it's little key-initiated edit/insert mode that's not really explained anywhere.  And no subroutines, just a continuation of segments.  I hated working with that product.

In the BeforeTime, when there were only two real PLCs in the US market (AB and Modicon), it's interesting to note that AB always used the rung-and-branch method while Modicon used the 7 x 11 network method.  You could have up to 7 contacts hanging on the rail with interconnecting logic

This was the comment that raised my eyebrows-

19 hours ago, Dan Blake said:

that is a serious flaw in the software suite and if not addressed by Unitronics would cause me to look elsewhere for my PLC solutions

Especially on your first post.

This software is free.  All of it.  Always has been.  So is the forum.  And support requests.  It does work, albeit with some quirky nuances.  I was just quoted $950 for an additional FactoryTalk View ME license to allow me to program the $5,000 PanelView Plus I just bought.  Add that to my $800 annual TechConnect contract.  It's one thing to pay for software, it's another thing to get totally bent over for it.

Hopefully you can get past the software weirdness and find the product to be a good and cost-effective solution. 

 

Joe T. 

 

  • Like 2

Share this post


Link to post
Share on other sites

Hi Joe,

Nice post.  While generally avoided, I have used a sequence of (reset) coils connected in series.  Usually the situation is when I need to clear previous operating states on power up.  I will enable the rung with the first-scan contact.  And you are correct, I do not like it when the logic is so complex that the rung has to fold back on itself.  Often the logic can be rewritten using a couple of rungs, but sometimes it cannot be avoided.

I am sorry if the comment you quoted came across as unduly harsh.  I didn't mean it to apply specifically to Unitronics.  In my current project I have replaced a 15" PV with a UniStream because I liked what I saw: cost, capabilities, and customer support.  I was responding to another poster's post that because he didn't have intimate knowledge of how the ladder logic compiler worked, he couldn't trust how a given design would function.  As programmers, it is not our job to understand the internal workings of a compiler.  It is the job of the compiler designer to faithfully translate a ladder logic design into executable code.

Cheers.

Share this post


Link to post
Share on other sites
8 minutes ago, Dan Blake said:

I have used a sequence of (reset) coils connected in series.  Usually the situation is when I need to clear previous operating states on power up. 

No need for this. Use the Power-Up value <RESET> for coils:

image.png.8d80637cd952d7e045186aad51d7d030.png

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...