Hello everyone, after doing some research on this topic, I feel the need to start fresh. I am currently utilizing Codesys to compute a Moving Average using the code provided below. However, when I try to translate it to ST in Compact Logix, it simply does not work as expected. The additions in Compact Logix seem to be computing differently, indicating a possible gap in my understanding of the systems. I apologize if this topic has been discussed before. In both scenarios, I am utilizing a timer and incrementing a new count to move to the next position in an array that stores previous frequency values. My goal is to calculate a rolling 5-minute average, so the array size is from [0..299]. The following logic works perfectly in Codesys ST but encounters issues in Compact Logix L36ER: ##################################################### New_count:=Timer_elapsed+1; IF New_count <> Old_Count THEN IF FCR_Mode THEN F_Sum:= F_Sum - Freq_Array [Old_Count]+FCR_Hz; Freq_Array [AEM_Old_Count]:= FCR_Hz; ELSIF NOT FCR_Mode THEN F_Sum:=F_Sum - Freq_Array [Old_Count]+50.0; Freq_Array [Old_Count]:= 50.0; END_IF; //Calculate the rolling average F_Avg5Min := F_Sum/299; //Update old count Old_Count:=New_count;
When it comes to programming in Codesys ST and Compact Logix L36ER, the following logic can work wonders. The code snippet below showcases how the frequency array is updated and the rolling average is calculated: ```CODE New_count := Timer_elapsed + 1; IF New_count <> Old_Count THEN Freq_Array[AEM_Old_Count] := FCR_Hz; IF FCR_Mode THEN FCR_Hz := 50.0; END_IF; F_Sum := F_Sum - Freq_Array[Old_Count] + FCR_Hz; // Calculate the rolling average F_Avg5Min := F_Sum / 299; // Update the old count Old_Count := New_count; END_IF; ``` Some points to consider include the source of `Timer_elapsed`, the division by 299 with 300 elements in the array, and the potential impact of floating-point roundoff errors on accuracy.
Hello drbitboy, it's always a pleasure to chat with you. Thank you for the tips on code formatting, it definitely helps in making things clearer. In regards to the value 299, I admit I was a bit careless in my translation to avoid any issues with the PLC index and causing it to stop. The Timer elapsed function is set to count to 300 within a scan task of 100 milliseconds. The precision here is not critical as this function is used to gradually decrease the inverter output power, for which we utilize a 5-minute rolling average function. Afterward, I made some adjustments using the MAVE function, which worked efficiently. Here is the updated code snippet: // Computing the Moving Average TONR(Timer_AEM_Freq); Timer_AEM_Freq.PRE:=299000; Timer_AEM_Stopped:=Timer_AEM_Freq.DN; Timer_AEM_elapsed:=Timer_AEM_Freq.ACC/1000; // Converting from milliseconds to seconds Timer_AEM_Freq.TimerEnable:= NOT Timer_AEM_Freq.DN; // Ensuring correct iteration AEM_New_count:=Timer_AEM_elapsed+1; IF AEM_New_count <> AEM_Old_Count THEN IF FCR_AEM_Mode THEN Freq_AEM_Array [AEM_Old_Count]:= FCR_Hz; AEM_5MinAVG.In:=Freq_AEM_Array [AEM_Old_Count]; mave(AEM_5MinAVG,Freq_AEM_Array2); F_Avg5Min:=AEM_5MinAVG.Out; ELSIF NOT FCR_AEM_Mode THEN Freq_AEM_Array [AEM_Old_Count]:= 50; AEM_5MinAVG.In:=Freq_AEM_Array [AEM_Old_Count]; mave(AEM_5MinAVG,Freq_AEM_Array2); F_Avg5Min:=AEM_5MinAVG.Out; END_IF; // Updating the old count AEM_Old_Count:=AEM_New_count; END_IF; This improved implementation incorporates the use of the MAVE function to enhance the accuracy of the calculations.
Enhance cleanliness with a slight adjustment -IF a THEN ... ELIF NOT a ... is essentially equal to IF a THEN ... ELSE ... In the provided code snippet, the Timer_AEM_elapsed will reset to 0 approximately within 100 or 200 milliseconds upon reaching 299, unless rounding occurs during division. Additionally, in the case of TONR being a retentive timer, it raises the question of where it gets reset. Here is the code snippet by frandESS: // Conduct Moving average calculation TONR(Timer_AEM_Freq); Timer_AEM_Freq.PRE:=299000; Timer_AEM_Stopped:=Timer_AEM_Freq.DN; Timer_AEM_elapsed:=Timer_AEM_Freq.ACC/1000; // converting milliseconds to seconds Timer_AEM_Freq.TimerEnable:= NOT Timer_AEM_Freq.DN; // Ensure correct iteration completion AEM_New_count:=Timer_AEM_elapsed+1; IF AEM_New_count <> AEM_Old_Count THEN IF FCR_AEM_Mode THEN Freq_AEM_Array [AEM_Old_Count]:= FCR_Hz; ELSE Freq_AEM_Array [AEM_Old_Count]:= 50; END_IF; AEM_5MinAVG.In:=Freq_AEM_Array [AEM_Old_Count]; mave(AEM_5MinAVG,Freq_AEM_Array2); F_Avg5Min:=AEM_5MinAVG.Out; // Update old count AEM_Old_Count:=AEM_New_count; END_IF;
Hi there! It sounds like you're trying to implement a circular buffer to compute your rolling average. I've also faced similar issues working with Compact Logix in terms of translation from Codesys. I'm wondering if the issue is not with your math, but rather in how you're incrementing and managing your NewCount and OldCount pointers. To loop back correctly and prevent running out of your array's bounds, consider using a modulus operation, like `New_Count := (Timer_elapsed + 1) MOD 300;` Similarly, make sure `Old_Count` is updated in a similar cyclic manner. Happy coding!
It seems like you are dealing with a classic issue while moving between coding platforms, which can behave differently, despite using the same language standards. Compact Logix in particular is known for some peculiarities when it comes to handling Floating Point Decimal Arithmetic, which could be the underlying issue here. You might want to break down your calculations to check each operation and how it's being computed. Additionally, always ensure that all your variables are initialized correctly before their usage. There are also specific anti-windup/bounding techniques that it could be worth while to apply to your integral terms. As a start, try simplifying your logic to identify where the discrepancies arise.
Hey there! It sounds like you’re grappling with some common issues when transitioning from Codesys to Compact Logix, especially with how data types and execution timing may differ between the two systems. One thing to double-check is the handling of your timer elapsed time—make sure it aligns with how Compact Logix interprets your logic. Additionally, verify the array index management to ensure you're not exceeding the limits, as even a small mistake here can lead to unexpected results. Sometimes minor differences in syntax or execution order can really throw off your calculations. Good luck, and don't hesitate to share any specific error messages you’re encountering!
It sounds like you're on the right track with your implementation, but the differences between Codesys and Compact Logix can definitely trip you up, especially with data types and indexing. Make sure the way you're handling the timer and incrementing the `New_count` aligns with how arrays operate in Compact Logix, as it uses zero-based indexing. You might also want to double-check the precision of your numbers since Compact Logix can sometimes give unexpected results with floating-point operations if the types don't match perfectly. Have you considered logging the values during your execution to see exactly how they differ from what you expect? That could help pinpoint where things are going wrong!
It sounds like you're encountering some interesting challenges with transitioning your code from Codesys to Compact Logix. One thing to consider is that Compact Logix may have different ways of handling data types and array indexing, so double-check that your array sizes and data types are defined the same way as in your Codesys setup. Also, ensure that your timer is functioning as intended, since any discrepancies there can affect your counting logic. It might help to add some debug outputs to check the values of `F_Sum`, `Old_Count`, and `New_Count` at various stages to pinpoint where things might be going wrong. Good luck, and it’s great to see you diving into this topic!
It sounds like you're facing some issues with the different syntax and execution flow between Codesys and Compact Logix. One common headache when transitioning to Compact Logix can be how array indexing works, since it starts at zero. Also, ensure that your timer is set up correctly and that the elapsed time is accurately captured—sometimes those subtle differences in how timers function can really throw off calculations like these. It might help to simplify your logic step-by-step in Compact Logix to pinpoint where things are going off-track. Don’t hesitate to break it down into smaller pieces and verify each part independently; this way, you can isolate the issue more effectively. Good luck!
✅ Work Order Management
✅ Asset Tracking
✅ Preventive Maintenance
✅ Inspection Report
We have received your information. We will share Schedule Demo details on your Mail Id.
Answer: - The goal is to compute a rolling 5-minute average by storing previous frequency values in an array and updating it based on the current frequency value.
Answer: - The differences in how additions are computed in Compact Logix compared to Codesys ST might be causing the issues, indicating a possible gap in understanding of the systems.
Answer: - These variables are essential components of the calculation process for the 5-minute moving average. `New_count` and `Old_Count` track position in the array, `F_Sum` stores the sum of frequency values, `Freq_Array` stores previous frequency values, `FCR_Hz` is a specific frequency value, `FCR_Mode` determines the mode of operation, and `F_Avg5Min` calculates the rolling average.
Answer: - The rolling 5-minute average is calculated by dividing the sum of frequency values (`F_Sum`) by 299, which is the size of the array storing previous frequency
Join hundreds of satisfied customers who have transformed their maintenance processes.
Sign up today and start optimizing your workflow.