CODESYS - the IEC 61131-3 automation software

Welcome to the official CODESYS Forum by 3S-Smart Software Solutions GmbH | A member of the CODESYS Group
Deutsche Version English version russian version 
It is currently Sun Dec 08, 2019 3:37 am

All times are UTC+01:00




Post new topic  Reply to topic  [ 6 posts ] 
Author Message
PostPosted: Fri Nov 29, 2019 1:59 am 
Offline

Joined: Fri Mar 10, 2017 4:45 am
Posts: 49
I'm trying to understand how parameters are passed to visualizations through the interface, and how that affects memory usage.

According to the manual:
Quote:
VAR_IN_OUT: If a data structure is transferred, it has to be defined as VAR_IN_OUT. Without pragma, the parameter values are copied when the visualization is opened. Entries are written to the copied data structure. When the visualization is closed, the values are written back to the parameters.
VAR_IN_OUT with attribute VAR_IN_OUT_AS_POINTER: Objects are allowed to be transferred as references to visualizations. This can be useful in situations where information is to be transferred to a visualization without actually copying the information, or for updating information from outside, while the dialog is open.


I have a function block defined in the interface of a visualization:
Code:
VAR_IN_OUT
   Meter:      ELECTRIC_METER;
END_VAR


My visualizations work fine with this setup. But I'm running out of memory. For example, let's say I have 15 meters, they're all defined in a program somewhere, then each one has an interface in a tab control. It seems to me that I'm running out of memory because each meter is now taking up twice the space (one for the program, and one in the visualization).

So, I thought I'd use the attribute VAR_IN_OUT_AS_POINTER, which makes more sense to me, passing a reference to the function block instead of copying it.
Code:
VAR_IN_OUT
   {attribute 'VAR_IN_OUT_AS_POINTER'}
   Meter:      ELECTRIC_METER;
END_VAR

Unfortunately that doesn't seem to work with frames or tab controls, only dialogs. If I use it in a tab control or frame I get the error:
Quote:
The interface of the referenced visualization does not match the current configuration. Please do an update of the frame references in the current visualization.


Am I understanding this correctly?

thanks

Tim


Top
   
PostPosted: Fri Nov 29, 2019 1:14 pm 
Offline
Frequent User
Frequent User

Joined: Thu Aug 30, 2018 8:40 am
Posts: 158
Hello Tim,

you are mixing a few things together here so let I try to separate everything:

Disclamer
I will not differentiate between frame and tabcontrol since they are technically the same element

Small explanations for this example
We have a function block defined in our GVL. The content of the fb does not matter.
Code:
VAR_GLOBAL
   data : FBData;
END_VAR


Dialogs
Normal dialog (VAR_IN_OUT)
Interface
Code:
VAR_IN_OUT
   data : FBData;
END_VAR


Generated code
The generated code for this interface kinda looks like this:
Code:
VAR_INPUT
   data : FBData;
END_VAR


The values of the functionblock will be copied once (when the dialog is opened)
Code:
Dialog.DATA := GVL.data;


Dialogs with Attribute VAR_IN_OUT_AS_POINTER
Interface
Code:
VAR_IN_OUT
   {attribute 'VAR_IN_OUT_AS_POINTER'}
   data : FBData;
END_VAR

This attribute is only available for dialogs. It has no effect for frames and therefore correctly reports an error.

Generated code
The generated code for this interface kinda looks like this:
Code:
VAR_INPUT
   data : REFERENCE TO FBData;
END_VAR


The reference to the data will be set once (when the dialog is opened)
Code:
DialogVarInOutPointer.DATA REF= GVL.data;


Frames
Interface
Code:
VAR_IN_OUT
   data: FBData;
END_VAR


Generated code
The generated code for this interface kinda looks like this:
Code:
VAR_INPUT
   data : REFERENCE TO FBData;
END_VAR


In each cycle the reference to the data will be updated (since the data can be different for each referenced visualization).
Code:
Frame.data REF= GVL.data;


