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?
/*
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));
}
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()
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:
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.
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));
}