Skip to content

Commit 4c36e03

Browse files
arvindr21me-no-dev
authored andcommitted
Added ESPNow basic example (#667)
* Added ESPNow basic example * fixed meta doc for slave * refactored folder structure
1 parent d27d297 commit 4c36e03

File tree

2 files changed

+359
-0
lines changed

2 files changed

+359
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
/**
2+
ESPNOW - Basic communication - Master
3+
Date: 26th September 2017
4+
Author: Arvind Ravulavaru <https://github.com/arvindr21>
5+
Purpose: ESPNow Communication between a Master ESP32 and a Slave ESP32
6+
Description: This sketch consists of the code for the Master module.
7+
Resources: (A bit outdated)
8+
a. https://espressif.com/sites/default/files/documentation/esp-now_user_guide_en.pdf
9+
b. http://www.esploradores.com/practica-6-conexion-esp-now/
10+
11+
<< This Device Master >>
12+
13+
Flow: Master
14+
Step 1 : ESPNow Init on Master and set it in STA mode
15+
Step 2 : Start scanning for Slave ESP32 (we have added a prefix of `slave` to the SSID of slave for an easy setup)
16+
Step 3 : Once found, add Slave as peer
17+
Step 4 : Register for send callback
18+
Step 5 : Start Transmitting data from Master to Slave
19+
20+
Flow: Slave
21+
Step 1 : ESPNow Init on Slave
22+
Step 2 : Update the SSID of Slave with a prefix of `slave`
23+
Step 3 : Set Slave in AP mode
24+
Step 4 : Register for receive callback and wait for data
25+
Step 5 : Once data arrives, print it in the serial monitor
26+
27+
Note: Master and Slave have been defined to easily understand the setup.
28+
Based on the ESPNOW API, there is no concept of Master and Slave.
29+
Any devices can act as master or salve.
30+
*/
31+
32+
#include <esp_now.h>
33+
#include <WiFi.h>
34+
35+
// Global copy of slave
36+
esp_now_peer_info_t slave;
37+
#define CHANNEL 3
38+
#define PRINTSCANRESULTS 0
39+
#define DELETEBEFOREPAIR 0
40+
41+
// Init ESP Now with fallback
42+
void InitESPNow() {
43+
if (esp_now_init() == ESP_OK) {
44+
Serial.println("ESPNow Init Success");
45+
}
46+
else {
47+
Serial.println("ESPNow Init Failed");
48+
// Retry InitESPNow, add a counte and then restart?
49+
// InitESPNow();
50+
// or Simply Restart
51+
ESP.restart();
52+
}
53+
}
54+
55+
// Scan for slaves in AP mode
56+
void ScanForSlave() {
57+
int8_t scanResults = WiFi.scanNetworks();
58+
bool slaveFound = 0;
59+
Serial.println("");
60+
if (scanResults == 0) {
61+
Serial.println("No WiFi devices in AP Mode found");
62+
} else {
63+
Serial.print("Found "); Serial.print(scanResults); Serial.println(" devices ");
64+
for (int i = 0; i < scanResults; ++i) {
65+
// Print SSID and RSSI for each device found
66+
String SSID = WiFi.SSID(i);
67+
int32_t RSSI = WiFi.RSSI(i);
68+
String BSSIDstr = WiFi.BSSIDstr(i);
69+
70+
if (PRINTSCANRESULTS) {
71+
Serial.print(i + 1);
72+
Serial.print(": ");
73+
Serial.print(SSID);
74+
Serial.print(" (");
75+
Serial.print(RSSI);
76+
Serial.print(")");
77+
Serial.println("");
78+
}
79+
delay(10);
80+
// Check if the current device starts with `Slave`
81+
if (SSID.indexOf("Slave") == 0) {
82+
// SSID of interest
83+
Serial.println("Found a Slave.");
84+
Serial.print(i + 1); Serial.print(": "); Serial.print(SSID); Serial.print(" ["); Serial.print(BSSIDstr); Serial.print("]"); Serial.print(" ("); Serial.print(RSSI); Serial.print(")"); Serial.println("");
85+
// Get BSSID => Mac Address of the Slave
86+
int mac[6];
87+
if ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x%c", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] ) ) {
88+
for (int ii = 0; ii < 6; ++ii ) {
89+
slave.peer_addr[ii] = (uint8_t) mac[ii];
90+
}
91+
}
92+
93+
slave.channel = CHANNEL; // pick a channel
94+
slave.encrypt = 0; // no encryption
95+
96+
slaveFound = 1;
97+
// we are planning to have only one slave in this example;
98+
// Hence, break after we find one, to be a bit efficient
99+
break;
100+
}
101+
}
102+
}
103+
104+
if (slaveFound) {
105+
Serial.println("Slave Found, processing..");
106+
} else {
107+
Serial.println("Slave Not Found, trying again.");
108+
}
109+
110+
// clean up ram
111+
WiFi.scanDelete();
112+
}
113+
114+
// Check if the slave is already paired with the master.
115+
// If not, pair the slave with master
116+
bool manageSlave() {
117+
if (slave.channel == CHANNEL) {
118+
if (DELETEBEFOREPAIR) {
119+
deletePeer();
120+
}
121+
122+
Serial.print("Slave Status: ");
123+
const esp_now_peer_info_t *peer = &slave;
124+
const uint8_t *peer_addr = slave.peer_addr;
125+
// check if the peer exists
126+
bool exists = esp_now_is_peer_exist(peer_addr);
127+
if ( exists) {
128+
// Slave already paired.
129+
Serial.println("Already Paired");
130+
return true;
131+
} else if (exists == ESP_ERR_ESPNOW_NOT_INIT) {
132+
// How did we get so far!!
133+
Serial.println("ESPNOW Not InitESP_ERR_ESPNOW_NOT_INIT");
134+
return false;
135+
} else if (exists == ESP_ERR_ESPNOW_ARG) {
136+
// Invalid Argument
137+
Serial.println("Invalid Argument");
138+
return false;
139+
} else {
140+
// Slave not paired, attempt pair
141+
esp_err_t addStatus = esp_now_add_peer(peer);
142+
if (addStatus == ESP_OK) {
143+
// Pair success
144+
Serial.println("Pair success");
145+
return true;
146+
} else if (addStatus == ESP_ERR_ESPNOW_NOT_INIT) {
147+
// How did we get so far!!
148+
Serial.println("ESPNOW Not Init");
149+
return false;
150+
} else if (addStatus == ESP_ERR_ESPNOW_ARG) {
151+
Serial.println("Invalid Argument");
152+
return false;
153+
} else if (addStatus == ESP_ERR_ESPNOW_FULL) {
154+
Serial.println("Peer list full");
155+
return false;
156+
} else if (addStatus == ESP_ERR_ESPNOW_NO_MEM) {
157+
Serial.println("Out of memory");
158+
return false;
159+
} else if (addStatus == ESP_ERR_ESPNOW_EXIST) {
160+
Serial.println("Peer Exists");
161+
return true;
162+
} else {
163+
Serial.println("Not sure what happened");
164+
return false;
165+
}
166+
}
167+
} else {
168+
// No slave found to process
169+
Serial.println("No Slave found to process");
170+
return false;
171+
}
172+
}
173+
174+
void deletePeer() {
175+
const esp_now_peer_info_t *peer = &slave;
176+
const uint8_t *peer_addr = slave.peer_addr;
177+
esp_err_t delStatus = esp_now_del_peer(peer_addr);
178+
Serial.print("Slave Delete Status: ");
179+
if (delStatus == ESP_OK) {
180+
// Delete success
181+
Serial.println("Success");
182+
} else if (delStatus == ESP_ERR_ESPNOW_NOT_INIT) {
183+
// How did we get so far!!
184+
Serial.println("ESPNOW Not Init");
185+
} else if (delStatus == ESP_ERR_ESPNOW_ARG) {
186+
Serial.println("Invalid Argument");
187+
} else if (delStatus == ESP_ERR_ESPNOW_NOT_FOUND) {
188+
Serial.println("Peer not found.");
189+
} else {
190+
Serial.println("Not sure what happened");
191+
}
192+
}
193+
194+
195+
196+
uint8_t data = 0;
197+
// send data
198+
void sendData() {
199+
data++;
200+
const uint8_t *peer_addr = slave.peer_addr;
201+
Serial.print("Sending: "); Serial.println(data);
202+
esp_err_t result = esp_now_send(peer_addr, &data, sizeof(data));
203+
Serial.print("Send Status: ");
204+
if (result == ESP_OK) {
205+
Serial.println("Success");
206+
} else if (result == ESP_ERR_ESPNOW_NOT_INIT) {
207+
// How did we get so far!!
208+
Serial.println("ESPNOW not Init.");
209+
} else if (result == ESP_ERR_ESPNOW_ARG) {
210+
Serial.println("Invalid Argument");
211+
} else if (result == ESP_ERR_ESPNOW_INTERNAL) {
212+
Serial.println("Internal Error");
213+
} else if (result == ESP_ERR_ESPNOW_NO_MEM) {
214+
Serial.println("ESP_ERR_ESPNOW_NO_MEM");
215+
} else if (result == ESP_ERR_ESPNOW_NOT_FOUND) {
216+
Serial.println("Peer not found.");
217+
} else {
218+
Serial.println("Not sure what happened");
219+
}
220+
}
221+
222+
// callback when data is sent from Master to Slave
223+
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
224+
char macStr[18];
225+
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
226+
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
227+
Serial.print("Last Packet Sent to: "); Serial.println(macStr);
228+
Serial.print("Last Packet Send Status: "); Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
229+
}
230+
231+
void setup() {
232+
Serial.begin(115200);
233+
//Set device in STA mode to begin with
234+
WiFi.mode(WIFI_STA);
235+
Serial.println("ESPNow/Basic/Master Example");
236+
// This is the mac address of the Master in Station Mode
237+
Serial.print("STA MAC: "); Serial.println(WiFi.macAddress());
238+
// Init ESPNow with a fallback logic
239+
InitESPNow();
240+
// Once ESPNow is successfully Init, we will register for Send CB to
241+
// get the status of Trasnmitted packet
242+
esp_now_register_send_cb(OnDataSent);
243+
}
244+
245+
void loop() {
246+
// In the loop we scan for slave
247+
ScanForSlave();
248+
// If Slave is found, it would be populate in `slave` variable
249+
// We will check if `slave` is defined and then we proceed further
250+
if (slave.channel == CHANNEL) { // check if slave channel is defined
251+
// `slave` is defined
252+
// Add slave as peer if it has not been added already
253+
bool isPaired = manageSlave();
254+
if (isPaired) {
255+
// pair success or already paired
256+
// Send data to device
257+
sendData();
258+
} else {
259+
// slave pair failed
260+
Serial.println("Slave pair failed!");
261+
}
262+
}
263+
else {
264+
// No slave found to process
265+
}
266+
267+
// wait for 3seconds to run the logic again
268+
delay(3000);
269+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/**
2+
ESPNOW - Basic communication - Slave
3+
Date: 26th September 2017
4+
Author: Arvind Ravulavaru <https://github.com/arvindr21>
5+
Purpose: ESPNow Communication between a Master ESP32 and a Slave ESP32
6+
Description: This sketch consists of the code for the Slave module.
7+
Resources: (A bit outdated)
8+
a. https://espressif.com/sites/default/files/documentation/esp-now_user_guide_en.pdf
9+
b. http://www.esploradores.com/practica-6-conexion-esp-now/
10+
11+
<< This Device Slave >>
12+
13+
Flow: Master
14+
Step 1 : ESPNow Init on Master and set it in STA mode
15+
Step 2 : Start scanning for Slave ESP32 (we have added a prefix of `slave` to the SSID of slave for an easy setup)
16+
Step 3 : Once found, add Slave as peer
17+
Step 4 : Register for send callback
18+
Step 5 : Start Transmitting data from Master to Slave
19+
20+
Flow: Slave
21+
Step 1 : ESPNow Init on Slave
22+
Step 2 : Update the SSID of Slave with a prefix of `slave`
23+
Step 3 : Set Slave in AP mode
24+
Step 4 : Register for receive callback and wait for data
25+
Step 5 : Once data arrives, print it in the serial monitor
26+
27+
Note: Master and Slave have been defined to easily understand the setup.
28+
Based on the ESPNOW API, there is no concept of Master and Slave.
29+
Any devices can act as master or salve.
30+
*/
31+
32+
#include <esp_now.h>
33+
#include <WiFi.h>
34+
35+
#define CHANNEL 1
36+
37+
// Init ESP Now with fallback
38+
void InitESPNow() {
39+
if (esp_now_init() == ESP_OK) {
40+
Serial.println("ESPNow Init Success");
41+
}
42+
else {
43+
Serial.println("ESPNow Init Failed");
44+
// Retry InitESPNow, add a counte and then restart?
45+
// InitESPNow();
46+
// or Simply Restart
47+
ESP.restart();
48+
}
49+
}
50+
51+
// config AP SSID
52+
void configDeviceAP() {
53+
char* SSID = "Slave_1";
54+
bool result = WiFi.softAP(SSID, "Slave_1_Password", CHANNEL, 0);
55+
if (!result) {
56+
Serial.println("AP Config failed.");
57+
} else {
58+
Serial.println("AP Config Success. Broadcasting with AP: " + String(SSID));
59+
}
60+
}
61+
62+
void setup() {
63+
Serial.begin(115200);
64+
Serial.println("ESPNow/Basic/Slave Example");
65+
//Set device in AP mode to begin with
66+
WiFi.mode(WIFI_AP);
67+
// configure device AP mode
68+
configDeviceAP();
69+
// This is the mac address of the Slave in AP Mode
70+
Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress());
71+
// Init ESPNow with a fallback logic
72+
InitESPNow();
73+
// Once ESPNow is successfully Init, we will register for recv CB to
74+
// get recv packer info.
75+
esp_now_register_recv_cb(OnDataRecv);
76+
}
77+
78+
// callback when data is recv from Master
79+
void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) {
80+
char macStr[18];
81+
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
82+
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
83+
Serial.print("Last Packet Recv from: "); Serial.println(macStr);
84+
Serial.print("Last Packet Recv Data: "); Serial.println(*data);
85+
Serial.println("");
86+
}
87+
88+
void loop() {
89+
// Chill
90+
}

0 commit comments

Comments
 (0)