TL;DR
Frames will use a reference, no need to use any attribute.

Best regards,
Marcel


Top
   
PostPosted: Fri Nov 29, 2019 7:49 pm 
Offline

Joined: Fri Mar 10, 2017 4:45 am
Posts: 49
Now I understand, thank you for that very comprehensive reply.

I'm still running out of memory, though, and that leads to another question. Let's say I have a tab control with 15 frames, all pointing to the same visualization, with different references. By process of elimination (removing one frame at a time), it looks like I'm using the same amount of memory for each frame (about 182K each, for a total of 2.8MB). I would have thought that the tab element would "know" that each frame is the same, and to only update the references when the tab is switched. Otherwise what's really the advantage of using a frame--might as well use separate visualizations. Or is there a different element that would accomplish this?

Tim


Top
   
PostPosted: Tue Dec 03, 2019 8:38 am 
Offline
Frequent User
Frequent User

Joined: Thu Aug 30, 2018 8:40 am
Posts: 158
Hello Tim,

there are a few reasons for that, but it is mostly that the referenced visualization was not stateless before SP15.
Starting with SP15 the referenced data will be updated in each cycle. Before SP15 the referenced data was only assigned once in the start of the application.

I added an improvement to cover this use case and reduce the data size.

Adding 15 visualization with different data is just a fancy way to write an array with different indexes in my honest opinion ;)

Best regards,
Marcel


Top
   
PostPosted: Tue Dec 03, 2019 8:09 pm 
Offline

Joined: Fri Mar 10, 2017 4:45 am
Posts: 49
Ok, I am using SP 12 (Schneider Machine Expert), so I guess I can't change the reference at runtime. However, what if I do it with interfaces and arrays?

Interface
Code:
VAR_IN_OUT
   Meter:    METER_ITF;   //function block interface.  This is hard to research because Codesys uses the term "interface" for both visualizations and function blocks
END_VAR


..but, in each cycle, the data won't be updated, since I'm using <SP15. Therefore, in a program:
Code:
   VAR
      MeterIndex:   UINT;
      AllMeters:      ARRAY[1..15] OF DATA_ITF;   //array of interfaces, assigned at runtime
      CurrentMeter:   DATA_ITF;            //linked to interface of visualization
   END_VAR


Then at runtime:
Code:
AllMeters[1]:= Meter1;
AllMeters[2]:= Meter2;
//..etc
CurrentMeter:= AllMeters[MeterIndex];


Seems like it should save a lot of memory. I won't be able to use the tab control, but should be able to do the same with with a single frame and a bunch of buttons that change the MeterIndex variable

I haven't tried this yet. I'll update if it works.


Top
   
PostPosted: Wed Dec 04, 2019 2:25 am 
Offline

Joined: Fri Mar 10, 2017 4:45 am
Posts: 49
Update: that works quite well.

Code:
FUNCTION BLOCK METER IMPLEMENTS ELECMETER_ITF
...
PROGRAM ElectricMeters_PRG
VAR
   Meter1:         METER;
   Meter2:         METER;
   //etc
   AllMeters:         ARRAY[1..13] OF ELECMETER_ITF:= [Meter1, Meter2, Meter3, Meter4, Meter5, Meter6, Meter7, Meter8, Meter9, Meter10, Meter11, Meter12, Meter13];
   MeterInterface:   ELECMETER_ITF:= AllMeters[1];   //it's very important to initialize this variable with a valid reference, or your visualization won't start
   SelectedMeter:      UINT(1..13):= 1;
END_VAR


point the visualization to ElectricMeters_PRG.MeterInterface. Change the SelectedMeter variable with a button or whatever to change the visualization reference

Saves >2MB of memory

Note: requires 'Activate property handling in all element properties' to be checked in Project Settings/Visualization to allow the use of properties in the visualization


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 6 posts ] 

All times are UTC+01:00


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Limited