Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Implementing a moving average

Implementing a moving average

Scheduled Pinned Locked Moved C#
tutorialcsharplinqgraphicsiot
28 Posts 6 Posters 3 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    auting82
    wrote on last edited by
    #1

    Really struggling with these fairly simple thing. I have some sensor values randomly generated from a class I call Sensor.cs. I use GeAnaloValues() method to get these values and display them in a text box i Form1.cs in the GUI. Now I need to make moving average filter and take moving average of the for example last 5 sensor values displayed on the screen. I just don't know how to implement these values generated from the method GetAnalogValues() in the moving average algorithm ? :confused: I also wonder if I should make a separate class for the implementation of the MA-Filter? This is my code: Form1.cs class

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.IO;
    using System.Xml.Linq;
    using System.Windows.Forms;
    using System.Globalization;

    namespace DAQ_Simulator
    {
    public partial class Form1 : Form
    {
    int counter;
    int count_lines;
    System.Timers.Timer t;

        //Log time varibles
        int LoggingTime=56;
        int LogTimeLeft;
    
        //Sampling variables
        float SamplingTime = 5.9f;
        
        private int clickcounter;
    
        private DateTime datetime;
        private DateTime datetime2;
        private DateTime NextLoggingTime;
        int maxAI = 7;
        int maxDI = 3;
        int maxSid = 9;
        String sTxt;
        String sTxt1;
        
        // Create an array of 10 sensor objects
        Sensor\[\] sObj = new Sensor\[10\];
        MA\_Filter\[\] fObj = new MA\_Filter\[10\];
        public Form1()
        {
            InitializeComponent();
    
            for (counter = 0; counter < maxSid; counter++)
            {
                sObj\[counter\] = new Sensor(counter);
                //fObj\[counter\] = new MA\_Filter(counter, 10); //Create filters
            }
        }
        private void displaySensorData(object sender, EventArgs e)
        {
        }
        private void groupSampl\_Enter(object sender, EventArgs e)
        {
    
        }
        private void textSampling\_TextChanged(object sender, EventArgs e)
        {
    
    
    
        }
        private void btnSampling\_Click(object sender, EventArgs e)
        {
            clickcounter++;
            if (clickcounter == 1)
            {
                textSensorValues.Text = "TimeStamp        AI.1,      AI.2,      AI.3,      AI.4,      AI.5,      AI.6,    AI.7,
    
    OriginalGriffO L 2 Replies Last reply
    0
    • A auting82

      Really struggling with these fairly simple thing. I have some sensor values randomly generated from a class I call Sensor.cs. I use GeAnaloValues() method to get these values and display them in a text box i Form1.cs in the GUI. Now I need to make moving average filter and take moving average of the for example last 5 sensor values displayed on the screen. I just don't know how to implement these values generated from the method GetAnalogValues() in the moving average algorithm ? :confused: I also wonder if I should make a separate class for the implementation of the MA-Filter? This is my code: Form1.cs class

      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.Data;
      using System.Drawing;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      using System.IO;
      using System.Xml.Linq;
      using System.Windows.Forms;
      using System.Globalization;

      namespace DAQ_Simulator
      {
      public partial class Form1 : Form
      {
      int counter;
      int count_lines;
      System.Timers.Timer t;

          //Log time varibles
          int LoggingTime=56;
          int LogTimeLeft;
      
          //Sampling variables
          float SamplingTime = 5.9f;
          
          private int clickcounter;
      
          private DateTime datetime;
          private DateTime datetime2;
          private DateTime NextLoggingTime;
          int maxAI = 7;
          int maxDI = 3;
          int maxSid = 9;
          String sTxt;
          String sTxt1;
          
          // Create an array of 10 sensor objects
          Sensor\[\] sObj = new Sensor\[10\];
          MA\_Filter\[\] fObj = new MA\_Filter\[10\];
          public Form1()
          {
              InitializeComponent();
      
              for (counter = 0; counter < maxSid; counter++)
              {
                  sObj\[counter\] = new Sensor(counter);
                  //fObj\[counter\] = new MA\_Filter(counter, 10); //Create filters
              }
          }
          private void displaySensorData(object sender, EventArgs e)
          {
          }
          private void groupSampl\_Enter(object sender, EventArgs e)
          {
      
          }
          private void textSampling\_TextChanged(object sender, EventArgs e)
          {
      
      
      
          }
          private void btnSampling\_Click(object sender, EventArgs e)
          {
              clickcounter++;
              if (clickcounter == 1)
              {
                  textSensorValues.Text = "TimeStamp        AI.1,      AI.2,      AI.3,      AI.4,      AI.5,      AI.6,    AI.7,
      
      OriginalGriffO Offline
      OriginalGriffO Offline
      OriginalGriff
      wrote on last edited by
      #2

      For starters, don't use two Random instances:

              rSensVal = new Random(id);
              digSensVal = new Random(id);
      

      Because they are initialized with the same value, they will have the same sequence - use a single instance (or better a single static instance) and you will get a "more random" set of values. You might want to consider using the parameterless version of the constructor, which uses the system clock as the seed value so it gives a different sequence each time your app runs. For a moving average, just add an array of values the same size as the group, an index, and a count. This will become a basic queue. So for five values, you would have five elements:

      private double[] samples = new double[5];
      private int index = 0;
      private int count = 0;

      Then its just a case of a simple method:

          private double GetMovingAverage(double newValue)
              {
              // Insert
              if (count != samples.Length) count++;
              samples\[index++\] = newValue;
              if (index == samples.Length) index = 0;
              // Get average
              double sum = 0.0;
              for (int i = 0; i < count; i++)
                  {
                  sum += samples\[i\];
                  }
              return sum / (double) (count);
              }
      

      And you are done.

      Bad command or file name. Bad, bad command! Sit! Stay! Staaaay... AntiTwitter: @DalekDave is now a follower!

      "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
      "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

      A R 2 Replies Last reply
      0
      • OriginalGriffO OriginalGriff

        For starters, don't use two Random instances:

                rSensVal = new Random(id);
                digSensVal = new Random(id);
        

        Because they are initialized with the same value, they will have the same sequence - use a single instance (or better a single static instance) and you will get a "more random" set of values. You might want to consider using the parameterless version of the constructor, which uses the system clock as the seed value so it gives a different sequence each time your app runs. For a moving average, just add an array of values the same size as the group, an index, and a count. This will become a basic queue. So for five values, you would have five elements:

        private double[] samples = new double[5];
        private int index = 0;
        private int count = 0;

        Then its just a case of a simple method:

            private double GetMovingAverage(double newValue)
                {
                // Insert
                if (count != samples.Length) count++;
                samples\[index++\] = newValue;
                if (index == samples.Length) index = 0;
                // Get average
                double sum = 0.0;
                for (int i = 0; i < count; i++)
                    {
                    sum += samples\[i\];
                    }
                return sum / (double) (count);
                }
        

        And you are done.

        Bad command or file name. Bad, bad command! Sit! Stay! Staaaay... AntiTwitter: @DalekDave is now a follower!

        A Offline
        A Offline
        auting82
        wrote on last edited by
        #3

        OriginalGriff, a bit confused in terms how I should implement the code you gave me here to my program? I am assuming that method GetMovingAverage() shall be in the main class Form1.cs, correct ?:confused: Also I tried to put in your code snippet, but what is newValue here?? Is that my AnalogValues? I have a series of "random" sensor values every time I click Sampling button. I tried to do something like this :~

        private double GetMovingAverage(double AnalogValue)
        {
        // Insert
        if (count != samples.Length) count++;
        samples[index++] = AnalogValue;
        if (index == samples.Length) index = 0;
        // Get average
        double sum = 0.0;
        for (int i = 0; i < count; i++)
        {
        sum += samples[i];
        }
        return sum / (double)(count);
        }

        I tried to print the Moving average values here,

        for (int id = 0; id < maxAI; id++)
        {

                    double AnalogSensorValues = sObj\[id\].GetAnalogValue();
                  // double MovingAverageValues= fObj\[id\].MA\_Filter(AnalogSensorValues);
        
        
                    //  double FilterValues=fObj\[id\].
                    sTxt = AnalogSensorValues.ToString("F3");
                  //  fTx1 = MovingAverageValues.ToString("F3");
                    textSensorValues.Text += sTxt + "    ";
                    txtFilterValues.Text = fTx1;
                
                    txtFilterValues.Text = GetMovingAverage(id).ToString("F3");
        
        
                }
        

        However when I printed to my Filter text box, I got rubbish :( I must have misinterpreted what you meant. My main problem is I don't know how I get those values inside the moving average. Any comments ?

        R 1 Reply Last reply
        0
        • OriginalGriffO OriginalGriff

          For starters, don't use two Random instances:

                  rSensVal = new Random(id);
                  digSensVal = new Random(id);
          

          Because they are initialized with the same value, they will have the same sequence - use a single instance (or better a single static instance) and you will get a "more random" set of values. You might want to consider using the parameterless version of the constructor, which uses the system clock as the seed value so it gives a different sequence each time your app runs. For a moving average, just add an array of values the same size as the group, an index, and a count. This will become a basic queue. So for five values, you would have five elements:

          private double[] samples = new double[5];
          private int index = 0;
          private int count = 0;

          Then its just a case of a simple method:

              private double GetMovingAverage(double newValue)
                  {
                  // Insert
                  if (count != samples.Length) count++;
                  samples\[index++\] = newValue;
                  if (index == samples.Length) index = 0;
                  // Get average
                  double sum = 0.0;
                  for (int i = 0; i < count; i++)
                      {
                      sum += samples\[i\];
                      }
                  return sum / (double) (count);
                  }
          

          And you are done.

          Bad command or file name. Bad, bad command! Sit! Stay! Staaaay... AntiTwitter: @DalekDave is now a follower!

          R Offline
          R Offline
          Rob Philpott
          wrote on last edited by
          #4

          Nice, but how about ditching the loop? Just add the newValue to the sum (as a member, not local) each time, then deduct the number which it replaces in the array and you've just reduced the algorithmic complexity. I know, I'm just in one of those picky moods today.

          Regards, Rob Philpott.

          OriginalGriffO 1 Reply Last reply
          0
          • A auting82

            OriginalGriff, a bit confused in terms how I should implement the code you gave me here to my program? I am assuming that method GetMovingAverage() shall be in the main class Form1.cs, correct ?:confused: Also I tried to put in your code snippet, but what is newValue here?? Is that my AnalogValues? I have a series of "random" sensor values every time I click Sampling button. I tried to do something like this :~

            private double GetMovingAverage(double AnalogValue)
            {
            // Insert
            if (count != samples.Length) count++;
            samples[index++] = AnalogValue;
            if (index == samples.Length) index = 0;
            // Get average
            double sum = 0.0;
            for (int i = 0; i < count; i++)
            {
            sum += samples[i];
            }
            return sum / (double)(count);
            }

            I tried to print the Moving average values here,

            for (int id = 0; id < maxAI; id++)
            {

                        double AnalogSensorValues = sObj\[id\].GetAnalogValue();
                      // double MovingAverageValues= fObj\[id\].MA\_Filter(AnalogSensorValues);
            
            
                        //  double FilterValues=fObj\[id\].
                        sTxt = AnalogSensorValues.ToString("F3");
                      //  fTx1 = MovingAverageValues.ToString("F3");
                        textSensorValues.Text += sTxt + "    ";
                        txtFilterValues.Text = fTx1;
                    
                        txtFilterValues.Text = GetMovingAverage(id).ToString("F3");
            
            
                    }
            

            However when I printed to my Filter text box, I got rubbish :( I must have misinterpreted what you meant. My main problem is I don't know how I get those values inside the moving average. Any comments ?

            R Offline
            R Offline
            Ralf Meier
            wrote on last edited by
            #5

            You should give your actual Analogue-Value to the Method from OG (as it's parameter) and you will get the Average-Value as Result back from this method. The Variables 'Count' and 'Samples' and 'Index' must be declared outside this method ...

            1 Reply Last reply
            0
            • R Rob Philpott

              Nice, but how about ditching the loop? Just add the newValue to the sum (as a member, not local) each time, then deduct the number which it replaces in the array and you've just reduced the algorithmic complexity. I know, I'm just in one of those picky moods today.

              Regards, Rob Philpott.

              OriginalGriffO Offline
              OriginalGriffO Offline
              OriginalGriff
              wrote on last edited by
              #6

              Yeah, but he seems to be a beginner, so I thought I'd make it as obvious as possible. I'd probably make it a MovingAverage<T> class in my code, and complicate it that way! :laugh:

              Bad command or file name. Bad, bad command! Sit! Stay! Staaaay... AntiTwitter: @DalekDave is now a follower!

              "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
              "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

              A 1 Reply Last reply
              0
              • OriginalGriffO OriginalGriff

                Yeah, but he seems to be a beginner, so I thought I'd make it as obvious as possible. I'd probably make it a MovingAverage<T> class in my code, and complicate it that way! :laugh:

                Bad command or file name. Bad, bad command! Sit! Stay! Staaaay... AntiTwitter: @DalekDave is now a follower!

                A Offline
                A Offline
                auting82
                wrote on last edited by
                #7

                Yes I am a beginner :laugh: Now I made some slight changes and I am getting average of the last 5 numbers, but still my problems is not solved :(( When I generate my Sensor values in the text box , they appear like this: TimeStamp AI.1 AI.2 AI.3 AI.4 AI.5 AI.6 AI.7 13:29:05.091 0.726 0.249 0.771 0.294 0.816 0.338 0.861 13:30:40.325 0.817 0.111 0.404 0.698 0.991 0.284 0.962 13:31:19.709 0.768 0.467 0.166 0.865 0.564 0.263 0.915 13:32:00.943 0.558 0.772 0.985 0.198 0.412 0.625 0.594 13:32:31.391 0.206 0.658 0.109 0.560 0.012 0.463 0.720 What happens is that program calculates average of the last five numbers in the text box which means in this case Moving Average=(0.109+0.560+0.012+0.463+0.720)/5=0.373. While the moving average for example for AI.1 would be:(0.726+0.817+0.758+0.558+0.206)/5=0.615 This is obviously Wrong as I am getting average of the values from different sensors. I need average of the last five values for Sensor AI.1, AI2,....etc So I need to make some more changes to get this done. Here is the code I have changed: No changes to your method:

                private double GetMovingAverage(double newVal)
                {
                // Insert
                if (count != samples.Length) count++;
                samples[index++] = newVal;
                if (index == samples.Length) index = 0;
                // Get average
                double sum = 0.0;
                for (int i = 0; i < count; i++)
                {
                sum += samples[i];
                }
                return sum / (double)(count);
                }

                The method was implemented like this:

                for (int id = 0; id < maxAI; id++)
                {

                            double AnalogSensorValues = sObj\[id\].GetAnalogValue();
                          // double MovingAverageValues= fObj\[id\].MA\_Filter(AnalogSensorValues);
                
                
                           
                            sTxt = AnalogSensorValues.ToString("F3");
                         
                            textSensorValues.Text += sTxt + "    ";
                            txtFilterValues.Text = fTx1;
                        
                            txtFilterValues.Text = GetMovingAverage(AnalogSensorValues).ToString("F3");
                        }
                
                OriginalGriffO 1 Reply Last reply
                0
                • A auting82

                  Yes I am a beginner :laugh: Now I made some slight changes and I am getting average of the last 5 numbers, but still my problems is not solved :(( When I generate my Sensor values in the text box , they appear like this: TimeStamp AI.1 AI.2 AI.3 AI.4 AI.5 AI.6 AI.7 13:29:05.091 0.726 0.249 0.771 0.294 0.816 0.338 0.861 13:30:40.325 0.817 0.111 0.404 0.698 0.991 0.284 0.962 13:31:19.709 0.768 0.467 0.166 0.865 0.564 0.263 0.915 13:32:00.943 0.558 0.772 0.985 0.198 0.412 0.625 0.594 13:32:31.391 0.206 0.658 0.109 0.560 0.012 0.463 0.720 What happens is that program calculates average of the last five numbers in the text box which means in this case Moving Average=(0.109+0.560+0.012+0.463+0.720)/5=0.373. While the moving average for example for AI.1 would be:(0.726+0.817+0.758+0.558+0.206)/5=0.615 This is obviously Wrong as I am getting average of the values from different sensors. I need average of the last five values for Sensor AI.1, AI2,....etc So I need to make some more changes to get this done. Here is the code I have changed: No changes to your method:

                  private double GetMovingAverage(double newVal)
                  {
                  // Insert
                  if (count != samples.Length) count++;
                  samples[index++] = newVal;
                  if (index == samples.Length) index = 0;
                  // Get average
                  double sum = 0.0;
                  for (int i = 0; i < count; i++)
                  {
                  sum += samples[i];
                  }
                  return sum / (double)(count);
                  }

                  The method was implemented like this:

                  for (int id = 0; id < maxAI; id++)
                  {

                              double AnalogSensorValues = sObj\[id\].GetAnalogValue();
                            // double MovingAverageValues= fObj\[id\].MA\_Filter(AnalogSensorValues);
                  
                  
                             
                              sTxt = AnalogSensorValues.ToString("F3");
                           
                              textSensorValues.Text += sTxt + "    ";
                              txtFilterValues.Text = fTx1;
                          
                              txtFilterValues.Text = GetMovingAverage(AnalogSensorValues).ToString("F3");
                          }
                  
                  OriginalGriffO Offline
                  OriginalGriffO Offline
                  OriginalGriff
                  wrote on last edited by
                  #8

                  If you want separate moving averages, then you want to set up separate values stores - the array in my code is what you need for a single sensor, for t=five sensors you need five arrays. The way I would do it is to set up a MovingAverage class, with its own count, index, and array, and move the method to that. Then in your "main code" you create five instances of the MovingAverage class and use one for each sensor. Does that make sense? (Remember, I don't know what "level" of beginner you are! :laugh:)

                  Bad command or file name. Bad, bad command! Sit! Stay! Staaaay... AntiTwitter: @DalekDave is now a follower!

                  "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
                  "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

                  A 1 Reply Last reply
                  0
                  • OriginalGriffO OriginalGriff

                    If you want separate moving averages, then you want to set up separate values stores - the array in my code is what you need for a single sensor, for t=five sensors you need five arrays. The way I would do it is to set up a MovingAverage class, with its own count, index, and array, and move the method to that. Then in your "main code" you create five instances of the MovingAverage class and use one for each sensor. Does that make sense? (Remember, I don't know what "level" of beginner you are! :laugh:)

                    Bad command or file name. Bad, bad command! Sit! Stay! Staaaay... AntiTwitter: @DalekDave is now a follower!

                    A Offline
                    A Offline
                    auting82
                    wrote on last edited by
                    #9

                    I am a complete beginner, started with C# like days ago.What you are saying makes sense :) , but another thing is how to do it?:confused: What confuses me generally are arrays, I have noticed I find working with those challenging right now. :(

                    OriginalGriffO R 2 Replies Last reply
                    0
                    • A auting82

                      I am a complete beginner, started with C# like days ago.What you are saying makes sense :) , but another thing is how to do it?:confused: What confuses me generally are arrays, I have noticed I find working with those challenging right now. :(

                      OriginalGriffO Offline
                      OriginalGriffO Offline
                      OriginalGriff
                      wrote on last edited by
                      #10

                      If you are having difficulty with arrays, then you probably need to shelve this project for a while - a week or two maybe - and focus on learning the basics before you continue to work on it. Classes, arrays, and so forth are the "Building blocks" of the language, and you really do need to understand them properly before you get much beyond "Hello world!" :laugh: If you don't, then you will end up with something that works - probably - but you have no real idea of how or why, and that means that it becomes unmaintainable which is very bad news! I can't teach you classes - there is far too much for a little text box like this, and I can't see when your eyes start to glaze over - and the only other way to do this is to have arrays of arrays, and several arrays of integers, which gets extremely clumsy and hard to read very, very quickly. Seriously: go back to your book - or your course - and follow it through. trying to jump ahead to "the interesting stuff" just leaves huge holes in your knowledge that makes more complicated things very difficult to work out.

                      Bad command or file name. Bad, bad command! Sit! Stay! Staaaay... AntiTwitter: @DalekDave is now a follower!

                      "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
                      "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

                      1 Reply Last reply
                      0
                      • A auting82

                        Really struggling with these fairly simple thing. I have some sensor values randomly generated from a class I call Sensor.cs. I use GeAnaloValues() method to get these values and display them in a text box i Form1.cs in the GUI. Now I need to make moving average filter and take moving average of the for example last 5 sensor values displayed on the screen. I just don't know how to implement these values generated from the method GetAnalogValues() in the moving average algorithm ? :confused: I also wonder if I should make a separate class for the implementation of the MA-Filter? This is my code: Form1.cs class

                        using System;
                        using System.Collections.Generic;
                        using System.ComponentModel;
                        using System.Data;
                        using System.Drawing;
                        using System.Linq;
                        using System.Text;
                        using System.Threading.Tasks;
                        using System.IO;
                        using System.Xml.Linq;
                        using System.Windows.Forms;
                        using System.Globalization;

                        namespace DAQ_Simulator
                        {
                        public partial class Form1 : Form
                        {
                        int counter;
                        int count_lines;
                        System.Timers.Timer t;

                            //Log time varibles
                            int LoggingTime=56;
                            int LogTimeLeft;
                        
                            //Sampling variables
                            float SamplingTime = 5.9f;
                            
                            private int clickcounter;
                        
                            private DateTime datetime;
                            private DateTime datetime2;
                            private DateTime NextLoggingTime;
                            int maxAI = 7;
                            int maxDI = 3;
                            int maxSid = 9;
                            String sTxt;
                            String sTxt1;
                            
                            // Create an array of 10 sensor objects
                            Sensor\[\] sObj = new Sensor\[10\];
                            MA\_Filter\[\] fObj = new MA\_Filter\[10\];
                            public Form1()
                            {
                                InitializeComponent();
                        
                                for (counter = 0; counter < maxSid; counter++)
                                {
                                    sObj\[counter\] = new Sensor(counter);
                                    //fObj\[counter\] = new MA\_Filter(counter, 10); //Create filters
                                }
                            }
                            private void displaySensorData(object sender, EventArgs e)
                            {
                            }
                            private void groupSampl\_Enter(object sender, EventArgs e)
                            {
                        
                            }
                            private void textSampling\_TextChanged(object sender, EventArgs e)
                            {
                        
                        
                        
                            }
                            private void btnSampling\_Click(object sender, EventArgs e)
                            {
                                clickcounter++;
                                if (clickcounter == 1)
                                {
                                    textSensorValues.Text = "TimeStamp        AI.1,      AI.2,      AI.3,      AI.4,      AI.5,      AI.6,    AI.7,
                        
                        L Offline
                        L Offline
                        Lost User
                        wrote on last edited by
                        #11

                        Into the deep...

                             double\[\] values = new double\[\] { 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 2.0 };
                             double avg = ( values.Length > 0 ) ? values.Reverse().Take( 5 ).Average() : 0;
                        
                             Console.WriteLine( $"Avg: {avg}" );
                        

                        "(I) am amazed to see myself here rather than there ... now rather than then". ― Blaise Pascal

                        1 Reply Last reply
                        0
                        • A auting82

                          I am a complete beginner, started with C# like days ago.What you are saying makes sense :) , but another thing is how to do it?:confused: What confuses me generally are arrays, I have noticed I find working with those challenging right now. :(

                          R Offline
                          R Offline
                          Ralf Meier
                          wrote on last edited by
                          #12

                          There is also another way to build this Average without using an array - but the base-problem is the same : it is necessary to know what the code does and how it works. Independant from this - here is another Code-Solution :

                          int CountAct = 0;
                          double ValueLast = 0;
                          
                          public double getAverage(double actValue, int Smoothing)
                          {
                              if (Smoothing < 1)
                                  Smoothing = 1;
                              CountAct = Math.Min(CountAct + 1, Smoothing);
                              double myDivider = Math.Max((double)CountAct - 1, 0);
                              double Result = (ValueLast \* myDivider + actValue) / (myDivider + 1);
                              ValueLast = Result;
                              return Result;
                          }
                          

                          Here you can build an average from as much values you like - you only have to tell the method the smoothing-value you like to have ...

                          A 1 Reply Last reply
                          0
                          • R Ralf Meier

                            There is also another way to build this Average without using an array - but the base-problem is the same : it is necessary to know what the code does and how it works. Independant from this - here is another Code-Solution :

                            int CountAct = 0;
                            double ValueLast = 0;
                            
                            public double getAverage(double actValue, int Smoothing)
                            {
                                if (Smoothing < 1)
                                    Smoothing = 1;
                                CountAct = Math.Min(CountAct + 1, Smoothing);
                                double myDivider = Math.Max((double)CountAct - 1, 0);
                                double Result = (ValueLast \* myDivider + actValue) / (myDivider + 1);
                                ValueLast = Result;
                                return Result;
                            }
                            

                            Here you can build an average from as much values you like - you only have to tell the method the smoothing-value you like to have ...

                            A Offline
                            A Offline
                            auting82
                            wrote on last edited by
                            #13

                            Thanks for the reply. Don't see exactly how this code snippet is gonna solve my exact problem, but thanks anyways :). Original Griff's code for getting the moving average of the last five values works , but problem is as I mentioned that I am getting moving average of last 5 values displayed on the screen and they are from different sensors so that obviously gives undesirable result. I need to make some sort of array to store my past values for the respective sensors and than apply the GetMovingAverage() on each of the stored arrays. The thing is I don't know how to do that :confused: :omg: :~

                            P R 2 Replies Last reply
                            0
                            • A auting82

                              Thanks for the reply. Don't see exactly how this code snippet is gonna solve my exact problem, but thanks anyways :). Original Griff's code for getting the moving average of the last five values works , but problem is as I mentioned that I am getting moving average of last 5 values displayed on the screen and they are from different sensors so that obviously gives undesirable result. I need to make some sort of array to store my past values for the respective sensors and than apply the GetMovingAverage() on each of the stored arrays. The thing is I don't know how to do that :confused: :omg: :~

                              P Offline
                              P Offline
                              Pete OHanlon
                              wrote on last edited by
                              #14

                              Alternatively, you could have a dictionary of moving average objects; one for each sensor. It shouldn't be too hard for you to modify Griff's code to do this (hint, each sensor would be a key in the dictionary).

                              This space for rent

                              1 Reply Last reply
                              0
                              • A auting82

                                Thanks for the reply. Don't see exactly how this code snippet is gonna solve my exact problem, but thanks anyways :). Original Griff's code for getting the moving average of the last five values works , but problem is as I mentioned that I am getting moving average of last 5 values displayed on the screen and they are from different sensors so that obviously gives undesirable result. I need to make some sort of array to store my past values for the respective sensors and than apply the GetMovingAverage() on each of the stored arrays. The thing is I don't know how to do that :confused: :omg: :~

                                R Offline
                                R Offline
                                Ralf Meier
                                wrote on last edited by
                                #15

                                The difference between my Solution and the Solution from OG is that my Solution don't need an Array for building a single Average. Another difference is that the smoothing is variable. If you want to build also an average from the average of some sensors you need to add the values of the sensor-averages and divide it throught the count of the sensors which are added. But that was allready mentioned by OG ... where do you stuck there ?

                                SumAverage := (Sensor_1_Average + Sensor_2_Average + Sensor_3_Average + Sensor_4_Average + Sensor_5_Average) / 5.0 ;

                                A 1 Reply Last reply
                                0
                                • R Ralf Meier

                                  The difference between my Solution and the Solution from OG is that my Solution don't need an Array for building a single Average. Another difference is that the smoothing is variable. If you want to build also an average from the average of some sensors you need to add the values of the sensor-averages and divide it throught the count of the sensors which are added. But that was allready mentioned by OG ... where do you stuck there ?

                                  SumAverage := (Sensor_1_Average + Sensor_2_Average + Sensor_3_Average + Sensor_4_Average + Sensor_5_Average) / 5.0 ;

                                  A Offline
                                  A Offline
                                  auting82
                                  wrote on last edited by
                                  #16

                                  Hi, OG's Moving Average works fine. The problem is I am not able to apply it to the proper values. It should be simple thing to fix, but its not. As I said in one of the posts above. I get the Moving Average, means I get the average of the last 5 numbers , but I need to get it for each sensor column not row wise as I am currently. See the explanation below. Ho do I fix that ??:confused: TimeStamp AI.1 AI.2 AI.3 AI.4 AI.5 AI.6 AI.7 13:29:05.091 0.726 0.249 0.771 0.294 0.816 0.338 0.861 13:30:40.325 0.817 0.111 0.404 0.698 0.991 0.284 0.962 13:31:19.709 0.768 0.467 0.166 0.865 0.564 0.263 0.915 13:32:00.943 0.558 0.772 0.985 0.198 0.412 0.625 0.594 13:32:31.391 0.206 0.658 0.109 0.560 0.012 0.463 0.720 What happens is that program calculates average of the last five numbers in the text box which means in this case Moving Average=(0.109+0.560+0.012+0.463+0.720)/5=0.373. While the moving average for example for AI.1 would be:(0.726+0.817+0.758+0.558+0.206)/5=0.615 This is obviously Wrong as I am getting average of the values from different sensors. I need average of the last five values for Sensor AI.1, AI2,....etc So I need to make some more changes to get this done.

                                  R 2 Replies Last reply
                                  0
                                  • A auting82

                                    Hi, OG's Moving Average works fine. The problem is I am not able to apply it to the proper values. It should be simple thing to fix, but its not. As I said in one of the posts above. I get the Moving Average, means I get the average of the last 5 numbers , but I need to get it for each sensor column not row wise as I am currently. See the explanation below. Ho do I fix that ??:confused: TimeStamp AI.1 AI.2 AI.3 AI.4 AI.5 AI.6 AI.7 13:29:05.091 0.726 0.249 0.771 0.294 0.816 0.338 0.861 13:30:40.325 0.817 0.111 0.404 0.698 0.991 0.284 0.962 13:31:19.709 0.768 0.467 0.166 0.865 0.564 0.263 0.915 13:32:00.943 0.558 0.772 0.985 0.198 0.412 0.625 0.594 13:32:31.391 0.206 0.658 0.109 0.560 0.012 0.463 0.720 What happens is that program calculates average of the last five numbers in the text box which means in this case Moving Average=(0.109+0.560+0.012+0.463+0.720)/5=0.373. While the moving average for example for AI.1 would be:(0.726+0.817+0.758+0.558+0.206)/5=0.615 This is obviously Wrong as I am getting average of the values from different sensors. I need average of the last five values for Sensor AI.1, AI2,....etc So I need to make some more changes to get this done.

                                    R Offline
                                    R Offline
                                    Ralf Meier
                                    wrote on last edited by
                                    #17

                                    You should read carefully what is suggested to you ... I would say : all what you need is told to you ...

                                    1 Reply Last reply
                                    0
                                    • A auting82

                                      Hi, OG's Moving Average works fine. The problem is I am not able to apply it to the proper values. It should be simple thing to fix, but its not. As I said in one of the posts above. I get the Moving Average, means I get the average of the last 5 numbers , but I need to get it for each sensor column not row wise as I am currently. See the explanation below. Ho do I fix that ??:confused: TimeStamp AI.1 AI.2 AI.3 AI.4 AI.5 AI.6 AI.7 13:29:05.091 0.726 0.249 0.771 0.294 0.816 0.338 0.861 13:30:40.325 0.817 0.111 0.404 0.698 0.991 0.284 0.962 13:31:19.709 0.768 0.467 0.166 0.865 0.564 0.263 0.915 13:32:00.943 0.558 0.772 0.985 0.198 0.412 0.625 0.594 13:32:31.391 0.206 0.658 0.109 0.560 0.012 0.463 0.720 What happens is that program calculates average of the last five numbers in the text box which means in this case Moving Average=(0.109+0.560+0.012+0.463+0.720)/5=0.373. While the moving average for example for AI.1 would be:(0.726+0.817+0.758+0.558+0.206)/5=0.615 This is obviously Wrong as I am getting average of the values from different sensors. I need average of the last five values for Sensor AI.1, AI2,....etc So I need to make some more changes to get this done.

                                      R Offline
                                      R Offline
                                      Ralf Meier
                                      wrote on last edited by
                                      #18

                                      A new day and I will try it once more to explain. The fact is : you don't understand what you got suggested. The Solution from OG and also the Solution from me builds the "moving Average" from the incoming values from ONE sensor - not from one timestanp. So - what both Solutions are doing is : take the raw-value of one sensor (that means the incoming actual value) and build an average with the saved/stored values from the same sensor - that means the values before). By this you get a kind of smoothing of the incoming values. The return-value (the result) of the posted method should be stored by you in your table. I suppose that you completly misunderstood the made Suggestions. If you now still don't know how to get further you should post your actual method which writes the incoming values in your table (or List or whatever). Perhaps then we could explain you the mistake you make ...

                                      A 2 Replies Last reply
                                      0
                                      • R Ralf Meier

                                        A new day and I will try it once more to explain. The fact is : you don't understand what you got suggested. The Solution from OG and also the Solution from me builds the "moving Average" from the incoming values from ONE sensor - not from one timestanp. So - what both Solutions are doing is : take the raw-value of one sensor (that means the incoming actual value) and build an average with the saved/stored values from the same sensor - that means the values before). By this you get a kind of smoothing of the incoming values. The return-value (the result) of the posted method should be stored by you in your table. I suppose that you completly misunderstood the made Suggestions. If you now still don't know how to get further you should post your actual method which writes the incoming values in your table (or List or whatever). Perhaps then we could explain you the mistake you make ...

                                        A Offline
                                        A Offline
                                        auting82
                                        wrote on last edited by
                                        #19

                                        Hi again Ralf and thanks for the patience. I understood what OG's method does in terms of the result I got. My problem is now how do I make this list to store my numbers that get generated by the GetAnalog Method. I would need to have historical analog values for each Sensor and then apply OG's method on each sensor array or list , whatever is made. Here is the GetAnalogMethod() from the Sensor.cs class,

                                        public double GetAnalogValue(double minAnalogVolt=0.00F,double maxAnalogVolt=1.00F)
                                        {
                                        if(minAnalogVolt <= AnalogVal && AnalogVal<= maxAnalogVolt) //defines measurement interval for sensor

                                                     AnalogVal = rSensVal.NextDouble(); //generates values between 0-1
                                                     return AnalogVal; //return a value        
                                            }
                                        

                                        In here I call this GetAnalogValue() method to generate "random" analog values for each of my sensor IDs:

                                        for (int id = 0; id < maxAI; id++)
                                        {
                                        double AnalogSensorValues = sObj[id].GetAnalogValue(); //for loops runs through the loop and inserts random number between 0-1 for each sensors ID
                                        sTxt = AnalogSensorValues.ToString("F3");//defines a string variable in order to print out sensor values
                                        textSensorValues.Text += sTxt + " ";//prints out sesnor values in text box
                                        txtFilterValues.Text = fTx1;//defines a string variable for moving average filtered values
                                        txtFilterValues.Text = GetMovingAverage(AnalogSensorValues).ToString("F3");//applies GetMoving Average method and prints the last fuive values in the textbox
                                        }

                                        If you see above I store all my sensor ID values in a double variable I call AnalogSensorValues.I should have ideally have had a list so that each value gets stored and can be accessed so that GetMoving Average() method can be applied to it. So yes, that is my problem. Basically sorting these values in a List. This may sound silly, but I don't know how to do it :~

                                        R 1 Reply Last reply
                                        0
                                        • A auting82

                                          Hi again Ralf and thanks for the patience. I understood what OG's method does in terms of the result I got. My problem is now how do I make this list to store my numbers that get generated by the GetAnalog Method. I would need to have historical analog values for each Sensor and then apply OG's method on each sensor array or list , whatever is made. Here is the GetAnalogMethod() from the Sensor.cs class,

                                          public double GetAnalogValue(double minAnalogVolt=0.00F,double maxAnalogVolt=1.00F)
                                          {
                                          if(minAnalogVolt <= AnalogVal && AnalogVal<= maxAnalogVolt) //defines measurement interval for sensor

                                                       AnalogVal = rSensVal.NextDouble(); //generates values between 0-1
                                                       return AnalogVal; //return a value        
                                              }
                                          

                                          In here I call this GetAnalogValue() method to generate "random" analog values for each of my sensor IDs:

                                          for (int id = 0; id < maxAI; id++)
                                          {
                                          double AnalogSensorValues = sObj[id].GetAnalogValue(); //for loops runs through the loop and inserts random number between 0-1 for each sensors ID
                                          sTxt = AnalogSensorValues.ToString("F3");//defines a string variable in order to print out sensor values
                                          textSensorValues.Text += sTxt + " ";//prints out sesnor values in text box
                                          txtFilterValues.Text = fTx1;//defines a string variable for moving average filtered values
                                          txtFilterValues.Text = GetMovingAverage(AnalogSensorValues).ToString("F3");//applies GetMoving Average method and prints the last fuive values in the textbox
                                          }

                                          If you see above I store all my sensor ID values in a double variable I call AnalogSensorValues.I should have ideally have had a list so that each value gets stored and can be accessed so that GetMoving Average() method can be applied to it. So yes, that is my problem. Basically sorting these values in a List. This may sound silly, but I don't know how to do it :~

                                          R Offline
                                          R Offline
                                          Ralf Meier
                                          wrote on last edited by
                                          #20

                                          I'm not sure if I got you right ... Basicly your 2nd code-snippet looks good. But ... what do you want to see in your Textbox 'txtFilterValues' ? Inside your loop you are overwriting each stored text with the new one ... My 2nd problem with your code is : You are using the method 'GetMovingAverage' completely wrong, because it builds it's average (as I described before) from it's own stored values (that you used for the method before). So your loop must be complete different (and in my opinion the posted method doesn't really solve your problem). Try as code something like this :

                                            double AnalogSensorAverage
                                            for (int id = 0; id < maxAI; id++)
                                                  {
                                                      double AnalogSensorValues = sObj\[id\].GetAnalogValue(); //for loops runs through the loop and inserts random number between 0-1 for each sensors ID
                                                      AnalogSensorAverage = GetMovingAverage(AnalogSensorValues);
                                          
                                                      sTxt = AnalogSensorValues.ToString("F3");//defines a string variable in order to print out sensor values
                                                      textSensorValues.Text += sTxt + "    ";//prints out sesnor values in text box 
                                                  }
                                                  txtFilterValues.Text = AnalogSensorAverage.ToString("F3");//applies GetMoving Average method and prints the last five values in the textbox
                                          
                                          A 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups