I gave up on trying to use DTIME for rolling averages a long time age. I got this code from a friend. Works like a charm. =================================================================================== The following code performs a rolling average calculation. The average is initiaized to the first value read from the input, and then it goes from there. The NUM_SAMPLES constant determines the number of "buckets" to use for calculating the rolling average, and the SAMPLE_PERIOD is the interval between samples (should be some multiple of the parent IND block's PERIOD). Therefore, your rolling average interval is NUM_SAMPLES * SAMPLE_PERIOD seconds. In this example, it is a 1-hour rolling average of 1-minute samples. INDEPENDENT_SEQUENCE {****************************************************** ** ** Rolling Average Calculation (IND block version) ** ** Calculate rolling average over a time period ** equal to NUM_SAMPLES * SAMPLE_PERIOD secs. ** Here we use a ring buffer to hold the samples. ** We initialize by filling the ring buffer with the ** first reading and get a starting "average" value = ** that reading. We then start a loop, getting the ** input value, poking it in the ring buffer after ** saving the value in that ring buffer location. ** We then calculate the sum of the ring buffer values ** by adding the new value to the sum and subtracting ** the saved old value, and get the average by dividing ** that sum by the number of samples (size of ring ** buffer. Finally we wait one sample interval, and ** lather rinse repeat. ******************************************************} CONSTANTS NUM_SAMPLES = 60; SAMPLE_PERIOD = 60; { secs; IND block period should be an integer multiple of this } VARIABLES ring_buf : R[NUM_SAMPLES]; i : I; USER_LABELS input : RI0001; { Live input value } roll_avg : RO0001; { Calculated rolling average } roll_sum : RO0002; { Sum of input values over averaging period } st_inp : RO0003; { Stored input value } rb_oldest : RO0004; { Saved ring buf value @ ptr loc } rb_ptr : IO0001; { Ring buffer index pointer } STATEMENTS { Initialize ring buffer } ring_buf := SET_ARRAY(input); rb_ptr := 1; { Starting "rolling sum" } roll_sum := ring_buf[1] * NUM_SAMPLES; { Wait until next scan before starting main loop } WAIT 1.0; { Main loop } <<loop_lbl>> { Get input, save old value at current ring buffer pointer location, and save input value. Store to an output for troubleshooting. } st_inp := input; rb_oldest := ring_buf[rb_ptr]; ring_buf[rb_ptr] := st_inp; { Calculate rolling sum and average } roll_sum := roll_sum + ring_buf[rb_ptr] - rb_oldest; roll_avg := roll_sum / NUM_SAMPLES; { Move ring buf pointer to next slot } IF rb_ptr < NUM_SAMPLES THEN rb_ptr := rb_ptr + 1; ELSE rb_ptr := 1; ENDIF; { Wait until next calculation cycle } WAIT SAMPLE_PERIOD; GOTO loop_lbl; ENDSEQUENCE =================================================================================== Roger Nugent Control Systems Coord Phone: 409-960-5392, E-Mail: roger.nugent@xxxxxxxx BASF Corporation, P. O. Box 2506, Hwy 366, Gate 99, Port Arthur, TX 77643 _______________________________________________________________________ This mailing list is neither sponsored nor endorsed by Invensys Process Systems (formerly The Foxboro Company). Use the info you obtain here at your own risks. Read http://www.thecassandraproject.org/disclaimer.html foxboro mailing list: //www.freelists.org/list/foxboro to subscribe: mailto:foxboro-request@xxxxxxxxxxxxx?subject=join to unsubscribe: mailto:foxboro-request@xxxxxxxxxxxxx?subject=leave