Calibrating Group of Analog Values and Smoothing them in Multidimensional Array

I am trying to:

  1. Create an array for calibration of multiple analog inputs
  2. Placing them in multidimensional array to smooth each one

I'm trying to combine these two examples basically:
https://www.arduino.cc/en/Tutorial/Calibration
https://www.arduino.cc/en/Tutorial/Arrays

I managed to compile the first set of code successfully, but in this case the group of calibrated analog inputs are not in an array. They are individually written.

The other issue is SensorValue needs to be placed back into the multidimensional array.
I attempted to do this by writing it as inputPinValue but got more errors.
When I try to place the calibrated values in an array. I get a compile error saying:

In function 'void setup()':

error: invalid types 'uint16_t {aka short unsigned int}[uint8_t {aka unsigned char}]' for array subscript

SensorValue[k] = 0;

error: invalid types 'uint16_t {aka short unsigned int}[uint8_t {aka unsigned char}]' for array subscript

SensorValue[l] = 0;

In function 'void loop()':

error: invalid types 'uint16_t {aka short unsigned int}[uint8_t {aka unsigned char}]' for array subscript

SensorValue[k] = {Azimuth, Elevation};

exit status 1
invalid types 'uint16_t {aka short unsigned int}[uint8_t {aka unsigned char}]' for array subscript

Successful code:

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

uint16_t Azimuth = 0;
uint16_t AzimuthMin = 4095; //minimum sensor value
uint16_t AzimuthMax = 0; //maximum sensor value

uint16_t Elevation = 0;
uint16_t ElevationMin = 4095; //minimum sensor value
uint16_t ElevationMax = 0; //maximum sensor value

// 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 = 2;

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

void setup()
{
  // initialize serial communication with computer:
  Serial.begin(115200);

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

void loop()
{
  // 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

  // calibrate during the first five seconds
  while (millis() < 5000)
  {
    // Read the sensor
    Azimuth = adc1_get_raw(ADC1_CHANNEL_6);
    Elevation = adc1_get_raw(ADC1_CHANNEL_7);

    // record the maximum sensor value
    if (Azimuth > AzimuthMax)
    {
      AzimuthMax = Azimuth;
    }

    // record the minimum sensor value
    if (Azimuth < AzimuthMin)
    {
      AzimuthMin = Azimuth;
    }

    if (Elevation > ElevationMax)
    {
      ElevationMax = Elevation;
    }

    // record the minimum sensor value
    if (Elevation < ElevationMin)
    {
      ElevationMin = Elevation;
    }
  }

  // Read the sensor
  Azimuth = adc1_get_raw(ADC1_CHANNEL_6);
  Elevation = adc1_get_raw(ADC1_CHANNEL_7);

  // apply the calibration to the sensor reading
  Azimuth = map(Azimuth, AzimuthMin, AzimuthMax, 0, 4000);

  // in case the sensor value is outside the range seen during calibration
  Azimuth = constrain(Azimuth, 0, 4000);

  // apply the calibration to the sensor reading
  Elevation = map(Elevation, ElevationMin, ElevationMax, 0, 4000);

  // in case the sensor value is outside the range seen during calibration
  Elevation = constrain(Elevation, 0, 4000);

  uint16_t  inputPin[ numSensors ] = {Azimuth, Elevation};

  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;

    Serial.print( "Average sensor: ");
    Serial.print( ai );
    Serial.print( "   " );
    Serial.println(average);
  }

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

Code that is not compiling properly.

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

uint16_t Azimuth = 0;
uint16_t Elevation = 0;

uint16_t SensorValue = 0;
uint16_t SensorMin = 4095; //minimum sensor value
uint16_t SensorMax = 0; //maximum sensor value

// 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 = 2;

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

void setup()
{
  // initialize serial communication with computer:
  Serial.begin(115200);

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

  for (uint8_t k = 0; k < numSensors; k++)
  {
    SensorValue[k] = 0;
  }

  for (uint8_t l = 0; l < numSensors; l++)
  {
    SensorValue[l] = 0;
  }
}

void loop()
{
  // 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

  // calibrate during the first five seconds
  while (millis() < 5000)
  {
    // Read the sensor
    Azimuth = adc1_get_raw(ADC1_CHANNEL_6);
    Elevation = adc1_get_raw(ADC1_CHANNEL_7);

    for ( uint8_t k = 0; k < numSensors; k++)
    {
      SensorValue[k] = {Azimuth, Elevation};

      // record the maximum sensor value
      if (SensorValue > SensorMax)
      {
        SensorMax = SensorValue;
      }

      // record the minimum sensor value
      if (SensorValue < SensorMin)
      {
        SensorMin = SensorValue;
      }
    }
  }

    // apply the calibration to the sensor reading
    SensorValue = map(SensorValue, SensorMin, SensorMax, 0, 4000);

    // in case the sensor value is outside the range seen during calibration
    SensorValue = constrain(SensorValue, 0, 4000);
  
  uint16_t  inputPin[ numSensors ] = {Azimuth, Elevation};

  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;

    Serial.print( "Average sensor: ");
    Serial.print( ai );
    Serial.print( "   " );
    Serial.println(average);
  }

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

I think I get what you mean based on looking at the tutorial examples.
I declared/initialized it in the beginning now.
For array size numSensors should take care of that?

The brace enclosed values thing only works when you are first creating an array. Anyplace else you have to work with one value at a time.

What do you mean by one value at a time?

Should I be putting this in another for loop?
(I am thinking of nesting the while statement inside the first for loop, and then nesting the remaining code below outside of the while statement, but still inside the same for loop)

  // apply the calibration to the sensor reading
  SensorValue[k] = map(SensorValue[k], SensorMin, SensorMax, 0, 4000);

  // in case the sensor value is outside the range seen during calibration
  SensorValue[k] = constrain(SensorValue[k], 0, 4000);

I included this again after declaring it the first time.
This will yield bad results?
Should I replace inputPin with SensorValue?

  uint16_t  inputPin[ numSensors ] = {Azimuth, Elevation};

The code below is compiling, although I don't think it's correct.

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

uint16_t Azimuth = 0;
uint16_t Elevation = 0;

uint8_t k = 0;

uint16_t SensorValue[] = {Azimuth, Elevation};
const uint8_t numSensors = 2; // number of pins (length of array)

uint16_t SensorMin = 4095; //minimum sensor value
uint16_t SensorMax = 0; //maximum sensor value

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


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

void setup()
{
  // initialize serial communication with computer:
  Serial.begin(115200);

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

  for (k = 0; k < numSensors; k++)
  {
    SensorValue[k] = 0;
  }
}

void loop()
{
  // 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

  // calibrate during the first five seconds
  while (millis() < 5000)
  {
    // Read the sensor
    Azimuth = adc1_get_raw(ADC1_CHANNEL_6);
    Elevation = adc1_get_raw(ADC1_CHANNEL_7);

    for (k = 0; k < numSensors; k++)
    {
      // record the maximum sensor value
      if (SensorValue[k] > SensorMax)
      {
        SensorMax = SensorValue[k];
      }

      // record the minimum sensor value
      if (SensorValue [k] < SensorMin)
      {
        SensorMin = SensorValue[k];
      }
    }
  }

  // apply the calibration to the sensor reading
  SensorValue[k] = map(SensorValue[k], SensorMin, SensorMax, 0, 4000);

  // in case the sensor value is outside the range seen during calibration
  SensorValue[k] = constrain(SensorValue[k], 0, 4000);

  uint16_t  inputPin[ numSensors ] = {Azimuth, Elevation};

  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;

    Serial.print( "Average sensor: ");
    Serial.print( ai );
    Serial.print( "   " );
    Serial.println(average);
  }

  // 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;
  }
}
Average sensor: 0   3812
Average sensor: 1   3812
Average sensor: 0   3875
Average sensor: 1   3875
Average sensor: 0   3937
Average sensor: 1   3937
Average sensor: 0   4000
Average sensor: 1   4000
Average sensor: 0   4000
Average sensor: 1   4000
Average sensor: 0   4000
Average sensor: 1   4000

