ESP-NOW Projects
Device to Device Communication with ESP-NOW
https://docs.arduino.cc/tutorials/nano-esp32/esp-now/
Communication Protocol
ESP-NOW operates as a peer-to-peer (P2P) protocol, meaning it allows direct communication between two ESP8266 or ESP32 devices without the need for a central server or access point, e.g. a Wi-Fi® router. Each ESP device has a unique MAC address which is used to identify the receiving board.
ESP-NOW can be set up in different ways:
One-way communication: In one-way communication mode, one device (the sender) can send data to another device (the receiver) without expecting a response. This mode is often used for scenarios where one device provides data or commands to another device, such as remote sensor readings or control commands.
ESP-NOW EXPLAINED: Easiest Wireless Communication Between Boards
https://dronebotworkshop.com/esp-now/
// Complete Instructions to Get ESP MAC Address:
#include "WiFi.h"
void setup(){
Serial.begin(115200);
WiFi.mode(WIFI_MODE_STA);
Serial.println(WiFi.macAddress());
}
void loop(){
}
/*
ESP-NOW Demo - Transmit
esp-now-demo-xmit.ino
Sends data to Responder
DroneBot Workshop 2022
https://dronebotworkshop.com
*/
// Include Libraries
#include <esp_now.h>
#include <WiFi.h>
// Variables for test data
int int_value;
float float_value;
bool bool_value = true;
// MAC Address of responder - edit as required
uint8_t broadcastAddress[] = {0x24, 0x6F, 0x28, 0x7A, 0xAE, 0x7C};
// Define a data structure
typedef struct struct_message {
char a[32];
int b;
float c;
bool d;
} struct_message;
// Create a structured object
struct_message myData;
// Peer info
esp_now_peer_info_t peerInfo;
// Callback function called 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() {
// Set up Serial Monitor
Serial.begin(115200);
// Set ESP32 as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Initilize ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Register the send callback
esp_now_register_send_cb(OnDataSent);
// Register peer
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
}
void loop() {
// Create test data
// Generate a random integer
int_value = random(1,20);
// Use integer to make a new float
float_value = 1.3 * int_value;
// Invert the boolean value
bool_value = !bool_value;
// Format structured data
strcpy(myData.a, "Welcome to the Workshop!");
myData.b = int_value;
myData.c = float_value;
myData.d = bool_value;
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
if (result == ESP_OK) {
Serial.println("Sending confirmed");
}
else {
Serial.println("Sending error");
}
delay(2000);
}
Responder Sketch:
-now-demo-rcv
C++
/*
ESP-NOW Demo - Receive
esp-now-demo-rcv.ino
Reads data from Initiator
DroneBot Workshop 2022
https://dronebotworkshop.com
*/
// Include Libraries
#include <esp_now.h>
#include <WiFi.h>
// Define a data structure
typedef struct struct_message {
char a[32];
int a;
float b;
bool d;
} struct_message;
// Create a structured object
struct_message myData;
// Callback function executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&myData, incomingData, sizeof(myData));
Serial.print("Data received: ");
Serial.println(len);
Serial.print("Character Value: ");
Serial.println(myData.a);
Serial.print("Integer Value: ");
Serial.println(myData.b);
Serial.print("Float Value: ");
Serial.println(myData.c);
Serial.print("Boolean Value: ");
Serial.println(myData.d);
Serial.println();
}
void setup() {
// Set up Serial Monitor
Serial.begin(115200);
// Set ESP32 as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Initilize ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Register callback function
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {
}
Transmitter code, using ADXL 335 analog accelerometer connected to GPIO pins 36 and 39.
#include <esp_now.h>
#include <WiFi.h>
int int_value;
uint8_t broadcastAddress[] = {0xE8, 0x6B, 0xEA, 0xDF, 0xE2, 0xD0}; //below- set MAC address of receiver ESP-32
typedef struct struct_message {
int a; // holds sensor value
int b; //holds sensor value
} struct_message;
struct_message myData;
esp_now_peer_info_t peerInfo;
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() {
Serial.begin(115200);
// Set ESP32 as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Initialize ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_send_cb(OnDataSent);
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
}
void loop() {
myData.a = (analogRead(36)-1400); //ADXL 335 accelerometer X-axis
myData.b = analogRead(39)-1400); //ADXL 335 accelerometer Y-axis
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
if (result == ESP_OK) {
Serial.println("Sending confirmed");
}
else {
Serial.println("Sending error");
}
delay(2000);
}