aghd
aghd

Reputation: 715

Instantiating of numerous function block in CODESYS (IEC61131)

I have made a function block using CODESYS to perform energy metering. The inputs of the function block is current and voltage and the output is energy. Now, we need to have 1000 instances of this function block to run the code for 1000 meter we have. Writing (and possibly copy and pasting) of these instances doesn't seem to be the most interesting work. Wondering if anybody has a smarter way of doing this numerous instantiation.

For example, here is how the code (in CODESYS) looks like for 2 instances:

meter_instance1(CURRENT:=I1, VOTAGE:=V2);
Energy1:= meter_instance1.ENERGY;

meter_instance2(CURRENT:=I2, VOTAGE:=V2);
Energy2:= meter_instance2.ENERGY;

And we like to have 1000 instances of it. Any idea is highly appreciated.

Upvotes: 3

Views: 2062

Answers (2)

Arndt
Arndt

Reputation: 98

Just make an array of the function block:

aEnergyMeter : array [0..999] of FB_EnergyMeter;

Also make arrays of the voltage and the current:

aVoltage : array [0..999] of INT; //if you use INT as type

aCurrent : array [0..999] of INT;

Then you can use it like that:

aEnergyMeter[0](CURRENT:= aCurrent[0], VOLTAGE := aVoltage[0]);

As you use different arrays with the same size, I would prefer to define some global constant:

VAR GLOBAL CONSTANT
firstDevice : UINT := 0;

lastDevice : UINT := 999;

END_VAR

Then you can define the array like that:

aEnergyMeter : array [firstDevice..lastDevice] of FB_EnergyMeter;

Upvotes: 5

mrsargent
mrsargent

Reputation: 2442

I agree with Arndt that you should use an array of function blocks and an array for voltage and current. Depending on your scan rate of your task you should be able to use a for loop to scan through all of your function blocks in a couple lines of code

var
  meterInstance : array[1..1000] of FB_EnergyMeter;
  voltage : array[1..1000] of int;
  current : array[1..1000] of int;
  energy  : array[1..1000] of int;
end_var


for i:=1 to 1000 by 1 do
  meterInstance[i](Voltage := voltage[i],Current:= current[i]);
  energy[i] := meterInstance.Energy;
end_for;

in that for loop you could also combine some error checks while you're at it

for i:=1 to 1000 by 1 do
  meterInstance[i](Voltage := voltage[i],Current:= current[i]);
  if meterInstance.Energy > MaxEnergy then
    //sound alarm
  end_if;
end_for;

The only caveat with this approach is if the scan time is too fast for your task. You could possibly get a watch dog error as the task would overrrun. However since you are only doing 1000 elements and I am assuming your function block is not extremely complex you should be ok with this approach. If you have problems try extending scan time or watch error time.

Upvotes: 2

Related Questions