In this project, you’ll learn how to host an ESP32 web server and use ESP-NOW communication protocol at the same time. You can have several ESP32 boards sending sensor readings via ESP-NOW to one ESP32 receiver that displays all readings on a web server. The boards will be programmed using Arduino IDE.
We have other guides related to ESP-NOW that you might be interested in:
- Getting Started with ESP-NOW (ESP32 with Arduino IDE)
- ESP-NOW Two-Way Communication Between ESP32 Boards
- ESP-NOW with ESP32: Send Data to Multiple Boards (one-to-many)
- ESP-NOW with ESP32: Receive Data from Multiple Boards (many-to-one)
Watch the Video Tutorial
Note: we’ve updated this tutorial with a better method to use ESP-NOW and Wi-Fi simultaneously. The video doesn’t use this current method. You can still watch the video to see how everything works, but we recommend that you take a look at the written article.
Using ESP-NOW and Wi-Fi Simultaneously
There are a few things you need to take into account if you want to use Wi-Fi to host a web server and use ESP-NOW simultaneously to receive sensor readings from other boards:
- The ESP32 sender boards must use the same Wi-Fi channel of the receiver board.
- The Wi-Fi channel of the receiver board is automatically assigned by your Wi-Fi router.
- The Wi-Fi mode of the receiver board must be access point and station (WIFI_AP_STA).
- You can set up the same Wi-Fi channel manually, or you can add a simple spinet of code on the sender to set its Wi-Fi channel to the same of the receiver board.
Project Overview
The following diagram shows a high-level overview of the project we’ll build.
- There are two ESP32 sender boards that send DHT22 temperature and humidity readings via ESP-NOW to one ESP32 receiver board (ESP-NOW many to one configuration);
- The ESP32 receiver board receives the packets and displays the readings on a web server;
- The web server is updated automatically every time it receives a new reading using Server-Sent Events (SSE).
Prerequisites
Before proceeding with this project, make sure you check the following prerequisites.
Arduino IDE
We’ll program the ESP32 boards using Arduino IDE, so before proceeding with this tutorial, make sure you have the ESP32 board installed in your Arduino IDE.
DHT Libraries
The ESP32 sender board will send temperature and humidity readings from a DHT22 sensor.
To read from the DHT sensor, we’ll use the DHT library from Adafruit. To use this library you also need to install the Adafruit Unified Sensor library. Follow the next steps to install those libraries.
1. Open your Arduino IDE and go to Sketch > Include Library > Manage Libraries. The Library Manager should open.
2. Search for “DHT” on the Search box and install the DHT library from Adafruit.
3. After installing the DHT library from Adafruit, type “Adafruit Unified Sensor” in the search box. Scroll all the way down to find the library and install it.
After installing the libraries, restart your Arduino IDE.
To learn more about the DHT11 or DHT22 temperature sensor, read our guide: ESP32 with DHT11/DHT22 Temperature and Humidity Sensor using Arduino IDE.
Async Web Server Libraries
To build the web server you need to install the following libraries:
These libraries aren’t available to install through the Arduino Library Manager, so you need to copy the library files to the Arduino Installation Libraries folder. Alternatively, in your Arduino IDE, you can go to Sketch > Include Library > Add .zip Library and select the libraries you’ve just downloaded.
Arduino_JSON Library
You need to install the Arduino_JSON library. You can install this library in the Arduino IDE Library Manager. Just go to Sketch > Include Library > Manage Libraries and search for the library name as follows:
Parts Required
To follow this tutorial, you need multiple ESP32 boards. We’ll use three ESP32 boards. You also need:
- 3x ESP32 (read Best ESP32 development boards)
- 2x DHT22 temperature and humidity sensor – DHT guide for ESP32
- 2x 4.7k Ohm resistor
- 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 Receiver Board MAC Address
To send messages via ESP-NOW, you need to know the receiver board’s MAC address. Each board has a unique MAC address (learn how to Get and Change the ESP32 MAC Address).
Upload the following code to your ESP32 receiver board to get its 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.
*/
#ifdef ESP32
#include <WiFi.h>
#include <esp_wifi.h>
#else
#include <ESP8266WiFi.h>
#endif
void setup(){
Serial.begin(115200);
Serial.print("ESP Board MAC Address: ");
#ifdef ESP32
WiFi.mode(WIFI_STA);
WiFi.STA.begin();
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");
}
#else
Serial.println(WiFi.macAddress());
#endif
}
void loop(){
}
After uploading the code, press the RST/EN button, and the MAC address should be displayed on the Serial Monitor.
ESP32 Receiver (ESP-NOW + Web Server)
The ESP32 receiver board receives the packets from the sender boards and hosts a web server to display the latest received readings.
Upload the following code to your receiver board – the code is prepared to receive readings from two different boards.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-esp-now-wi-fi-web-server/
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 "ESPAsyncWebServer.h"
#include <Arduino_JSON.h>
// Replace with your network credentials (STATION)
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Structure example to receive data
// Must match the sender structure
typedef struct struct_message {
int id;
float temp;
float hum;
unsigned int readingId;
} struct_message;
struct_message incomingReadings;
JSONVar board;
AsyncWebServer server(80);
AsyncEventSource events("/events");
// callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac_addr, const uint8_t *incomingData, int len) {
// Copies the sender mac address to a string
char macStr[18];
Serial.print("Packet received from: ");
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
Serial.println(macStr);
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
board["id"] = incomingReadings.id;
board["temperature"] = incomingReadings.temp;
board["humidity"] = incomingReadings.hum;
board["readingId"] = String(incomingReadings.readingId);
String jsonString = JSON.stringify(board);
events.send(jsonString.c_str(), "new_readings", millis());
Serial.printf("Board ID %u: %u bytes\n", incomingReadings.id, len);
Serial.printf("t value: %4.2f \n", incomingReadings.temp);
Serial.printf("h value: %4.2f \n", incomingReadings.hum);
Serial.printf("readingID value: %d \n", incomingReadings.readingId);
Serial.println();
}
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<title>ESP-NOW DASHBOARD</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<link rel="icon" href="data:,">
<style>
html {font-family: Arial; display: inline-block; text-align: center;}
p { font-size: 1.2rem;}
body { margin: 0;}
.topnav { overflow: hidden; background-color: #2f4468; color: white; font-size: 1.7rem; }
.content { padding: 20px; }
.card { background-color: white; box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5); }
.cards { max-width: 700px; margin: 0 auto; display: grid; grid-gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.reading { font-size: 2.8rem; }
.packet { color: #bebebe; }
.card.temperature { color: #fd7e14; }
.card.humidity { color: #1b78e2; }
</style>
</head>
<body>
<div class="topnav">
<h3>ESP-NOW DASHBOARD</h3>
</div>
<div class="content">
<div class="cards">
<div class="card temperature">
<h4><i class="fas fa-thermometer-half"></i> BOARD #1 - TEMPERATURE</h4><p><span class="reading"><span id="t1"></span> °C</span></p><p class="packet">Reading ID: <span id="rt1"></span></p>
</div>
<div class="card humidity">
<h4><i class="fas fa-tint"></i> BOARD #1 - HUMIDITY</h4><p><span class="reading"><span id="h1"></span> %</span></p><p class="packet">Reading ID: <span id="rh1"></span></p>
</div>
<div class="card temperature">
<h4><i class="fas fa-thermometer-half"></i> BOARD #2 - TEMPERATURE</h4><p><span class="reading"><span id="t2"></span> °C</span></p><p class="packet">Reading ID: <span id="rt2"></span></p>
</div>
<div class="card humidity">
<h4><i class="fas fa-tint"></i> BOARD #2 - HUMIDITY</h4><p><span class="reading"><span id="h2"></span> %</span></p><p class="packet">Reading ID: <span id="rh2"></span></p>
</div>
</div>
</div>
<script>
if (!!window.EventSource) {
var source = new EventSource('/events');
source.addEventListener('open', function(e) {
console.log("Events Connected");
}, false);
source.addEventListener('error', function(e) {
if (e.target.readyState != EventSource.OPEN) {
console.log("Events Disconnected");
}
}, false);
source.addEventListener('message', function(e) {
console.log("message", e.data);
}, false);
source.addEventListener('new_readings', function(e) {
console.log("new_readings", e.data);
var obj = JSON.parse(e.data);
document.getElementById("t"+obj.id).innerHTML = obj.temperature.toFixed(2);
document.getElementById("h"+obj.id).innerHTML = obj.humidity.toFixed(2);
document.getElementById("rt"+obj.id).innerHTML = obj.readingId;
document.getElementById("rh"+obj.id).innerHTML = obj.readingId;
}, false);
}
</script>
</body>
</html>)rawliteral";
void setup() {
// Initialize Serial Monitor
Serial.begin(115200);
// Set the device as a Station and Soft Access Point simultaneously
WiFi.mode(WIFI_AP_STA);
// Set device as a Wi-Fi Station
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Setting as a Wi-Fi Station..");
}
Serial.print("Station IP Address: ");
Serial.println(WiFi.localIP());
Serial.print("Wi-Fi Channel: ");
Serial.println(WiFi.channel());
// 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 recv CB to
// get recv packer info
esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html);
});
events.onConnect([](AsyncEventSourceClient *client){
if(client->lastId()){
Serial.printf("Client reconnected! Last message ID that it got is: %u\n", client->lastId());
}
// send event with message "hello!", id current millis
// and set reconnect delay to 1 second
client->send("hello!", NULL, millis(), 10000);
});
server.addHandler(&events);
server.begin();
}
void loop() {
static unsigned long lastEventTime = millis();
static const unsigned long EVENT_INTERVAL_MS = 5000;
if ((millis() - lastEventTime) > EVENT_INTERVAL_MS) {
events.send("ping",NULL,millis());
lastEventTime = millis();
}
}
How the Code Works
First, include the necessary libraries.
#include <esp_now.h>
#include <WiFi.h>
#include "ESPAsyncWebServer.h"
#include <Arduino_JSON.h>
The Arduino_JSON library is needed because we’ll create a JSON variable with the data received from each board. This JSON variable will be used to send all the needed information to the web page as you’ll see later in this project.
Insert your network credentials on the following lines so that the ESP32 can connect to your local network.
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Data Structure
Then, create a structure that contains the data we’ll receive. We called this structure struct_message and it contains the board ID, temperature and humidity readings, and the reading ID.
typedef struct struct_message {
int id;
float temp;
float hum;
int readingId;
} struct_message;
Create a new variable of type struct_message that is called incomingReadings that will store the variables’ values.
struct_message incomingReadings;
Create a JSON variable called board.
JSONVar board;
Create an Async Web Server on port 80.
AsyncWebServer server(80);
Create Event Source
To automatically display the information on the web server when a new reading arrives, we’ll use Server-Sent Events (SSE).
The following line creates a new event source on /events.
AsyncEventSource events("/events");
Server-Sent Events allow a web page (client) to get updates from a server. We’ll use this to automatically display new readings on the web server page when a new ESP-NOW packet arrives.
Important: Server-sent events are not supported on Internet Explorer.
OnDataRecv() function
The OnDataRecv() function will be executed when you receive a new ESP-NOW packet.
void OnDataRecv(const uint8_t * mac_addr, const uint8_t *incomingData, int len) {
Inside that function, print the sender’s MAC address:
// Copies the sender mac address to a string
char macStr[18];
Serial.print("Packet received from: ");
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
Serial.println(macStr);
Copy the information in the incomingData variable into the incomingReadings structure variable.
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
Then, create a JSON String variable with the received information (jsonString variable):
board["id"] = incomingReadings.id;
board["temperature"] = incomingReadings.temp;
board["humidity"] = incomingReadings.hum;
board["readingId"] = String(incomingReadings.readingId);
String jsonString = JSON.stringify(board);
Here’s an example of how the jsonString variable may look like after receiving the readings:
board = {
"id": "1",
"temperature": "24.32",
"humidity" = "65.85",
"readingId" = "2"
}
After gathering all the received data on the jsonString variable, send that information to the browser as an event (“new_readings”).
events.send(jsonString.c_str(), "new_readings", millis());
Later, we’ll see how to handle these events on the client side.
Finally, print the received information on the Arduino IDE Serial Monitor for debugging purposes:
Serial.printf("Board ID %u: %u bytes\n", incomingReadings.id, len);
Serial.printf("t value: %4.2f \n", incomingReadings.temp);
Serial.printf("h value: %4.2f \n", incomingReadings.hum);
Serial.printf("readingID value: %d \n", incomingReadings.readingId);
Serial.println();
Building the Web Page
The index_html variable contains all the HTML, CSS and JavaScript to build the web page. We won’t go into details on how the HTML and CSS works. We’ll just take a look at how to handle the events sent by the server.
Handle Events
Create a new EventSource object and specify the URL of the page sending the updates. In our case, it’s /events.
if (!!window.EventSource) {
var source = new EventSource('/events');
Once you’ve instantiated an event source, you can start listening for messages from the server with addEventListener().
These are the default event listeners, as shown here in the AsyncWebServer documentation.
source.addEventListener('open', function(e) {
console.log("Events Connected");
}, false);
source.addEventListener('error', function(e) {
if (e.target.readyState != EventSource.OPEN) {
console.log("Events Disconnected");
}
}, false);
source.addEventListener('message', function(e) {
console.log("message", e.data);
}, false);
Then, add the event listener for “new_readings”.
source.addEventListener('new_readings', function(e) {
When the ESP32 receives a new packet, it sends a JSON string with the readings as an event (“new_readings”) to the client. The following lines handle what happens when the browser receives that event.
console.log("new_readings", e.data);
var obj = JSON.parse(e.data);
document.getElementById("t"+obj.id).innerHTML = obj.temperature.toFixed(2);
document.getElementById("h"+obj.id).innerHTML = obj.humidity.toFixed(2);
document.getElementById("rt"+obj.id).innerHTML = obj.readingId;
document.getElementById("rh"+obj.id).innerHTML = obj.readingId;
Basically, print the new readings on the browser console, and put the received data into the elements with the corresponding id on the web page.
setup()
In the setup(), set the ESP32 receiver as an access point and Wi-Fi station:
WiFi.mode(WIFI_AP_STA);
The following lines connect the ESP32 to your local network and print the IP address and the Wi-Fi channel:
// Set device as a Wi-Fi Station
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Setting as a Wi-Fi Station..");
}
Serial.print("Station IP Address: ");
Serial.println(WiFi.localIP());
Serial.print("Wi-Fi Channel: ");
Serial.println(WiFi.channel());
Initialize ESP-NOW.
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
Register for the OnDataRecv callback function, so that it is executed when a new ESP-NOW packet arrives.
esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));
Handle Requests
When you access the ESP32 IP address on the root / URL, send the text that is stored on the index_html variable to build the web page.
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html);
});
Server Event Source
Set up the event source on the server.
events.onConnect([](AsyncEventSourceClient *client){
if(client->lastId()){
Serial.printf("Client reconnected! Last message ID that it got is: %u\n", client->lastId());
}
// send event with message "hello!", id current millis
// and set reconnect delay to 1 second
client->send("hello!", NULL, millis(), 10000);
);
server.addHandler(&events);
Finally, start the server.
server.begin();
loop()
In the loop(), send a ping every 5 seconds. This is used to check on the client side, if the server is still running.
static unsigned long lastEventTime = millis();
static const unsigned long EVENT_INTERVAL_MS = 5000;
if ((millis() - lastEventTime) > EVENT_INTERVAL_MS) {
events.send("ping",NULL,millis());
lastEventTime = millis();
}
The following diagram summarizes how the Server-sent Events work on this project and how it updates the values without refreshing the web page.
After uploading the code to the receiver board, press the on-board EN/RST button. The ESP32 IP address should be printed on the Serial Monitor as well as the Wi-Fi channel.
ESP32 Sender Circuit
The ESP32 sender boards are connected to a DHT22 temperature and humidity sensor. The data pin is connected to GPIO 4. You can choose any other suitable GPIO (read ESP32 Pinout Guide). Follow the next schematic diagram to wire the circuit.
ESP32 Sender Code (ESP-NOW)
Each sender board will send a structure via ESP-NOW that contains the board ID (so that you can identify which board sent the readings), the temperature, the humidity, and the reading ID. The reading ID is an int number to know how many messages were sent.
Upload the following code to each of your sender boards. Don’t forget to increment the id number for each sender board and insert your SSID in the WIFI_SSID variable.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-esp-now-wi-fi-web-server/
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 <esp_wifi.h>
#include <WiFi.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
// Set your Board ID (ESP32 Sender #1 = BOARD_ID 1, ESP32 Sender #2 = BOARD_ID 2, etc)
#define BOARD_ID 1
// Digital pin connected to the DHT sensor
#define DHTPIN 4
// Uncomment the type of sensor in use:
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
DHT dht(DHTPIN, DHTTYPE);
//MAC Address of the receiver
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;
float temp;
float hum;
int readingId;
} struct_message;
esp_now_peer_info_t peerInfo;
//Create a struct_message called myData
struct_message myData;
unsigned long previousMillis = 0; // Stores last time temperature was published
const long interval = 10000; // Interval at which to publish sensor readings
unsigned int readingId = 0;
// Insert your SSID
constexpr char WIFI_SSID[] = "REPLACE_WITH_YOUR_SSID";
int32_t getWiFiChannel(const char *ssid) {
if (int32_t n = WiFi.scanNetworks()) {
for (uint8_t i=0; i<n; i++) {
if (!strcmp(ssid, WiFi.SSID(i).c_str())) {
return WiFi.channel(i);
}
}
}
return 0;
}
float readDHTTemperature() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
//float t = dht.readTemperature(true);
// Check if any reads failed and exit early (to try again).
if (isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return 0;
}
else {
Serial.println(t);
return t;
}
}
float readDHTHumidity() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
if (isnan(h)) {
Serial.println("Failed to read from DHT sensor!");
return 0;
}
else {
Serial.println(h);
return h;
}
}
// 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");
}
void setup() {
//Init Serial Monitor
Serial.begin(115200);
dht.begin();
// Set device as a Wi-Fi Station and set channel
WiFi.mode(WIFI_STA);
int32_t channel = getWiFiChannel(WIFI_SSID);
WiFi.printDiag(Serial); // Uncomment to verify channel number before
esp_wifi_set_promiscuous(true);
esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
esp_wifi_set_promiscuous(false);
WiFi.printDiag(Serial); // Uncomment to verify channel change after
// 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.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// Save the last time a new reading was published
previousMillis = currentMillis;
//Set values to send
myData.id = BOARD_ID;
myData.temp = readDHTTemperature();
myData.hum = readDHTHumidity();
myData.readingId = readingId++;
//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");
}
}
}
How the Code Works
Start by importing the required libraries:
#include <esp_now.h>
#include <esp_wifi.h>
#include <WiFi.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
Set Board ID
Define the ESP32 sender board ID, for example set BOARD_ID 1 for ESP32 Sender #1, etc…
// Set your Board ID (ESP32 Sender #1 = BOARD_ID 1, ESP32 Sender #2 = BOARD_ID 2, etc)
#define BOARD_ID 1
DHT Sensor
Define the pin the DHT sensor is connected to. In our example, it is connected to GPIO 4.
#define DHTPIN 4
Select the DHT sensor type you’re using. We’re using the DHT22.
// Uncomment the type of sensor in use:
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
Create a DHT object on the pin and type defined earlier.
DHT dht(DHTPIN, DHTTYPE);
Receiver’s MAC Address
Insert the receiver’s MAC address on the next line (for example):
uint8_t broadcastAddress[] = {0x30, 0xAE, 0xA4, 0x15, 0xC7, 0xFC};
Data Structure
Then, create a structure that contains the data we want to send. The struct_message contains the board ID, temperature reading, humidity reading, and the reading ID.
typedef struct struct_message {
int id;
float temp;
float hum;
int readingId;
} struct_message;
Create a new variable of type struct_message that is called myData that stores the variables’ values.
struct_message myData;
Timer Interval
Create some auxiliary timer variables to publish the readings every 10 seconds. You can change the delay time on the interval variable.
unsigned long previousMillis = 0; // Stores last time temperature was published
const long interval = 10000; // Interval at which to publish sensor readings
Initialize the readingId variable – it keeps track of the number of readings sent.
unsigned int readingId = 0;
Changing Wi-Fi channel
Now, we’ll get the receiver’s Wi-Fi channel. This is useful because it allows us to automatically assign the same Wi-Fi channel to the sender board.
To do that, you must insert your SSID in the following line:
constexpr char WIFI_SSID[] = "REPLACE_WITH_YOUR_SSID";
Then, the getWiFiChannel() function scans for your network and gets its channel.
int32_t getWiFiChannel(const char *ssid) {
if (int32_t n = WiFi.scanNetworks()) {
for (uint8_t i=0; i<n; i++) {
if (!strcmp(ssid, WiFi.SSID(i).c_str())) {
return WiFi.channel(i);
}
}
}
return 0;
}
This snippet of code was proposed by Stephane (one of our readers). You can see his complete example here.
Reading Temperature
The readDHTTemperature() function reads and returns the temperature from the DHT sensor. In case it is not able to get temperature readings, it returns 0.
float readDHTTemperature() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
//float t = dht.readTemperature(true);
// Check if any reads failed and exit early (to try again).
if (isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return 0;
}
else {
Serial.println(t);
return t;
}
}
Reading Humidity
The readDHTHumidity() function reads and returns the humidity from the DHT sensor. In case it is not able to get humidity readings, it returns 0.
float readDHTHumidity() {
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
if (isnan(h)) {
Serial.println("Failed to read from DHT sensor!");
return 0;
}
else {
Serial.println(h);
return h;
}
}
Note: to learn more about getting temperature and humidity from the DHT22 or DHT11 sensors, read: ESP32 with DHT11/DHT22 Temperature and Humidity Sensor using Arduino IDE.
OnDataSent Callback Function
The OnDataSent() callback function will be executed when a message is sent. In this case, this function prints if the message was successfully delivered or not.
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");
}
setup()
Initialize the Serial Monitor.
Serial.begin(115200);
Set the ESP32 as a Wi-Fi station.
WiFi.mode(WIFI_STA);
Set its channel to match the receiver’s Wi-Fi channel:
int32_t channel = getWiFiChannel(WIFI_SSID);
WiFi.printDiag(Serial); // Uncomment to verify channel number before
esp_wifi_set_promiscuous(true);
esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
esp_wifi_set_promiscuous(false);
WiFi.printDiag(Serial); // Uncomment to verify channel change after
Initialize ESP-NOW.
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
After successfully initializing ESP-NOW, register the callback function that will be called when a message is sent. In this case, register for the OnDataSent() function created previously.
esp_now_register_send_cb(OnDataSent);
Add peer
To send data to another board (the receiver), you need to pair it as a peer. The following lines register and add the receiver as a peer.
// Register peer
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
loop()
In the loop(), check if it is time to get and send new readings.
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// Save the last time a new reading was published
previousMillis = currentMillis;
Send ESP-NOW Message
Finally, send the message structure via ESP-NOW.
// 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");
}
Recommended reading: Getting Started with ESP-NOW (ESP32 with Arduino IDE)
Upload the code to your sender boards. You should notice that the boards change their Wi-Fi channel to the channel of the receiver board. In our case, the boards changed their Wi-Fi channel number to 6.
Demonstration
After uploading the code to all the boards and if everything is going as expected, the ESP32 receiver board should start receiving sensor readings from the other boards.
Open a browser on your local network and type the ESP32 IP address.
It should load the temperature, humidity, and reading IDs for each board. Upon receiving a new packet, your web page updates automatically without refreshing the web page.
Wrapping Up
In this tutorial you’ve learned how to use ESP-NOW and Wi-Fi to set up a web server to receive ESP-NOW packets from multiple boards (many-to-one configuration).
Additionally, you also used Server-Sent Events to automatically update the web page every time a new packet is received without refreshing the web page.
We hope you like this project. Other projects/tutorials you may like:
- Getting Started with ESP-NOW (ESP32 with Arduino IDE)
- ESP-NOW with ESP32: Send Data to Multiple Boards (one-to-many)
- ESP-NOW with ESP32: Receive Data from Multiple Boards (many-to-one)
- ESP-NOW Two-Way Communication Between ESP32 Boards
- ESP32 LoRa Sensor Monitoring with Web Server (Long Range Communication)
Learn more about the ESP32 with our resources:
- Learn ESP32 with Arduino IDE (eBook + video course)
- MicroPython Programming with Arduino IDE
- More ESP32 tutorials …
We would like to thank our readers that helped us improve this tutorial, namely Stéphane Calderoni and Lee Davidson for their valuable inputs. Thanks you.
I believe this could be used with any sensor, like BME280, rain sensor, etc
Yes, that’s right.
Regards,
Sara
Hi Rui & Sara,
Many thanks, RNT team, for another great tutorial, as usual!…
It will be just wonderful if (as a great complement to this one) you could publish a follow-up tutorial describing the “other-way-around” dashboard CONTROL and REMOTE operation of an ESP-NOW network comprising a master and a multiple-slaved ESP32s (…perhaps maybe just by somehow “joining” and “tweaking” this one with another one of your most popular previous one: the “One-to-Many” ESP-NOW tutorial…??).
Looking forward to hear from you soon!
Kind regards from South Africa,
Daniel.
Hi Daniel.
That’s a great idea! Thanks for suggestion.
We’ll take a look at something like that.
Regards.
Sara
I would also be interested in this functionality.
Will this receive ESPNow from esp8266s?
And how do you add more ‘senders’? I hope that when I can read this on a full size screen I find this last question to be a stupid one
I am finding your post amazing as training aids, thank you
Hi Clive.
Yes, this can receive packets via ESP-NOW from ESP8266. You can see in this example a sender code for the ESP8266: https://randomnerdtutorials.com/esp-now-esp8266-nodemcu-arduino-ide/
To add more senders, you just need to copy the sender code to the other boards you want to add, and then, prepare the receiver to receive more packets. You also need to change the HTML text to display more readings.
It may help taking a look at this tutorial: https://randomnerdtutorials.com/esp-now-many-to-one-esp32/
Regards,
Sara
Hello Sara,
I have attempted to use an esp32 as a master – connected to a router for displaying the data on a web page, and an esp8266 as the slave device which gathers the data. The data exchange is via esp_now. The 32 master requests a data packet from the 8266 which triggers the 8266 to send the data to the master. The logic works perfectly until the esp32 master is connected to the router. After this connection the esp master can send it’s request to the 8266. When the 8266 receives the request, the transmission of the data fails. Have you a working example of an esp master connected to a router and 2 way communication with an 8266?
With thanks for your great tutorials,
Glen
Hi Glen.
This project worked fine for me using only ESP32 boards.
I haven’t tried it with ESP8266 😐
Regards,
Sara
Multiple ESP-01 Sending Data to on ESP32 Web Dashboard is a major application one should look into.
Especially with ESP-MESH and ESP-NOW together a WebDasboard in HighCharts on Board (without WebServer)
I think the problem is with the channel. Once you connect to the router it messes things up. I got a ESP8266 sender and a ESP32 receiver. The sender logs temperature every hour and send it to the receiver, the receiver sends it over the internet to a server. What I ended up doing was:
ESP32 receives data
Save data on EEPROM
Restart the ESP32
Check if there is data to send
Send it to the server
Remove data and restart again
Shitty solution but it worked
It is still a solution that works. 🙂
You don’t need to restart your ESP, just disconnect from Wi-Fi and then reconnect again after you’re done with that communication
Rui,
This gets more and more interesting all the time!
I need to get more ESP32, ESP8266 and WeMos D1 minis to keep up with all the projects that I need to make.
I completed and installed 2 room controllers that use ESP NOW, and they work awesome.
I also used the same ESP NOW technique with 3 WeMos D1 Minis working with two way communications, that update from any location by using hard buttons. the updated status is then visible on SSD1306 displays as well.
This is prompting me to make a mobile version, that I can carry with me to select audio sources when i am outside, or away from the wall controllers.
I never dreamed I would be able to create useful controls with low cost, and ease of programming…thanks to yours and Sarah’s coding skills and lessons!
Thank you!!
Is the facebook page a place that projects can be shared?
Hi Bob, I do hope there is a place you can share your project using the 3 Wemos Minis as I would be extremely interested in it. I think you can share projects on RNT members forum, I am sure Ruis or Sarah will clarify that.
I didn’t know there was a Forum until today & this was not obvious from the RNT front page BUT I’ve just poked about and found this site… https://rntlab.com/forum/
Enjoy
Hi Ray.
The forum is for RNTLAB members only.
If you have purchased one of our courses, you have access to the forum.
Regards,
Sara
Ruiz y Sara…se puede subir los datos recolectados del esp now a la nube?
Hi.
This particular project doesn’t save the data on the cloud.
We have other projects that show how to save data:
https://randomnerdtutorials.com/esp32-esp8266-mysql-database-php/
https://randomnerdtutorials.com/esp32-esp8266-publish-sensor-readings-to-google-sheets/
https://randomnerdtutorials.com/esp32-data-logging-temperature-to-microsd-card/
Regards,
Sara
Hi Bob.
Thank you so much for your nice words.
I’m really happy that people learn with our projects and tutorials 🙂
Yes, you can share your projects on our Facebook group.
If you are an RNTLAB member, you can also share it in the forum, if you want. However, your project will have more visibility on the FB group.
Regards,
Sara
It this somehow integrated to SmartThings hub for home automation?
Hi.
No, this isn’t integrated with any third-party service.
Regards,
Sara
Hello Rui and Sara,
I follow offen your website and try to build some projects from your site.
Now i see that you are using esp_now.h file, if i use that in my code it gives an error.
Witch library contains esp_now.h file? hope you can help me, ik tried to understand it.
i want to understand esp now beceause i want to make a project to control a servo with a joystick over wifi.
I like your site!!
Thanks so far.
Regards Remon
From the Netherlands
Hi.
That library is installed automatically when you install the ESP32 boards.
Simply select an ESP32 board in the Boards menu before uploading or compiling the code.
If you’re using an ESP8266, this code is not compatible. It uses the espnow.h library and uses slightly different methods.
Regards,
Sara
Ah thanks, now it is more clear for me! I buy an ESP32 now, then i go on with more project from you.
Thanks!
Hi Rui and Sara,
Yet another excellent tutorial giving many techniques for my own projects.
One question: How can I put an ESP32 into “Promiscuous” mode?
IE the ESP32 version of the popular ESP8266 code ..
wifi_set_opmode(STATION_MODE);
wifi_promiscuous_enable(1);
Many thanks
David
Hi Sara and Rui,
Another great project. Is there a simple way to log the collected data from the units in a CSV-file to be imported in Excel?
Hi.
There are many ways to do that.
We have these tutorials that might help:
https://randomnerdtutorials.com/esp32-esp8266-publish-sensor-readings-to-google-sheets/
https://randomnerdtutorials.com/esp32-data-logging-temperature-to-microsd-card/
Regards,
Sara
Thanks, it’s working now!
I have a lot of Wemos D1mini’s lying around I would like to use for the sensor-boards, but they are ESP8266 based.
Is it enough to use the <espnow.h> library instead of the <esp_now.h> library, or does it take more adjustments?
If so, could you point those out to me?
Keep up your fantastic work!
Hi Sara and Rui
Is it possible to use ESP NOW as a mesh like features.? Crude way could be to insert all the esp MAC as receivers MAC in the program. Am I right ? Or can you suggest a solution?
Hi.
Yes, you can add more boards sending data to each other. I think you can have a maximum of 20 added peers.
Regards,
Sara
Hi Sara,
The number of paired is 14 max, I found this info here:
demo-dijiudu.readthedocs.io/en/latest/api-reference/wifi/esp_now.html#add-paired-device
” The range of the channel of paired device is from 0 to 14″…
Regards
Hi.
I think that refers to the number of wi-fi channels.
Here we are referring to 20 ESP-NOW peers.
See page 4: espressif.com/sites/default/files/documentation/esp-now_user_guide_en.pdf
Regards,
Sara
Hi Sara,
“you can add more boards sending data to each other. You can have a maximum of 20 added peers”
Please let me know which statement below is correct base on the statement above:
One esp32 can send data to maximum of 20 esp32.
One esp32 can receive data from maximum of 20 esp32.
One eps32 can send and receive data to maximum of 20 esp32.
One eps32 can send only to maximum 20 esp32 but can receive from limitless number of esp32.
Hi.
I’m not sure. The sentence on the documentation can be interpreted in different ways.
But I think the last statement makes more sense.
Regards,
Sara
Great project, to change the DTH22 out for a DS18B20 would you just change all reference to DTH to DS18B20 and include DS18B20 library. I am a 70yr old Newbie, but really facinates me. have the project working in its present form.
Hi Philip.
That’s great!
To learn more about the DS18B20 sensor, you can follow this tutorial: https://randomnerdtutorials.com/esp32-ds18b20-temperature-arduino-ide/
Regards,
Sara
Hola Rui & Sara !
Thanks again for this tutorial. I really appreciate following-up your posts!
Rui wrote: “We’re not sure if there’s a better way to use ESP-NOW and Wi-Fi simultaneously. This solution worked reliably for us.”
Your example shows Access Point Connexion as mandatory in order to create a connexion between the sender (Slave) and the receiver (Master). This reduces the communication range between the two boards (distance).
I guess the Master should be an Access Point to communicate with another ESP32 as a Web server in order to maximize the ESP-Now functionality. Otherwise I dont’ see why using ESP-NOW data exchange with the master (i.e through Access point). Wi-Fi should be just fine.
My new project under progress is: ESP32-Sender (slave) to a ESP32-Receiver (master) using ESP-Now (only) for communicating, and having more than 150 ft of distance range between the two boards. The ESP32 Master is than communicating to another ESP32 which is used a gateway. The connexion between the ESP32 Master and the ESP32 Gateway will be either through Serial or Wi-Fi. The ESP32 gateway is then communicating using MQTT to the a Web Server.
What do you think?
Merci,
Hi.
That’s a great project and I think you can easily have a distance of more than 150 ft.
Good luck with your projects 😀
Regards,
Sara
this is almost exactly what I am working towards- have you got Serial (hardware Serial1?) to work for communication to the gateway yet?
Hi, great job again, thanks RNT Team!
I like this solution, because the peer to peer communication between the ESP is not “sniffable” on the WIFI and is a more secured way to transmit data: you will not sniff them easily as UDP and TCP packets.
Now if you need to access occasionnaly to your webserver, WIFI current consommation is greater than ESPNow current consommation, so with few data sent by other boards, you will get a longer battery life-time than using WIFI and MQTT.
By sending data every 10 or more minutes, and using DeepSleep, it looks more interresting than WIFI, don’t you think so?
So ESP-Now looks safer and more interesting for battery life-time.
If you need long range, use Lora or change your antennas.
I’m going to try this solution for my home hand-made alarm with multiple zones.
Is MQTT usable with ESPNow?
Regards
Sébastien
Hi.
Yes. You can use MQTT and ESPNow at the same time.
However, keep in mind that you need to connect to Wi-Fi to use MQTT to connect to your broker.
Regards,
Sara
Hi Sara
This was an awsome post –, as you said I would like to get date through ESP-NOW and then publish with MQTT, but I can’t :C. Any suggestion for the configuration?
Thank you for the tutorial! Great write up as always. However, It seems this has the same problem as my previous code. I am trying to have the ‘master’ be able to send and receive ESPNow data as well as connect to wifi to send data. It seems if you start wifi, once you register a peer it’ll kill ESPNow.
It seems like its either or… Wifi AP OR ESPNow sending, but not both. Let me know what you think.
Hi Tom.
This project works fine for us.
We don’t have that problem.
However, I haven’t tried sending data from the main ESP32 that is acting as a web server.
I plan to try that out in the future.
Regards,
Sara
Thank you Sara. Do you know a way I may be able to trigger a ‘slave’ esp32 over serial to start an function, instead of needing the ‘master’ to trigger it over ESPNow? This would solve my issue of needing both ESPNow sending AND WiFi.
Hi Tom,
You’re right. That was my point. The example uses Access Point and ESP-now at the same for the sender to the receiver. This is not appropritate.
Senders should just use ESP-Now only. Fore the receiver (Master), I use it as a gateway. I connect this one using a serial connexion to another ESP32. This last one is then an Access Point to the Web network .
For the serial connexion :
#define RXD2 16 // should connect to Tx of ESP32-Now Receiver (Master)
#define TXD2 17 // should connect to Rx of ESP32-Now Receiver (Master)
In Setup ()
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
So when the ESP32-Now Receiver (Master) output
Serial.printf(“Board ID %u: %u bytes\n”, incomingReadings.id, len);
Serial.printf(“t value: %4.2f \n”, incomingReadings.temp);
Serial.printf(“h value: %4.2f \n”, incomingReadings.hum);
Serial.printf(“readingID value: %d \n”, incomingReadings.readingId);
Serial.println();
then the ESP-32 (Gateway) receives the info (using serial2) and could sent it to the Web using Wi-Fi connexion.
In other words, only the last ESP32 (Gateway) should be connected using Wi-Fi, but all the others should just use ESP-Now.
Hope this can help
Hi.
Thank you for sharing your solution.
It is a great idea. Can you share your code with us? We would like to write a tutorial about that in the future, if you don’t mind us sharing.
Contact us using our contact form: https://randomnerdtutorials.com/support/
You can write “ESP-NOW Wi-Fi Serial” on the subject.
Regards,
Sara
Here’s the code for the Serial transfer between the last ESP32 Gateway and the ESP32 Master which receives data from esp32 sender through ESP-Now protocol. Bt the way , my tests do not conclude ESP-Now as a very solid communication protocol. Very unstable and not very performant. I’m am abandonning this approach… I guess LoRaWAN will be evaluate as a better protocol. To follow…
/*
* There are three serial ports on the ESP known as U0UXD, U1UXD and U2UXD.
*
* U0UXD is used to communicate with the ESP32 for programming and during reset/boot.
* U1UXD is unused and can be used for your projects. Some boards use this port for SPI Flash access though
* U2UXD is unused and can be used for your projects.
*
* This programm extract info from ESP32 Serial connexion
* Message info received is under the following structure :
* Temp_Ext:11.30 Humi_Ext:3277.30 Soil_Jar:23.34 Watr_Lev:12.18 #
*
* each value is corresping to a different sensor sensor input (ex. DHT11, Soil Moisture, Water Level(HC-SR04) ,…)
* ref. to void extractDisplay_transf() function below
*/
#define DEBUG 1 //after you no longer need the debug code, then comment out this #define DEBUG 1 line
#define VERSION 2.5
#define RXD2 16 // should connect to Tx of ESp32 d1 (TX) ESP32-Now Master
#define TXD2 17 // should connect to Rx of Esp32 d3 (RX) ESP32-Now Master
String message_esp32;
int Board_Id; // Sender ESP32-Now Board ID
int incomingMessage_Id = 0; // Message Id
float Temp_Ext = 0.8; // Exterior Temperature (DHT sensor) 0.8 value is a trace-point for validation
float Humi_Ext = 0.8; // Exterior Humidity (DHT sensor)
float Moisture = 0.8; // Soil Moisture value (garden sensor)
float Water_Level = 0.8; // Water Level value (conteiner of water HC-SR04 sensor)
void setup() {
// Note the format for setting a serial port is as follows: Serial2.begin(baud-rate, protocol, RX pin, TX pin);
Serial.begin(115200);
//Serial1.begin(9600, SERIAL_8N1, RXD2, TXD2);
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2); // Serial2 is not Rx, Tx of the usual Serial pin, but from GPIO 16 and 17
Serial.println(“Serial Txd is on pin: “+String(TXD2));
Serial.println(“Serial Rxd is on pin: “+String(RXD2));
}
void loop() { //Choose Serial1 or Serial2 as required
while (Serial2.available()) {
int result;
char sub[100];
delay(10);
message_esp32 = Serial2.readString() ; // read the message as it comes (lapse_temps du Master)
// message type ex: Temp_Ext:11.30 Humi_Ext:3277.30 Soil_Jar:0.00 Watr_Lev:0.00 #
extractDisplay_transf(message_esp32);
#ifdef DEBUG
Serial.println(message_esp32);
Serial.println(“Final Results”);
Serial.println(Board_Id);
Serial.println(Temp_Ext);
Serial.println(Humi_Ext);
Serial.println(Moisture);
Serial.println(Water_Level);
#endif
}
}
// Extractinf value from a message like : Temp_Ext:11.30 Humi_Ext:3277.30 Soil_Jar:0.00 Watr_Lev:0.00 #
//
void extractDisplay_transf(String string_tmp){
String str_val1; // Board_Id
String str_val2; // Temp_Ext (temperature ext. )
String str_val3; // Humi_Ext (humudity ext. )
String str_val4; // Soil_Jar (soil moisture jardin/garden)
String str_val5; // Watr_Lev (Water Level)
int firstValue_pos = string_tmp.indexOf(‘:’);
int secondValue_pos = string_tmp.indexOf(‘:’, firstValue_pos + 1 );
int thirdValue_pos = string_tmp.indexOf(‘:’, secondValue_pos + 1);
int fourthValue_pos = string_tmp.indexOf(‘:’, thirdValue_pos + 1);
int fifthValue_pos = string_tmp.indexOf(‘:’, fourthValue_pos + 1);
int secondMessage_pos = string_tmp.indexOf(‘ ‘);
int thirdMessage_pos = string_tmp.indexOf(‘ ‘, secondValue_pos + 1);
int fourthMessage_pos = string_tmp.indexOf(‘ ‘, thirdValue_pos + 1);
int fifthMessage_pos = string_tmp.indexOf(‘ ‘, fourthValue_pos + 1);
int endMessage_pos = string_tmp.lastIndexOf(‘#’); // symbol for the ending message
str_val1 = string_tmp.substring(firstValue_pos + 1, secondMessage_pos);
Board_Id = str_val1.toFloat();
str_val2 = string_tmp.substring(secondValue_pos + 1, thirdMessage_pos);
Temp_Ext = str_val2.toFloat();
str_val3 = string_tmp.substring(thirdValue_pos + 1, fourthMessage_pos);
Humi_Ext = str_val3.toFloat();
str_val4 = string_tmp.substring(fourthValue_pos + 1, fifthMessage_pos);
Moisture = str_val4.toFloat();
str_val5 = string_tmp.substring(fifthValue_pos + 1, endMessage_pos);
Water_Level = str_val5.toFloat();
}
Hi.
Thank you so much for sharing 😀
Regards,
Sara
Yup, serial connection was the key. My layout is a bit different but so far its working…
I now have my ‘master’ signalling the first slave to GO over serial after it receives a trigger JSON from WiFi. Once slave1 is done is sends its packet over ESPNow to slave2 which triggers and does the same. slave3, once complete with its game, then sends all three slave responses back to the master over ESPNow. The master then authenticates with oAuth and sends the complete data over JSON (and WiFi)
Master is currently using Wifi, ESPNow (receive ONLY), and serial
slave1 is serial and ESPNow (send and receive)
slave 2\3 utilizing just ESPNow (send and receive)
Thanks for the push in the right direction Francois!
Hi,
I wonder – could you give me a pointer to how I get more boxes (cards) in the grid rows (I really need the grid to be a 5 rows x 3 columns) as I just can’t seem to get it. Also I am struggling with changing the justification within a box.
Great project
Dave
Hi thanks for the tutorial
I have a question, is it possible if the sender acts as a access point not as a station?
Hello, have you considered using some framework like Mustache ( https://mustache.github.io/ ) to dinamically generate the dashboard on the web server?
I am not sure whether it may work nicely (if you keep all JSON separated, probably it will only display the data from the last JSON received), or if this may create more headaches in manading the data flow…but it could help to design a dashboard where the number of sender is not necessarily known in advance, or make it seamless to add one more sender board.
I’m currently using Mustache on a different type of project (web based), and I found it quite handy…I’ll try to see how it works next time I’ll be on a ESP32 based project with a web view!
Hi.
Thanks for sharing.
That is very interesting. I’ll take a look at it.
Regards,
Sara
Hi,
perhaps you might be able to help – In the temperature box, how might I have the title centred (as is) and have the data and labels left/right aligned?
I’ve been banging my head against the wall for a day now and can’t get it right.
Thanks
Really good tutorials! thanks! Sort of side question, but how can you have separate files for the webserver and the sensor’s in the same project? It seems crazy to try to have multiple projects for each of the code basis, and I’m working to strip out most of the webserver const code into an include file. I’ve never really built anything other than in the main.cpp, so now I’m suddenly wondering could you have multiple object files that “make” or compile to different uploads?
Hi Jeff.
If you mean having the web server HTML text on a different file, you can use SPIFFS to save a separate HTML file.
See this example: https://randomnerdtutorials.com/esp32-web-server-spiffs-spi-flash-file-system/
Regards,
Sara
Thanks! I actually figured out how to have the const char* const for the web page in a .h, but I’m going to look at the CSS/SPIFFS version you posted too!
But…what I’m really curious about, is how to have multiple compiled objects/code for different ESP32’s all in one project. I mean, I would like to have sender.cpp and receiver.cpp and compile them separate/upload to different esp32’s, but still be in the same project. I was hoping it would compile each target based on what was active and upload that, but I’m guessing that isn’t really possible (from what I read, the Arduino IDE links all .cpp files to main.cpp, or tries to). Even in VSC/PlatformIO, it doesn’t allow me to use separately.
Thanks!
Jeff
I found this to be one of the most educational experiences I have had from RNT. I suggest that once people get the code running as given to try adding another measurement; in my case I needed a battery monitor. That really got me into the code as I had to make changes to the sender and receiver, use a little JSON, html, CSS, and trial and error; but in the end I was really happy to get it working. What a blast! Thank you!
This is really a wonderful project.
Please guide me with a link or pointer to have Two Way communication in my Esp-Now web server to control a relay in one node, based on sensor reading on the other node
Hi.
We have these projects that might help:
https://randomnerdtutorials.com/esp-now-two-way-communication-esp32/
https://randomnerdtutorials.com/esp32-relay-module-ac-web-server/
Regards,
Sara
would it be possible to use ESP-Now to connect to a remote esp32 hooked up to an 8 channel relay switch but control it from the master(two way comm)? also also a sensor hut that would send data(bme280, ir data, etc), one way to the same master?
I see in the example that each ‘Sender’ is using similar sensors as inputs so the same message structure is acceptable as follows:
typedef struct struct_message {
int id;
float temp;
float hum;
int readingId;
} struct_message;
Question is: what if one of the ‘Senders’ uses entirely different sensor mix, can this new Sender have it’s own message structure format with different mix of value types e.g. float temp1 and also a float temp2.
If this was the case would it be simply that in the ‘Receiver Code’ we would need to define both message structures ?
I suspect that it may be OK to have different message structure in each sender as long as both are defined in the common receiver. BUT as an alternative I just have one comprehensive message structure in all devices and this works OK. See my struct message used below.
In addition I have one of my Senders also sending values out to Bluetooth so I can monitor temperatures on my smartphone or other BT device.
typedef struct struct_message { // all int store a 2-byte value.
int id;
float A11; // 1st A/I from Sender # 1 for BMP280 ‘C’ SupplyAir
float A12; // 2nd A/I from Sender # 1 for BMP280 ‘S/A Air Pressure’
float A13; // 3rd A/I from Sender # 1 for DS18B20 #1 RtnAir
float A14; // 4th A/I from Sender # 1 for DS18B20 #2 Supply Air
int D11; // 1st D/I from Sender # 1 for Spare D/I #1
int D12; // 2nd D/I from Sender # 1 for Spare D/I #2
float A21; // 1st A/I from Sender # 2 for DHT22 ‘C’
float A22; // 2nd A/I from Sender # 2 for DHT22 ‘RH’
float A23; // 3rd A/I from Sender # 2 for LDR
float A24; // 4th A/I from Sender # 2 for Spare A/I – maybe Batt Volts
float A25; // 5th A/I from Sender # 2 for Spare A/I – maybe Batt Amps
int D21; // 1st D/I from Sender # 2 for Spare D/I #1 – maybe gate status
int D22; // 2nd D/I from Sender # 2 for Spare D/I #2
} struct_message;
Please disregard my last message, I figured it out – the router was on a 5GHz channel instead of a 2.4GHz one. fixed!
Hey everybody,
I don’t want to sound like a killjoy, but in my opinion the implementation of the ESP-NOW protocol needs to be fully reviewed in this tutorial. Indeed, ESP-NOW is a connectionless protocol! And that’s not at all what is implemented here. I myself experimented a couple of things and finally found a solution. But it doesn’t satisfy me. If you have any ideas on the subject, you might be able to come and contribute to the discussion I’ve started on this subject:
https://rntlab.com/question/esp-now-gateway-wifi_mode_sta-with-a-wifi-router/
I think François has taken note of the problem and his idea to isolate the ESP-NOW network by linking the receiver to another ESP32 (by serial link) which is connected to the Internet (as a station on a WiFi router), is an excellent idea.
Nevertheless this solution allows to bypass the problem but not to solve it 😉
Steph,
At https://rntlab.com/question/esp-now-gateway-wifi_mode_sta-with-a-wifi-router/, you said, “I’ve done a lot of research myself as well… and I’ve come across these proposals as well. Unfortunately, none of them work with the current version of the arduino-esp32 core.” I’m not a member of RNT Lab, so I cannot contribute over there.
It is not impossible to set a channel other than channel 1 on ESP-NOW senders. After some experimentation, I’ve found that the concepts presented in the example linked to by Steven just prior to your post do indeed work. You just need to #include <esp_wifi.h>. Is that not part of the arduino-esp32 core?
The project presented in this post can be easily converted to use purely ESP-NOW between the sender and receiver with just a few simple changes.
Let’s start with the receiver code. (Note: Line numbers are current line numbers before any edits.)
Lines 21-26 and 157-158 are not needed. There is no need to configure and start an Access Point.
Line 144 IS needed as is. Though we do not need a ‘hot’ AP, we do need to enable the AP interface else communication will be unreliable.
Done there. Let’s go to the sender code. (Again, current line numbers.)
#include <esp_wifi.h>
Lines 17-19 are not needed. There is no reason to connect to an AP that isn’t there.
At line 38, set the channel number (CHAN_AP) to the SAME channel number as the receiver’s WiFi channel number. It must be the same else communication will be unreliable.
Since we are not connecting to an AP, lines 99-105 are also not needed. But we need to do something else here. So, replace those lines with:
// Set device as a Wi-Fi Station & set channel
WiFi.mode(WIFI_STA);
//WiFi.printDiag(Serial); // Uncomment to verify channel number before
esp_wifi_set_promiscuous(true);
esp_wifi_set_channel(CHAN_AP, WIFI_SECOND_CHAN_NONE);
esp_wifi_set_promiscuous(false);
//WiFi.printDiag(Serial); // Uncomment to verify channel change after
Unless I’ve overlooked some of the edits I did to make it work, that should be it.
Keep in mind that if you set the peer_addr (or in this case broadcastAddress at line 35) to FF:FF:FF:FF:FF:FF, then any device on the channel will receive it. If you wish to specifically target the receiver, you should set it to the WiFi MAC address of the receiver. You probably already know, but others may not, that you can get the address of the receiver by adding “Serial.println(WiFi.macAddress());” to the receiver code after setting the WiFi mode.
Hey Lee,
Sorry for my previous answer, which I accidentally took out of the thread.
I was finally able to test the solution proposed on the Espressif forum (which you mentioned in your comment)… and it works!!!
I was sure I had tested it, but it probably escaped me while I was trying to change my code all the time.
Anyway, thanks a lot to you and Steve for bringing this solution to my attention.
I’ve posted a complete sample code on GitHub so that it can be used by the whole RNT community. And I encourage Sara and Rui to quickly modify their tutorial to propose a correct implementation of the ESP-NOW protocol.
Thanks again!
Thank you Lee for your input.
I don’t rely on the code in this tutorial. I developed my own project.
However, I’ll know what you’re referring to with your line numbers.
Nevertheless… the one and only thing that I think is important here (and that I thought I had tested without success on my side) is the use of the following directive:
esp_wifi_set_promiscuous(flag); // true / false
I will try again as soon as possible (I need to finish another project first).
And I will come back to you to let you know the result.
Thank you for taking the time to study the problem.
Best regards.
Steph
Can you handle im the same way OTA on both sides of a ESPnow communication – Sender and Receiver side?
The statement
server.on(“/”, HTTP_GET, [](AsyncWebServerRequest *request)
{
request->send_P(200, “text/html”, index_html);
});
sends fixed “const char index_html” content to the client when a request is received. How could I modify the statement to call a function that would compose a dynamic response, i.e., containing a series of
server.sendContent(“text “);
server.sendContent(value);
statements or something similar?
Hello, thank you so much for the project. The receiver code works perfectly fine. But I am getting an error in the sender code in this line “peerInfo.channel = CHAN_AP;”
‘CHAN_AP’ was not declared in this scope.
Thank you
Hi.
I’m sorry about that.
You just need to delete that line and it should work.
That was a typo when updating the code in our Github repository.
Regards,
Sara
Thank you so much. Works perfectly fine now. 🙂
Hi Sara and Rui,
Are you planning to add a tutorial on showing how to use encryption when sending/receiving messages?
Would like to add an additional level of security on top of my application, as such, message encryption solution that ESP-NOW provides would be be perfect.
Thanks!
Hi.
Thanks for the suggestion.
Unfortunately, at the moment we don’t have any tutorial covering that subject.
Regards,
Sara
Hello Sara,
i’m also interested in such a tutorial.
I have written some short code and it seems to work, but i’m not really sure. If you are interested i could send you a copy for review and basis for a new tutorial.
It’s heavily based on your ESP-NOW getting started guide.
I’m looking forward for your answer!
Best Regards
Maik
Hi
i have problem with #include <esp_now.h>
because (esp_now.h) no such file or directory
i want this library
please
Hi.
Make sure you have an ESP32 board selected in your Arduino IDE under Tools > Board.
Regards,
Sara
Hi Sara
I am working on a project where I need to collect yield data in an open field and save it in the webserver so it can be accessed remotely. Using Arduino DUE and Openlog SD module I successfully saved the data in an SD card. My next step is to transfer data saved in an SD card to a WebServer. Do you have any tutorials using ESP32 to do the transfer?
Hi.
We don’t have any tutorials about that.
You can follow our tutorial that uses SPIFFS. But instead of using SPIFFS filesystem, use the SD card filesystem:
https://randomnerdtutorials.com/esp32-web-server-spiffs-spi-flash-file-system/
Regards,
Sara
can you have one of the esp boards control relays on/off and transmitt the data to the receiver board and be displayed on a dashboard ?
Hi guys,
Thanks for another useful tutorial. However I’m a bit confused with this one.
Should the senders boards also have access to the same WiFi network as the receiver one? I had the impression that we could run ESP NOW without WiFi access, but it seems to me that in this tutorial, the senders are also checking for the same SSID as the receiver board. Will this work if the sender board is outside the reach of the router?
Hi Nuno,
ESP32s can communicate without any connection thanks to the ESP-NOW protocol, and no WiFi network is required for this. In this tutorial ESP32s actually communicate with the ESP-NOW connectionless protocol.
Nevertheless, here the ESP32 that receives the measured data from the sensors also exposes a web server to display this data and make it remotely accessible from a simple smartphone or PC. It is precisely for this reason that the receiving node is connected to a WiFi router, to share this data with the entire local network. In this particular context, in order for ESP-NOW communications to continue working, it is imperative that the channel used is the same as the one imposed by the WiFi router to which the receiving ESP32 is connected. Indeed, it must be able to simultaneously ensure ESP-NOW communications and TCP/IP communications exchanged with the clients of the local network. Its communication radio interface must therefore be configured to use the same frequency channel for this purpose.
As such, the sender nodes must necessarily use the same channel. This is one of the difficulties that must be taken into account and which is explained here. For this reason, they scan WiFi networks within range to identify the one to which the receiving node is connected and at the same time determine the channel they need to use to communicate with it.
I hope I have been able to clarify things for you.
Regards,
Steph
Hi Steph,
Thanks for your thorough reply, I think it addressed all my doubts. I guess my thought process was: if ESP-NOW works without WiFi, why should the multiple sender boards be also connected to the same WiFi network as the receiver, but it is clear now.
I’m raising these questions due to a project I have in hands, but we can use this one as example. I want to have an ESP32 doing some sensor readings and feeding them to a MQQT broker. However, the ESP + sensor is to be deployed in a location in my house that isn’t covered by WiFi (outside router range). That’s why I was thinking of using two ESP32 boards, one next to the router, handling the MQQT communications and receiving sensor data by ESP-NOW from the other board. But I guess that won’t work, from what I got from your reply, right? If it can’t sender board can’t see the same network, then it won’t be able to handle ESP-NOW since it won’t be able to find the same channel. Right?
If I may ask, do you think in this scenario, communications handled by LoRa would be better? I don’t have line of sight between router and location where the sender ESP32 is to be deployed, but it should work better than regular WiFi/ESP-NOW for indoor operation, no?
Thanks again Steph,
Cheers,
Nuno
Hi Nuno,
For your project, the receiving node must of course be within range of the WiFi network broadcast by the router… but not necessarily placed right next to it. This allows you to extend the range of the sensor network. Indeed, these sensors can then be located out of range of the WiFi router, as long as they remain within range of the ESP32 which will receive the measurement data.
The easiest way is to set the communication channel of the router (for example by configuring it to use channel 1) and make sure it remains constant. In this case, it is sufficient that all the ESP32s use channel 1 and the problem is solved. You can of course choose the channel that suits you best…
In the event that you can’t set the router’s channel, because your neighbors generate too much interference, and you prefer your router to choose the channel that seems the least congested automatically, then you can consider the following methodology:
You initialize all the nodes of your sensor network on a common channel (e.g. channel 1): the ESP32 senders (which broadcast the data from their sensors) and the ESP32 receiver, in charge of collecting the measurement data. The latter will be considered as the gateway between the ESP-NOW network and the WiFi network.
The ESP32 gateway scans the WiFi networks within range and identifies the WiFi network in your house with its SSID, and at the same time determines the channel imposed by the router… but without connecting!
Then it communicates the channel number via ESP-NOW to all the ESP32 connected to the different sensors. This is quite possible since they are all synchronized on channel 1.
All the sensor nodes (ESP32s) reset their radio interface configuration to switch to the new channel.
The ESP32 gateway connects to the WiFi network of the router (It will automatically switch to the same channel as the router).
There you go! Everyone is now on the same channel as the router.
You can also use LoRa interfaces, that will work too. But that gives you extra equipment to add to each ESP32. The advantage here is the very important increase of the communication range. LoRa technology will allow you, in a crowded environment (with many obstacles), to make your nodes communicate at several hundred meters away. Whereas ESP-NOW will limit you to a few dozen meters.
Was I clear enough?
All the best,
Steph
The only issue I have is that when the sender board after the initial setup are moved beyond the reach of the router and I have to reset the slave for any reason which highly plausible during power loss or whatever, then the sender wifi chanel scanning snippet will not work so I have to bring all boards again within the proximity of the router and repeat the set up process.
I will have to experement with the slave board connected to another board via hardwired seial communication to obtain more reliable set up
But I have to say that I learned quite a bit from following this tutorial and discussion
Philip
Hi Philippe,
I have experimented with a much simpler way of doing this, which does not require additional controllers, nor does it require bringing all the sender modules closer to the router in order to scan the available WiFi networks again. I intend to publish my code as soon as time allows me to comment it a bit, so if you are interested, I can give you the link here. I guess it will be of interest to other readers who have encountered the same problem.
Steph
Hi Sara
Thank you. I will look into it.
Also, do you have any tutorial that demonstrates how to transfer sd card data to a computer using ESP32?
Hi.
Unfortunately, we don’t have any tutorial about that subject.
Regards,
Sara
Hi Sara.
I have been going through examples with one ESP32 doing a NOW with another. In the Struct using floats I keep getting a 0 or garbage numbers. I have to change from float to a uint32_t to get any information thru. I did the examples that you provided with the master/slave example using a BME280 sensor with no luck. I also found that if I put an int value in the struct as the ID then followed by the floats I just get the ID and nothing of the other values.
Do you have any idea as to what my issue could be? I seem to have had this issue using the NLF24 radios. Something with struct?
thanks for any help on this.
Love the stuff you guys do.
Any idea how I could swap the webserver on the receiver for a httpclient call ? I want to push the value to an external webserver. I have tried many things, but having the httpclient call in the datareceive function is not working. If I set a flag try the httpclient call in the loop, the board core dumps. Anything you might suggest would be great.
Hi,
It’s not possible to make an httpClient call using the wifi object in the callback function for esp-now received data. It gives errors on dns or connect operations, probably because the radio is busy/locked at that moment.
You can post the data to a Queue (https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos.html?highlight=queue#queue-api) and then check periodically from the main loop if there are pending messages on the queue and then send them using an HtttpClient.
Or a more simpler approach using your flag and global static variables. This should work, your coredump is probably because you try to access memory allocated for the callback that is not there after it finishes. If you copy the data, you should have no problem sending it later.
No words will explain how educational this thread was
Thanks Rui and Sara thanks Stephane, Lee and others
Thank you 🙂
Good day and Season’s greetings, Rui & Sara!!…
One quick enquiry: which ones ESP-NOW functions one might need to add to the “master” device of this great tutorial, in order for the ESP-NOW ESP32s “slaves” devices to gain output control from the Dashboard?…that enhancement will give the whole project a fantastic “both-ways” functionality!!…
Thanks again for your continuous efforts and sharing your knowledge with this ever expanding group of ESP32 fans, worldwide!!
Hi.
In that case, first you need to add some controls to the web server, like buttons, for example.
When you click the buttons, the ESP32 should receive a request by the client, so that it knows the button was clicked.
When that happens, it should send a message to the right board with the state of the GPIO.
The board should interpret that message and control the GPIOs accordingly.
That is feasible, but I didn’t had the time to develop that yey.
I hope this helps.
Regards,
Sara
Thanks for your prompt response to my enquiry, Sara!…I’ll take your hints and I will try to implement the cellphone Dashboard ‘remote-control’ WiFi/ESP-NOW control functionality I’m after. Hope that you and Rui will have some time to publish a tutorial in the near future complementing this great Dashboard remote monitoring one!…All the best wishes for 2021 for all the dedicated members of the RNT team!
That’s on our to-do list of projects.
Regards,
Sara
I’m not able to get it working and really fail to see where things go wrong. I have a kind if mixed setup, 2 esp01’s sending dht data to a ttgo esp32. Works fine using the ‘standard’ many to one approach, both esp01s can communicate with the esp32 and the results are written on the ttgo screen. So basic setup is ok.
Yet, whenever I add the script that should deal with the channel part the communication is lost between all. I assume part of the reason might be my main router is a meshrouter, so could it be the script works fine as long as you have just one router / network available but get’s confused when there’s plenty of choice?
In the original setup you clearly stated the esp-now part had to use a different channel, yet now it seems to force the same channel, is this correct or should I be using different channels on both?
Hi Koen.
If you’re using ESP32 and ESP8266 boards on the same project, I advise to read this discussion: https://rntlab.com/question/esp8266-to-esp32-wifi-esp-now-problem/
Regards,
Sara
Thanks Sara, it works fine indeed when I use the FF broadcast address, need to look a bit further now in the discussion to get it working less broad but at least I got it up now. Great content, highly appreciated!
Is there a way how to avoid WiFi.scanNetworks()? I want to make the sender run on battery, but WiFi.scanNetworks() takes 2 seconds to finish, which is too much when the rest of the code takes about 120 milliseconds. I don’t mind setting everything static but was unsuccessful to make it work.
I build this project with a ESP8266 as Sender and a ESP32 as Receiver, just from your sources. But it won’t work. I can open the website, but there is no information from the Sender. When I look to the Senders output it says: Last Packet Send Status: Delivery fail. The channels are the same. Do you have any idea what goes wrong?
Hi.
It is very difficult to troubleshoot without further information.
Just check the receiver’s MAC address.
Also try using the FF broadcasting MAC address and see if that works.
Regards,
Sara
Hello Sara,
thanks for the reply. I am sorry I was’n clear enough. I build the ESP_NOW and WiFi project from your examples on the site. Only with a ESP8266 as Sender and a ESP32 as receiver. Exactly as you describes. The only changes were of course my network credentials and the MAC address of the receiver.
But anyway, later I found your discussion with Michel Tremblay on the LAB site. He had the same problem. With this information I solved my problem by only changed the MAC address of the receiver with his soft MAC address. No changes in the ESP_now_peer( etc) function were necessary. So it was not necessary to use the channel in this function.
It now works fine. But I still don’t know what a FF broadcasting MAC address is. Could not find a clear explanation on the internet. I even did not know there was something like a soft MAC address for a device.
Finally, I learned a lot from your website explanations; thank you very much!
Regards, Bernard
Thank you so much for all the information.
I am a newbie (-:
I would love if you can upload a code of example of how to upload the reading of the sensor to thingspeak.
Thanks a Lot
Avner
Hi.
You can take a look at this tutorial that might help: https://randomnerdtutorials.com/esp32-http-post-ifttt-thingspeak-arduino/
Regards,
Sara
Hi
I have some issue with this code, i use 14 node sender (esp32 and esp8266) and 1 receiver (esp32). But they didn’t work for a long time. Is this code have max sender?
Hello Sara,
Which is the best way to proceed? I have completed the tutorial on ESP-NOW ESP32 2-way communication and got my project working to the point that I could split mode code to work as required. I have also done the tutorial on ESP32 BLE and created an MIT App to communicate using serial. So far so good! I also started to do this project but blew up a module and waiting for a replacement.
Image link – (https://drive.google.com/file/d/1NWuy5ZtgthAQKFJZXCMCQMP_JOrDTrgr/view?usp=sharing)
Ideally, I would like to control things using an App rather than the IP address as in the ESP-NOW Server example, though that does look good. I would also like the project to be completely independent, so that 10 users next to each other don’t get interference.
There are so many protocols on the ESP32 that it’s driving me mad, any advice would be extremely appreciated.
Hello Sara,
First of all, congrats for all these work. Your articles are from now on my reference manual for using ESP-NOW on my Wemos devices. One doubt I have is that I don´t find the article where ESP8266 (not ESP32) is working with ESP-NOW and Wi-Fi simultaneously. Is it that because there is no way to put them working together in the ESP8266? I hope the answer to this question is that you are working on it…
Regards,
Ander.
Hi.
Here is the tutorial that you are looking for: https://randomnerdtutorials.com/esp8266-esp-now-wi-fi-web-server/
Regards,
Sara
Hi Sara,
Thanks! Exactly what I was looking for. Anyway, I see that in the example the “Receiver” receives data and displays all readings on a web server, but it doesn´t send anything. ¿Is it possible that in your example the “Receiver” device could also send data to other devices via ESP-NOW (apart from receiving data and displaying it on a web server)?
I will try it asap (using the necessary sender code lines from https://randomnerdtutorials.com/esp-now-one-to-many-esp8266-nodemcu/) but I would like to know if you think it is possible.
Regards,
Ander.
Hi.
Yes.
The receiver device can also be a sender.
We have another tutorial that might help: https://randomnerdtutorials.com/esp-now-two-way-communication-esp8266-nodemcu/
Regards,
Sara
Hi Sara,
Thank you for your reply. I’ve just tried it and works perfectly: Wemos D1 Mini as receiver and NodeMCU as sender, two way communication via ESP-NOW and Wemos posting data on a server.
This way I can continue in my home automation project. Thanks Sara for this all interesting posts.
Regards,
Ander.
Hi Sara, Rui,
Greetings from Australia 🙂
I am an avid, long time reader of your work at RNT and have learnt a great deal about this magnificent esp32 MCU; Thank you so much!
This TERRIFIC project has given me pause to post my first question. I apologise in advance for the lengthy post.
BACKGROUND:
Based broadly on RNT work, I have successfully built a project based on 2 x esp32-devkit-d1 30 pin boards for an ESP-NOW + BME280 project. My LiPo/solar-charger based sender is mounted in an outdoor plastic, 55cm wingspan ‘flying hawk’ which has short ws2812b strips on it’s wings and a BM280 mounted on its’ undercarriage. Though this 30-pin board in the sender will probably swap out for a D1 Mini.
My indoor receiver currently has a basic ssd-1306 display… as does the sender while on the development bench .
— I used Rui’s little “ESP32 Solar Powered Circuit” with the TP4056 to which I added a tiny step-up booster to get 3.3v up to static 5v for the LED strips.
— a later SW version may even vary the WS2812 palette triggered by current temperature.
It is this last point that finally gets me to ask my question regarding OTA for occasional SW updates to the sender.
BTW, though I have on another project, I am not wanting to use WebServer pages for this. That’s saying something for a long-retired ex pro IT / WebDev guy ! ;).
I have read broadly on this (ESP-NOW + WiFi) issue and see mixed messages regarding ESP-NOW and WiFi being mutually exclusive for OTA.
QUESTION:
So, my question is this: Will the [WiFi.mode(WIFI_AP_STA);] method above work for OTA and ESP-NOW?
— For example, I have seen on arduino.stackexchange.com (77344)
[quote] “Another method that works if you don’t mind having both at the same time:
Instead of WiFi.begin(ssid, password); I use WiFi.softAp(ssid,password,channel); for both Sender and Receiver.”[/quote]
… in addition to a C++ method for switching WiFi ON/OFF, based on the receiver sending a boolean switch to the sender (same post).
Any and all suggestions to help clear my confusion – and save me countless hours – will be gratefully received.
Thanks again and regards,
Chris
Hi Chris.
Thanks for following our work 🙂
I haven’t experimented with OTA with this project.
But you can try our new OTA project and try to integrate it with the ESP-NOW web server and see if it works as expected.
It is straightforward to use. So, in under 5 minutes, you’ll have OTA in your project, and you’ll be able to test if it will work.
Here’s the tutorial: https://randomnerdtutorials.com/esp32-ota-over-the-air-arduino/
Then, let me know your findings.
Regards,
Sara
Thanks Sara,
I tried the AsyncElegantOTA library – found it be terrific.
— I got your demo working in minutes.
A small heads-up… at first it wasn’t working… but then I realised…
I had a Firefox upgrade and forgot about the [about:config] trick for getting rid of their default setting of putting www in front of URL’s which causes the URL to fail.
— That is, manual IP addresses etc.
— I tried three browsers – but only tweaked FF.
In case you’re not a FF (Win10) user and others who are, might not be aware…
:: To stop Firefox from automatically adding www in front of URLs
:: address bar: > about:config
:: search for [browser.fixup.alternate.prefix]
:: —– delete the www, (or set to false) … restart FF.
I hope this helps others.
Chris
Great!
Thanks for sharing.
Regards,
Sara
Hi Sara
This project is top notch!!!
does the master-receiver have the ability to send back info to the slave/s via esp-now?
have you got a project for this?
thanks
Nick
Hi,
I was wondering if this will also work with an ESP32-CAM instead of a temperature sensor? So it sends the data from the camera to an ESP32-WROOM-32U/D via ESPNOW and the WROOM sends it via wifi to the network.
Is this possible? How do I implement this if it is possible?
Thanks in advance
Greetings Alex
Good Afternoon Sara,
It’s possible not use a wifi router? just connect the computer directly to the receiver board wifi?
Thanks in advance.
Hi sara,
Thank you very much for this great tutorial!
Using WiFi.scanNetworks to get the wifi channel work fine as long as the transmitter is in the wifi coverage area .
Here is a code that works fast and reliable if not. (testing all wifi channels)
Hi everybody from Belgium
#include <ESP8266WiFi.h>
#include <espnow.h>
// softAPMacAdress of receiver here
uint8_t broadcastAddress[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// Structure example to send data
// Must match the receiver structure
typedef struct struct_message
{ String texte;
}struct_message;
// Create a struct_message called myData
struct_message myData;
boolean recuConfirm=false;
boolean envoiOk=false;
boolean ok=false;
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
if(sendStatus==0){
recuConfirm=true;
envoiOk=true;
}
else {
recuConfirm=true;
envoiOk=false;
}
}
void setup() {
// Init Serial Monitor
Serial.begin(115200);
Serial.println(“\nstart”);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
myData.texte = “Test”;
//scan wifi channels
for (int32_t can=1;can<14;can++){
wifi_promiscuous_enable(1);
wifi_set_channel(can);
wifi_promiscuous_enable(0);
// Try init ESP-NOW
if (esp_now_init() == 0) {
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
esp_now_register_send_cb(OnDataSent);
esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE,1, NULL, 0);
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
if( confirme()){ //Yess..found it
Serial.print(“channel:”);
Serial.print(can);
ok=true;
break;
}
}
delay(20); //don’t remove, needed.
esp_now_deinit();
}
if (ok) {
myData.texte =”Hello World”;
// Send message via ESP-NOW
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
if (confirme())Serial.println(“Sending ok”);
}
else Serial.println(“Sorry, not found”);
}
void loop() {
}
boolean confirme(){ // wait sending information
unsigned long troplong;
troplong =millis()+1000;
// wait confirmation (from OnDataSent)
while (millis()<troplong&&recuConfirm==false)delay(10);
if (millis()>troplong) return false; //si + 3sec ->false
else return envoiOk;
}
Hi,
wifi channel can be changed independent of ESP-Now and must not before initializing ESP-Now.
So the simplest way for the sender to find the right channel is to change channel if sending is not successfull and try again:
….
boolean isSent; //sending successfull?
// Callback when data is sent
void onDataSent(const uint8_t *mac_addr, esp_now_send_status_t sendStatus) {
isSent = (sendStatus == 0) ? true : false;
}
void loop() {
….
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
delay(1000); //may be less
if (!isSent) {
for(int cnl=1; cnl<14; cnl++){
esp_wifi_set_promiscuous(true);
esp_wifi_set_channel(cnl, WIFI_SECOND_CHAN_NONE);
esp_wifi_set_promiscuous(false);
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
delay(1000); //may be less
if (isSent) break;
}
}
}
Tested. Works @me.
Sorry for my german english: “must not” is wrong, “may be but don’t need” is right.
Artur
This works great for me and I think it is the best and the fastest way to connect to the receiver. A delay of 100ms instead of 1000ms works well for me. It works even better if the last successful channel is stored in the RTC memory which I did try successfully.
Ótimo conteudo, porem tenho uma dúvida.
Até quantos dispositivos posso integrar ao Sistema?
Olá. Não sei.
Tudo vai depender do projecto.
Mas a fonte oficial do espressif menciona o seguinte:
“ESP-NOW technology also has the following limitations:
Limited encrypted peers. 10 encrypted peers at the most are supported in Station mode; 6 at the most in SoftAP or SoftAP + Station mode;
Multiple unencrypted peers are supported, however, their total number should be less than 20, including encrypted peers;
Payload is limited to 250 bytes.”
Nunca experimentei com um número tão elevado de dispositivos. Por isso, não posso dar a certeza.
Cumprimentos.
Sara Santos
Congratulations for this great tutorial and video. Excelent quality.
Just a little comment, to avoid two resistors use you could activate PULL-UP in GPIO4 of ESP32. Just to include this sentence in slave setup() void:
pinMode(DHTPIN, INPUT_PULLUP);
It is same effect thank resistor, but inside ESP32, that allow this function in almost all GPIO.
Gracias,
Oscar
Hi. Is there a way to put the device’s network into both STA and AP using MicroPython? I have a device that is able to do both separately but not in the same code. I have the device receive a message via ESP-Now and then I want it to text me that it received it. Is that possible or is there another way? Thanks
Hi.
I don’t think so. Check the documentation here: https://docs.micropython.org/en/latest/esp8266/tutorial/network_basics.html
I haven’t tested ESP-NOW with MicroPython yet.
Regards,
Sara
Ola, preciso de uma ajuda.
Estou querendo inserir um valor numa chave dentro do preferences ao clicar num icone no html, dessa forma:
server.on(“/ativaMR1”, HTTP_GET, [](AsyncWebServerRequest *request){ request->send(200, “text/html”); jso.putString(“MR1”, MR1ativar); Serial.println(); Serial.println(“SOLICITAÇÃO OK: ATIVAR (MR1)”); Serial.println();});
Ele nao esta atualizando a chave dessa forma… pde me ajudar?
att
15:8:21.389 -> ets Jun 8 2016 00:22:57
15:8:21.390 ->
15:8:21.390 -> rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
15:8:21.391 -> configsip: 0, SPIWP:0xee
15:8:21.401 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
15:8:21.427 -> mode:DIO, clock div:1
15:8:21.434 -> load:0x3fff0018,len:4
15:8:21.441 -> load:0x3fff001c,len:1044
15:8:21.447 -> load:0x40078000,len:10124
15:8:21.454 -> load:0x40080400,len:5856
15:8:21.470 -> entry 0x400806a8
15:8:21.476 -> Setting as a Wi-Fi Station..
15:8:22.833 -> Setting as a Wi-Fi Station..
15:8:23.836 -> Setting as a Wi-Fi Station..
15:8:24.833 -> Setting as a Wi-Fi Station..
15:8:25.834 -> Setting as a Wi-Fi Station..
15:8:26.893 -> Setting as a Wi-Fi Station..
15:8:27.831 -> Setting as a Wi-Fi Station..
15:8:28.830 -> Setting as a Wi-Fi Station..
15:8:29.832 -> Setting as a Wi-Fi Station..
15:8:30.827 -> Setting as a Wi-Fi Station..
15:8:31.828 -> Setting as a Wi-Fi Station..
15:8:32.828 -> Setting as a Wi-Fi Station..
… … ….
The Wifi doesn’t even start. Haven’t done any special changes to the code.
Hi.
Did you double-check your network credentials?
Regards,
Sara
Yes, I think I have but still the same results. Could you please elaborate a bit?
Hii,
The esp32 are able to send the readings to the receiver using ESP-now but it displays that it fails to deliver.
Hi.
Double-check the MAC address of the receiver and the distance between the boards.
To test, you can try it with the broadcast MAC address:
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
Regards,
Sara
Good day,
I would like to ask if the IP address that has been given by the Receiver can be change by the user? For example the given IP address is 192.168.45.232, can I change it to 192.168.54.232?
Hi.
You can set an IP address of your choice: https://randomnerdtutorials.com/esp32-static-fixed-ip-address-arduino-ide/
Regards,
Sara
Thank you. One more thing, this project of yours can integrate to database like phpAdmin?
Hi Sara,
Is the given IP address of the receiver can be change? For example the given IP addess is 192.168.45.232, can I change it to 192.168.53.232? And can you also tell me more about the given IP address? Thank you.
High, great example, but I’m not getting it. I’m attempting to do this in the esp mesh and am having a hard time putting the piees together since I’m just using the hello from node x. my main page is this:
//Async webserver
server.on(“/”, HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, “text/html”, ”
Text to Broadcast
“);
if (request->hasArg(“BROADCAST”)){
String msg = request->arg(“BROADCAST”);
mesh.sendBroadcast(msg);
}
});
server.begin();
So I can send a message from the web sever to the nodes and verify they receive it just as the nodes send a message to the server and it receives it on the web page, not on the serial interface.. The nodes send ID and a simple message of hello from node ID I think once I can do this and figure it out I’ll be good to go for the rest of the program. Please help! I use to be a VB6 programmer but this just doesn’t seem to click for my on how the events pull everything to gether.
to the server and it receives it on the web page.
This is what I want to happen, instead, these messages end up on the serial port console.
Hello and thank you both for all your hard work. I have been looking for a clearer understanding of ESP-NOW and using wifi also… my question is will the wifi still work correctly with my ESP32-CAM board as a TX & RX setup?
Hello, thank you for your efforts. I am trying to use this example as a groundwork for receiving ESP-NOW packets and retransmitting them over WIFI as MQTT. Is this something that you have tried from a single ESP32 receiving ESP-NOW and transmitting MQTT to a PC? I have tried many channel combinations and configurations but it seems that every time I connect WIFI the ESP-NOW communcations stop, any Ideas?
Hi,
I have done this but there is a problem.
The mac address of the receiving unit changes when you turn on the WIFI and enable it as a Access point. The actual mac address can be found from Serial.print(WiFi.softAPmacAddress());
In my case it was one digit greater than the normal mac address
Hope this helps
Hi.
The Acccess point mac address is always one digital greater than the normal mac address.
Regards,
Sara
Hi Sara,
This is a great tutorial for receiving ESP-Now data on the same ESP32 that acts as a web server. But how about transmitting ESP-Now + webserver on the same ESP32? I can’t find anything online about it – does it mean it is not possible?
In a post from June 2, 2020 at 10:14 am you say “I haven’t tried sending data from the main ESP32 that is acting as a web server. I plan to try that out in the future.”
– Did you ever try it? 🙂
Hi.
not yet.
But, it should be possible.
Our ESP-NOW tutorials show how to transmit data. You just need to combine the tutorials.
– https://randomnerdtutorials.com/?s=esp-now
Regards,
Sara
I guess you are right, I can try it at some point and get back to you. I’m assuming I can then skip the whole part of syncing the WIFI channel across all boards? Because the ESP-now sender is now the webserver, and the receivers won’t need to know about its channel, no?
hello everybody,
I implemented the project and it works perfectly right away. The extension to more ESPs also works without any problems.
For the implementation in my own project, I have considerable problems with the website, whose logic and structure I do not understand properly.
I don’t just want to equip each individual ESP with a DHT, I want to use all IOs of the ESP for different alarm contacts.
To do this, I just want to change the telegram to
Board ID
description (of alarm line)
value
ReadingID
Changing the structure is not the problem. But I can’t change the website on the receiver.
I just want to play back a list of alert points.
Can someone help me with that?
Thank you both for this smashing write up.
After some changes I was able to adapt your code for my weather station.
I’m now able to display windspeed (from an anemometer), wind direction (from a weather vane), indoor and outdoor temperatures (from x2 DS18B20-type thermometers) on 4 “cards” in a browser.
Moreover I also use the data to wirelessly drive a 21 module (1 metre) long LED matrix display to display the above information and locally at the main weather station head end on a smaller 6 module long LED matrix display for house keeping the station.
A further module also transmits this data over LoRa for added telemetry flexibility.
I look forward to adapting your other code project to be able to plot wind gusts over a time axis.
hi that is a great tutorial. but is it possible to publish these sensor data using mqtt. i actually want to send this that to Home Assistant which have mqtt broker addon to listen to mqtt messages. can you guys make a tutorial on espnow to mqtt gateway or give any suggestion.
i really appreciate your help.
thank you
Hi.
Yes. I think it is possible.
You just need to combine the ESP-NOW tutorials with the MQTT tutorials.
I’m not sure if there are any tricks to make both work at the same time.
We have many MQTT tutorials that you can check on the following link: https://randomnerdtutorials.com/?s=MQTT
Regards,
Sara
Hi Author,
Great tutorial. I’m currently have my own hosting and database. How can I send the data to the database at my hosting site? Thanks
Hi.
We have these tutorials:
https://randomnerdtutorials.com/visualize-esp32-esp8266-sensor-readings-from-anywhere/
https://randomnerdtutorials.com/cloud-weather-station-esp32-esp8266/
I hope this helps.
Regards,
Sara
Hi,
I have to ESP32 talking with each other using ESP-Now and one of the ESP32 acts as an Webserver. Quite similar to the described tutorial here.
But unfortunatley the function WiFi.localIP() delivers only and all the times 0.0.0.0.
Could you solve this issue. This may very helpful to find the webpage with non-static IP-Addresses.
Problem solved: The correct IP is available round about 2,5 seconds after establishing of the WiFi connection.
So the best way is to ask in a loop for a valid IP address and then continue with normal work.
Where to find this specific esp_now.h library for downloading or cloning? On github.com there is only a idf version of it at
esp-idf/components/esp_wifi/include/esp_now.h, whwere zou can not cloe it.
do you have the code that enable the ESP32 to read from the sensors and sent the values to a web page and bring me her ip adress
can i send the ip adress dynamicly to github
how to upload sensor values received by master esp to thingspeak colud using wifi. Here slave esp will be connected to the sensor and send data to master esp using espnow BLE comminucation
Hi.
We have the following tutorials about ThingSpeak that might help:
– https://randomnerdtutorials.com/esp32-thingspeak-publish-arduino/
– https://randomnerdtutorials.com/esp32-http-post-ifttt-thingspeak-arduino/
Regards,
Sara
thank you Sara ma’am for replying
I have checked those tutorials. I would like to explain my project in much detail so that you can help me out. we have two esp32 one is a master and one is a slave. so through BLE communication slave sends sensor data to master esp32.then this master esp32 should upload received data to thingspeak cloud using wifi communication. The problem I am facing is I am not getting data from the slave but the master is uploading 0 to thingspeak. And rarely master receive data from slave and upload it to thingspeak. sometimes it works and sometimes it doesn’t communication is unstable
Hello Sara thank you for great tutorial, but i have problem my device cannot peer to peer each other. Here’s the message I got
Mode: STA
Channel: 1
SSID (0):
Passphrase (0):
BSSID set: 0
Mode: STA
Channel: 6
SSID (0):
Passphrase (0):
BSSID set: 0
E (2302) ESPNOW: Peer interface is invalid
Failed to add peer
28.80
49.00
Error sending the data
is there any solution? Thank you
Hi Haxnel M,
You should put the “esp_now_peer_info_t peerInfo;” out of the void setup() and let it before the void setup(). It will work perfectly.
Best regards.
Hi Minh Tien,
Thanks for your reply, I’ve tried what you suggested and it worked great. Thank you
Hi,
I’ve had the same problem, but found solution. Sara posted solution for this issue here https://rntlab.com/question/espnow-peer-interface-is-invalid/
Basicaly the solution is to make peerInfo variable global and move declaration line “esp_now_peer_info_t peerInfo;” for instance just before “void setup()” line.
Hope it helps.
I have been successful in using both ESP32s and ESP8266s is in a many-to
-many ESPNOW broadcasting network and still provide a coded WiFi connection. I use the connection mostly for a simple web console for debug display and user control, but a more elaborate Dashboard is certainly doable. I’ve only tried up tp nine ESPs ‘cause I ran out a of available ESPs laying about the house. And it is blindingly fast. I call it ENNN for ESP Now Node Network.
Greg
Is the same setup i.e many to one comunication between esp32 using BLE is possible?
I built a weather station based on this project.
It works great and displays data on a LCD display, and saves the data to an SD card.
I can connect to the IP address of my board from any computer or phone in the house and see the values.
I sent the IP address to a friend who lives about a mile away.
He said he got this message: ERR_CONNECTION_TIMED_OUT
Is there any way to speed the connection up?
Thanks.
Hi.
The web server is only accessible on your local network.
Regards,
Sara
Please how conversion my MAC adress: “e8:db:84:9e:55:0f”
to command:
snprintf(macStr, sizeof(macStr), “%02x:%02x:%02x:%02x:%02x:%02x” ???
Hi, first of all, thanks for the tutorial.
I am new on coding, and i’m trying to send more data (temperature and humidity) from a DHT11 connected on the server ESP32 board, the one that receives temperature and humidity from other ESP32, connected via ESP NOW, like the tutorial.
How do i send the data read directly on the ESP32 that are connected on the DHT11, with the values received from the others boards, to the web?
I have to insert more lines on de JSON string (board)?
Thank you.
Hi,
thanks for the good example. I was fiddling around trying to get ESP NOW sensors to speak with a HomeSpan / HomeKit bridge (server) and the channel settings in your code was the right hint! Nowhere else mentioned…
I’m still looking for a better way to find out the right channel for communicating with the slave, may be by trying with trail and error: Sending a ‘Ping’ packet over every channel and waiting for slave respond with a ‘Pong’.
Cheers
Bernd
Hi.
One of our readers created a sketch with auto-pairing.
We’ll publish a tutorial about that in a few weeks.
Meanwhile, you can check his code on the following link: https://github.com/Servayejc
I hope this helps.
Regards,
Sara
Thanks, Sara, looks like I could do it that way!
Best
Bernd
Hello Sarah,
Thank you for this fantastic example. I would like to implement a similar setup but using a websocket server instead which acts as ESP Now receiver AND sender to multiple sensor boards. I need to read sensor data from several boards AND also want to send instructions to the sensor boards (switch heating on/off for example). So that I am able to read and control the boards via internet. Is that possible?
Best regards
Juergen
Hi.
Yes. One of our readers created a sample example for that. You can check his code on the following links:
https://github.com/Servayejc/esp_now_web_server (SERVER)
https://github.com/Servayejc/esp_now_sender (SENDER)
I hope this helps.
Regards,
Sara
Obviously people are getting this to work.
I am having issues with the library side.
#include “ESPAsyncWebServer.h” means the library is local. It says to install in the arduino/library folder.
are we to strip out the one .H file?
Any reason for using a local library file rather than using the main library folder?
I got this working. Seems there were some breaking changes in the updated libraries. Nothing to do with this code. Google any errors you get, and the changes will be shown.
Changes to the library are required.
Has anyone got this to work as a softaccess point rather than connecting to an access point?
I want this to be stand alone.
I have cut and pasted items, but cant get this to work as a soft access point server.
Sara,
I’m testing this circuit but it’s not working the web communication doesn’t appear at all on the computer or smartphone just the screen but the temperature and humidity values don’t change. I noticed that in ESPnow communication the channel does not change from 1 to 6 as shown. Could you or someone help me?
Hi.
Take a look at the most recent version of this project: https://randomnerdtutorials.com/esp-now-auto-pairing-esp32-esp8266/
I hope this helps.
Regards,
Sara
Newbie question:
Can someone please explain why the receiver has to be configured in station + AP mode? It’s not obvious to me what part of the AP mode is being used.
Thanks.
Hi,
Thank you very much for this valuable demo, Can I stream video from multi esp32 cameras by using their unique Mac Address to one client such web browser or Mobile App ? If yes, can you navigate me to an example?
Hi.
You can have multiple videos streaming from multiple cameras on one web page by referring to their IP addresses, not their MAC addresses.
You can use Node-RED, for example, to receive the streaming for all videos.
You can take a look at this tutorial: https://randomnerdtutorials.com/esp32-cam-video-streaming-web-server-camera-home-assistant/
After setting up the video streaming, scroll down to the Node-RED integration and repeat the process for the other cameras.
The example is not very detailed but will give you an idea.
Regards,
Sara
Can i use two way communication ESP-NOW with async web server?
Yes.
That’s possible.
Regards,
Sara
Hi sara, can we get blog on ble mesh using esp32
Can you show how to do it?
Because I’ve tried it and the esp that has a local async web server can’t send to other esp
Best regards to all the staff and thanks for this project which I found very interesting.
I state that I use a wemos mini as a receiver, two esp32 as transmitters. I modified the code to adapt it to the SHTC3 sensors, instead of the DHT11. It all works wonderfully well. However, after leaving it to work all day and night, I encountered a problem in the morning: there was no data on the web server. The serial monitor of the receiver was empty while that of the transmitters sent but the sending failed. I restarted the 3 cards and everything started working again, starting again with “Reading ID: 1, 2, etc.. The next morning it was blocked again: Receiver monitor empty. I wanted to do an analysis: I restarted “only” the receiver. After a few seconds, his serial monitor showed: “Client reconnected! Last message ID that it got is: 56819757”. Then I also restarted the two transmitters and everything started working again. My question: What do you think?
Hi.
Do you get any errors on the Serial Monitor right after crashing?
Regards,
Sara
Hi, thanks for the question.
I do not know. Now I put a sniffer and when it stops I send it to you.
See you soon.
Here, it stopped. Now, the receiver’s serial no longer receives anything. Posting the last lines of the log until the break:
Packet received from: 9c:9c:1f:c4:bd:38
Board ID 2: 16 bytes
t-value: 14.76
h value: 54.49
readingID value: 2146
Packet received from: c8:c9:a3:c6:c6:bc
Board ID 1: 16 bytes
t-value: 15.35
h value: 43.81
readingID value: 2153
Packet received from: 9c:9c:1f:c4:bd:38
Board ID 2: 16 bytes
t-value: 14.77
h value: 54.59
readingID value: 2147
dhcps: send_nak>>udp_sendto result 0
dhcps: send_nak>>udp_sendto result 0
Subsequently I will “only” reset the receiving card to check if and what it receives…
For the moment this is the log after the reset:
ets Jun 8 2016 00:22:57
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip:0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5856
entry 0x400806a8
Setting as a Wi-Fi Station..
Setting as a Wi-Fi Station..
Setting as a Wi-Fi Station..
Station IP Address: 192.168.1.71
WiFi Channels: 11
2023-03-16 16:25:37 –> Clients reconnected! Last message ID that it got is: 24661261
I’m getting the following from my board 1. It is reading the DHT22 just fine and displaying the readings. But it can’t send to the reciever. The reciever is working fine because I can bring up the webpage just fine.
Anyone have any thoughts.
10:21:42.510 -> Mode: STA
10:21:42.510 -> Channel: 2
10:21:42.510 -> SSID (13): mynetwork
10:21:42.510 -> Passphrase (8): mypassword
10:21:42.510 -> BSSID set: 0
10:21:42.510 -> E (159) ESPNOW: Peer interface is invalid
Hi.
How did you insert the receiver MAC address?
Regards,
Sara
I had the same error on all 3 senders … you must initialize the memory first.
try this …
In the sender sketch
add this line of code > memset(&peerInfo, 0, sizeof(peerInfo));
right above this line of code > memcpy(peerInfo.peer_addr, broadcastAddress, 6);
Regards,
Do you have any tutorial of ESP32 using ESP now , getting Sensor MPU6050 readings on OLED
Hi Sara,
Thanks for the tutorial.
I have setup communication between two ESp32 S3 boards. and I am sending an array of size 10 from one to another:
uint8_t Test[10] = {0,1,2,3,4,5,6,7,8,9};
I do not get any error but sometimes I get garbage output on the receiver board as follows:
values1 = 1 hex: 0x68,0xB6,0xB3,0x36,0xAA,0x7C data: 2,0,1,3,4,5,6,7,8,9
values1 = 1 hex: 0x68,0xB6,0xB3,0x36,0xAA,0x7C data: 2,0,1,3,4,5,6,7,8,9
values1 = 1 hex: 0x68,0xB6,0xB3,0x36,0xAA,0x7C data: 2,0,1,3,4,5,6,7,8,9
values1 = 1 hex: 0x68,0xB6,0xB3,0x36,0xAA,0x7C data: 72,96,108,3,1,1,45,26,45,64
values1 = 1 hex: 0x68,0xB6,0xB3,0x36,0xAA,0x7C data: 2,0,1,3,4,5,6,7,8,9
values1 = 1 hex: 0x68,0xB6,0xB3,0x36,0xAA,0x7C data: 2,0,1,3,4,5,6,7,8,9
values1 = 1 hex: 0x68,0xB6,0xB3,0x36,0xAA,0x7C data: 2,0,1,3,4,5,6,7,8,9
values1 = 1 hex: 0x68,0xB6,0xB3,0x36,0xAA,0x7C data: 2,0,1,3,4,5,6,7,8,9
I really can not find any source helping me with this error.
Any thoughts on this issue?
Thanks
Hi Sara,
Im using esp-now two way communication between a master and a slave. The slave reads from a dht22, sends the readings to the master that hosts a web server and displays those readings. From this server a user can chose the threshold value and a checkbox and those data are being sent back to the slave and control a fan using a bi-stable relay. My problem is on the slave part of the code. Im using deep sleep mode to preserve power. The data are being sent and received successfully, but every time the esp goes to sleep the fan closes not because the gpio doesn power the relay (again im using a bi-stable relay), but because the memory erases the incoming data and the if statement doesnt know what to do. My solution was to use light sleep so that the core and memory stay active. The relay now works fine, but temp and humidity readings are not being sent for a reason and the web server displays nothing. Its quite intresting the fact that the data are being sent with success using deep sleep but without success when i use light sleep, considering that the only thing i change in the code is one line. Do you have anything in mind? Below is the void loop where i think is the problem. Inside the setup i use the command esp_sleep_enable_timer_wakeup(30 * 1000000); to wake up after 30 seconds.
Thanks in advance!
void loop() {
unsigned long currentMillis = millis();
if (currentMillis – previousMillis >= interval) {
// Save the last time a new reading was published
previousMillis = currentMillis;
//Set values to send
myData.id = BOARD_ID;
myData.tempc = readDHTTemperature();
myData.tempf = readDHTTemperatureF();
myData.hum = readDHTHumidity();
myData.volts = readBatteryVolts();
myData.perc = readBatterypercentage();
myData.drst = digitalRead(DOOR_SENSOR_PIN);
//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");}
float temperature = dht.readTemperature();; // read temperature in Celsius
doorState = digitalRead(DOOR_SENSOR_PIN); // read state
if (doorState == LOW) {
Serial.println(“The door is closed!”);
if (isnan (temperature)) {
Serial. println (“Failed to read from DHT sensor!”); }
else{
if (temperature > incomingReadings.thres && incomingReadings.checkbox == “true” &&
!triggerActive){
Serial.println (“Turn the freezer unit on”);
triggerActive = true;
digitalWrite (26, LOW); //turn on
digitalWrite (25,HIGH);
delay(10);
digitalWrite (25,LOW);
}
else if (temperature < incomingReadings.thres && incomingReadings.checkbox == “true” && triggerActive) {
Serial.println (“Turn the freezer unit off”);
triggerActive = false;
digitalWrite (26, HIGH);
delay(10);
digitalWrite (26,LOW);
digitalWrite (25,LOW);}}}//turn off
if (doorState == HIGH) {
esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, HIGH);
triggerActive = false;
digitalWrite(26, HIGH);
delay(10);
digitalWrite(26, LOW);
digitalWrite(25, LOW);
}
delay(1000);
//esp_deep_sleep_start();
esp_light_sleep_start();
}
}
Hi.
When the ESP32 goes to sleep, it doesn’t run the rest of the code.
Then, when it wakes up, it starts running the code from the start.
So, any code that you add after the instruction to deep sleep will not run.
Regards,
Sara
Dear Sara and Rui ;
I hope this message finds you well. I am reaching out to seek your guidance and expertise regarding a technical issue I am facing with my smart radar project implementation. I would greatly appreciate any assistance or insights you can provide to help me overcome this challenge.
The objective of my project is to develop a radar system using an ultrasonic sensor, ESP32 development module, ESP32-CAM module, and ESP-NOW communication protocol. The system is designed to detect objects within a specific range, capture images using the ESP32-CAM module, and display the collected data on a web server for visualization.
While I have successfully implemented the ultrasonic sensor and established communication between the ESP32 modules, I am encountering two main problems:
1-Camera Image Capture: The ESP32 module successfully sends the distance data to the ESP32-CAM module. However, the camera does not capture any images when instructed to do so. I have verified the camera module’s connections and confirmed that it is functional. I suspect that there might be an issue with the code responsible for triggering the image capture.
2-Web Server Display: Despite the successful transmission of data from the ESP32-CAM module to the web server, the collected readings are not being displayed on the web page. I have double-checked the web server configuration and ensured that it is running correctly. However, there might be a code-related issue that prevents the data from being properly rendered on the web page.
I kindly request your assistance in resolving these issues. It would be immensely helpful if you could provide guidance on how to modify the code to ensure proper image capture and data display on the web server. Additionally, any insights or suggestions you may have to troubleshoot these problems would be highly appreciated.
If you require any specific details, such as the code snippets or circuit diagram, please let me know, and I will gladly provide them to assist in troubleshooting.
Thank you in advance for your valuable support. Your expertise and guidance will undoubtedly contribute to the successful completion of this project. I look forward to your response and the opportunity to further discuss and resolve these technical challenges.
Best regards,
Hi.
First, you need to adress one problem at a time.
Does the ESP32 get the sensor data from the ESP32-CAM? How are you sending the data to the web server?
Regards,
Sara
Dear Sara,
Thank you for your prompt response. I apologize for any confusion caused. To clarify, in my project, the ESP32-CAM module serves as the receiver, while the ESP32 module functions as the sender.
Currently, I have successfully implemented the ESP-NOW protocol to establish communication between the ESP32 (sender) and ESP32-CAM (receiver). The ESP32 module is able to send the data to the ESP32-CAM module without any issues.
However, the problem I am facing is that the data received by the ESP32-CAM is not being displayed on the web server. I have utilized the code you provided above , and i modifie it so that it works using one sender board.
Regarding the second question, I am using the code you provided, which includes the implementation of the ESP-NOW protocol for communication between the ESP32 and ESP32-CAM.
Thank you for your response. If it would be helpful, I can provide you with the code I have implemented for the project. Please let me know if you would like me to send it to you.
I appreciate your willingness to assist me in resolving the issue.
Best regards,
Hi.
Have you checked that you have the right BOARD ID set up?
In the tutorial we have the id for two boards. If you’re just using one board you should have the right names on the web page too. did you check that?
Regards,
Sara
Interesting project.
Can you give us your email
This is a great project. My chicken coop is out of range of my router, but with ESP-Now and Wi-Fi, I can make a connection from the coop to the house. So I highly modified the webpage and sender code to read 2 DS18B20s, send over C and F readings, display them on the webpage, and all is good! Well…almost! (esp32 core V1.0.6 is good.)
Today I started playing with a newly arrived ESP32-S3 dev board, and found I needed to update the esp32 Arduino core to use it. (V2.0.10) Later, returning to my coop project, I made minor cleanups in the code and tried to recompile. Uh Oh! Broke It! (Many words that don’t apply here!)
(Small portion of verbose output!) Error:
”
Linking everything together…
/home/dave/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/esp-2021r2-patch5-8.4.0/bin/xtensa-esp32-elf-g++ -Wl,–Map=/tmp/arduino_build_743492/esp32_ORIG_Receiver_ESPNOW_DHT_WebServer.ino.map -L/home/dave/.arduino15/packages/esp32/hardware/esp32/2.0.10/tools/sdk/esp32/lib -L/home/dave/.arduino15/packages/esp32/hardware/esp32/2.0.10/tools/sdk/esp32/ld -L/home/dave/.arduino15/packages/esp32/hardware/esp32/2.0.10/tools/sdk/esp32/qio_qspi -T esp32.rom.redefined.ld -T memory.ld -T sections.ld -T esp32.rom.ld -T esp32.rom.api.ld -T esp32.rom.libgcc.ld -T esp32.rom.newlib-data.ld -T esp32.rom.syscalls.ld -T esp32.peripherals.ld -mlongcalls -Wno-frame-address -Wl,–cref -Wl,–gc-sections -fno-rtti -fno-lto -Wl,–wrap=esp_log_write -Wl,–wrap=esp_log_writev -Wl,–wrap=log_printf -u ld_include_hli_vectors_bt -u _Z5setupv -u _Z4loopv -u esp_app_desc -u pthread_include_pthread_impl -u pthread_include_pthread_cond_impl -u pthread_include_pthread_local_storage_impl -u pthread_include_pthread_rwlock_impl -u include_esp_phy_override -u ld_include_highint_hdl -u start_app -u start_app_other_cores -u __ubsan_include -Wl,–wrap=longjmp -u __assert_func -u vfs_include_syscalls_impl -Wl,–undefined=uxTopUsedPriority -u app_main -u newlib_include_heap_impl -u newlib_include_syscalls_impl -u newlib_include_pthread_impl -u newlib_include_assert_impl -u __cxa_guard_dummy -DESP32 -DCORE_DEBUG_LEVEL=0 -DARDUINO_RUNNING_CORE=1 -DARDUINO_EVENT_RUNNING_CORE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -Wl,–start-group /tmp/arduino_build_743492/sketch/esp32_ORIG_Receiver_ESPNOW_DHT_WebServer.ino.cpp.o /tmp/arduino_build_743492/libraries/WiFi/WiFi.cpp.o /tmp/arduino_build_743492/libraries/WiFi/WiFiAP.cpp.o /tmp/arduino_build_743492/libraries/WiFi/WiFiClient.cpp.o /tmp/arduino_build_743492/libraries/WiFi/WiFiGeneric.cpp.o /tmp/arduino_build_743492/libraries/WiFi/WiFiMulti.cpp.o /tmp/arduino_build_743492/libraries/WiFi/WiFiSTA.cpp.o /tmp/arduino_build_743492/libraries/WiFi/WiFiScan.cpp.o /tmp/arduino_build_743492/libraries/WiFi/WiFiServer.cpp.o /tmp/arduino_build_743492/libraries/WiFi/WiFiUdp.cpp.o /tmp/arduino_build_743492/libraries/ESPAsyncWebServer/AsyncEventSource.cpp.o /tmp/arduino_build_743492/libraries/ESPAsyncWebServer/AsyncWebSocket.cpp.o /tmp/arduino_build_743492/libraries/ESPAsyncWebServer/SPIFFSEditor.cpp.o /tmp/arduino_build_743492/libraries/ESPAsyncWebServer/WebAuthentication.cpp.o /tmp/arduino_build_743492/libraries/ESPAsyncWebServer/WebHandlers.cpp.o /tmp/arduino_build_743492/libraries/ESPAsyncWebServer/WebRequest.cpp.o /tmp/arduino_build_743492/libraries/ESPAsyncWebServer/WebResponses.cpp.o /tmp/arduino_build_743492/libraries/ESPAsyncWebServer/WebServer.cpp.o /tmp/arduino_build_743492/libraries/FS/FS.cpp.o /tmp/arduino_build_743492/libraries/FS/vfs_api.cpp.o /tmp/arduino_build_743492/libraries/AsyncTCP/AsyncTCP.cpp.o /tmp/arduino_build_743492/libraries/Arduino_JSON/JSON.cpp.o /tmp/arduino_build_743492/libraries/Arduino_JSON/JSONVar.cpp.o /tmp/arduino_build_743492/libraries/Arduino_JSON/cjson/cJSON.c.o /tmp/arduino_build_743492/core/core.a -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -lconsole -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lasio -lbt -lcbor -lunity -lcmock -lcoap -lnghttp -lesp-tls -lesp_adc_cal -lesp_hid -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lesp_https_server -lesp_lcd -lprotobuf-c -lprotocomm -lmdns -lesp_local_ctrl -lsdmmc -lesp_serial_slave_link -lesp_websocket_client -lexpat -lwear_levelling -lfatfs -lfreemodbus -ljsmn -ljson -llibsodium -lmqtt -lopenssl -lperfmon -lspiffs -lulp -lwifi_provisioning -lrmaker_common -lesp_diagnostics -lrtc_store -lesp_insights -ljson_parser -ljson_generator -lesp_schedule -lespressif__esp_secure_cert_mgr -lesp_rainmaker -lgpio_button -lqrcode -lws2812_led -lesp32-camera -lesp_littlefs -lespressif__esp-dsp -lfb_gfx -lasio -lcmock -lunity -lcoap -lesp_lcd -lesp_websocket_client -lexpat -lfreemodbus -ljsmn -llibsodium -lperfmon -lesp_adc_cal -lesp_hid -lfatfs -lwear_levelling -lopenssl -lspiffs -lesp_insights -lcbor -lesp_diagnostics -lrtc_store -lesp_rainmaker -lesp_local_ctrl -lesp_https_server -lwifi_provisioning -lprotocomm -lbt -lbtdm_app -lprotobuf-c -lmdns -ljson -ljson_parser -ljson_generator -lesp_schedule -lespressif__esp_secure_cert_mgr -lqrcode -lrmaker_common -lmqtt -lcat_face_detect -lhuman_face_detect -lcolor_detect -lmfn -ldl -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -lconsole -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls_2 -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -lconsole -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls_2 -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -lconsole -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls_2 -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -lconsole -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls_2 -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lesp_ringbuf -lefuse -lesp_ipc -ldriver -lesp_pm -lmbedtls -lapp_update -lbootloader_support -lspi_flash -lnvs_flash -lpthread -lesp_gdbstub -lespcoredump -lesp_phy -lesp_system -lesp_rom -lhal -lvfs -lesp_eth -ltcpip_adapter -lesp_netif -lesp_event -lwpa_supplicant -lesp_wifi -lconsole -llwip -llog -lheap -lsoc -lesp_hw_support -lxtensa -lesp_common -lesp_timer -lfreertos -lnewlib -lcxx -lapp_trace -lnghttp -lesp-tls -ltcp_transport -lesp_http_client -lesp_http_server -lesp_https_ota -lsdmmc -lesp_serial_slave_link -lulp -lmbedtls_2 -lmbedcrypto -lmbedx509 -lcoexist -lcore -lespnow -lmesh -lnet80211 -lpp -lsmartconfig -lwapi -lphy -lrtc -lesp_phy -lphy -lrtc -lesp_phy -lphy -lrtc -lxt_hal -lm -lnewlib -lstdc++ -lpthread -lgcc -lcxx -lapp_trace -lgcov -lapp_trace -lgcov -lc -Wl,–end-group -Wl,-EL -o /tmp/arduino_build_743492/esp32_ORIG_Receiver_ESPNOW_DHT_WebServer.ino.elf
Multiple libraries were found for “WiFi.h”
Used: /home/dave/.arduino15/packages/esp32/hardware/esp32/2.0.10/libraries/WiFi
Not used: /home/dave/arduino-1.8.19/libraries/WiFi
/home/dave/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/esp-2021r2-patch5-8.4.0/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /tmp/arduino_build_743492/libraries/ESPAsyncWebServer/WebAuthentication.cpp.o:(.literal._ZL6getMD5PhtPc+0x4): undefined reference to
mbedtls_md5_starts'
getMD5(unsigned char*, unsigned short, char*)’:/home/dave/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/esp-2021r2-patch5-8.4.0/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /tmp/arduino_build_743492/libraries/ESPAsyncWebServer/WebAuthentication.cpp.o: in function
/home/dave/Arduino/libraries/ESPAsyncWebServer/src/WebAuthentication.cpp:73: undefined reference to `mbedtls_md5_starts’
collect2: error: ld returned 1 exit status
Using library WiFi at version 2.0.0 in folder: /home/dave/.arduino15/packages/esp32/hardware/esp32/2.0.10/libraries/WiFi
Using library ESPAsyncWebServer at version 1.2.3 in folder: /home/dave/Arduino/libraries/ESPAsyncWebServer
Using library FS at version 2.0.0 in folder: /home/dave/.arduino15/packages/esp32/hardware/esp32/2.0.10/libraries/FS
Using library AsyncTCP at version 1.1.4 in folder: /home/dave/Arduino/libraries/AsyncTCP
Using library Arduino_JSON at version 0.2.0 in folder: /home/dave/Arduino/libraries/Arduino_JSON
exit status 1
Error compiling for board ESP32 Dev Module.”
Reverted back to 1.0.6, and all is fine.
(Yes, I changed the board selection as required for the board I was working with…in this case a generic ESP32 Dev Module)
So, can two core libraries exist on the same system? (Incidentally, I tried it in Arduino 2.1.1 with the same results.) Or, can this project code be changed to allow it to compile with the new core?
Best Always,
Thanks, Dave
Maybe the issues is with a library. I did see an error
undefined reference to `mbedtls_md5_starts’ where the error started
Hi Terry,
I search the error (mbedtls_md5_starts) on espressif with no results. All my libraries report up to date. (No items in ‘updatable’).
Next I’ll go to the async libraries and see what I can learn there.
I appreciate your help.
See last reply to Sara, AND THANK YOU!
Great. I’m glad the issue is solve.d
Regards,
Sara
Hi.
I think you can just have one core for the ESP32 on Arduino IDE at a time.
Are you using Arduino IDE or VS Code?
Regards,
Sara
Arduino IDE. Tried 1.8.19 and 2.1.1. Same error on both versions after esp32 upgrade from 1.0.6 to 2.0.10.
In Arduino IDE v1.8.19:
It seems it was indeed an Async library. I updated AsyncTCP and ESPAsyncWebServer, then updated the ESP32 core and compiled without issue.
Thanks for Your and Terry’s help! I never would’ve thought the libraries were an issue as they never flagged as update-able. But of course that too makes sense since they are not “Arduino” libraries. (hindsight is 20-20!)
Again, Thanks for Your Support Folks!
Dave
E (6162) ESPNOW: Peer interface is invalid
Failed to add peer
I’m getting this error. what could be the problem? I’m using different IMU sensor
Hello, amazing tutorial. everything work fine but i have one question as i was also trying to upload the reading to firebase. i also followed your firebase data logging tutorial. but i am still unable to figure out how can separated that data and stored separately to firebase as id 1 and id 2. i tried to used if statement but still i am able to get data for only one esp. so any suggestions please?
I would also like to know if this is possible
E (6159) ESPNOW: Peer interface is invalid
Failed to add peer
Error sending the data
I’m getting this error.What could be the problem? Help me out
Hi.
Check the improved version of that tutorial here https://randomnerdtutorials.com/esp-now-auto-pairing-esp32-esp8266/
Regards,
Sara
Hi Sara. I have successfully implimented a webserver project based on one of a mixture of tutorials in your e-book about webservers. I have a device acting as a server and it’s all good.
I parkerd that code, copied to a new version am now integrating ESP-NOW that reads RFID cards from an ‘outstation’. That also works and the data is happily forwarded to my telegram bot via the existing webserver/bridge device . However the webserver no longer works, as in the webpage does not connect/display data anymore, however ESP-NOW is OK. There seems to be a lot of chatter about WiFi channels. My existing device is connetred to channel 6, as is the ESPO-NOW sender. As I said, my webserver is no longer connectiong to the client. Any thoughts?
When I give 2 two ID i’m not getting the data from 2 board
how can i connect three esp32 together, where the middle one act as a repeater to farward the packet or data from the esp32 (with the sensor reading) to the esp32 (with the webserver)…is this possible
You might want to look at ESP-Now mesh, and ESP32 webserver.
I loved the GUI.
Hi
Could this code be modified to receive data from another device via ESP-NOW and then post the data to Firebase?
Thanks
Excellent project but one observation which might be helpful to others….
In the Sender code I found that I had to move the ” esp_now_peer_info_t peerInfo; ” statement to the global definitions area.
Leaving it in Setup resulted in comm failure between the Sender and Receiver.
Don’t know why that happens but have noticed it in other projects.
Regards
My browser block non HTTPS URL
How should I get around that?
Hello,
thanks for this interesting tutorial, I would like to test it.
Unfortunately I get the following error (m1 mea, Arduino 2.3.0 and MBA intel, Arduino 1.8: Receiver_ESPNow_Webserver_t01.ino:9:
/Users/…/Library/Arduino15/packages/esp32/tools/esp32-arduino-libs/idf-release_v5.1-3662303f31/esp32/include/esp_wifi/include/esp_now.h:156:54: note: initializing argument 1 of ‘esp_err_t esp_now_register_recv_cb(esp_now_recv_cb_t)’
156 | esp_err_t esp_now_register_recv_cb(esp_now_recv_cb_t cb);
| ~~~~~~~~~~~~~~~~~~^~
exit status 1
Compilation error: invalid conversion from ‘void ()(uint8_t, uint8_t*, uint8_t)’ {aka ‘void ()(unsigned char, unsigned char*, unsigned char)’} to ‘esp_now_recv_cb_t’ {aka ‘void ()(const esp_now_recv_info, const unsigned char*, int)’} [-fpermissive]
Did anyone else have this compiling error?
Thanks in advance,
regards,
Tobias
Thanks, great project that I can use to upgrade my heating system. Unfortunately my esp32 dev. kit v1keeps rebooting after uploading the server code. Repeated this with same result. Any idea why?
Could this be updated to have the esp32 web server as as an AP? I know this uses the asyncweb server, and ties in the slaves for ESP-Now; while you have another article showing the way you would do a web server /AP combination but it is not using the asyncweb server.
Instead of creating a web server in the receiving sketch is it possible to simply call a web page to post the results to a database.
eg Receive Temperature message
Get or Post to :
TestIOT.com?Temp=32
Hi.
Yes.
check our tutorial about HTTPS requests: https://randomnerdtutorials.com/esp32-https-requests/
Regards,
Sara
Hi Sara and Rui,
First off, I would just like to say thank you for the public service you are doing with the projects you have on your web page. I have learned so much from the projects you have shared 🙂
This project which utilizes ESP Now and a WiFi Web Server does exactly what I need for a DIY irrigation system that I am building. However, I am running into an issue.
I can access the web page that the ESP32 receiver is hosting on my WiFi network without issues, but I am having a problem with the ESP32 transmitter connecting as a peer to the ESP32 receiver. In the receiver code, I have added my WiFi SSID and password. In the transmitter code, I have included and verified that the MAC address of the receiver and updated my WiFi SSID (for the transmitter, the SSID password isn’t needed?). I can see in the serial monitor that the Channel is initially set to “1” but is then set to “8” which matches the channel number I see in the serial monitor on the receiver side. But when the transmitter tries to register as a peer, I get an error saying that the Peer interface is invalid and the transmitter fails to be added as a peer.
It seems that I am missing something and I would really appreciate your help to overcome this issue. As a test, I have successfully been able to configure the two ESP32’s that I am using as you did in this project: ESP-NOW with ESP32: Receive Data from Multiple Boards (many-to-one). I was able to establish the ESP-NOW link between the two ESP32’s so I wonder if I am making a mistake that is obvious to someone more familiar with the code.
Here is the serial output of the Receiver…
Setting as a Wi-Fi Station..
Setting as a Wi-Fi Station..
Station IP Address: 10.0.0.18
Wi-Fi Channel: 8
Here is the serial output of the Transmitter…
Mode: STA
Channel: 1
SSID (0):
Passphrase (0):
BSSID set: 0
Mode: STA
Channel: 8
SSID (0):
Passphrase (0):
BSSID set: 0
E (6716) ESPNOW: Peer interface is invalid
Failed to add peer
23.90
37.00
Error sending the data
Should the SSID and passphrase be displayed in the serial output above? I am seeing exactly what I have copied and pasted above.
Thank you again for sharing your amazing projects and I hope you can provide some guidance 🙂
Sincerely,
-Scotty
Dear Sarah and Rui,
I’m currently working on a project that needs WiFi and ESP_NOW simultaniously. I came across your instruction page for just that and am trying to compile it for an ESP32S Dev Module. I keep getting the following error (both in the ESP_NOW + WiFi sketch, and this sketch here):
”
FQBN: esp32:esp32:esp32s2
Using board ‘esp32s2’ from platform in folder: .
.
.
C:\Users\Frank\Documents\Arduino\ESP32S2_WiFi\ESP32S2_WiFi.ino:158: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]
158 | 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\Frank\AppData\Local\Arduino15\packages\esp32\tools\esp32-arduino-libs\idf-release_v5.1-442a798083/esp32s2/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]
”
This error occures on line 158 (this sketch):
”
esp_now_register_recv_cb(OnDataRecv);
”
How can I fix this?
Thanks in advance for your help.
Kind regards,
Frank
I don’t get the Ping code..
shouldn’t “lastEventTime ” be declared outside Loop() so it can retain its value..
Also unless another function updates it then it will always ping every 5sec regardless of the “last event”..
But right now I don’t see how it will ever see any milliseconds since we test time elapsed right after assigning it..
Maybe I’m missing something..
// web server stuff
static unsigned long lastEventTime = millis();
static const unsigned long EVENT_INTERVAL_MS = 5000;
if ((millis() – lastEventTime) > EVENT_INTERVAL_MS) {…
Thank you for this project,
do you know how much time it takes to get the wifi channel for the senders?
Im thinking about using this code and modify it for deepsleep and low power application.
I want to power it by a CR2032. So time is really critical. If im using a BME280 the sensorreadings are quite “fast” and the circuit shouldnt be powerd more then 100ms.