Jump to content

I/O addressing practices, buffering


Recommended Posts

Good day,

I have been racking my brain for over a fort-night and I can't specifically understand how to choose memory bit locations. In theory I should be able to just use any arbitraury value and use that. I can't say one way or the other what is specifically the best way to choose a memory bit address. Does anyone have any theories on the best way to proceed. ( I am trying understand Ladder Logic, so please forgive me if I'm not using the correct nomenclatre)

Link to comment
Share on other sites

It depends on may factors and some of them are totaly subjecive - like stile and "taste" of the programmer.

Some ideas from my experience:

The easiest way is to click the "blue button" to select the next free operand. In many cases this is good enough and for sure is the fastest way.

If there is a chance, that multiple registers will be operated together (group of alarms, data to be sent/received by communication) it highly recommended to define them in array. Then you can operate them with Vector functions. If yo utransfer them by communication (for example Modbus), it's much easier to program and takes much shrter time to execute one command with vector of 10 operands then 10 commands with one operand each.

This is in general...

Link to comment
Share on other sites

generally speaking, I don't specifically know how to use a vector to array for addressing purposes. I think this could be a useful tool, theoretically speaking of course. I would like to know more and will hopefully have some extra minutes to specifically figure it out and then I'll move on to understanding the way unitronics does it's math. Ironically enough, I started using arbitrary addressing descriptors and that seems to work well unless I need to describe a register for a specific function or action. I think your advice was useful.

Link to comment
Share on other sites

Theoretically clicking on the blue button to select the next operand will work however I find that specifying a specific bit will prevent possible issues. I am not saying one way or the other is better. I had an instructor that was dead set in his ways, but I found a better way and by the end of the class was teaching the others how it worked. Try to keep like bits together to achieve maximum clarity and in theory will work much better in the end.

  • Upvote 1
Link to comment
Share on other sites

  • MVP 2023

A fortnight is a long damn time to worry about how to lay your bits out :o

I use addresses starting with even multipliers of 10 or 100 to organize my bits and registers into functionally similar groups. Be careful not to crowd too many together at one end of the address range or the other, as your PLC will tend to lean left or right and you may wind up tipping your panel over. (Theoretically of course)

Joe T.

  • Upvote 1
Link to comment
Share on other sites

  • External Moderators

I have enough gray hair to remember DOS and the concepts of "TSR" and "HIMEM". So I use high-number memory locations for certain canned subroutines like alarms and communications, and lower addresses for the system playground. Like Joe, I group things in 10s and 100s for station and process logic, ordered based on the workflow of the system.

One exception to this, timers. Aside from timers assigned to those canned routines (which I try to avoid) I just use the "next operand" button. I'm rarely concerned with a particular timer and what it does, only with the effect on logic flow (alarms, for instance), and since there are fewer available timers than other bits, it makes no practical sense to reserve 10 timers for a station, then end up only using 3 or 5 of them.

TM

  • Upvote 1
Link to comment
Share on other sites

Organization of data can be just as important as organization of the program itself.

Large programs with no clear data organization are difficult to debug and follow.

For everything that is seemingly arbitrary, you can usually figure out some means to treat it in a non-arbitrary fashion in order to add a level of clarity.

As an example, I like to buffer all of my inputs and outputs into separate subroutines.

If I have physical inputs I0 through I 15 I may buffer them to MB1000 to MB1015.

For my physical outputs, O0 through O15 I may choose the "manual" buffer bits as MB2000 to MB2015 and the "auto" buffer bits as MB3000 to MB3015.

If I have HMI screens with parameters, I may choose to limit each screen to 10 parameters. I will then use 10 contiguous values in the data area and the order that they are layed out on the screen.

Even more important is when you start doing communication. For example with Modbus much of the communication time is lost in the overhead of the "packaging" of the data. If you don't oranize this data so that it is contiguous, you will have to get the data piecemeal with separate instructions. If you group properly you can a larger chuck of that data all with one single read.

If you have like functions that require unique data and code, then you can save a lot of time with data organization.

For example, say you have 8 PID loops that all control 8 temperature zones in exactly the same way. Assign Zone 1 Data Values MI1100 to MI1149, Zone 2 to MI1200 to MI1249, etc.

Now simple write the code for one PID loop in its own subroutine. Debug it and get it running prefect. Once it is perfect, copy that subroutine. Then blow down through each one and simple change the values tby 100.

Then, as an added bonus, now you can perform vector copies to tranfer the data for zone 1 to the rest of the zones without having to re-type all that stuff. Just copy MI1100-MI1149 to MI1200-MI1249, etc. Now you have a good starting point for the rest of your loops.

Also works great for motion axis. Say Axis 1, 2, 3 ect. Setup all identical and just offset the data area by 100 or so. Then in your communication routine you simply indirectly reference that specific axis data area and keep running it through the same sequence of code as if it were a user defined function block.

  • Upvote 1
Link to comment
Share on other sites

Ooo fantastic question... I find myself doing the same thing while fishing. Wondering which is the best specific place to start fishing for great white sharks. I like to find my specific spot by just randomly selected places. I tend to do the same while programming. Sometimes I just set a specific bit, sometimes I just drop some code... usually I get something to happen eventually, somtimes I do not. Sometimes I like to pretend I know what I'm doing, but most times I do not. In theory though I can just skip bits and make it work.

  • Upvote 1
Link to comment
Share on other sites

  • 6 months later...

Organization of data can be just as important as organization of the program itself.

Large programs with no clear data organization are difficult to debug and follow.

For everything that is seemingly arbitrary, you can usually figure out some means to treat it in a non-arbitrary fashion in order to add a level of clarity.

As an example, I like to buffer all of my inputs and outputs into separate subroutines.

If I have physical inputs I0 through I 15 I may buffer them to MB1000 to MB1015.

For my physical outputs, O0 through O15 I may choose the "manual" buffer bits as MB2000 to MB2015 and the "auto" buffer bits as MB3000 to MB3015.

Please forgive me for reviving an old post and possibly changing its topic, But by buffering your inputs and outputs in separate subroutines are you referring to having you inputs in their own subroutine and having them activate the MB and then using the MB in a different Subroutine instead of using the actual input? If so is there any issues using Positive and negative transitions on the MB from the Inputs in the program?

The situation I have is I have similar machines with V280 controllers but different input cards. I would like to have the subroutines the same in the programs but use an I/O subroutine that would be Machine specific for the particular input card that is on the controller. I will refine a particular subroutine on one machine and will need to add that refinement to the others but the input format is different and is causing problems.

Thank you in advance for any insight you will be able to give.

Jason

Link to comment
Share on other sites

Please forgive me for reviving an old post and possibly changing its topic, But by buffering your inputs and outputs in separate subroutines are you referring to having you inputs in their own subroutine and having them activate the MB and then using the MB in a different Subroutine instead of using the actual input?

Yes, my Main subroutine never has any code in it other than calls to other subroutines. One of the very first is the call to the "Inputs" subroutines, and one of the very last is the "Outputs" subroutine.

If so is there any issues using Positive and negative transitions on the MB from the Inputs in the program?

I would say first that you should specify what you regard as an issue.

But beyond that, I would contend that there are certain caveats with positive and negative transitions that in fact make buffering inputs and outputs even more valuable, not less. It gives you much more control.

With ladder, the traditional definition of the scan had the physical IO only updating between single scans of the program. This way you could rely on knowing that the physical Inputs would not change state while your program was in a scan cycle. Some modern controllers, (AB Compact Logix) no longer adhere to this. They have what is considered an asynchronous scan and results in the I/O possibly being updated mid scan, perhaps even multiple times per scan. At face value it may not seem like that would be all that bad of a situation, but in actuality it creates a host of complications and extra considerations that need to be made while coding. Most of us mandate buffered IO on a Compact Logix system as a result, so that we know that we are looking at one single snap shot of the IO for every single scan.

The use of buffering has created a rift where most are usually adamantly opposed to it or fervently for it. Those that oppose it often cite extra time to code, extra memory use, and believe it adds a layer of complexity that doesn't need to be there. Those of us who are for it feel the cost of the memory and time is generally negligible and is won back over time by having a more robust system. We contend that it makes the code simpler to understand, not more complex. It also makes it nice if you blow an IO point on a card and want to move the logic over to a spare. With the buffering you simply change it in one spot and your done. The retort to that is usually that you can simply do a find/replace just as quickly. Well maybe, but what if you want to for example debounce that signal. All of a sudden find/replace falls flat. Whereas I would simply go to my buffer and put a timer between my physical IO and my buffered IO and it automatically takes effect for all instances of that signal.

And by the same token, this is where some other nice aspects of buffering come in to play. The buffering doesn't need to be a straight one to one mapping. It can serve the function of creating ON debounce, OFF debounce, ON and OFF debounce, one shots, and signal combinations. Having this stuff in the buffer removes it from the actual code so that the code is easier to read and understand.

I often find reason to have an input debounced in both the ON and OFF direction, and the code to do this is will just clutter the actual sequence program.

I also often buffer things in multiple ways. For example I may have a normal instance of an input and a one-shot instance of that same input. This serves two nice functions and illustrates why I think it addresses exactly what you were alluding to with your question. For one, you will find in the documentation that Unitronics discourages overuse of P and N contacts because they have a detrimental effect on the PLC resources. If you need to use the positive transitions of the same signal several times in your program you are much better off using one transition contact to control one normal buffer bit and then just use regular contacts throughout with that buffer bit. You can make it clear with a naming convention (ex. P Control Start PB) that it is transition. The other benefit is you have complete control over how that transition is refreshed now. If you recorded that transition with the buffer bit right in the first subroutine you can count on the fact that that buffer bit will carry the same state throughout the rest of the scan, no matter how many times you jump in and out of subroutines. That is of course unless YOU modify that buffer bit elsewhere.

And not to be forgotten, the combination signal. What is this? Well possibly it is making more inputs out of fewer. Perhaps you have three aux guard contacts coming into the PLC in separate inputs. It might be beneficial to have one single signal that tells you if all three are on. Or, perhaps you have a mulitplexed signal coming in. Maybe it is a selector switch for a product select where product one is both off, product 2 is one on, product 3 is the other on, and product 4 is both on. Now you can make four buffered inputs that decode this one for one and product one selected, product two select, etc. Again, stuff like this tends to just obfuscate the sequence code. Perhaps you have buttons on the HMI that perform the same function as physical buttons, then you combine these and have both signals controlling the same buffered bit. I could go on and on.

The situation I have is I have similar machines with V280 controllers but different input cards. I would like to have the subroutines the same in the programs but use an I/O subroutine that would be Machine specific for the particular input card that is on the controller. I will refine a particular subroutine on one machine and will need to add that refinement to the others but the input format is different and is causing problems.

Thank you in advance for any insight you will be able to give.

Jason

This is again another example of where buffering is handy. It allows you to write code that is non-hardware specific and then just attach those mapping in one spot. I am not certain what you mean by the input format is different. Perhaps you could clarify? What kind of problems are you having?

  • Upvote 1
Link to comment
Share on other sites

  • MVP 2023

What a terrific post, Damian. I do all of the things you discuss, basically from a process of dicovery after having "bad" things happen. Buffering was an early discovery after a customer completely miswired the I/O after providing me with the specification - the process of fixing my program to match the wiring made me realize there was an easier way and I decided never again! I'm so glad to see validation from experts that this technique is both appropriate and often superior.

I've been requesting a Unitronics webinar on best programming practices, tips, and tricks for some time now. I/O buffering should be front and center, as well as data organization. In the meantime, perhaps we could find a place in this forum to gather best practices in order to learn from each other and provide a valuable resource for newbies.

Link to comment
Share on other sites

Hi guys,

I read this through--and let me second Flex--Damian, terrific post.

I just rearranged a few things in the forum, to include:

Best Programming Practices

Tips from Unitronics gurus

forums

So please--Damian, would you (or may I) put that post of yours there?

Great idea, Flex, and I will look around for posts that should be moved/copied there.

  • Upvote 1
Link to comment
Share on other sites

My apologies for the delayed response.

Damian,

Thank you for the response, as soon as I can get back to this project I will be modifying my project and buffer the input and outputs.

I have the task of modifying another person’s project without rendering the original functions not operational.

Thanks again.

Jason

Link to comment
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...