Before I was getting values ranging from 0-4095 when I was not calibrating and just reading without smoothing results.
Now it just ramps up in the beginning and stays at 4000 no matter how much light I put on the photodiodes or how much I put my finger over one or the other.

Hmm....

I stuck to the same variable this time to use throughout the loop for the array.

I'm recalibrating inside the void loop() because as the day moves on the photodiodes will get varying amount of sunlight. I want them recalibrate accordingly as the sun is being tracked.
I'm considering just putting the calibration code in the void setup() area just like on the Arduino site's calibration example and then just doing a software restart.

The previous code was just delivering results of 0....

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

uint16_t Azimuth;
uint16_t Elevation;

uint8_t k = 0; //index into the array

const uint8_t numSensors = 2; // number of sensors (length of array)
uint16_t SensorValue[numSensors] = {Azimuth, Elevation};

uint16_t SensorMin = 4095; //minimum sensor value
uint16_t SensorMax = 0; //maximum sensor value

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

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

// delay to process smoothing readings
uint8_t numReadingsInterval = 1000;
uint32_t lastEventAtMs = 0 ;

void setup()
{
  // initialize serial communication with computer:
  Serial.begin(115200);

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

void loop()
{
  // 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

if ( millis() - lastEventAtMs >= numReadingsInterval )
{
  lastEventAtMs = millis();
    
  for (k = 0; k < numSensors; k++)
  {
    // calibrate during the first five seconds
    while (millis() < 5000)
    {
      
    // Read the sensor
  Azimuth = adc1_get_raw(ADC1_CHANNEL_6);
  Elevation = adc1_get_raw(ADC1_CHANNEL_7);
      
      // record the maximum sensor value
      if (SensorValue[k] > SensorMax)
      {
        SensorMax = SensorValue[k];
      }

      // record the minimum sensor value
      if (SensorValue [k] < SensorMin)
      {
        SensorMin = SensorValue[k];
      }
    }
    // apply the calibration to the sensor reading
    SensorValue[k] = map(SensorValue[k], SensorMin, SensorMax, 0, 4000);

    // in case the sensor value is outside the range seen during calibration
    SensorValue[k] = constrain(SensorValue[k], 0, 4000);

    // subtract the last reading:
    total[ k ] = total[ k ] - readings[k][readIndex];
    // read from the sensor:
    readings[k][readIndex] = SensorValue[k];
    // add the reading to the total:
    total[k] = total[k] + readings[k][readIndex];
    // calculate the average:
    average = total[k] / numReadings;

    Serial.print( "Average sensor: ");
    Serial.print( k );
    Serial.print( "   " );
    Serial.println(average);
  }

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