Click here to Skip to main content
14,550,550 members
Rate this:
Please Sign up or sign in to vote.
See more:
i have an data value which updates in every on second and i want to take average of it of one min.
i have tried this code but no result found.
please help

What I have tried:

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
   'Timer1 with intervel 1000ms    
    Dim OneSecPulse As Boolean
    Dim Data As Double
    Dim Total As Double
    Dim Average As Double
    Dim Counts As Integer

    OneSecPulse = True
    
    If OneSecPulse = True Then
        Counts = Counts + 1
        Total = Total + Data
        OneSecPulse = False
    End If

    If Counts = 60 Then
        Average = Total / 60
        Total = 0
        Counts = 0
    End If

End Sub
Posted
Updated 21-May-20 5:59am
v2
Comments
ZurdoDev 21-May-20 11:36am
   
Add them up and then divide. What's the problem?
F-ES Sitecore 21-May-20 11:48am
   
Your variables are all local to the tick event so get initialised to 0 every time it fires. You need to move the declaration of the count and total variables to class level so their values persist outside of the event.

1 solution

Rate this:
Please Sign up or sign in to vote.

Solution 1

Local variable values do not persist between calls to the method. Each time your Timer1_Tick method is called, all of the local variables will be set to their defaults.

You also don't have any code to retrieve the data - you're just adding 0 to the total each time.

You need to store the list of values in a field. Each time you add a new value, remove any values which are too old before you calculate the average.

A simple class to store the values might looks something like:
Imports System
Imports System.Collections.Generic
Imports System.Linq

Public Class RollingAverage
    Private ReadOnly _limit As Integer
    Private _values As Queue(Of Double)
    
    Public Sub New(ByVal limit As Integer)
        _limit = limit
        _values = New Queue(Of Double)
    End Sub
    
    Public Sub Add(ByVal value As Double)
        If _values.Count = _limit Then
            _values.Dequeue()
        End If
        
        _values.Enqueue(value)
    End Sub
    
    Public ReadOnly Property Count As Integer
        Get
            Return _values.Count
        End Get
    End Property
    
    Public ReadOnly Property Average As Double
        Get
            Return _values.Average()
        End Get
    End Property
End Class
Store an instance of that class in a field, and use it to calculating the averages:
Private _averages As New RollingAverage(60)

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    
    Dim data As Double = ... TODO: Get the data from somewhere ...
    
    _averages.Add(data)
    
    If _averages.Count = 60 Then
        Average = _averages.Average
    End If
End Sub
   
Comments
Maciej Los 21-May-20 16:26pm
   
Excellent!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100