Trouble assigning a value to a variable based on multidimensional array output

I have 2 analog inputs.
I’m smoothing their values after taking 64 readings.
I’m using a multidimensional array to get the outputs.
(Want to do this for future use of multiple analog inputs and to avoid repeating code)

Based on the output of the array I’m assigning it a certain data value

The problem is that the output is not updating properly on the serial output based on the if and elseif conditions I have in place.

Basically my conditional statements say that if the array values for analog input 1 or 2 are above 2060 then the data variables should equal 1 and 4 respectively and not 0 and 3.

Am I not using the proper syntax for the array output in the conditional statements?

Success
Success
2473
2121
0
3
Success
Success
2473
2121
0
3
Success
Success
2474
2121
0
3
/*
    Free and open source, CC BY-SA 4.0

    https://espressif.com/sites/default/files/documentation/esp-now_user_guide_en.pdf
    https://docs.espressif.com/projects/esp-idf/en/stable/api-reference/wifi/esp_now.html

    http://www.arduino.cc/en/Tutorial/Smoothing
*/

//ESP-Now WiFi power saving protocol
#include <esp_now.h>
#include <WiFi.h>

// Channel used for connection
#define CHANNEL 1

// Structure with information about the next peer
esp_now_peer_info_t peer;

// Master Mac Address: D8:A0:1D:69:F8:30
// Mac Address of the peer to which we will send the data, D8:A0:1D:6A:00:58
uint8_t peerMacAddress[] = {0xD8, 0xA0, 0x1D, 0x6A, 0x00, 0x58};

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

uint16_t LowLimit = 2000;
uint16_t HighLimit = 2060;
int8_t ElevationAngle;
uint8_t ElevationAngleLimit = 70;

uint8_t data;

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

// interval to stabilize analog input smoothing readings
// analogRead time for one value is ~100 microseconds --> 64 readings x 100 = 6.4 ms
uint8_t numReadingsInterval = 8;
uint32_t numReadingsStart = 0;

void setup() {
  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;
  }

  // Call the function that initializes the station mode
  modeStation();

  // Call function that initializes ESPNow
  InitESPNow();

  // Add the peer
  addPeer(peerMacAddress);

  // Registers the callback that will inform us about the status of the submission.
  // The function that will be executed is onDataSent and is stated below
  esp_now_register_send_cb(OnDataSent);
}

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

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

    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;
      readAndSend();
      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;
    }

    if ((total[Azimuth] / numReadings) < LowLimit)
    {
      data = 0;
      Serial.println(data);
    }
    else if ((total[Azimuth] / numReadings) > HighLimit)
    {
      data = 1;
      Serial.println(data);
    }

    else if (LowLimit < (total[Azimuth] / numReadings) < HighLimit)
    {
      data = 2;
      Serial.println(data);
    }

    if ((total[Elevation] / numReadings) < LowLimit)
    {
      data = 3;
      Serial.println(data);
    }
    else if ((total[Elevation] / numReadings) > HighLimit)
    {
      data = 4;
      Serial.println(data);
    }

    else if (LowLimit < (total[Elevation] / numReadings) < HighLimit)
    {
      data = 5;
      Serial.println(data);
    }
    if (ElevationAngle > ElevationAngleLimit)
    {
      data = 6;
    }
  }
}

// Function responsible for pin reading and sending of data to the peer
void readAndSend() {
  // Send the data to the peer
  send(&data, peerMacAddress);
}

// Function that serves as a callback to warn us about the sending situation we made
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Success" : "Fail");
}

// Function to initialize the station mode
void modeStation() {
  // We put the ESP in station mode
  WiFi.mode(WIFI_STA);
  // We show on Serial Monitor the Mac Address
  // of this ESP when in station mode
  Serial.print("Mac Address in Station: ");
  Serial.println(WiFi.macAddress());
}

// ESPNow startup function
void InitESPNow() {
  // If the initialization was successful
  if (esp_now_init() == ESP_OK) {
    Serial.println("ESPNow Init Success");
  }
  // If initialization failed
  else {
    Serial.println("ESPNow Init Failed");
    ESP.restart();
  }
}

// Function that adds a new peer through your MAC address
void addPeer(uint8_t *peerMacAddress) {
  // We inform the channel
  peer.channel = CHANNEL;
  // 0 not to use encryption or 1 to use
  peer.encrypt = 0;
  // Copy array address to structure
  memcpy(peer.peer_addr, peerMacAddress, 6);
  // Add slave
  esp_now_add_peer(&peer);
}

// Function that will send the data to the peer that has the specified mac address
void send(const uint8_t *data, uint8_t *peerMacAddress) {
  esp_err_t result = esp_now_send(peerMacAddress, data, sizeof(data));
}

Esp32EspNowDataSent_R1.ino (6.13 KB)

This line is your problem

    if ((total[Azimuth] / numReadings) < LowLimit)

The variable ‘Azimuth’ is the adc reading, not the index into the total array.

