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+ }
0 commit comments