Smooth an Array of Analog Values and Print them

knightridar
Posts: 15
Joined: Sun Nov 25, 2018 10:05 pm

Smooth an Array of Analog Values and Print them

Postby knightridar » Fri Nov 08, 2019 1:23 am

This code can be useful if anyone wants to get a bunch of analog values and smooth out the results and then output them after smoothing them.

The array helps to prevent repetition of code and so makes things more efficient.
I have to thank user 6v6gt on the Arduino forums for helping to complete it when I was totally lost with respect to multidimensional arrays.

This code is only reading ADC1 channel values because I read somewhere in the Espressif ESP32 documentation that WiFi can't be used if other certain channels are being used for ADC,etc. My application uses WiFi and ESP-Now.

However, for other non WiFi based applications people just have to add on the correct pins and duplicate the code as they make the array larger.

Code: Select all

// ESP32 adc conversion
#include <driver/adc.h>

// Define the number of samples to keep track of. The higher the number, the
// more the readings will be smoothed, but the slower the output will respond to
// the input. Using a constant rather than a normal variable lets us use this
// data to determine the size of the readings array.
const uint8_t numReadings = 64;
const uint8_t numSensors = 4;

uint32_t readings[numSensors][numReadings];   // multi-dimensional readings from analog input
uint32_t readIndex = 0;              // the index of the current reading
uint32_t total[numSensors] = {0};    // the running total
uint32_t average = 0;                // the average

// interval to stabilize analog input smoothing readings
// ADC1 Channel read time ~9.5µs per sample --> 64 readings x 9.5 = 608 µs = .608 ms
uint8_t numReadingsInterval = 2;
uint32_t numReadingsStart = 0;

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

  // Voltage divider analog in pins
  adc1_config_width(ADC_WIDTH_12Bit);
  adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_11); //Pin34

  adc1_config_width(ADC_WIDTH_12Bit);
  adc1_config_channel_atten(ADC1_CHANNEL_7, ADC_ATTEN_DB_11); //Pin35

  adc1_config_width(ADC_WIDTH_12Bit);
  adc1_config_channel_atten(ADC1_CHANNEL_1, ADC_ATTEN_DB_11); //Pin37

  adc1_config_width(ADC_WIDTH_12Bit);
  adc1_config_channel_atten(ADC1_CHANNEL_2, ADC_ATTEN_DB_11); //Pin38

  // initialize all the readings to 0
  // multidimensional array takes into account multiple sensors and multiple readings for each sensor
  for (uint8_t thisReading = 0; thisReading < numReadings; thisReading++)
  {
    for ( uint8_t j = 0; j < numSensors; j++)  readings[j][thisReading] = 0;
  }
}

//loop function being used to smooth analog input values
// void OnDataSent function sends values over and over again
void loop()
{
  if ( millis() - numReadingsStart >= numReadingsInterval * numReadings )
  {
    numReadingsStart = millis();

    // Read the sensor
    uint16_t AzimuthCW = adc1_get_raw(ADC1_CHANNEL_6); //Pin34
    uint16_t AzimuthCCW = adc1_get_raw(ADC1_CHANNEL_7); //Pin35

    uint16_t ElevationCW = adc1_get_raw(ADC1_CHANNEL_1); //Pin37
    uint16_t ElevationCCW = adc1_get_raw(ADC1_CHANNEL_2); //Pin38

    uint16_t  inputPin[ numSensors ] = {AzimuthCW, AzimuthCCW, ElevationCW, ElevationCCW};

    uint8_t ai;

    for (ai = 0; ai < numSensors ; ai++)
    {
      // subtract the last reading:
      total[ ai ] = total[ ai ] - readings[ai][readIndex];
      // read from the sensor:
      readings[ai][readIndex] = inputPin[ai];
      // add the reading to the total:
      total[ai] = total[ai] + readings[ai][readIndex];
      // calculate the average:
      average = total[ai] / numReadings;
    }

    // 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;
    }

    uint16_t ACW = total[0] / numReadings; // AzimuthCW
    uint16_t ACCW = total[1] / numReadings; // AzimuthCCW
    uint16_t ECW = total[2] / numReadings; // ElevationCW
    uint16_t ECCW = total[3] / numReadings; // ElevationCCW

    Serial.print("AzimuthCW: ");
    Serial.println(ACW);
    Serial.print("AzimuthCCW: ");
    Serial.println(ACCW);
    Serial.print("ElevationCW: ");
    Serial.println(ECW);
    Serial.print("ElevationCCW: ");
    Serial.println(ECCW);
  }
}

zekageri
Posts: 35
Joined: Mon Sep 03, 2018 11:04 am

Re: Smooth an Array of Analog Values and Print them

Postby zekageri » Mon Nov 11, 2019 10:01 am

Can i use it to measure on one pin a 4khz signal?

knightridar
Posts: 15
Joined: Sun Nov 25, 2018 10:05 pm

Re: Smooth an Array of Analog Values and Print them

Postby knightridar » Wed Nov 13, 2019 7:06 pm

https://esp32.com/viewtopic.php?f=2&t=1075&start=10

This is what I found hope it helps.
They claim 6 khz but results not so good.

tommeyers
Posts: 89
Joined: Tue Apr 17, 2018 1:51 pm
Location: Santiago, Dominican Republic

Re: Smooth an Array of Analog Values and Print them

Postby tommeyers » Thu Nov 14, 2019 12:21 am

It looks like an unweighted rolling average. All good. Is that correct?

Each type has different natures.

Tom Meyers
IT Professional, Maker
Santiago, Dominican Republic

Who is online

Users browsing this forum: No registered users and 8 guests