In this guide, we’ll show you how to establish a two-way communication between two ESP32 boards using ESP-NOW communication protocol. As an example, two ESP32 boards will exchange sensor readings (with a range in open field up to 220 meters ~ 722 feet).
Watch the Video Introduction
For an introduction to ESP-NOW protocol, you can watch the following video:
If you want to learn more about ESP-NOW, you can read this guide: Getting Started with ESP-NOW (ESP32 with Arduino IDE).
Introducing ESP-NOW
ESP-NOW is a connectionless communication protocol developed by Espressif that features short packet transmission. This protocol enables multiple devices to talk to each other without using Wi-Fi.
This is a fast communication protocol that can be used to exchange small messages (up to 250 bytes) between ESP32 boards. ESP-NOW is very versatile and you can have one-way or two-way communication in different arrangements.
In this tutorial, we’ll show you how to establish a two-way communication between two ESP32 boards.
Note: read our ESP-NOW Getting Started Guide for a complete introduction to ESP-NOW protocol with ESP32.
Project Overview
The following diagram shows a high-level overview of the project we’ll build.
- In this project we’ll have two ESP32 boards. Each board is connected to an OLED display and a BME280 sensor;
- Each board gets temperature, humidity and pressure readings from their corresponding sensors;
- Each board sends its readings to the other board via ESP-NOW;
- When a board receives the readings, it displays them on the OLED display;
- After sending the readings, the board displays on the OLED if the message was successfully delivered;
- Each board needs to know the other board MAC address in order to send the message.
In this example, we’re using a two-way communication between two boards, but you can add more boards to this setup, and having all boards communicating with each other.
Prerequisites
Before proceeding with this project, make sure you check the following prerequisites.
ESP32 add-on Arduino IDE
We’ll program the ESP32 using Arduino IDE, so before proceeding with this tutorial you should have the ESP32 add-on installed in your Arduino IDE. Follow the next guide:
Install libraries
Install the following libraries in your Arduino IDE. These libraries can be installed through the Arduino Library Manager. Go to Sketch > Include Library> Manage Libraries and search for the library name.
- OLED libraries (ESP32 OLED Guide): Adafruit_SSD1306 library and Adafruit_GFX library
- BME280 libraries (ESP32 BME280 Guide): Adafruit_BME280 library and Adafruit Unified Sensor library
Parts Required
For this tutorial you need the following parts:
- 2x ESP32 development boards (read Best ESP32 boards)
- 2x BME280 sensors (BME280 Complete Guide)
- 2x 0.96 inch OLED displays (OLED Complete Guide)
- Breadboard
- Jumper wires
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
Getting the Boards MAC Address
To send messages between each board, we need to know their MAC address. Each board has a unique MAC address (learn how to Get and Change the ESP32 MAC Address).
Upload the following code to each of your boards to get their MAC address.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/get-change-esp32-esp8266-mac-address-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#include <WiFi.h>
#include <esp_wifi.h>
void readMacAddress(){
uint8_t baseMac[6];
esp_err_t ret = esp_wifi_get_mac(WIFI_IF_STA, baseMac);
if (ret == ESP_OK) {
Serial.printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
baseMac[0], baseMac[1], baseMac[2],
baseMac[3], baseMac[4], baseMac[5]);
} else {
Serial.println("Failed to read MAC address");
}
}
void setup(){
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.STA.begin();
Serial.print("[DEFAULT] ESP32 Board MAC Address: ");
readMacAddress();
}
void loop(){
}
After uploading the code, press the RST/EN button, and the MAC address should be displayed on the Serial Monitor.
Write down the MAC address of each board to clearly identify them.
Schematic Diagram
Wire an OLED display and a BME280 sensor to each ESP32 board. Follow the next schematic diagram.
You can use the following table as a reference when wiring the BME280 sensor.
BME280 | ESP32 |
VIN | 3.3V |
GND | GND |
SCL | GPIO 22 |
SDA | GPIO 21 |
You can also follow the next table to wire the OLED display to the ESP32.
OLED Display | ESP32 |
GND | GND |
VCC | VIN |
SCL | GPIO 22 |
SDA | GPIO 21 |
Learn more about interfacing multiple I2C peripherals with the ESP32.
ESP32 Two-Way Communication ESP-NOW Code
Upload the following code to each of your boards. Before uploading the code, you need to enter the MAC address of the other board (the board you’re sending data to).
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp-now-two-way-communication-esp32/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#include <esp_now.h>
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Adafruit_BME280 bme;
// REPLACE WITH THE MAC Address of your receiver
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
// Define variables to store BME280 readings to be sent
float temperature;
float humidity;
float pressure;
// Define variables to store incoming readings
float incomingTemp;
float incomingHum;
float incomingPres;
// Variable to store if sending data was successful
String success;
//Structure example to send data
//Must match the receiver structure
typedef struct struct_message {
float temp;
float hum;
float pres;
} struct_message;
// Create a struct_message called BME280Readings to hold sensor readings
struct_message BME280Readings;
// Create a struct_message to hold incoming sensor readings
struct_message incomingReadings;
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(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
if (status ==0){
success = "Delivery Success :)";
}
else{
success = "Delivery Fail :(";
}
}
// Callback when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
Serial.print("Bytes received: ");
Serial.println(len);
incomingTemp = incomingReadings.temp;
incomingHum = incomingReadings.hum;
incomingPres = incomingReadings.pres;
}
void setup() {
// Init Serial Monitor
Serial.begin(115200);
// Init BME280 sensor
bool status = bme.begin(0x76);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
// Init OLED display
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
// 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);
// 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;
}
// Register for a callback function that will be called when data is received
esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));
}
void loop() {
getReadings();
// Set values to send
BME280Readings.temp = temperature;
BME280Readings.hum = humidity;
BME280Readings.pres = pressure;
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &BME280Readings, sizeof(BME280Readings));
if (result == ESP_OK) {
Serial.println("Sent with success");
}
else {
Serial.println("Error sending the data");
}
updateDisplay();
delay(10000);
}
void getReadings(){
temperature = bme.readTemperature();
humidity = bme.readHumidity();
pressure = (bme.readPressure() / 100.0F);
}
void updateDisplay(){
// Display Readings on OLED Display
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("INCOMING READINGS");
display.setCursor(0, 15);
display.print("Temperature: ");
display.print(incomingTemp);
display.cp437(true);
display.write(248);
display.print("C");
display.setCursor(0, 25);
display.print("Humidity: ");
display.print(incomingHum);
display.print("%");
display.setCursor(0, 35);
display.print("Pressure: ");
display.print(incomingPres);
display.print("hPa");
display.setCursor(0, 56);
display.print(success);
display.display();
// Display Readings in Serial Monitor
Serial.println("INCOMING READINGS");
Serial.print("Temperature: ");
Serial.print(incomingReadings.temp);
Serial.println(" ºC");
Serial.print("Humidity: ");
Serial.print(incomingReadings.hum);
Serial.println(" %");
Serial.print("Pressure: ");
Serial.print(incomingReadings.pres);
Serial.println(" hPa");
Serial.println();
}
How the code works
We’ve covered in great detail how to interact with the OLED display and with the BME280 sensor in previous tutorials. Here, we’ll just take a look at the relevant parts when it comes to ESP-NOW.
The code is well commented so that you understand what each line of code does.
To use ESP-NOW, you need to include the next libraries.
#include <esp_now.h>
#include <WiFi.h>
In the next line, insert the MAC address of the receiver board:
uint8_t broadcastAddress[] = {0x30, 0xAE, 0xA4, 0x07, 0x0D, 0x64};
Create variables to store temperature, humidity and pressure readings from the BME280 sensor. These readings will be sent to the other board:
// Define variables to store BME280 readings to be sent
float temperature;
float humidity;
float pressure;
Create variables to store the sensor readings coming from the other board:
// Define variables to store incoming readings
float incomingTemp;
float incomingHum;
float incomingPres;
The following variable will store a success message if the readings are delivered successfully to the other board.
// Variable to store if sending data was successful
String success;
Create a structure that stores humidity, temperature and pressure readings.
typedef struct struct_message {
float temp;
float hum;
float pres;
} struct_message;
Then, you need to create two instances of that structure. One to receive the readings and another to store the readings to be sent.
The BME280Readings will store the readings to be sent.
// Create a struct_message called BME280Readings to hold sensor readings
struct_message BME280Readings;
The incomingReadings will store the data coming from the other board.
// Create a struct_message to hold incoming sensor readings
struct_message incomingReadings;
Create a variable of type esp_now_peer_info_t to store information about the peer.
esp_now_peer_info_t peerInfo;
Then, we need to create two callback functions. One will be called when data is sent, and another will be called when data is received.
OnDataSent() callback function
The OnDataSent() function will be called when new data is sent. This function simply prints if the message was successfully delivered or not. If the message is delivered successfully, the status variable returns 0, so we can set our success message to “Delivery Success”:
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
if (status ==0) {
success = "Delivery Success :)";
}
If the success message returns 1, it means the delivery failed:
else {
success = "Delivery Fail :(";
}
OnDataRecv() callback function
The OnDataRecv() function will be called when a new packet arrives.
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
We save the new packet in the incomingReadings structure we’ve created previously:
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
We print the message length on the serial monitor. You can only send 250 bytes in each packet.
Serial.print("Bytes received: ");
Serial.println(len);
Then, store the incoming readings in their corresponding variables. To access the temperature variable inside incomingReadings structure, you just need to do call incomingReadings.temp as follows:
incomingTemp = incomingReadings.temp;
The same process is done for the other variables:
incomingHum = incomingReadings.hum;
incomingPres = incomingReadings.pres;
setup()
In the setup(), initialize ESP-NOW.
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
Then, register for the OnDataSent callback function.
esp_now_register_send_cb(OnDataSent);
In order to send data to another board, you need to pair it as a peer. The following lines register and add a new peer.
// 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;
}
Register for the OnDataRecv callback function.
esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));
loop()
In the loop(), we call the getReadings() function that is responsible for getting new temperature readings from the sensor. That function is created after the loop().
After getting new temperature, humidity and pressure readings, we update our BME280Reading structure with those new values:
BME280Readings.temp = temperature;
BME280Readings.hum = humidity;
BME280Readings.pres = pressure;
Then, we can send the BME280Readings structure via ESP-NOW:
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &BME280Readings, sizeof(BME280Readings));
if (result == ESP_OK) {
Serial.println("Sent with success");
}
else {
Serial.println("Error sending the data");
}
Finally, call the updateDisplay() function that will update the OLED display with the readings coming from the other ESP32 board.
updateDisplay();
The loop() is executed every 10 seconds.
That’s pretty much how the code works. You should upload the code to both of your boards. You just need to modify the code with the MAC address of the board you’re sending data to.
Recommended reading: Guide for OLED Display with ESP32 and Guide for BME280 Sensor with ESP32.
Demonstration
After uploading the code to both boards, you should see the OLED displaying the sensor readings from the other board, as well as a success delivery message.
As you can see, it’s working as expected:
We tested the communication range between the two boards, and we are able to get a stable communication up to 220 meters (approximately 722 feet) in open field. In this experiment both ESP32 on-board antennas were pointing to each other.
Wrapping Up
In this tutorial we’ve shown you how to establish a two-way communication with two ESP32 boards using ESP-NOW. This is a very versatile communication protocol that can be used to send packets with up to 250 bytes. ESP-NOW communication protocol can also be used with ESP8266 boards: Getting Started with ESP-NOW (ESP8266 NodeMCU with Arduino IDE).
As an example, we’ve shown you the interaction between two boards, but you can add many boards to your setup. You just need to know the MAC address of the board you’re sending data to.
We’ll be publishing more tutorials about ESP-NOW, so stay tuned. Additionally, write a comment below saying which tutorial you would like to see with ESP-NOW.
To learn more about the ESP32 board, take a look at our resources:
- Learn ESP32 with Arduino IDE (video course + eBook)
- MicroPython Programming with ESP32 and ESP8266
- More ESP32 resources…
Thanks for reading.
Thank you very much Rui.
This is the tutorial i was looking for.
Your site is like Alibaba’s Cave from “Ali Baba and the Forty Thieves”
Full of treasures.
Hi Ion.
Great comparison ahahah 😀
Thank you.
Regards,
Sara
This example is very difficult. a simpler example. sending (int) between two modules. very simple
Can ESP8266 run ESP-NOW protocol?
Hi Bob.
Yes, ESP8266 can run ESP-NOW. But, I don’t think this code is compatible. I haven’t tried it yet.
We’ll probably write a new tutorial for ESP-NOW with ESP8266.
Regards,
Sara
Hi Sara,
Have you made the code for esp8266 with esp now. If yes then pls share its link.
Thanks
Raza
It’s here: https://randomnerdtutorials.com/esp-now-two-way-communication-esp8266-nodemcu/
Regards,
Sara
Thanks sara 🙂
Andreas Spiess did something about that (and others did as well) https://www.youtube.com/watch?v=6NsBN42B80Q
It is not quite the same. I saw it long time ago, and it is in the Master slave configuration.
What Rui did here is like ESP-NOW combo mode, when each of the boards can talk when he want and is not master slave. Both are equal.
“https://www.espressif.com/sites/default/files/documentation/esp-now_user_guide_en.pdf” , page 2.7, table 2-1
hence me saying ‘something’
Hi Rui,
Great write up! But I am having a lot of issues compiling the code; the error is with the library. For some reason the Arduino IDE is unable to find it. I did install all of the board libraries for esp32, esp12 and esp8266. I am able to run their example sketches without any issues. I tried this on 3 different Window PC’s without much luck. Any help is welcome. Abrigado!
Hi.
What is the exact error that you’re getting?
Regards,
Sara
Hi Sara,
I get the following error when compiling the ESP_Now_Les_Example_1 sketch
exit status 1
esp_now.h: No such file or directory
Thanks for helping me out!! 🙂
Brett
Hi.
The esp_now.h file is installed by default.
So, make sure you have an ESP32 board selected in the Boards menu and that the ESP32 boards are properly installed.
Also, can you run the example sketch in File > Examples > ESP32 > ESPNow?
Regards,
Sara
Hi Sara,
I found espnow.h is for the ESP8266, and esp_now.h is for the ESP32.
I have been taking notes as I make mistakes…and find solutions.
With esp8266 also make sure to add:
WiFi.mode(WIFI_STA);
WiFi.disconnect(); // it will improve signal responses.
Hi Ruis
Any way to encrypt the datas sent between boards ?
Thanks for your feedback.
Yes, I think so for what I’ve read, but we don’t have any examples on that subject…
Can you still use any of the Wi-Fi modes while using ESP-NOW?
How can this configuration share their data with the outside world?
Yes, we’ll be posting a project on that subject in a couple of weeks!
Hi Rui, haven’t seen anything on this project, have I missed it?
Rob
It’s not ready, yet! We’ll try to post it in 2 weeks or something. We had to complete other projects in the meanwhile.
Hi Rui,
This method of communication between ESP32 boards is very interesting.
I built an arduino based audio controller, for my whole home audio system.
I want to add control from a second station in another room, and upgrade to either an ESP32 or ESP8266.
After seeing this system, I think it could be adapted to do what I need.
I want it to display the current Mode in both rooms, yet allow the source selection, power off commands to be updated from either location.
I will set up this project as a start, so I can go through the code step by step.
Thank you, and Sara, so much for all the great tutorials!
Hi Sara and Rui,
Great tutorial.
As I saw in the comments in the tutorial for the “ESP-NOW One-Way communication”, it is possible to use the ESP-NOW with Wi-Fi (it is possible right?).
And about the ESP32-CAM, does the ESP-NOW works well with it? I’m thinking in building an web server in the ESP32-CAM and this server receives the data os temperature, pressure, umidity from another ESP32, via ESP-NOW.
Eduardo. This might be of interest to you: https://github.com/HarringayMakerSpace/IoT/blob/master/ESP-Now/espnow-gateway/espnow-gateway.ino
Thanks Man!
I’ll take a look at it, for sure!
I’ll change a project which I wrote some months ago which uses a web server in an ESP32-CAM. But I updated the sensor readings shown in the web server using MQTT. If you are interested, you can check the whole project here (it is a little awkward, but worked well):
https://github.com/dualvim/WebServer_ESP32CAM_Sensors_MQTT
Now, I will use the ESP-NOW to simplify this project (I wish I knew the ESP-NOW before).
Is that possible to communicate esp8266 and esp32 with this way?
Hi.
Yes.
But you need a slightly different code for the ESP8266. The ESP-NOW functions are a little bit different.
Read this guide about the ESP8266 and then adapt it for a two-way communication: https://randomnerdtutorials.com/esp-now-esp8266-nodemcu-arduino-ide/
I hope this helps.
Regards,
Sara
It is not quite the same. I saw it long time ago, and it is in the Master slave configuration.
What Rui did here is like ESP-NOW combo mode, when each of the boards can talk when he want and is not master slave. Both are equal.
“https://www.espressif.com/sites/default/files/documentation/esp-now_user_guide_en.pdf” , page 2.7, table 2-1
Thanks again! Great tutorial and it works good too! 🙂
Joe
Great! 😀
Assuming i do not have sensors and no float data, if a replace float with double , can i send 8 bytes to the other end ?
Or better,
float replaced with double
float replaced with double
float replaced with double
so in this case i can send 24 bytes from one board to other.
I am new to that, so correct me if i am wrong.
Hi Ion.
Yes, you can send a double.
Just make sure the structure you send, is the same structure on the receiver side.
Regards,
Sara
Thank you Sara
I just found this 15 minutes ago and now it’s up and running! I just happened to get some BME280 (s) and some OLED (s) last week.
Great!
😀
I do not know what is wrong on my side but both of the boards they display on the port monitor that they do not find BME280.
I am surprised because they are just 4 wire.
The power is OK 3.3V
Also the display is completely blank/black.
I put for the display 5V from USB as power.
Any suggestion.
I forgot to mention that i use Adafruit Feather ESP32. But i do not where they are the SCL and SDA pins on the board. Last two pins on battery connector side.
the BME it is from Sparkfun
“SparkFun Atmospheric Sensor Breakout – BME280”
And i trust sparkfun as quality.
I am at the end of the rope.
1.I am using a breakout from sparkfun for BME280:
SparkFun Atmospheric Sensor Breakout – BME280-SEN-13676
The address is by default 0x77 (default, ‘1’ side) – The same like in
Adafruit library:
#define BME280_ADDRESS (0x77) // Primary I2C Address
I tried the simple BME test sketch from
“ESP32 with BME280 Sensor using Arduino IDE (Pressure, Temperature, Humidity)”
and all the time i get the same error:
“Could not find a valid BME280 sensor, check wiring!”
On the Adafruit Feather board : “Assembled Adafruit HUZZAH32 – ESP32 Feather Board – with Stacking Headers”
SCL pin is pin 11 on the battery side and
SDA is pin 12.
I have two identical boards and i exclude possibility to be both of them bad.
Can anybody give me a suggestion because i do not see any one now.
Hi Ion,
I suggest you to try a different sensor. In my case, I didn’t have a BME280 and used other I²C sensors… or better, with analog or one-wire sensors.
One question: The I²C pins in the Adafruit boards follows a different numeration? In all my ESP32 boards the SCL pin is the 22 and the SDA is the 21… this is the other suggestion that I can tell you right now…. I’m not as good as Rui or Sara!
Thank you Eduardo. I will try tomorrow with different sensors if i get them in time. For pinout, i just follow the Adafruit pinout table, not the numbers, like here
“https://learn.adafruit.com/adafruit-huzzah32-esp32-feather/pinouts”
I never used this board.
Now I understand when you said that used pins 11 and 12.
Well, I’ll try to find some free time in this next days and try to organize and document what I built this weekend. I built a project using I²C sensors a ESP32 and a ESP32-CAM. After organizing it I can upload the project to my github, if someone is interested.
As I am new born in the ESP world I am the first to be interested.
Let us know when you are done, so we can benefit from your hard work.
Hi Ion.
The SDA and SCL pins of the Huzzah 32 are: GPIO 23 (SDA) and GPIO 22 (SCL)
By default, our code uses GPIO 21 (SDA) and GPIO 22 (SCL). So, this might be the problem.
I suggest that you run an I2C scanner sketch to see if your board is able to find the sensor. The sketch is this: https://randomnerdtutorials.com/esp32-esp8266-i2c-lcd-arduino-ide/
If it doesn’t detect any sensor on the I2C pins, you need to add a few lines of code so that it uses other I2C pins.
To use other I2C pins, in the setup() add the following:
I2CBME.begin(23, 23, 400000);
Then, initialize the sensor as follows:
if (!bme.begin(0x76, &I2CBME)) {
Serial.println(“Could not find a valid BME280 sensor, check wiring!”);
while (1);
}
This should solve the problem.
Also, this tutorial might be useful: https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/
Let me know the results.
Regards,
Sara
Hello Sara,
First i got an error that i have too many wifi. I tried each one at the time, but no luck. I deleted all. and of course i get
“WiFi.h: No such file or directory”
Which one to download again and use ?
Thank you
The scanner found the bme280 at address 77, for both of them.
How about the I2C address for display?
What is the brand and model of display you used ?
More news tomorrow as i just bought 2 new NodeMCU from Amazon canada with delivery today.
The I2C is on port GPIO 21 and 22.
Hi.
For the display, you can run the same I2C scanner sketch to find out the address.
Our OLED is an SSD1306 model: https://makeradvisor.com/tools/oled-display-128×64-0-96-inch/
We usually get ours from eBay or Banggood.
Regards,
Sara
One LCD it is fund and have 3C address.
The other defective.
The same, i bought new LCD coming today.
I will keep you posted.
Please a link for ESP32 WIFI library you use in the sketch.
Thank you
Hello Sara,
I will do the test immediately.
is it for sure
I2CBME.begin(23, 23, 400000);
because above you said it use pins 22,23 .
“The SDA and SCL pins of the Huzzah 32 are: GPIO 23 (SDA) and GPIO 22 (SCL)”
I’m sorry.
I mean
I2CBME.begin(23, 22, 400000);
Thank you Sara.
I hope by tomorrow will be fixed.
I bought from Amazon Canada 2 new chips with the I2C at GPIO that you use.
What is the link for wifi library you use please .
I made it to work with only one BME280
In the sketch where i do not have BME, i just comment the “while” line like here
” // while (1); ”
Now i have communication on both directions and i wait to get the parts and put them on the breadboard.
One side display on the port monitor the temperature and Hum and Press from the other side like here
13:30:50.317 -> Last Packet Send Status: Delivery Success
13:30:50.317 -> INCOMING READINGS
13:30:50.317 -> Temperature: 25.60 �C
13:30:50.317 -> Humidity: 38.87 %
13:30:50.317 -> Pressure: 987.90 hPa
13:30:58.316 ->
13:30:58.316 -> Bytes received: 12
13:31:00.315 -> Sent with success
And the other monitor, does not have info about the value of temp,hum, or pressure and display
13:32:58.428 -> INCOMING READINGS
13:32:58.428 -> Temperature: 0.00 �C
13:32:58.428 -> Humidity: 0.00 %
13:32:58.428 -> Pressure: 0.00 hPa
13:33:00.362 ->
13:33:00.362 -> Bytes received: 12
13:33:08.426 -> Sent with success
13:33:08.426 ->
13:33:08.426 -> Last Packet Send Status: Delivery Success
I want to Thank You in particular to Sara for patience to babysit me.
I will update tomorrow when i have all the parts.
Thank you ALL.
Hi Geoge,
As I told you yesterday, I was documenting the project I built this weekend using the ESP-NOW and a web server. If you’re interested in something alike in a close future, the link is here: https://github.com/dualvim/ESP32CAM_ESPNOW_Sensors_WebServer
Fell free to ask or suggest anything here or there. Sara and Rui the same thing!
Thank you Eduardo.
Eduardo, What you do for a Power Loss with the RTC ?
Do you have a battery backup ?
The ZS-042 RTC module that I used in the project is a DS3231 RTC chip with a battery. Yes, I have a battery backup to save the time!
Interesting. I have to look closer to it even though it looks big.
I did a thermostat one time and i used MCP7940N.
But of course i did my own PCB and i put it on the same board with the display, and BME680.
You took the IC MCP7940N and built your own PCB with battery? Congratulations! It really looks great!
The ZS-042 may look big, but is because the battery which powers it. It is a CR2032 battery (3V, 2cm of diammeter). The dimensions of the module is 2cm x 4cm.
Also, the ZS-042 is a very nice module to use. It is I²C powered too. Of course the DS3231 don’t have all the features of the MCP7940N, but it solves my problems here!
God luck Ion!
If you write me at [email protected] i can send you a pdf print of the board.
I do all my boards and i am happy to do them how i want, not having a pcb designer doing it 5 times until i am happy.
Some times, i do small changes and it take me few hours and i am done.
It works !!!
New components and now i see the LCD and values sent.
Thanks again to all of you which had patience and help me to get it working.
That’s great!
I’m glad it is working now.
Regards,
Sara
I have a question. I put an extra row on the display after pressure to display the lenght of the bytes received.
Like here
display.print(“Bytes Received: “);
display.print(“len”);
But here of course is just printing len
I tried as a variable like is defined here
Serial.print(“Bytes received: “);
Serial.println(len);
Then i wrote on the display
display.print(“Bytes Received: “);
display.print(len);
and i got an error
ESP-NOW_LEFT:177:17: error: ‘len’ was not declared in this scope
display.print(len);
^
exit status 1
‘len’ was not declared in this scope
What should i write to display the number of bytes received ?
Thank you
Hi Ion.
When you print “len”, it is a String. So, it will output exactly that “len”.
What is happening is that the variable len is defined locally inside the OnDataRecv() function. When you define a variable locally, you can’t access it anywhere else in the code except where it was defined.
You need to create a global variable that can be accessed anywhere in the code. Usually, variables created outside functions are global.
To do that, you can for example: create a variable called messageLength before the setup(), for example:
int messageLength;
Then, inside the OnDataRecv() function update the messageLength variable to match the bytes received. You can add the following line:
messageLength = len;
Now, you can use the messageLength variable to display the number of bytes received:
display.print(“Bytes Received: “);
display.print(messageLength);
I hope this helps.
Regards,
Sara
Thank you Sara.
It works like a charm.
Great! 😀
Hi would it be possible to have a master ESP32 requesting data from 2 slaves and writing data on them?
i´m trying to do something like this: https://i.imgur.com/xvwJgKZ.png
Thank you very much
Yes.
You can do that with ESP-NOW.
Regards,
Sara
Hi,
i want to do the same. Did you managed to run it?
Can i use the code from this example for this?
Thank you, for the very goog tutorial!
greatings Sebastian
*very good
Yes I like the project a lot .What would be nice is a real time graph for the readings done on the biggest color Tiff display you can get. Have the reading and background in different colors. And maybe add some graphics. Just a thought. Thanks for the projects.
Rainman…….
Thanks for the project idea!
hi! can someone help me solve my problem.
i used similar sensor and got this message from serial monitor : “Sent with success
Last Packet Send Status: Delivery Fail”
is it sent or not? I open the serial monitor of the received ESP32 but nothing in the monitor. so it didnt received any data?
Hi Josephine.
That means that the command to send the message was successfully executed but the other board didn’t receive the package.
It can be due to:
– you didn’t inserted the receiver MAC address or you’ve inserted it wrong;
– the receiver structure doesn’t match the sender structure
– you’ve forgotten to upload the receiver code to the other board.
I hope this helps.
Regards,
Sara
Hi,
I am planning to do a project named wireless call buttons. This project has two main devices. One is Button(esp32) and another one is receiver(esp32). The buttons are going to implement in patient rooms in a hospital. The receiver kept in one corner. When the patient press button, the receiver has to receive message from the specific button.
May i know is this possible with ESP, because every floor in hospital has more than 10 rooms and the distance between Room No:10(button10) and receiver will be 200 meters. It may not line of sight also. In my case we should not use internet.
ESP-Now i can use, but my doubt is how 200 meters is possible in this case?
Hi.
You have to experiment. But I’m not sure if it is possible to get a distance of 200 meters inside a building with walls and obstacles – seems very unlikely.
But you really have to try it to figure it out.
Regards,
Sara
Maybe you can use a repeater.
Put a receiver at room No:5, collect data from all 10 rooms and resend it to nurse station – your main receiver. It is unlikely that all the 10 buttons will be pressed in the same time, I mean, same fraction of second and make a collision on the traffic. On the repeater i suggest to have a ESP to receive data, a PIC or whatever processor to store it, and a second ESP to send it further. In this way you have a receiver ESP and a transmitter ESP. You can explore the options. Do not forget, but in the hospitals everything must be redundant. Is like planes or space shuttle. If one line fail, MUST be a second to instantly replace it and keep working.
If the patient in room 8 press the button to call the nurse because he feel ill and needs assistance, that message MUST go to nurse station.
Complementing Ion Gheorghe’s idea, wouldn’t it be nice for Yuvaraj create a Wi-Fi web server with one ESP32 and the others (doesn’t need to be a ESP32, can be a ESP8266, PIC or something cheaper) and when a button in one device is pressed the web server shows to the nurse the exactly device wich pressed the button. To solve the redundancy issue pointed by Ion, the device with the pacient sends the signal continually untill the moment that the nurse do something in the web server to tell to the pacient’s device that he/she received the message (in ESP-NOW, there is a risk of the nurse’s device receive the message but he/she don’t see it because is busy with another pacient). Also, the Wi-Fi repeaters suggested by Ion probably will work better in this sittuation.
Of course, this suggestion is just a guessing that came in to my mind, built over I imagined whe I read Yuvaraj’s comment.
Excelente idea Eduardo.
Of course at nurse station we can get an output of the receiving ESP to drive also a buzzer or similar.
The nurse might be busy surfing the net, chatting on the phone, having a coffee, or …..
BUT, whatever you put in a hospital, be sure it is 1000000% reliable.
The patients and hospitals will not hesitate to sue you for smallest issue.
The system also must pass Safety Approval.
I wanted to propose to a hospital in Toronto a wireless thermostat .
Yes, a dummy thermostat but with a lot of benefits and energy saving for hospital. The safety tests i had to pass, was so expensive that i just renounced. They told me that temperature in some of the rooms is critical, and constantly recorded, and they cannot afford to use whatever system and lose some patients, medicines or similars.
Yes, Ion is more right impossible…
The best suggestion for you, Yuvaraj, is first test your idea in a different space and after beig sure that you figured out in your mins all the suing possibilities (or at least almost, because human creativity is something really to beat) I believe that you can suggest this project for your superiors.
Well thought Ion!
Hi , i have a specific question , i have 100 points(esp8266) that have a button, this button is in deepsleep mode, when the people press the button this button send a data via espnow and go to deepsleep mode, the esp32 that receive the data can support 100 call button ? not all the 100 buttons are pressed at the same time , if this possible or i need maximun 10 call buttons ?
can i register one button send data and after disconect this peer to de server (espnow esp32)…
thanks
Hi.
If all buttons are in deep sleep mode and only the “receiver” is awake, I think you shouldn’t have problems with all the buttons.
It should also work for your scenario, if you simply use the 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF MAC address. All receivers that are awake will receive the message – in your case, it’s just one.
But as I haven’t experimented with so many devices, I can’t really tell what happens with all those buttons.
Regards,
Sara
Hello Paolo,
What i see:
1-Buttons are not registered anywhere. As long as as you tell them where to send data – MAC – they do not care how many they are, nor the receiver knows in advance, and you can have in my opinion 1000s.
2-You said, that not every button is pressed in the same time. This is a very fine statement. Button 1 is pressed now, and button 2 is pressed a fraction of second after.
So while the server is busy receiving data from button 1, data from button 2 is lost.
This involve your creativity in coding. Each message sent must have the MAC of sender. The receiver, must acknowledge the sender back that the message arrived in full.
The sender button does not have to go to sleep, or permit another press until he get the response that his first message was received OK. If the receiver button does not get the acknowledge reply in let’s say 100 ms, it has to resend the message.
100ms it is a pure imaginary value. By trying with one button only, you can find out the total time until you get the response, and replace the 100 ms.
So, the transmitter button, will resend the message until it receive the acknowledge that the message was received.
Here it is the BIG picture of 100 buttons or more.
Imagine an army of messages at the gate of receiver , trying to be received by the server.
Of course, one by one in time will be received, and finally the last one is in. But during all that period, all the buttons waiting a reply, will not respond to eventual users, nor sleep.
BUT your purpose of the buttons is to send SUCCESSFULLY a message to server.
Try to imagine …..
Hi, Can esp32 join any WiFi network and same time used ESP-NOW to send data to other esp32.
Yes.
You can do that.
Regards,
Sara
Amazing post!
Hey guys, thanks a lot for your explanation!
In my case i have one ds18b20 sensor connectedto one board and i have another board sending the measurement interval and resolution to this board in order to perform the measurements following the interval and resolution that it has received.
My problem is that when i send the interval and resolution to the second board it only works correctly when both boards are close. When they are a bit more far away, it only receives the interval, instead, it doesn’t update the resolution values.
I send the data like you the temp, hum, pres.
Is it possible that due to the distance, it only receives a part of the message correctly (interval) and lose the resolution part? I thought that if the message reached the destination, reached the whole message.
I calculate that interval reachs up to 18 m, instead, interval and resolution values only reach up to 12 m.
I don’t know if you, Rui and Sara or someone have faced this kind of problems, but i would thank a lot your help.
I’m looking forward to hearing from you!
Hi.
That issue is very strange. It seems that due to the distance, it doesn’t receive the whole message.
Maybe you can try sending different messages. One with the interval and other with the resolution one after the other and see if that solves the problem.
Regards,
Sara
Hi Sara. But if both messages come from the same board, how can i identify them as an interval message and resolution message?
Normally i identified the message by the MAC of the board coming from. But in this case both messages come from the same board, so both have the same MAC.
Thank you!
Hi.
You can send the messages as a string, in which the interval message starts with an i and the resolution message starts with an r: for example
“i20”
“r1250”
Then, on the receiver, you can split the strings to get only the number. Then, you can convert them to int or float or other variable type is more suitable.
This is just a suggestion.
Regards,
Sara
where can i find esp_now.h i look thruogh hole web and no luck
Hi.
This code only works with ESP32.
If you try to use it with ESP8266 you’ll get that error.
For the ESP8266, you can follow this tutorial and adapt to exchange sensor readings: https://randomnerdtutorials.com/esp-now-esp8266-nodemcu-arduino-ide/
Regards,
Sara
Guys did you ever do a ESP8266 version of this example, specifically using OLEDs on both the Sender / Receiver
Further to my request above do we have a tutorial on using ESP NOW between ESP32 and ESP8266. sure it will be of value to many. Cheers
Hi.
No, I don’t have that specific project.
But what you have to do for the ESP8266 is to combine a sender and receiver ESP8266 code on the same sketch.
Regards,
Sara
Hey,
I am trying to create a Wi-Fi mesh using esp32 where one esp32 node (AP) is connected to a webserver (as demonstrated in your tutorials) and the other esp32 nodes communicate with each other using esp-now ( 2 way communication). My question is how do i Incorporate the client-server and peer to peer infrastructure in one to complete a mesh.
I am also trying to generate hops between esp32 incase one is out of range of the AP. I’d appreciate your help.
Thanks
Hi.
To do that, you need to define a Wi-Fi channel for the access point and a different wi-fi channel for ESP-NOW.
We’ll be publishing a project with Wi-Fi + ESP-NOW soon, so stay tuned.
Regards,
Sara
Hi Sara
Have you got a link to this project yet?
thanks
Nick
Hi.
Here’s the project: https://randomnerdtutorials.com/esp32-esp-now-wi-fi-web-server/
Regards,
Sara
hi im using espnow on 2 * esp32s, one as a master sending data and 1 as a slave recieving data, I have seen examples where a master can send to many slaves. is there any examples of a slave recieving sensor details from more than 1 master. maybe in a closed mesh network??
board 1 data send >>>
board 2 data send >>>
board 3 data recieve <<<<<< from board 1 and board 2?????
Hi Rik.
Yes, you can follow this tutorial: https://randomnerdtutorials.com/esp-now-many-to-one-esp32/
I hope this helps.
Regards,
Sara
HI,
Working with this code from the beginning, I now have bidirectional comms sent over ESP-NOW. But I am only in the beginning of my code. One ESP32 has a couple of DS18B20s, and it sends indoor and outdoor temperatures to it’s local display, and the remote ESP32’s display too. (GREAT! BTW!!). I created a new struct for information of switch (button) states on the return from the remote, That data will eventually act as remote control switches for functions on the local. The switches are readable on the local, so the rest will be trivial, but I came to a question because I would like to save space.
Why do you have local variables as well as a struct for the data? My guess is because then you can use one struct to transmit either way. Is this the case? And, since I am using different data and 2 structs, then I should be able to omit the local global variables and just use the struct variables throughout the code, (since the structs are global) correct? Or am I missing something?
Thanks,
Dave K
Hello
I’m trying something that I assumed would be simple — sending 4 digits from one esp32 board to a second esp32 board.
I’ve copied and pasted the SENDER and RECEIVER sketches from the https://randomnerdtutorials.com/esp-now-two-way-communication-esp32/ page. The RECEIVER sketch uploads without trouble. But I am having trouble with the SENDER sketch.
I tried both verifying and uploading the SENDER sketch as copied and both are fine. But when I replace the MAC address {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} with the MAC address of the RECEIVER it fails. It highlights line 16… “uint8_t broadcastAddress1[] = {24:6F:28:2B:0A:88};”
and gives the error message… “expected ‘}’ before ‘:’ token” .
I have done nothing more to the code other than remove reference to the broadcast addresses 2 and 3, which aren’t needed
I see the formatting of the MAC address I have inserted is different to that in the copied sketch, but this is how it was returned when I followed the procedure to get the MAC address of my RECEIVER board.
Any suggestions would be gratefully appreciated.
Hi Andrew.
If your MAC address is 24:6F:28:2B:0A:88
You should place it like this:
uint8_t broadcastAddress1[] = {0x24, 0x6F, 0x28, 0x2B, 0x0A, 0x88};
I’m sorry if that is not clear enough.
I hope you get it working now.
Regards,
Sara
hola Sara. Escribote en galego porque sendo portuguesa imaxino que entenderas ben.
Gustoume moito o teu tutorial. Levaba moitisimo tempo na procura de alguen que conseguira unha comunicacion nos dous sentidos cas esp32.
A parte do LCD e o sensor non me fai falta pero tentarei sacar do teu codigo a parte da comunicacion porque vale ouro.
Moito obrigado Sara!
Olá Luís.
Muito obrigada pelo teu comentário.
Fico contente que o tutorial te tenha ajudado.
Cumprimentos,
Sara Santos
Olá de novo Sandra.
Andiven a traballar onte no teu codigo pero non sei o que fago mal que nin tan sequeira vense no bluetooth do movel.
eu so quero mandar bits dun o outro e o reves.
Iste é o meu codigo, a ver se seche ocurre cal é o problema:
#include <esp_now.h>
#include <WiFi.h>
#include <Wire.h>
uint8_t broadcastAddress[] = {0x24, 0x0A, 0xC4, 0x60, 0xB5, 0x3C}; //MAC ROBOT. Direccion de envio
int salida0=0;
int salida2=2;
int entrada4=4;
int entrada5=5;
int buttonState = 0;
int dato1;
int dato2;
int dato3;
int dato4;
int recibido1;
int recibido2;
int recibido3;
int recibido4;
typedef struct struct_message {
int dat1;
int dat2;
int dat3;
int dat4;
} struct_message;
struct_message datos_propios;
struct_message datos_recibidos;
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status){
}
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&datos_recibidos, incomingData, sizeof(datos_recibidos));
recibido1 = datos_recibidos.dat1;
recibido2 = datos_recibidos.dat2;
recibido3 = datos_recibidos.dat3;
recibido4 = datos_recibidos.dat4;
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
pinMode (salida0, OUTPUT);
pinMode (salida2, OUTPUT);
pinMode (entrada4, INPUT);
pinMode (entrada5, INPUT);
if (esp_now_init() != ESP_OK) {
Serial.println(“Error initializing ESP-NOW”);
return;
}
// Register peer
esp_now_peer_info_t peerInfo;
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {
getReadings();
datos_propios.dat1 = dato1;
datos_propios.dat2 = dato2;
datos_propios.dat3 = dato3;
datos_propios.dat4 = dato4;
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &datos_propios, sizeof(datos_propios));
buttonState = digitalRead(recibido4);
if (buttonState == HIGH) {
// turn LED on:
digitalWrite(salida0, HIGH);
} else {
// turn LED off:
digitalWrite(salida0, LOW);
}
}
void getReadings(){
dato1 = salida0;
dato2 = salida2;
dato3 = entrada4;
dato4 = entrada5;
}
bo dia Sara
Hi.
What do you mean that you can’t see it using bluetooth?
This is ESP-NOW communication protocol, it is different than bluetooth.
Regards,
Sara
I don´t understand. your code isn
t able to communicate anything by bluetooth? only by serial port?.
t find the way to do it or send something from one to another.It´s assumed that the esp has bluetooth and wifi but i can
Do you know what kind of instructions i have to look for to achieve my goal?
if not for esp at least for a couple of hc-05 i have.
Thank you very much for your time and attention Sara.
Have a nice day
Hi.
This specific tutorial is for ESP-NOW.
We have other tutorials about bluetooth.
https://randomnerdtutorials.com/esp32-bluetooth-low-energy-ble-arduino-ide/
https://randomnerdtutorials.com/esp32-bluetooth-classic-arduino-ide/
Regards,
Sara
This is brilliant. I have managed to create a Master which can connect to 3 Clients individually. The clients control vertical window blinds.
I have entered the three Client MAC addresses into the Master code as such:
uint8_t broadcastAddress[][6] = {
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
};
(These MAC addresses here are not the exact ones of course) I then control any one of the three blinds by sending different values using a TFT touch screen.
Everything works perfectly fine but I would like to store the MAC address on the SD card, then call the address from the SD card and fill them into the uint8_t broadcastAddress[] [] array.
The reason I want to do this is that if I want to add more blind controllers in the future I can just add them to the text file on the SD card instead of having to modify the Master code.
However, when I try to do this it tells me I can’t cast String to uint8_t which is quite obvious really.
So, is there a way to copy the MAC address String from the SD card into the uint8_t array?
I can convert the text file into HEX format and print them but I can’t fill them into the array in the same format as the code requires.
Hope all this makes sense!!
I had a problem with an error when attaching a peer:
ESPNOW: Peer interface is invalid.
One solution I found was to make the creation of peerInfo global.
If you want to keep it local to the setup function, then it has to be initialised to zeros before changing any of the entries. I used
memset(&peerInfo, 0, sizeof(peerInfo));
I’m assuming that when the structure is created on the heap it probably contains invalid data.
I hope this helps someone.
Regards, Ian
Thank you very much, very helpful!
Yes, indeed, this part of memory is clogged with some data, if initialized during operation from a function, and it must be cleared.
I try to add a Telegram communication to the 2-way ESP NOW project. It did not work.
Is it correct the Wifi used by ESP NOW can not be connected to the internet as the same time?
Thanks for clarification.
Hi Rui and Sara
Do you know if it is possible to use ESP-NOW with MicroPython on the ESP-32? If so, do you have a tutorial on it?
Cheers
Andy
Hi, I have two esp32s talking to each other.
One of them sends a message then does an action. The other one receives the message, does the same action and then sends a message back.
I need them both to be in sync with each other so the actions cant be done without the message being passed between them, however I am having to put a delay in the loop or else the messages dont get sent and received properly, do you know if this is because the loop is going too fast for the esp-now to keep up?
Any help would be appreciated
Hi Pete, I also meet this question, and I just test if the delay in loop is more than 10ms, the sync will be ok, however when I set the delay in loop is less (for example 5ms), the communication between those board will be chaos.
So have you solve this question? can we have exchange some idea or discuss with each other?
My email address: whensveny at gmail.com.
Hello
Can I get Rssi information when two esp32 are communicating.
With the function rssi = WiFi.RSSI ();
Hi Rui,
I am trying the similar example but sending 5 flex sensor values from one esp to another i.e one being the master and the other being the slave
The problem i am facing is that the receiver doesn’t get updated values when flex sensor value changes i have to reset the master to receive the updated value
I am using your master/slave example
Please let me know if you can help
Hi Rui/Sara
I am sending flex sensor values from one esp to another esp but on the receiver side the values don’t update unless i push the reset button on the sender esp
Can i know why this is happening?
Hi,
I am been trying to set up a 2 way com between 2 ESP32 boards and MLX90614 sensors.
Each board has a sensor and OLED display and I want Board 1 to send temp readings to Board 2. But hey don’t seems to be working. Can you help med with issue?
//Jay
I am having a strange Problem., As soon as I move my OnDataRecv Function to any tab other than first tab, even if it is on top of second tab (before setup and loop , which are on third or fourth tab); The Error
‘esp_now_send_status_t’ has not been declared
appears while compilation/verification; this error appears in OnDataSent Function. If I move OnDataRecv back to end of first tab, verification is done , code works perfectly.
Even if I split the code from above example at OnDataSent … into two tabs … , no change in sequence of commands this error occurs
I have also created a discussion on Arduino Forum on this too at following link:
https://forum.arduino.cc/t/espnow-compile-error-esp-now-send-status-t-has-not-been-declared/871040?u=athersaleem
I have the same problem, as soon as i move the callback to another tab this error occurs. it’s kind of strange, if you find the solution please tell me
Update: I’ve just found a solution to the problem, what i understood is that function prototype of this callback is missplaced at some point and defaults is type to int instead of esp_now_send_status_t, so you only need to put the function prototype of your callback at the first ino file, the one named same as your project folder and the code now compiles without problem, i´ll leave this explanation in spanish because i can explain more clearly.
Actualizacion: Acabo de encontrar una solucion para el problema, al parecer todo tiene que ver con que el prototipo de la funcion de callback se pierde en algun punto antes de incluir los archivos de la libreria esp_now y por eso no encuentra la definicion de esp_now_send_status_t y lo define por defecto como int, entonces lo unico que hay que hacer es declarar el prototipo de la funcion callback en el archivo ino principal, el que tiene el mismo nombre que la carpeta y todo compila bien. Espero te ayude.
Hey, could you please share the code for this. I do not understand how to declare the prototype of the callback function as mentioned in the response 🙁
This tutorial has been a great help to me! A question for you: it appears that all stations are constantly listening for incoming information, even while executing other code; is this true? If so, what is a good way to suspend receiving information until desired? Thanks for your work putting these tutorials together.
Jack
Hello, first of all congratulations for the project.
In your project, you read data from boards every 10 seconds. How faster can I do the same? I’ve to read data every 10ms. Is It possible?
Regards
Maria
Hello Maria,
Just an advice.
I believe reading data is more related to the sensor update time.
I did not read the sensor data sheet, but i believe it is marked somewhere in small letter how fast the sensor update itself.
Then, second step is to take in consideration how long it take for a transmission and receiving the message if the transmission was received or not.
Once you have these parameters you calculate the scan time of a program and reduce your update time.
This is just my opinion.
Hi Ion. First of all, thank you.
My sensors update time is 10ms. My concerns are about the transmission.
I am trying to set up a two-way communication multiple-to-one and I need the central receives signal every 10ms from each board. Do you think that is possible?
Hi what part whould you have to change to control 2 relays?
of the code
Hello, is it possible to have like a combo unit in which you can receive from manny and send some data to a specific selected address?
Yes.
You can do that.
You can read the following tutorial to learn how to receive data from many:
– https://randomnerdtutorials.com/esp-now-many-to-one-esp8266-nodemcu/
And, you just need to add the code to send data to the address you want.
Regards,
Sara
i pair both esp32 after change mac address
it detect slave device
when changing mac address
first step
not accepting verify fail
Hi.
Can you better explain your issue?
Regards,
Sara
first of all thank you all so much for this toturial : Muito Obrigado
era isto que procurava para o meu projecto.
a questao que tenho e em x de ser um sensor de humidade e ter um ecra posso so ter tipo uma wireless box a comunicar entre os 2 esp32
num liga 4 fios que sao envio e recepcao de comunicao e no outro a mesma coisa e fazerem a partilha de dados como esta no vosso projecto.
obrigado pela atencao
Olá MArco.
Sinceramente, não sei. Nunca tentei tentei integrar uma wireless box.
Cumprimentos.
Sara
Hi Maria,
I love your examples and made them work,no problem with transmitting strings,chars,int…
Notherless i’ve got a problem with a two-ways CHAT between two nextion screens wired
on serial and i think it’s interrupts problem,i have to often reset one esp32 to begin receive
or sending.
Strange hat this problem doesn’t occur with the two arduino monitors
attributed to two serial ports,it works in each monitors without any interruption.
I tested it with two nextion simulators at the same time and the problem appears again.
I also tried with hardware serial in each esp32 wired to nextion,but the same.
i don’t use any millis delay in my sketches.
To resume,it work one,two times and then nothing unless i reset the esp32.
What’s going on?
Hi,
Thanks for your great tutorials!
I have tried unsuccessfully to send and receive two different structs using ESP32_NOW. It appears to send ok but the data seems to be received in a slightly blended way, I suspect it might have something to do with memory?? Is it possible to do? The reason I ask is because of the 250 byte struct size restriction on send.
Any advice or sample code would be gratefully accepted.
Regards
Geoff
RNT Fan
Hi Geoff.
The data structure must be the same on the sender and receiver.
Regards,
Sara
I’m starting a project and I’m having trouble doing it with 4 boards. 3 of these cards connected to one.
This main sends and receives data from the others, would it be possible to do this?
Yes.
It is possible.
Check all the other ESP-NOW tutorials that might help:
ESP-NOW with ESP32: Send Data to Multiple Boards (one-to-many)
ESP-NOW with ESP32: Receive Data from Multiple Boards (many-to-one)
Hi,
Great tutorials!
I have 2 way comms on 2 ESP32’s via ESP-NOW, is it possible for one of the ESP32’s to also act as a webserver or would I need a 3rd ESP32 to be the webserver receiver?
Thanks
Steve
Yes.
See this tutorial: https://randomnerdtutorials.com/esp32-esp-now-wi-fi-web-server/
Regards,
Sara
A complete treasure trove of stuff on RNT keep it up you two wonderful people, thank you for all the great stuff.
I am collecting parts for a combo of many of you tutorials and this one fills in a lot of gaps.
I want to have a plethora of esp8266 connected sensors some mains powered and some solar and/or deep sleep.
I have deduced a data structure that will encompass all the various readings I want to see and will devise a ‘no data in here’ for esp remotes that are for other readings.
I was going to create a many to one but I will see if I can create essentially 2 receivers to receive the same data. (How would you describe Many to Two?)
The idea is that I want to put 2 tft colour screens with the data shown graphically off the back of 2 esp32 in different rooms of my home. They will display live data from the sending esp8266 sensors.
I want to monitor some 12 volt batteries, a greenhouse, some outside weather devices, my roof space and temperature in different parts of my home and garden.
Sounds a lot but isn’t really, I was going to use your web server and gleam the data from json but after seeing this I am hoping to use the tft screen esp’s to allow me to send control back to some of the esp8266.
It’s going to be a slow process as I start small and slowly add the remote esp8266 and work out their bit too.
This is a quick draft of my generic data structure that will give me some flexibility. Voltage will be those on battery power and each remote head will be monitored for temperature using ds18b one wire chips
EspNow Board
Device ID 2
Device Name – Text N+2
Device Voltage- Float 4
Device Temperature- Float 4
Maintenance Mode – Boolean 1
Alarm – Boolean 1
Sensor1 – Float 4
Sensor1 – Text X+2
Sensor2 – Float 4
Sensor2 – Text Y+2
Digital In – Integer 2
Digital Out – Integer 2
Byte Count = N+X+Y+40
It shows hopefully how data can be mixed up and still be very much smaller that 250bytes
I haven’t worked out how as yet but a byte is 8 bits so I have the potential to read and write 8 digital devices using just the 2 digital integers. I suspect I will limit the text name too so as to increase reliability.
It’s going to take a while but maybe you’ll be impressed in time?
Cheers Clive
HI Sara & Rui,
I have tried your example above with slight variations.
I am just sending data to one ESP32 board from another ESP32 board. The boards are working with the serial monitor. I see the receiver board getting the data but if I disconnect the serial cable and battery power the sender or the receiver then the there is no data transmission. I cannot figure out why?
//Jay
Jay, have you found what caused this? I am trying to get two-way communication working. One ESP32 being powered by a battery. I have not got it to work, I am thinking I have the same issue as you.
Great tutorial and well presented.
I am new to ESP32s and trying to get basic two way communication working for a project. I simplified your examples to just use potentiometers and the serial monitor. I always get the error “Error sending the data”. I used the MAC addresses I found using your code then I also used the common MAC address {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} and still had no luck. I confirmed the ESP32s work by using the Arduino ESP32_NOW master/slave example sketch.
Here is the code I used:
#include <esp_now.h>
#include <WiFi.h>
// REPLACE WITH THE MAC Address of your receiver
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
// Define variables to store BME280 readings to be sent
int Pot_Val;
// Define variables to store incoming readings
int incomingpot;
// Variable to store if sending data was successful
String success;
//Structure example to send data
//Must match the receiver structure
typedef struct struct_message {
int pot;
} struct_message;
// Create a struct_message called BME280Readings to hold sensor readings
struct_message BME280Readings;
// Create a struct_message to hold incoming sensor readings
struct_message incomingReadings;
// 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(status == ESP_NOW_SEND_SUCCESS ? “Delivery Success” : “Delivery Fail”);
if (status ==0){
success = “Delivery Success :)”;
}
else{
success = “Delivery Fail :(“;
}
}
// Callback when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
Serial.print(“Bytes received: “);
Serial.println(len);
incomingpot = incomingReadings.pot;
}
void setup() {
// Init Serial Monitor
Serial.begin(115200);
// 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);
// Register peer
esp_now_peer_info_t peerInfo;
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;
}
// Register for a callback function that will be called when data is received
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {
getReadings();
// Set values to send
BME280Readings.pot = Pot_Val;
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &BME280Readings, sizeof(BME280Readings));
if (result == ESP_OK) {
Serial.println(“Sent with success”);
}
else {
Serial.println(“Error sending the data”);
}
updateDisplay();
delay(1000);
}
void getReadings(){
Pot_Val = analogRead(34);
Serial.println(Pot_Val);
}
void updateDisplay(){
// Display Readings in Serial Monitor
Serial.println(“INCOMING READINGS”);
Serial.print(“Pot “);
Serial.print(incomingReadings.pot);
Serial.println();
}
how do i convert my mac adress to uint8
Excellent question, if you find an answer please share it. Whomever wrote this tutorial clearly has their head up their ****.
you put 0x before each of the digits so C8, F0, 9E, 79, 3E, 94 becomes 0xC8, 0xF0, 0x9E, 0x79, 0x3E, 0x94
Even I am facing same issue.
compilation error in arduino IDE:
error: invalid conversion from ‘void ()(const uint8_t, const uint8_t*, int)’ {aka ‘void ()(const unsigned char, const unsigned char*, int)’} to ‘esp_now_recv_cb_t’ {aka ‘void ()(const esp_now_recv_info, const unsigned char*, int)’} [-fpermissive]
138 | esp_now_register_recv_cb(OnDataRecv);
I have two questions. First, my receiving Slave ESP32’s are using batteries and must go into DeepSleep. The ESP User’s Guide states that STAION mode alone should not be used for receiver’s using deep sleep. Why is this and what mode should I use, and will this require other codes changes? My second question is If a receiver is asleep when a message is sent, does the Master automatically resend the message until the Slave awakens and receives the message?
Hello
Good time
How can I program this connection as a broadcast for this protocol?
I see you use a broadcast MAC address to send the message to everyone. This means that I can have more than 2+ units and being able to communicate with each other?
thank you
Oz
Yes.
Thank you very much for this Great tutorial. I have a question. Why is used the memcpy instruction? Is not posile to assign data as always (=)?
In this part foe example:
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
Serial.print(“Bytes received: “);
Serial.println(len);
incomingTemp = incomingReadings.temp;
incomingHum = incomingReadings.hum;
incomingPres = incomingReadings.pres;
}
It Could be something like:
incomingTemp = incomingData.temp; etc, without the memcpy instuction?
Thank you very much 🙂 .
Hi,
Thank you very much for this Great tutorial. I have a question.
is it possible to read from Rx Tx on ESP32 datas incoming from à RS485 TTL modul send throught ESP NOW reciev by an other ESP32 and write to RX TX to a RS485 modul
(a transparent RS485 passtrough bridge ) ?
Hi and thank for this great tutoral,
is it possible with ESP NOW to (bridge serial ports ) ?
i need to RS485 modul > rx tx to ESP32 > wireless communication > ESP32 > rx tx to RS485 modul.
Can we use this range for many to one ESP Now communication?
Thank you for your excellent tutorial.
Using your tutorial I have easily been able to get two ESP32 modules with ESP-NOW talking to each other.
But one thing I have not been able to figure out is how to detect when loss of incoming packets happens at the Rx. When the Tx is shut off the Rx just keeps chugging along on the last data sent.
Hi,
Do they need to know each other before communication?
Is possible to have a master wait for random unknown communication, and the slaves hold the key to authenticate in the master?
Something like that.
Thank lá
Hugo
Hi.
You can do all that manually, since the master can use the FF:FF:FF:FF:FF MAC address to send data to all available devices.
After that, you can try to handle the connections.
Regards,
Sara
Hi, first of all, thank you for this tutorial. It is working on my end.
Just a question, if ESP-NOW protocol doesn’t need Wi-Fi to have multiple devices to communicate with each other, why there is a declaration of WiFi.h and the initialization of WiFi.mode(WIFI_STA) in your code? Is it possible to remove them?
Thanks
Daniel
Is it possible to find RSSI ( Received Signal Strength Indication ) in ESP – NOW. If so can you please share
Hi.
This code contains some lines to get the RSSI:
https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/ESPNow/Basic/Master/Master.ino
I hope this helps.
Regards,
Sara
wondering if esp-now protocol makes sure the packet is send and received? So, when I send something and the status of the on_data_send call is success, does that imply the other side has actually received the data? If the other side is out-of-range or the communication fails otherwise, will the call to on_data_send have a status of “fail”.
Or do I need to write my own code with two-way communication to ensure the data was processed on the receiving end?
Hi.
You need to write your own code with two-way communication to ensure the data was received.
Redgards,
Sara
If you are unicasting to a specific peer MAC address, the on_data_send success means that an acknowledgement was received back from that peer that the data was received accurately. That is part of the 802.11 action frames protocol that ESP-NOW uses. There is a really good explanation of this in MrDIY’s video about it youtube.com/watch?v=Xmzk6v5qIjo
Please note that this only acknowledges that the packet was received error free. What your device does with the received data is up to you. If your data is absolutely critical, it’s probably not a bad idea to write your own checksum verification and have your application acknowledge separately. For my immediate application, I only need to send a byte or two that contain a simple command. If my byte matches what the remote unit is expecting, that’s good enough for me 🙂
Would it be possible to adapt this idea to having 4 buttons on one esp32 and 4 relays on another esp32, then just have the button presses actuate the relays through bluetooth? The buttons would be momentary switches and need to mimic that same function with the relays.
I se as very possible and not difficult. From the ESP connected to the buttons, you send a message with the state of the four buttons by ESP-NOW and the receiver ESP replicate the states of the buttons in the relay module. So, when the the programmed state in a button change, the sender send another message to the receive and it replicate then in the relays.
Of course, it’s only a possibility that I thought here, when I read your message. Probably there are another ones.
Yes, as for Eduardo’s rely, I would also suggest using interupts to detect a momentay on button press.
problem, for compile from mac aderss
Compilation error: unable to find numeric literal operator ‘operator””b’
dont accept mac address
uint8_t broadcastAddress[] = {e8:6b:ea:d0:c9:c4};
Hi.
You should pass the address in the following format:
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
In your case, it will be:
uint8_t broadcastAddress[] = {0xE8:0x6B:0xEA:0xD0:0xC9:0xC4};
I hope this helps.
REgards,
Sara
Hi, good night.
I’m Brazilian, sorry for my English.
I’m using Arduino IDE 2.3.2, directly on the ESP32-WROOM-32D board, configured in the IDE as “ESP32 DEV MODULE”; compiling your sketch “ESP32 Two-Way Communication ESP-NOW Code”, I got the compilation errors below. Can you help me? thanks in advance.
C:\Users\renat\Documents\Arduino\Testes\EmTestes\EmTestes\TxRx\ExemploRandomNerd\ExemploRandomNerd.ino: In function ‘void setup()’:
C:\Users\renat\Documents\Arduino\Testes\EmTestes\EmTestes\TxRx\ExemploRandomNerd\ExemploRandomNerd.ino:129:28: error: invalid conversion from ‘void ()(const uint8_t, const uint8_t*, int)’ {aka ‘void ()(const unsigned char, const unsigned char*, int)’} to ‘esp_now_recv_cb_t’ {aka ‘void ()(const esp_now_recv_info, const unsigned char*, int)’} [-fpermissive]
129 | esp_now_register_recv_cb(OnDataRecv);
| ^~~~~~~~~~
| |
| void ()(const uint8_t, const uint8_t*, int) {aka void ()(const unsigned char, const unsigned char*, int)}
In file included from C:\Users\renat\Documents\Arduino\Testes\EmTestes\EmTestes\TxRx\ExemploRandomNerd\ExemploRandomNerd.ino:16:
C:\Users\renat\AppData\Local\Arduino15\packages\esp32\tools\esp32-arduino-libs\idf-release_v5.1-442a798083/esp32/include/esp_wifi/include/esp_now.h:157:54: note: initializing argument 1 of ‘esp_err_t esp_now_register_recv_cb(esp_now_recv_cb_t)’
157 | esp_err_t esp_now_register_recv_cb(esp_now_recv_cb_t cb);
| ~~~~~~~~~~~~~~~~~~^~
exit status 1
Compilation error: invalid conversion from ‘void ()(const uint8_t, const uint8_t*, int)’ {aka ‘void ()(const unsigned char, const unsigned char*, int)’} to ‘esp_now_recv_cb_t’ {aka ‘void ()(const esp_now_recv_info, const unsigned char*, int)’} [-fpermissive]
Hi.
There were breaking changes from ESP32 boards version 2 to version 3.
You’re probably using version 3.
Downgrade to version 2 while we don’t update the codes for the newest version.
Go to Tools > Board > Boards Manager, search for ESP32 and downgrade to version 2.
Regards,
Sara
Hi Sara! I downgraded the ESP32 to 2.0.17 and everything worked perfectly. Thank you for your help!
Hi Rui,
I want to read 3 x DS18B20 temperature sensors on a Wemos &Bluetooth Battery board and send on an other Wemos &Bluetooth Battery board. I use your sketch above (ESP32 Two-Way Communication ESP-NOW), “mixed” with your sketch : https://randomnerdtutorials.com/esp32-ds18b20-temperature-arduino-ide/#more-86576. It doesn’t compile: the main problem seems to be the GPIO declaration (herebelow the 2 first error messages) :
In file included from c:\Users\papa\Documents\Electronique\libraries\OneWire\OneWire.cpp:144:
c:\Users\papa\Documents\Electronique\libraries\OneWire\util/OneWire_direct_gpio.h: In function ‘uint32_t directRead(uint32_t)’:
c:\Users\papa\Documents\Electronique\libraries\OneWire\util/OneWire_direct_gpio.h:134:17: error: ‘GPIO’ was not declared in this scope
134 | return (GPIO.in >> pin) & 0x1;
c:\Users\papa\Documents\Electronique\libraries\OneWire\util/OneWire_direct_gpio.h:136:17: error: ‘GPIO’ was not declared in this scope
136 | return (GPIO.in1.val >> (pin – 32)) & 0x1;
…… and so on…..
Is there a compatibility problem of ESP-NOW with OneWire library ?
Thanks for your help.
Regards.
You can remove my previous message, my sketch runs correctly now !
Sorry for the disturbance….
You can remove my previous hereabove message, my sketch runs correctly now !
Sorry for the disturbance….