Moving average sticks in fictitious zeroes for the first readings. This delays accuracy My 9/10 Moving Average inserts zeroes for the first 9 readings. For example, if the first voltage reading is 100, the first moving average given is 10. That is the average of 9 zeroes and one 100. How can I get the moving average to only use actual readings from the adc? Or how can I get the moving average to wait until at least 10 readings are finished before starting its calculations?

#include &lt;SPI.h&gt;
#include &lt;SoftwareSerial.h&gt;
#include &lt;math.h&gt;
#include &lt;ads1262.h&gt;

#define PGA 1 // Programmable Gain = 1
#define VREF 2.50 // Internal reference of 2.048V
#define VFSR VREF/PGA             
#define FSR (((long int)1&lt;&lt;23)-1)  

ads1262 PC_ADS1262; // class

float volt_V=0;
float volt_mV=0;
float MovingAverage=0;
volatile int i;
volatile char SPI_RX_Buff[10];
volatile long ads1262_rx_Data[10];
volatile static int SPI_RX_Buff_Count = 0;
volatile char *SPI_RX_Buff_Ptr;
volatile int Responsebyte = false;
volatile signed long sads1262Count = 0;
volatile signed long uads1262Count=0;
double resolution;

void setup() {
  // initalize the  data ready and chip select pins:
  pinMode(ADS1262_DRDY_PIN, INPUT); //data ready input line
  pinMode(ADS1262_CS_PIN, OUTPUT); //chip enable output line
  pinMode(ADS1262_START_PIN, OUTPUT);  // start
  pinMode(ADS1262_PWDN_PIN, OUTPUT); // Power down output
  Serial.begin(9600);
  //initalize ADS1292 slave
  PC_ADS1262.ads1262_Init(); // initialise ads1262
  Serial.println("ads1262 Initialised successfully....");
}

void loop() {
  volatile int i, data;
  if((digitalRead(ADS1262_DRDY_PIN)) == LOW) {
    // monitor Data   ready(DRDY pin)
    SPI_RX_Buff_Ptr = PC_ADS1262.ads1262_Read_Data();
    // read 6 bytes conversion register
    Responsebyte = true;
  }
  if(Responsebyte == true) {
    for(i = 0; i &lt;5; i++) {
      SPI_RX_Buff[SPI_RX_Buff_Count++] = *(SPI_RX_Buff_Ptr + i);
    }
    Responsebyte = false;
  }
  if(SPI_RX_Buff_Count &gt;= 5) {
    ads1262_rx_Data[0]= (unsigned char)SPI_RX_Buff[1];
    // read 4 bytes adc count
    ads1262_rx_Data[1]= (unsigned char)SPI_RX_Buff[2];
    ads1262_rx_Data[2]= (unsigned char)SPI_RX_Buff[3];
    ads1262_rx_Data[3]= (unsigned char)SPI_RX_Buff[4];
    uads1262Count = (signed long) (((unsigned long)ads1262_rx_Data[0]&lt;&lt;24)| ((unsigned long)ads1262_rx_Data[1]&lt;&lt;16)|(ads1262_rx_Data[2]&lt;&lt;8)|        ads1262_rx_Data[3]);
    //get the raw 32-bit adc count out by shifting
    sads1262Count = (signed long) (uads1262Count);
    // get signed value
    resolution = (double)((double)VREF/pow(2,31));
    //resolution=  Vref/(2^n-1) , Vref=2.5, n=no of bits
    volt_V = (resolution)*(float)sads1262Count;
    // voltage = resolution * adc count
    MovingAverage = (9*MovingAverage + volt_V)/10;
    Serial.print(MovingAverage,8);
  }
  SPI_RX_Buff_Count = 0;
}

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
There are essentially two ways of initializing a low pass filter. The
first is to let it initialize itself “naturally” by feeding it data
until it reaches its steady state. This is the approach of jwpat7's
answer, and it works really well with FIR filters, like a plain
moving average.

Your exponentially-weighted moving average, however, is an
IIR filter. Given constant input, it converges asymptotically to its
steady state. After feeding it 10 values, it will only have reached 65%
of the steady state (exactly 1&nbsp;−&nbsp;0.910), thus you
may want to feed it significantly more than 10 points. E.g., you should
give it 22 points if you want it to be 90% initialized.

The other approach is to provision a specific initialization procedure
that sets the internal state of the filter to what it would have been
had it processed an infinite stream of constant values. This is actually
really easy to do with this particular filter, as we only have to set
the output equal to its first input. Here is the self-initializing
filter written as a function (this keeps the code cleaner):

static float movingAverage(float x)
{
  static bool initialized;
  static float output;

  // Initialize the filter as if this input had been on forever.
  if (!initialized) {
    output = x;
    initialized = true;
  }

  output += 0.1 * (x - output);
  return output;
}


You loose the benefit of the averaging on the very first data points,
but in return you have a simple to use self-initializing filter.

Unrelated to your question, I looked at your code and fond so many
confusing and useless statements that I felt compelled to remove all
that cruft. I did not test the simplified version though:

#include &lt;ads1262.h&gt;

const float VREF = 2.50;  // Internal reference

ads1262 PC_ADS1262;  // ADC object

void setup() {
  // initialize the  data ready and chip select pins:
  pinMode(ADS1262_DRDY_PIN,  INPUT);   // data ready input line
  pinMode(ADS1262_CS_PIN,    OUTPUT);  // chip enable output line
  pinMode(ADS1262_START_PIN, OUTPUT);  // start
  pinMode(ADS1262_PWDN_PIN,  OUTPUT);  // power down output
  Serial.begin(9600);

  // initialize ADS1292 slave
  PC_ADS1262.ads1262_Init();
  Serial.println("ads1262 Initialised successfully....");
}

static float movingAverage(float x) { ... }  // as before

void loop() {
  // Nothing to do unless data ready is asserted.
  if (digitalRead(ADS1262_DRDY_PIN) == HIGH) return;

  // Get a reading and convert to voltage.
  uint8_t *buffer = (uint8_t *) PC_ADS1262.ads1262_Read_Data();
  signed long reading = (uint32_t) buffer[1] &lt;&lt; 24
                      | (uint32_t) buffer[2] &lt;&lt; 16
                      | (uint32_t) buffer[3] &lt;&lt;  8
                      | (uint32_t) buffer[4] &lt;&lt;  0;
  float voltage = VREF / (1UL&lt;&lt;31) * reading;

  // Report a smoothed-out reading.
  Serial.println(movingAverage(voltage), 8);
}