You have already calculated the average a few lines earlier, so you should use that value which makes your code look like this

    average = total[0] / numReadings; // azimuth

    if (average < LowLimit)
    {
      data = 0;
      Serial.println(data);
    }
    else if (average > HighLimit)
    {
      data = 1;
      Serial.println(data);
    }
    else if (LowLimit < average && average < HighLimit)
    {
      data = 2;
      Serial.println(data);
    }

Also, you shouldn’t need to configure your adc each time through the loop. That is setup code so it should be placed in… setup()

Thanks what you mentioned regarding the indexing works.

Just out of curiousity I didn’t get why average && average is used here:

else if (LowLimit < average && average < HighLimit)

Why is it not just average in between the inequalities?
I did check the usage cases for when && is used so I’m confused even more now.

I moved the ADC settings to void setup ()

Because C++ doesn't support that syntax. You have two test. 1. LowLimit below average 2. average below HighLimit

You have to combine both of those test with 'and' which is '&&' or 'and' to make ti work.

the C++ refererance is not new. You can look things up and thy will work as expected.

I see got it thanks.

Had to change the code up a bit for 4 analog inputs versus 2.
The disparity in results of my photodiode values with same light conditions is pretty bad.
Here is what I’m currently using:
https://grabcad.com/library/5800b-led-photocell-1
I’ll try something like this next:

The smoothing results are great though.

Looks like I’ll have to calibrate the values prior to going into the array.
Or perhaps create an array to calibrate them.

AzimuthCW: 1994
AzimuthCCW: 2383
ElevationCW: 2196
ElevationCCW: 2505
0
3
Success
AzimuthCW: 1995
AzimuthCCW: 2384
ElevationCW: 2197
ElevationCCW: 2505
0
3

Here is fixed code if any one wants to use it for reference:

/*
    Free and open source, CC BY-SA 4.0

    https://espressif.com/sites/default/files/documentation/esp-now_user_guide_en.pdf
    https://docs.espressif.com/projects/esp-idf/en/stable/api-reference/wifi/esp_now.html

    http://www.arduino.cc/en/Tutorial/Smoothing
*/

//ESP-Now WiFi power saving protocol
#include <esp_now.h>
#include <WiFi.h>

// Channel used for connection
#define CHANNEL 1

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

// Structure with information about the next peer
esp_now_peer_info_t peer;

// Master Mac Address: D8:A0:1D:69:F8:30
// Mac Address of the peer to which we will send the data, D8:A0:1D:6A:00:58
uint8_t peerMacAddress[] = {0xD8, 0xA0, 0x1D, 0x6A, 0x00, 0x58};

int8_t ElevationAngle;
uint8_t ElevationAngleLimit = 70;

uint8_t Tolerance = 100;

uint8_t data;

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

  // Call the function that initializes the station mode
  modeStation();

  // Call function that initializes ESPNow
  InitESPNow();

  // Add the peer
  addPeer(peerMacAddress);

  // Registers the callback that will inform us about the status of the submission.
  // The function that will be executed is onDataSent and is stated below
  esp_now_register_send_cb(OnDataSent);
}

//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);
    
    if (ACW < ACCW)
    {
      data = 0;
      Serial.println(data);
    }

    else if (ACW > ACCW)
    {
      data = 1;
      Serial.println(data);
    }

    else if (abs(ACW - ACCW)  < Tolerance)
    {
      data = 2;
      Serial.println(data);
    }

    if (ECW < ECCW)
    {
      data = 3;
      Serial.println(data);
    }

    else if (ECW > ECCW)
    {
      data = 4;
      Serial.println(data);
    }

    else if (abs(ECW - ECCW) < Tolerance)
    {
      data = 5;
      Serial.println(data);
    }

    if (ElevationAngle > ElevationAngleLimit)
    {
      data = 6;
    }

    readAndSend();
  }
}

// Function responsible for pin reading and sending of data to the peer
void readAndSend() {
  // Send the data to the peer
  send(&data, peerMacAddress);
}

// Function that serves as a callback to warn us about the sending situation we made
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Success" : "Fail");
}

// Function to initialize the station mode
void modeStation() {
  // We put the ESP in station mode
  WiFi.mode(WIFI_STA);
  // We show on Serial Monitor the Mac Address
  // of this ESP when in station mode
  Serial.print("Mac Address in Station: ");
  Serial.println(WiFi.macAddress());
}

// ESPNow startup function
void InitESPNow() {
  // If the initialization was successful
  if (esp_now_init() == ESP_OK) {
    Serial.println("ESPNow Init Success");
  }
  // If initialization failed
  else {
    Serial.println("ESPNow Init Failed");
    ESP.restart();
  }
}

// Function that adds a new peer through your MAC address
void addPeer(uint8_t *peerMacAddress) {
  // We inform the channel
  peer.channel = CHANNEL;
  // 0 not to use encryption or 1 to use
  peer.encrypt = 0;
  // Copy array address to structure
  memcpy(peer.peer_addr, peerMacAddress, 6);
  // Add slave
  esp_now_add_peer(&peer);
}

// Function that will send the data to the peer that has the specified mac address
void send(const uint8_t *data, uint8_t *peerMacAddress) {
  esp_err_t result = esp_now_send(peerMacAddress, data, sizeof(data));
}

Esp32EspNowDataSent_R1.ino (6.78 KB)