QUOTE(servant @ Oct 22 2007, 05:07 PM) [snapback]60750[/snapback]
Is there a simple way to perform ControlLogix 1second, 1 minute, and 15minute average calcs, and then reset the average to prepare for the next time period averages?
I am reading some analog inputs and a modbus input, and need them to be averaged at the aforementioned intervals, so that drift calculations can be performed.
Please assist.
1. Run the task periodically so that you can control the timing rate at which it takes samples. So for instance if the task runs every 25 ms, then you will have 1000/25 = 40 samples.
1a. Alternatively, set up say a millisecond timer with a preset of 1 second. The timer preset can be anything as long as it is significantly larger than the sampling interval. On each program scan, check if the timer accumulator exceeds your resolution (25 ms in this example). If so, then SUBTRACT 25 ms out of the accumulator and trigger the totalizer code. This will introduce some timing jitter to your sampling but it has the advantage that you don't have to have a specialized task for the timing issue.
2. Clear 2 registers. One will be a sample count. The other will be a totalizer. The sample count can be implemented as a counter which is handy because some of the logic is built-in.
3. At each time interval, add 1 to the sample count. Take a sample and add it into the totalizer (a running total).
4. At the end of your time period, divide the totalizer by the sample count. This is your average. Then go back to step 2.
5. Since your time intervals are exact multiples of each other, you can either repeat this block of code 2 more times (with different sample counts and time intervals) or simply add the 1 second total to a second sample count/totalizer for 1 minute (for 60 samples), and then add THAT one to a totalizer for 15 minutes (15 samples). The results are the same but this version can be more efficient since 2/3rds of your code runs very infrequently (once per second, once per minute). A second issue is that for the 15 minute interval at 25 ms intervals, you will have to use something other than an integer (40 samples per second * 60 secs/min * 15 minutes = 36000 samples, which is larger than 32767).
This version is a running totalizer. Alternatives (which are slower since division is slow on virtually all CPU's) is to do the division operation on every sampling interval. You could do the division every time following the same math as above or calculate ((old average * sample count-1) + new sample) / sample count). The downside of this calculation is that it will have precision issues (division is almost always approximate) so it is best to avoid it.
Finally, you can trigger this sort of code just as easily off the real time clock instead of a sample counter. In this case, most of the time I use a trigger that looks something like the following (in pseudo-code):
If LastReading <> ClockSeconds then
LastReading=ClockSeconds
Set "trigger" to run the code that should run once per second
end if
The primary advantage of triggering off the real time clock is that frequently when doing running totals or averages, managers get hung up with the physical clock on the screen/wall and expect 15 minutes to be synchronized with "real time".
There are also issues with this. If someone is screwing with your clock (since PLC clocks are notoriously inaccurate and can gain/lose a few seconds per day, and also to implement daylight savings time sanely), it will screw up your code if you don't account for it. For the same reasons, if you run a sample count, you may find some jitter in that say on 25 ms intervals, you will sometimes have 40 samples, sometimes 39 samples, or sometimes 41 samples. So the safest bet of course is to implement both (keep a sample count but use the real time clock in the PLC) if you find yourself in a situation of running block averages tied to the wall clock.
All previous versions are a running totalizer system. The previously mentioned FAL or AVERAGE instructions also work. They take more memory and have more processor timing jitter since the processor does the addition step all at once at the end of the interval. Plus, the 15 minute average with 25 ms sampling rates amounts to 36,000 samples. Even on Contrologix, that is going to be one heck of a delay every time it executes an FAL for that many samples.