Hello everyone, i have 3 Adafruit QT PY ESP32S2 boards that i am using ESP-NOW with to communicate with each other (two boards that gets the temperature using a DS18B20 sensor and sends it to one board that displays the temperature on a screen). I have got it to work but the callback function OnDataSent
only gets called sometimes and the if-statement that checks if it got sent on line 128 says success even if the receiver is not getting any power.
Here is the code that doesn't work
#include <esp_now.h>
#include <WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Adafruit_NeoPixel.h>
#define NUMPIXELS 1 // How many neopixels i have
// Create a pixels instance to use the built in neopixel on the Adafruit QT PY ESP32-S2 with u.FL connector
Adafruit_NeoPixel pixels(NUMPIXELS, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800);
// Data wire is plugged into pin 4 on the ESP32
#define ONE_WIRE_BUS 18
// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 10 /* Time ESP32 will go to sleep (in seconds) */
// The recievers MAC address
uint8_t broadcastAddress[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
// Structure example to send data
// Must match the receiver structure
typedef struct struct_message {
int id; // must be unique for each sender board
int size;
int temp;
int test;
} struct_message;
// Create a struct_message called readings
struct_message readings;
// Create peer interface
esp_now_peer_info_t peerInfo;
// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("\r\nLast Packet Send Status:\t");
// Checks if the send was a success
if (status == ESP_NOW_SEND_SUCCESS) {
Serial.println("Delivery Success");
pixels.fill(0x00FF00); // Turn the neopixel green
pixels.show();
} else {
Serial.println("Delivery Fail");
pixels.fill(0xFF0000); // Turn the neopixel red
pixels.show();
}
delay(500); // Delay so that you can see the neopixel color
}
void setup() {
// Init Serial Monitor
Serial.begin(9600);
Serial.setDebugOutput(true);
delay(2000);
#if defined(NEOPIXEL_POWER)
// If this board has a power control pin, we must set it to output and high
// in order to enable the NeoPixels. We put this in an #if defined so it can
// be reused for other boards without compilation errors
pinMode(NEOPIXEL_POWER, OUTPUT);
digitalWrite(NEOPIXEL_POWER, HIGH);
#endif
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
pixels.setBrightness(20); // not so bright
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
} else {
Serial.println("Successfully initialized ESP-NOW");
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Transmitted packet
esp_now_register_send_cb(OnDataSent); // I think this is where the problem is but i don't know what else the problem could be
// Register peer
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
sensors.begin(); // IC Default 9 bit.
//Print the wakeup reason for ESP32
// print_wakeup_reason();
// Set values to send
sensors.requestTemperatures(); // Send the command to get temperatures
readings.id = 1; // Set the id of the sender board
readings.test = 1; // A test variable
readings.temp = sensors.getTempCByIndex(0); // Get the temperature in °C
// Checks if the temperature is -127, if it is then the wiring is probably incorrect
if (readings.temp == -127.00) {
Serial.println("Failed to read from DS18B20.");
} else {
Serial.println("Successfully read from DS18B20.");
}
readings.size = sizeof(readings); // Set readings.size to be the size of readings
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *)&readings, sizeof(readings));
// Checks if the data was sent with success (but even if the reciever is offline it still shows "Sent with success!")
if (result == ESP_OK) {
Serial.printf("Sent with success! %u bytes\n", readings.size);
} else {
Serial.println("Error sending the data");
}
/*
First we configure the wake up source
We set our ESP32 to wake up every 10 seconds
*/
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) + " Seconds");
// esp_sleep_enable_ext0_wakeup(GPIO_NUM_17, 1);
Serial.println("Going to sleep now");
Serial.flush(); // Flush the Serial monitor (idk what it is used for)
esp_deep_sleep_start(); // Go in to sleep
}
void loop() {
// We will never get here
}
And here is the code that does work but i don't wanna use
#include <esp_now.h>
#include <WiFi.h>
#include <Adafruit_NeoPixel.h>
#define NUMPIXELS 1 // How many neopixels i have
// Create a pixels instance to use the built in neopixel on the Adafruit QT PY ESP32-S2 with u.FL connector
Adafruit_NeoPixel pixels(NUMPIXELS, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800);
#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 10 /* Time ESP32 will go to sleep (in seconds) */
// The recievers MAC address
uint8_t broadcastAddress[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; // Yes i changed this when i uploaded the code to the real MAC address
// Structure example to send data
// Must match the receiver structure
typedef struct struct_message {
char a[32];
int b;
float c;
bool d;
} struct_message;
// Create a struct_message called readings
struct_message readings;
// Create peer interface
esp_now_peer_info_t peerInfo;
// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("\r\nLast Packet Send Status:\t");
// Serial.println( ? "Delivery Success" : "Delivery Fail");
if (status == ESP_NOW_SEND_SUCCESS) {
Serial.println("Delivery Success");
pixels.fill(0x00FF00);
pixels.show();
delay(500);
} else {
pixels.fill(0xFF0000);
pixels.show();
delay(500);
}
}
void setup() {
// Init Serial Monitor
Serial.begin(9600);
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
pixels.setBrightness(20); // not so bright
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
esp_now_register_send_cb(OnDataSent); // It works here, the OnDataSend callback function gets called
// Register peer
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
// Set values to send
strcpy(myData.a, "THIS IS A CHAR");
myData.b = random(1, 20);
myData.c = 1.2;
myData.d = false;
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *)&myData, sizeof(myData));
if (result == ESP_OK) {
Serial.println("Sent with success");
} else {
Serial.println("Error sending the data");
}
delay(1000);
/*
First we configure the wake up source
We set our ESP32 to wake up every 10 seconds
*/
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) + " Seconds");
// esp_sleep_enable_ext0_wakeup(GPIO_NUM_17, 1);
Serial.println("Going to sleep now");
Serial.flush(); // Flush the Serial monitor (idk what it is used for)
esp_deep_sleep_start(); // Go in to sleep
}
void loop() {
// We will never get here
}
Any ideas of what makes it so that OnDataSent
only gets called sometimes?
Thank you.