Based on the results of the analog values I output certain data variable values.
These data variable values should get transferred to the receiver/slave ESP32 but they are not.
I'm using the ESP-Now protocol to transfer the values.
I'm getting conflicting results from the serial monitor output of the ESP32 slave.
It' not getting the correct data variable values on the slave end.
I've confirmed it by placing my hands on the photodiode sensors and the ESP32 master sender values are correct in the serial monitor.
Any idea what could be wrong?
I'm suspecting on the receiver/slave side the data variable is not being received properly.
Esp32 Master Serial out:
Code: Select all
Success
AzimuthCW: 0
AzimuthCCW: 0
ElevationCW: 0
ElevationCCW: 0
2
5
Success
AzimuthCW: 0
AzimuthCCW: 0
ElevationCW: 0
ElevationCCW: 0
2
5
Success
Code: Select all
3
ELEVATION MOTOR MOVES CLOCKWISE
6
ELEVATION MOTOR STOPS
1
AZIMUTH MOTOR MOVES COUNTERCLOCKWISE
3
ELEVATION MOTOR MOVES CLOCKWISE
6
ELEVATION MOTOR STOPS
1
AZIMUTH MOTOR MOVES COUNTERCLOCKWISE
Master code:
Code: Select all
/*
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));
}
Code: Select all
/*
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
uint8_t data;
uint16_t period = 2000;
unsigned long time_now = 0;
// Azimuth and elevation pwm (pulse width modulation) pins on each h-bridge must be connected to four pwm pins on microprocessor.
// For ESP32 the GPIO pwm pins are: 0,1,2,3,4,6,7,8,9,10,11,12,14,16,17,18,19,21,22,23,25,26,27,32,33,34,35,36,39
// motor azimuth adjustment
uint8_t AzimuthClockwiseEnable = 26;
uint8_t AzimuthCounterClockwiseEnable = 27;
uint8_t AzimuthClockwisePWM = 32;
uint8_t AzimuthCounterClockwisePWM = 33;
// motor elevation adjustment
uint8_t ElevationClockwiseEnable = 34;
uint8_t ElevationCounterClockwiseEnable = 35;
uint8_t ElevationClockwisePWM = 36;
uint8_t ElevationCounterClockwisePWM = 37;
// Setting PWM properties
uint16_t freq = 30000;
uint8_t resolution = 8;
uint8_t DutyCycleAzimuthCW = 200;
uint8_t DutyCycleAzimuthCCW = 200;
uint8_t DutyCycleElevationCW = 200;
uint8_t DutyCycleElevationCCW = 200;
void setup() {
Serial.begin(115200);
// Call the function that initializes the station mode
modeStation();
// Call function that initializes ESPNow
InitESPNow();
// Registers the callback that will inform us that we receive data. The function to be executed is onDataRecv and is declared below
esp_now_register_recv_cb(onDataRecv);
// Registers the callback that will inform us
// about the status of the submission.
// The function to be executed
// is onDataSent and is declared below
esp_now_register_send_cb(onDataSent);
//set all motor control pins to outputs
pinMode(AzimuthClockwiseEnable, OUTPUT);
pinMode(AzimuthCounterClockwiseEnable, OUTPUT);
pinMode(AzimuthClockwisePWM, OUTPUT);
pinMode(AzimuthCounterClockwisePWM, OUTPUT);
pinMode(ElevationClockwiseEnable, OUTPUT);
pinMode(ElevationCounterClockwiseEnable, OUTPUT);
pinMode(ElevationClockwisePWM, OUTPUT);
pinMode(ElevationCounterClockwisePWM, OUTPUT);
// configure LED PWM functionalitites
ledcSetup(AzimuthClockwisePWM, freq, resolution);
ledcSetup(AzimuthCounterClockwisePWM, freq, resolution);
ledcSetup(ElevationClockwisePWM, freq, resolution);
ledcSetup(ElevationCounterClockwisePWM, freq, resolution);
// attach the channel to the GPIO to be controlled
ledcAttachPin(AzimuthClockwiseEnable, AzimuthClockwisePWM);
ledcAttachPin(AzimuthCounterClockwiseEnable, AzimuthCounterClockwisePWM);
ledcAttachPin(ElevationClockwiseEnable, ElevationClockwisePWM);
ledcAttachPin(ElevationCounterClockwiseEnable, ElevationCounterClockwisePWM);
}
// We send the data as soon as we get from the other esp by the callback
void loop()
{
if (millis() > time_now + period)
{
time_now = millis();
}
if (data = 0) // if average light sensor values on left side are greater than right side, azimuth motor rotates clockwise
{
digitalWrite(AzimuthClockwiseEnable, HIGH); ledcWrite(AzimuthClockwisePWM, DutyCycleAzimuthCW); // set speed out of possible range 0~255
digitalWrite(AzimuthCounterClockwiseEnable, HIGH); digitalWrite (AzimuthCounterClockwisePWM, LOW);
Serial.println(data);
Serial.println("AZIMUTH MOTOR MOVES CLOCKWISE");
Serial.println(" ");
}
else if (data = 1)// if average light sensor values on right side are greater than on left side, azimuth motor rotates counterclockwise
{
digitalWrite(AzimuthCounterClockwiseEnable, HIGH); ledcWrite(AzimuthCounterClockwisePWM, DutyCycleAzimuthCCW);
digitalWrite(AzimuthClockwiseEnable, HIGH); digitalWrite(AzimuthClockwisePWM, LOW);
Serial.println(data);
Serial.println("AZIMUTH MOTOR MOVES COUNTERCLOCKWISE");
Serial.println(" ");
}
else if (data = 2) // if difference is smaller than tolerance, stop azimuth motor
{
digitalWrite(AzimuthClockwiseEnable, LOW); digitalWrite(AzimuthCounterClockwiseEnable, LOW);
Serial.println("AZIMUTH MOTOR STOPS");
Serial.println(" ");
}
if (data = 3) // if average light sensor value on top side is greater than on bottom side then elevation motor rotates clockwise
{
digitalWrite(ElevationClockwiseEnable, HIGH); ledcWrite(ElevationClockwisePWM, DutyCycleElevationCW);
digitalWrite(ElevationCounterClockwiseEnable, HIGH); digitalWrite(ElevationCounterClockwisePWM, LOW);
Serial.println(data);
Serial.println("ELEVATION MOTOR MOVES CLOCKWISE");
Serial.println(" ");
}
else if (data = 4) // if average light sensor value on bottom side is greater than on top side then elevation motor rotates counterclockwise
{
digitalWrite(ElevationCounterClockwiseEnable, HIGH); ledcWrite(ElevationCounterClockwisePWM, DutyCycleElevationCCW);
digitalWrite(ElevationClockwiseEnable, HIGH); digitalWrite(ElevationClockwisePWM, LOW);
Serial.println(data);
Serial.println("ELEVATION MOTOR MOVES COUNTERCLOCKWISE");
Serial.println(" ");
}
else if (data = 5) // if difference is smaller than tolerance, stop elevation motor
{
digitalWrite(ElevationClockwiseEnable, LOW); digitalWrite(ElevationCounterClockwiseEnable, LOW);
Serial.println(data);
Serial.println("ELEVATION MOTOR STOPS");
Serial.println(" ");
}
if (data = 6)
{
digitalWrite(ElevationClockwiseEnable, LOW); digitalWrite(ElevationCounterClockwiseEnable, LOW);
Serial.println(data);
Serial.println("ELEVATION MOTOR STOPS");
Serial.println(" ");
}
}
// Function that serves as a callback to warn us we received data
void onDataRecv(const uint8_t *mac_addr, const uint8_t *data, int len) {
// Place the received data at the output of the pin
Serial.println(*data);
}
// 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();
}
}