Averaging Sampled Data

Averaging Sampled Data
none 0.0 0
  • HMI Model: cMT-FHDX820
  • EasyBuilder Pro Version:

I have data samples that I am taking at 1 minute intervals over 24 hours. This represents a percentage of speed / uptime. Is there an easy way to calculate an average of these 1440 samples to display on a dashboard?

Hi @jjansen,

I would recommend that you use a macro to calculate this average, here is an example that may be suitable for this application:

  1. Within the “Project” tab click “Macro”:

  2. Within the following menu, click “New”:

  3. Follow the instructions within this post to implement a GetData() command and pull the sampled data into the macro:
    Note: In this example I’m retrieving data from LW-59. You may need a variable to hold the total sum and average and a variable to count the number of samples. The data type I am reading this example is a short, but please configure the data type of the variable used within GetData() such that it matches the type sampled.

  4. Store the total count within HMI memory, in this example I am storing the count within LW-1000:
    Note: Information related to the SetData() command can be found within the post mentioned above as well.

  5. Add the current data to a running total and save this data within HMI memory as well:

  6. Calculate the average and set this within HMI memory:

  7. Enable periodical execution and run this macro every one minute:

  8. Click “Save & Compile” when finished:

Here is a link to a demo project: Link

My concern is that I have 1440 samples, each representing 1 minute of data. Wouldn’t I have to have 1440 GetData() calls to read in the values?


Is each sample obtained from a different register or tag within the external device or is this data read into the same register at one minute intervals?

A single register at intervals. The plan was to use the Data Sampling under Data/History to keep 24 hours worth, and hopefully summarize it from in there. Ultimately there are 35 production lines to do all of this with.


If it is only a single register, then you can develop a solution using the example mentioned above. The GetData() will occur at 1 minute intervals due to periodical execution. It will retain a running total and average based on the current sample count. I would recommend that you reset the total and count registers daily to ensure that these values remain within a valid range.

I need to do a rolling average of the last 24 hours. Can I pull data from the Data Sampling like a FIFO so as I add the latest minute, I can remove the minute from 24 hours ago?

Or some way to maintain a FIFO that doesn’t involve 1440 GetData() and SetData() commands?


Can you please advise the data type of the data you would like to average? I will try to give you an example of a queue as defined within our macro shortly.

I will be using integer data. Updates come in at 60 second intervals, and I plan to keep 24 hours (1440 samples) as a “Last 24 hours” display in a rolling queue.

FWIW: I have found a way and decided to use Codesys for this instead, as I have easier access to arrays. Thanks for the help!

Hi @jjansen,

Thank you for the update, if you have time it would be great if you can post the solution you’ve developed or a brief description of it on our forum for anyone else that might have this question. Have a great day!

running : BOOL;
runSeconds : WORD;
avg24H : REAL;
snapshot : BOOL;
active : ARRAY[0…60] OF BOOL;
history24H : ARRAY[0…1440] OF BYTE;
secondCount : INT;
calcAvg : DWORD;
i : INT;

// Function is called every 1 second
secondCount := secondCount + 1;

// Once per minute, reset the second counter and set the snapshot bit for 1 scan
IF (secondCount = 60) THEN
secondCount := 0;
snapshot := TRUE;
snapshot :=FALSE;

// Active array tracks each seconds status
active[secondCount] := running;

// Generate a rolling average for the current minute
calcAvg := 0;
FOR i := 0 TO 59 DO
IF(active[i] = TRUE) THEN
calcAvg := calcAvg + 1;

// Set the runSecond output for display
runSeconds := DWORD_TO_WORD(calcAvg);

// Each minute, recalculate the 24 hour rolling average
IF(snapshot = TRUE) THEN
calcAvg := 0;
FOR i:= 0 TO 1439 DO
history24H[i] := history24H[i+1];
calcAvg := calcAvg + history24H[i];
history24H[1440] := WORD_TO_BYTE(runSeconds);
calcAvg := calcAvg + runSeconds;
avg24H := 100.0*(DWORD_TO_REAL(calcAvg) / 86400); // 86,400 seconds in 24 hours. X100 to get a percentage