Convert custom data types to array for displaying in table

Hi All,

Our project consists of a lot of function blocks (CM’s) which all contain an settings input. In the settings consists of severeval types, for example:

Screenshot 2025-02-19 110345

When we use several of the same function blocks, we want declare the settings only once and make them into an array, like this:
image

But for easy access we want to show the values inside the settings into a table on the HMI: an column for Speed, one for Acceleration and one for deceleration.

Currently we do that by reading/writing the values into a new array structure, like this:

The downside of this is dat we need to have all the values twice and you need a button on the HMI to read/write the values.

What would be nice to have is a function that can write the values from a structure into an array, as if it are pointered values. Basically sometime like:
image
But this does not work, because you cannot access the seperate values into an array with the access function.

Is there anybody with a solution for this problem?

Hi there,

an asorted list of things I am wondering about and recommending:

a) Why do you basically have the same structure array twice? If you map the “ValueSettings” to the visu directly, any read and write do directly modify the structure as expected - no need for a dedicated button to read and/or write

b) Using VC4 (I am quite sure mappView allows for similar things but am not familiar with it) you could use the Completion Datapoint on the text fields, and any time it’s set, you refresh the Set data, otherwise you read the data:

IF SettingsChanged THEN
    SettingsChanged := FALSE;
    // we copy the data from the Visu to our local structures
    brsmemcpy(ADR(ValueSettings), ADR(HMISettings), SIZEOF(ValueSettings));
ELSE
    // we copy the local structure to the HMI
    brsmemcpy(ADR(HMISettings), ADR(ValueSettings), SIZEOF(ValueSettings));
END_IF

Note: even when not going with this solution, I recommend the use of brsmemcpy instead of iterating the arrays manually

SettingsChanged would be mapped to ALL fields on the visu that this specific structure is representing (you don’t need to distinguish, which field was changed - the info THAT it changed is enough)

Hope that helps
Michael

Thank you for your reply.

a) The problem with mapping the structure directly into the visu is that we want to use an table. The input of a table is always an array with one type. e.g. real[0…2], so ValueSettings cannot be mapped directly to a table.

b) That could be a nice solution, but the problem with that is that ValueSettings and HMISettings do not have the same structure:
Variables.var:
image
Types:

The suggestion b) would then still work, just not with using brsmemcpy

IF SettingsChanged THEN
    SettingsChanged := FALSE;
    // we copy the data from the Visu to our local structures
    FOR i := 0 TO 2 DO
        ValueSettings[i].Speed := HMISettings.Speed[i];
        ...
    END_FOR
ELSE
    // we copy the local structure to the HMI
    FOR i := 0 TO 2 DO
        HMISettings.Speed[i] := ValueSettings[i].Speed;
        ...
    END_FOR
END_IF

I also didn’t look close enough, your initial screenshot already would have shown that these are different types…

Probably it would still work with memcopy, but then one array value at the time. But your solution will work aswell. I’m now looking if the ‘value change’ works on a table, but it still feels like a ‘dirty’ solution.

One where I can use a pointered value between the ‘ValueSettings’ and ‘HMIsettings’ would be a much more cleaner solution and then I also don’t have to declare the memories twice.

Well, using memcpy for one value at a time doesn’t make sense anymore. This was just a "i want one structure content to be the same as another one - which with your datatypes won’t work.
“Array of reference to” doesn’t work unfortunately, only “Reference to array of”, so what you suggest is not possible.

What you could do is to abandon the ValueSettings structure and use the HMISettings one, then, only. This will then work for your tables, and the code is more flexible in that regard so you can adapt to change ValueSettings[index]. to HmiSetting.[index]

Maybe that improves things a little

“Array of reference to” doesn’t work unfortunately, only “Reference to array of”, so what you suggest is not possible.

Yes, that is also my understanding after testing a lot of combinations with ACCESS and ADR(). Too bad.

What you could do is to abandon the ValueSettings structure and use the HMISettings one, then, only. This will then work for your tables, and the code is more flexible in that regard so you can adapt to change ValueSettings[index]. to HmiSetting.[index]

The suggestion is the first thing that we tried, and generally that works, but the rest of our project structure and code becomes a real mess with that solution, so that is the reason why we went back to a seperate structure.

Think the real solution would be to create a own dedicated table widget that can handle the array with structures.

Then you don’t have to mess with copying data back etc.

Hi Job,

Yes that would be a great solution, and something we are also investigating currently. The tools which are available for that are unfortunally not very user friendly, so this will take some time to get to know this.

Maybe you could get some inspiration from WeekPlanning - mappView custom widgets

Or build a custom 'tableItem" from the brease so it could be placed in a normal table.