Need help smoothing 4 input

Hi All,

I need help writing code for smoothing from 4 analog input, really new to the coding and just don't know how to alter from the example code. Any help would be greatly appreciated. :slight_smile:

const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average



void setup() {
  // initialize serial communication with computer:
  Serial.begin(9600);
  // initialize all the readings to 0:
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }
}

void loop() {
  // subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  readings[readIndex] = analogRead(inputPin);
  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;

  // if we're at the end of the array...
  if (readIndex >= numReadings) {
    // ...wrap around to the beginning:
    readIndex = 0;
  }

  // calculate the average:
  average = total / numReadings;
  // send it to the computer as ASCII digits
  Serial.println(average);
  delay(1);        // delay in between reads for stability
}

Just duplicate everything 4 times. Easiest way, arrays :slight_smile:

I found one post here..

smoothing multiple sensor

but no idea how to apply it in full code..anyone can help?

Yeah, sure. Show us what you tried. Why you think it should work. And how it fails (aka, what it really does).

Because the code you posted earlier does what you like only for a single input. Not that hard to have everything multiple times.

Just wrap the moving average in a class:

template <uint8_t N, class input_t = uint16_t, class sum_t = uint32_t>
class SMA {
  public:
    input_t operator()(input_t input) {
        sum -= previousInputs[index];
        sum += input;
        previousInputs[index] = input;
        if (++index == N)
            index = 0;
        return (sum + (N / 2)) / N;
        static_assert(
            sum_t(0) < sum_t(-1),  // Check that `sum_t` is an unsigned type
            "Error: sum data type should be an unsigned integer, otherwise, "
            "the rounding operation in the return statement is invalid.");
    }

  private:
    uint8_t index             = 0;
    input_t previousInputs[N] = {};
    sum_t sum                 = 0;
};

class FilteredAnalog {
  public:
    FilteredAnalog (uint8_t pin) : pin(pin) {}
    uint16_t read() {
        return filter(analogRead(pin));
    }
    uint8_t pin;
    SMA<10> filter;
};

FilteredAnalog inputs [] = {
  A0, A1, A2, A3
};

void setup() {
  Serial.begin(115200);
}

void loop() {
  for (auto &input : inputs) {
    Serial.print(input.read());
    Serial.print('\t');
  }
  Serial.println();
  delay(10);
}

(Untested code)

Pieter

PieterP:
Just wrap the moving average in a class:

C++ Implementation

template <uint8_t N, class input_t = uint16_t, class sum_t = uint32_t>

class SMA {
 public:
   input_t operator()(input_t input) {
       sum -= previousInputs[index];
       sum += input;
       previousInputs[index] = input;
       if (++index == N)
           index = 0;
       return (sum + (N / 2)) / N;
       static_assert(
           sum_t(0) < sum_t(-1),  // Check that sum_t is an unsigned type
           "Error: sum data type should be an unsigned integer, otherwise, "
           "the rounding operation in the return statement is invalid.");
   }

private:
   uint8_t index             = 0;
   input_t previousInputs[N] = {};
   sum_t sum                 = 0;
};

class FilteredAnalog {
 public:
   FilteredAnalog (uint8_t pin) : pin(pin) {}
   uint16_t read() {
       return filter(analogRead(pin));
   }
   uint8_t pin;
   SMA<10> filter;
};

FilteredAnalog inputs [] = {
 A0, A1, A2, A3
};

void setup() {
 Serial.begin(115200);
}

void loop() {
 for (auto &input : inputs) {
   Serial.print(input.read());
   Serial.print('\t');
 }
 Serial.println();
 delay(10);
}



(Untested code)

Pieter

Thanks Pieter..but i didn't know how to apply those..Lastly i just modified from the example.

const int numReadings = 10;

float readings1[numReadings];
float readings2[numReadings];
float readings3[numReadings];
float readings4[numReadings];

int readIndex = 0;              

float total1 = 0;int average1 = 0;                  
float total2 = 0;int average2 = 0;                  
float total3 = 0;int average3 = 0;                  
float total4 = 0;int average4 = 0;                   
              

void setup() {
  Serial.begin(9600);
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings1[thisReading] = 0;
    readings2[thisReading] = 0;
    readings3[thisReading] = 0;
    readings4[thisReading] = 0;
  }
}

void loop() {
  
  total1 = total1 - readings1[readIndex];
  total2 = total2 - readings2[readIndex];
  total3 = total3 - readings3[readIndex];
  total4 = total4 - readings4[readIndex];
  
  readings1[readIndex] = analogRead(A0);
  readings2[readIndex] = analogRead(A1);
  readings3[readIndex] = analogRead(A2);
  readings4[readIndex] = analogRead(A3);
  
  total1 = total1 + readings1[readIndex];
  total2 = total2 + readings2[readIndex];
  total3 = total3 + readings3[readIndex];
  total4 = total4 + readings4[readIndex];
  
  readIndex = readIndex + 1;

  if (readIndex >= numReadings) {
    readIndex = 0;
  }

  average1 = total1 / numReadings;
  average2 = total2 / numReadings;
  average3 = total3 / numReadings;
  average4 = total4 / numReadings;

  float voltage1 = average1 * (5.0 / 1023.0);
  float voltage2 = average2 * (5.0 / 1023.0);
  float voltage3 = average3 * (5.0 / 1023.0);
  float voltage4 = average4 * (5.0 / 1023.0);
  
  Serial.print(voltage1);Serial.print(", ");
  Serial.print(voltage2);Serial.print(",");
  Serial.print(voltage3);Serial.print(", ");
  Serial.println(voltage4);
    
  delay(1);        // delay in between reads for stability
}