Skip to content

Initialisation of FB input variables

Hi All,

What i notice is (new) behaviour of initialisation of FB input variables. (New because in earlier versionsof PNE this was not the behaviour). Input variables which are not initialised at the call of the FB will not initialised with there default value.

Sometimes i use FB's in a reëntrant way (using the same instance twice).

A test FB is init as follows:


The code is


this is the debug result


As you can see is that at the 2nd call the i_iInput value still has the value of the first call and is not initialised with the default value 10.

It is also not possible to initialise the input variable to a known value when leaving the FB.

I think this is unwanted behaviour which can introduce confusion.

So:

1) Or you do not init the input value but give the programmer the possibility to set the input value to a known state (as in PCWorx)

2) Or not initialised values at the FB call will be init with the default value.

In this cases the behaviour of FB can be guaranteed .


What is the opinion of Phoenix?

Marco van Os

GeoComfort B.V.

Comments

  • edited August 2023

    Hi!

    You use the same fb instance in calls, and it has already initialize input variable with "1" on line 3. Why it should reinitialise with 10 in the next call? Even if you comment substitution of input value on line 8, in the memory area of RFP_TestReEntrant_1() it has already defined as "1" because of substitution on line 3. It will be mach more surprise if the same instance call with the same input parameters return different result.

    You have to create new instance RFP_TestReEntrant_2() to deal with it's initial (default) inputs values.

    Actually input variable does not have to be changed at the moment of return from fb internal scope. It is not dedicated for this (It provide variable by value, for internal scope of fb usage). You have to use InOut variable usage type, if you want to change "input" (provide variable by reference) for changes in outer scope of program.

    PLCNext has a little bit tricky visibility scopes and usage types for variables and instance entrances, so kindly reading of corresponding manual pages are greetings.

    Best regards

  • Try to rewrite code in the next manner, for more clearity

    1. According to IF conditions, call fb on line 2. It implicitly set i_iInput with initial value 10 and transfer it to output.

    2. Now we call fb with input value explicitly set, and have new return value of output. This explicit value 3 stored in internal memory of fb.

    3.Now we go back to implicit branch, but it return updated output value according to fb internal stored data.


  • Hi Oleksandr

    thanks for your response. The example was made to show that if you do not initialise an input variable the state is unknown cq. it has the state of the last call. You are right that the first call is the actual initial call. And of course there are workarounds outside the FB. The most efficient solution is always initialising all inputvariables.

    The basic issue in this case is that the behaviour of a FB is influenced by it older calls and that I, als programmer can not solve this within the FB. So I deliver FB's with predictable behaviour.

    My problem was that in a new revision of a FB a inputvariable was added and that on one case i forgot to initialise this specifc inputvariable. After a while i discovered some unpredicted behaviour of the FB caused by holding older states.

    In the future my collegues (my customers) will work with my FB's. So if i make a revision, they have to recheck the whole code and may not forgot to initialise the new variables. They must be aware that using my FB can introduce unprodictable behaviour. If I, as developer, can write the input variable at the end of leaving the FB to a well-known value, Input values have always a defined value, state and I unburden the customer.

    This is the way how it is implemented in PCWORX and it gives the possiblity to produce beter en more safe code (for me and my customers).

    Greetings

    Marco van Os

    GeoComfort B.V.

  • Hi Marco,

    you can write the inputs at the end before leaving the FB.

    There is an option to enable it

    or maybe it isn't that simple and I did not understand the problem.


    Cheers

    DivisionByZero

  • Hi DivisionByZero

    Normally 'division by zero' gives a lot of problems.. In this case it solves my problem ;-)

    thanks.. I was not be aware of this option.

    (It reminds me to look more to the option page.. )

    Marco van Os

    GeoComfort B.V.

  • edited August 2023

    I think that you are mixing definition of concepts for function and function block. You want fb operate like fc, but it is not exact it used for.

    You have to use several independend fb instances, where each call will be dedicated to individual task and in one case you will define all inputs, and in another just certain one (with implicit input initialization). (Store internal states between calls)

    Or you have to use function, where it is impossible to miss any input without initialization with values from the outer scope. (Re initiate internal state on each call).

    For now it's looks like you use the same R_trigger for several different variables and as a result can't deal with front detection....

  • Hi Oleksandr

    I Agree, I want to use FB with the benefits of FC's.

    The reason is maybe old fashioned but re-entrancy saves memory space because only one instance is made instead of many which do exactly the same. (I am from the generation who had to work with 4K, 8L and 32K space.) In the ILC plc's I had memory problems and re-entrancy saved memory.

    In PLCnext the memory is less a problem (at this moment.. but give me space and i use it :-))) )

    And Re-entrancy has also disadvantages. Example: the are hard to debug.

    It's true that giving each FB its own instance is more secure.

    Marco

  • edited August 2023

    @Marco van Os I think @Oleksandr Guminskiy 's assumption is correct and you want FBs to act like FCs.

    Is there a reason you use function blocks instead of functions?


    Edit: It seems that I did not refresh the page and you answered already ;)

  • @DivisionByZero and @Oleksandr Guminskiy

    Most has its origin in the limits in use of FC in PCWorX and older PNE versions.

    ex.

    • There is only 1 return value and in older versions it was not possible to return structs
    • Older FC's couldn't reach global defines memoryspaces. The re-entry FB's have in common that they work on global memory-spaces.

    Nowaday's the FC's in PNE are more powerfull end the limitations are gone. And also there is more space.

    So Re-entrancy becomes less necessary. More that it has some disadvantages: debugging etc.

    But for now i have to deal with some libraries which use it.

    Marco

  • edited August 2023

    Ok, in this case, you should be more strict when instruct the plc)

    it seems that adding of init method to the FB can be good idea.


    In this case it is possible to return internal state of fb to certain predefined point. At the moment it is necessary.

  • Just to add - if I understand the issue correctly, the behaviour of Function Block variables in PLCnext Engineer is now identical to the corresponding behaviour in Siemens PLCs. In Siemens PLCs, function block instance data - including the values of the Input and Output variables - is stored in an "instance DB". The data in an Instance DB will stay the same between every call to the FB that uses that Instance DB, so if you don't provide a value for one of the input variables, it will still have the same value as the last time the FB was called with that Instance DB.

    Perhaps that's why the behaviour was changed in PLCnext Engineer - to make the behaviour more familiar to Siemens programmers.

  • edited August 2023

    I switched from TIA Portal straight to PLN Enineer, probably that's why fb work for me as expected, in general cases.

  • @Martin PLCnext Team

    Martin, If i understand correctly. If there are 2 or more instances of a FB, the data (input, output, locals etc) is stored in a DB. But the code from the FB is stored once in memory. Like a taskmanager, every time the FB is called, the taskmanager swaps the data pointer to the correct dataset and the code is running?

    It isn't that the code of each instance is implemented in the final runtime? (ex. 10 FB is 10 times the code)

    Marco

  • edited August 2023

    Correct. The same code is always called for every instance of a single FB, but there is a unique set of data for each of those FB instances.

    If the same FB instance is called twice in one Task cycle, then both those calls will share the same set of data. If one of the FB input values is assigned during the first call to that FB instance (e.g. by connecting a variable to the input), but not on the second call to that FB instance, then the value of that input during the second call will be whatever the value was set to by the first call. This is exactly what you demonstrated in your first post:

    So 10 x FB instances = 1 x the FB code and 10 x the FB data.

    Your example above only has one FB instance, so it's 1 x FB code and 1 x FB data.

    A Siemens PLC makes this more obvious, because you would see 10 "Instance Data Blocks", one for each instance of the FB. Those "data blocks" are not visible in PLCnext Engineer, in accordance with the IEC 61131 standard.

  • thx all,

    this was a very constructive and clarifying discussion for me.


    Best regards

    Marco van Os

    GeoComfort B.V.

Sign In or Register to comment.