Smooth an Array of Analog Values and Print them
Posted: 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.
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);
}
}