kvlada Posted March 29 Report Share Posted March 29 Is it possible to execute ForEach loop on a list of structs? What I'm looking to do: For every motor element I have a "run" struct (run, feedback, hours counter, wye-delta soft timers...) and a "settings" struct (power-up time, setting bits, preset times, etc). This way I have a neat "motor object" for every motor, without having to take care of 100s of individual bits and integers everywhere. Instead of manually calling a function for each motor, I'd like to have it somehow automated. I made a list of "run" structs and "setting" structs for each motor. Number of list elements of run and setting structs is the same. But when I create a ForEach loop, I can't choose any of the lists I made. Only way I can feed a list into a ForEach loop is if that list consists of primitive data types, that is: bits, integers, reals, etc. Not structs! Is this possible in any way? Link to comment Share on other sites More sharing options...
Saragani Posted March 31 Report Share Posted March 31 Yes, As I missing something? Isn't it what you want to do? 20240331-0503-17.3933096.mp4 Link to comment Share on other sites More sharing options...
kvlada Posted April 1 Author Report Share Posted April 1 Ah yes, that's it. Thank you @Saragani! ❤️ Why I couldn't do it, is that I forgot the "Properties Window" on the right, I have to select proper data type in there. Otherwise it won't work! Now I have additional question: can I have multiple struct types as inputs to a for-each loop? Because I've defined one struct for "current" data which isn't retained, and other one with different settings data which *is* retained. For example: Run, Feedback, RPM, CurrentLoad... are stored in a non-retained struct, and data like WorkingHours, OnDelayTime, IsMonitored, ... are stored in retained struct. I've done this to save memory space, because max space for retained vars is less than non-retained. If this isn't possible then,... I might have to merge these two structs into one which is wholly retained. Or are there any other workarounds? Can I have structs within structs? Or an array of structs? Link to comment Share on other sites More sharing options...
Saragani Posted April 2 Report Share Posted April 2 Unfortunately, you cannot have 2 types of lists as an input for a foreach function. I can't think of any solution rather than combining them. Link to comment Share on other sites More sharing options...
pascal Posted April 2 Report Share Posted April 2 10 hours ago, kvlada said: Ah yes, that's it. Thank you @Saragani! ❤️ Why I couldn't do it, is that I forgot the "Properties Window" on the right, I have to select proper data type in there. Otherwise it won't work! Now I have additional question: can I have multiple struct types as inputs to a for-each loop? Because I've defined one struct for "current" data which isn't retained, and other one with different settings data which *is* retained. For example: Run, Feedback, RPM, CurrentLoad... are stored in a non-retained struct, and data like WorkingHours, OnDelayTime, IsMonitored, ... are stored in retained struct. I've done this to save memory space, because max space for retained vars is less than non-retained. If this isn't possible then,... I might have to merge these two structs into one which is wholly retained. Or are there any other workarounds? Can I have structs within structs? Or an array of structs? unfortunately, you can't have a struct in a struct.... nor an array of structs 😒 Link to comment Share on other sites More sharing options...
Daniel_EWW Posted June 19 Report Share Posted June 19 On 4/2/2024 at 11:01 AM, pascal said: unfortunately, you can't have a struct in a struct.... nor an array of structs 😒 @Saragani The possibility to have an array of structs would be great (without DataTable). Is there something planed for the future? Link to comment Share on other sites More sharing options...
Saragani Posted June 20 Report Share Posted June 20 @Daniel_EWW What about Lists? isn't that helping you? Link to comment Share on other sites More sharing options...
Daniel_EWW Posted June 20 Report Share Posted June 20 I can create a List. But it is not possible to feed the foreach loop input with this list. Link to comment Share on other sites More sharing options...
Saragani Posted June 20 Report Share Posted June 20 You need to set the type of the foreach loop to match the type of the list. When you select the foreach function in the solution tree, then in the property grid, you can select the type of the list: See the video I posted like 7 posts up. Link to comment Share on other sites More sharing options...
Daniel_EWW Posted June 20 Report Share Posted June 20 Great, thanks! This is what I was looking for! And than the variables are listed as Local Tag. One last question: Using a Data Table this way it is easy (with store) to read and write cell values. Is this correct? Or is it better to use a List and read and write the row back to the data table seperately? (Is there a difference in speed/ cpu usage) Link to comment Share on other sites More sharing options...
Saragani Posted June 20 Report Share Posted June 20 When you work with a data table as List parameter inside a "For Each" function, then you don't need to use Read Row and Write Row. The whole point of the For each function is that it accepts Arrays, Data Tables and Lists, and it iterates the items one by one as the "Current Item". In fact, it accesses the row directly, in case of a Data Table, so altering a member of the current item, immediately affects the value inside the data table. Link to comment Share on other sites More sharing options...
Daniel_EWW Posted June 20 Report Share Posted June 20 Ok, I understand. And there no speed difference, because everything is in the same memeory area? The reason why I'm looking for this is to improve our PLC software. Please find attached 2 videos. The first one is UniLogic version 1.33.161. With the bit "Tag: Data Entry Complete" the read row command of the data table is locked. I think in Versions up 1.33.161 the timing of the "Tag: Data Entry Complete" is different and the read row lock is not working anymore? V1_33.mp4 1_37.mp4 Link to comment Share on other sites More sharing options...
Saragani Posted June 20 Report Share Posted June 20 I don't exactly understand what happens in the video. I see only a portion of the screen of the PLC, and I don't know what is expected to happen. I know that there is an open issue about Numeric Box, that the Data Entry Complete bit is being set about 500ms after the edit was actually completed. What do you mean by read row lock? Link to comment Share on other sites More sharing options...
Daniel_EWW Posted June 20 Report Share Posted June 20 The 500ms delay is exactly the problem we currently have. Link to comment Share on other sites More sharing options...
Saragani Posted June 20 Report Share Posted June 20 OK, this is a know issue, and it has a high priority. Just for curiosity, how does the delay in the bit affects your code? As far as I understand from the issue description, the numeric value is being set to the tag, and 500ms later the Data Entry complete bit is set. In the ladder, if the code checks for the Data Entry Complete for being 1, and only then performs something, then it shouldn't care if the bit is being set 500ms later. I understand that your case is different because you check for the Data Entry Complete being 0 (I'm not sure what AI.Aktive[23] is and what it does). Is your code constantly reading the current row from the Data Table into the struct (I assume that it's AI23_Ist.....), and only on the cycle that the Data Entry Complete is set it doesn't? Do you have a global struct per row of the data table? (So if your table has 50 rows, then you have 50 instances of the same struct), and if you read row 1 you read it to Instance1 and if you read row 2 then you read it to Instance2, etc. ? Link to comment Share on other sites More sharing options...
Daniel_EWW Posted June 21 Report Share Posted June 21 Currently the data table for the analog values has 121 rows. The data table contains the current values of the sensor data and settings (e.g. linearization and threshold for process and alarm triggering). We use data tables for all digital and analogue values to be independent of the hardware I/O address. The configuration of the facility setup is done in this data table. Typically our facilities only have about 30 analogue sensors out of the option pool from 121. “Aktiv” = Active just means that the sensor is relevant for this facility. So we read – manipulate – and write back each active row of the data table in one PLC cycle. We can modify the setting data in the data table. If the modification of settings is done on the HMI we use the “Data Entry Complete” bit to lock the read row operation for this cycle. Only for the analogue data we have for each row a global struct containing the row data. This data is used for the program and HMI. For digital IO’s we us an array and tag aliasing. Tag aliasing for analogue data would be possible but it is faster to have a struct because the name is inherited for all tags within this struct. Maybe everything is realised too complicated. However, it brings flexibility. The foreach loop and lists definitely bring new options. However, I will still keep the data table because of the overview and the easy import/ and export of data. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now