Hi team,
I’m using PLCnext Engineer v2023.0 and wanted know how to create a child program and call it to the main program. Thanks
If you want to call some code from Main, strictly speaking what you 're looking for is a Function Block, not a Program. You create them on the right side in Programming → Local → Functions and Function Blocks. Then you can go to Main program’s code and call an instance of the FB (or however many you want).
On the other hand, if you want to create another program, you can create them on the right side in Programming → Local → Programs. But programs can 't be called by other programs. Programs are called by tasks (cyclic or event). Those are on the left menu: Project → → PLCnext. Double click PLCnext and go to the Tasks and Events tab. By default you’ll have a „Cyclic100“ task (cyclic, every 100ms) which calls one instance of Main program (instance is called MainInst by default IIRC). If you made another program you call call an instance of it from here, wether on Cyclic 100 or on another new task you create. You can also call several instances of a program (even main, you could call it more times too).
Which one of those fits depends on what you’re trying to do.
I have the same problem.
It’s a bit frustrating that there is no possibility to call programs by other programs. I have alway used this kind of calls to structure a programm and jump over some code.
For example: If you want a that some part of the code is not beeing excuted if there is a profinet error.
Has someone a clean workaround for this problem?
As mentioned, according to the IEC 61131 standard, a program instance is executed as part of a Task, not as part of another program instance.
Why does a Function Block not help in your case?
If you want to conditionally execute a section of code in a Program, then you could use a conditional statement, e.g. IF … THEN in ST, or JUMP in FBD/NOLD. You could put that block of code in its own code sheet to add some additional structure to the program, if you want.
Perhaps you’re used to some other vendor or software that calls its reusable code pieces that can be called in other parts of the code “program” or some situation like that? I can’t think of why a function block wouldn’t help your use case if you need a reusable piece of code that can be called from some other code
If what’s happening is that you’re getting caught up in the terminology let’s just rename things. For the sake of example let’s say a “reusable piece of code which can be instanced and called from some other code” is a “codeCallable” and “piece of code that can be called by a task (time cycle or event)” is a “taskCallable”. PLCNext calls its codeCallables “Function Block” and its taskCallables “Program”.
PLCNext does do some things in its own particular way and does require adjusting but so does any vendor or technology really. Sometimes you just need to re-estructure or rethink an architecture differently instead of fighting against it. If you’re used to something else whose codeCallables use the name “Program” that could be a source of confusion, perhaps?
Other vendors is not the focus of this forum but a bit of broad strokes examples from my particular experience: other vendors (but most) seem to also use “Function Block” for their codeCallables, but I think there’s one that calls them “AOI”. Some other vendors don’t make the distinction between taskCallables and the tasks themselves and merge them into one, and you just create a “cyclic task” or an “event task”
Like Martin said, there is a JUMP instruction if we interpret your “jump over some code” literally but fair warning I think most current day programmers would agree: JUMPs are not advised as they can easily lead to incredibly spaghettified code and are often the symptom of not properly rewriting something to make use of loops, conditionals, functions, etc.
For example: If you want a that some part of the code is not beeing excuted if there is a profinet error.Call a Function Block containing said code only if there is no Profinet error with a conditional/LD contact? I don’t think you strictly need a program, in fact, it sounds counterproductive. Example checking the condition externally and calling an FB (could also be the FB itself checks inside). “DO_STUFF_ALWAYS” and “DO_STUFF_NO_ERR” are 2 different FBs containing code to do in their situation (could contain more FB calls inside them too)
Ladder example:
| DO_STUFF_ALWAYS |
|-----------------------------------------| EN ENO |------------------|
| |
| |
| |
| xProfinetErr | DO_STUFF_NO_ERR | |
|--------|/|------------------------------| EN ENO |------------------|
ST example:
DO_STUFF_ALWAYS1
IF NOT xProfinetError THEN
DO_STUFF_NO_ERR1;
END_IF
Thanks to both of you! Your explanations are very helpfull. Yes, maybe i am a bit „shaped“ from using other vendors’ Software. Since in other universes a „program“ is taskCallable and codeCallable. Its just a a collection of code, which can’t be instantiated
I understand that using a function block would work. But i am not talking about code that shut be reused. It’s just about structuring the code. So it is a little bit against my current mindset to but it in a function block and create an instance of it. The bigger the project gets, the more important it ist to get some structure.
Maybe in the PLCNext universe using the codesheets is what i am searching for. But then there is still the problem with conditional calling a sheet.
At the moment i have a very specific problem. I am using the ALM_STATE structure for pushing alarm messages to the OPC UA server. Since the alarms have to be registered (which can take more then one cylce) before activate them, i need kind of an „initialization phase“ before the main code is beeing executed (were alarms are activateted). I now solved this by using a code sheet called „initialization“. At the end of this code sheet i put a conditonal Return. So every sheet positioned after the initialization sheet is jumped over, if the return statement is true. I think at the moment this is the way to go for me.
Any Opinion about that?
Yes you are absolutely correct, you always have to „adjust“ to a new environment. But i just realised: The older you get, the harder it is to adjust. ![]()
But i am not talking about code that shut be reused. It’s just about structuring the code. So it is a little bit against my current mindset to but it in a function block and create an instance of it.Oh I think I get where you were coming from now. You could still put it in a Function Block that is meant to be called once. It sounds counterintuitive at first: it could be reused, but no one says you have to reuse it multiple times if you don’t want or need to. You can make an FB that is meant to be called only in one part and it still helps structure/modularize the code. And the FB name summarizes what actually happens inside it: if wanna look at the overall way the program works you just look at it from outside, if you need the details of what it actually does you go inside its code.
Maybe in the PLCNext universe using the codesheets is what i am searching forThose basically subdivide code for a Program in different tabs. Useful for grouping or categorizing but you can’t call separate codesheets selectively, you either call the entire program from a task (all of its sheets) or not. I think, not quite 100% sure since those are brand new for me and I haven’t seen something like them elsewhere.
If you need to call but only when some condition is present, a FB being called with conditionals like before sounds like the best option. But if you want to divide/categorize code that gets called always, yes, they can work.
There I can’t help you, as I’m also trying to figure out how the alarming related functions work in here haha. I tried a short while but I couldn’t get it working right, from when I read the docs it seems they’re a fair bit more involved and roughly speaking need you to be very careful when and how many you call, and they give a done signal when you should call another, from what I understand, but you need to handle all that properly for it to work
Thank you very much for your efforts in this topic. It helped a lot.
From my site there are no open questions left. I think i just need to get used to the new environment.
If you are interested in alarming via ALM_STATE, i have started a new discusion about my problem here:
Forum - PLCnext Community (plcnext-community.net)