Reputation: 715
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
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
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