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 multiple ESP32 Slaves
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(s)
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
+ // Sample Serial log with 1 master & 2 slaves
33
+ Found 12 devices
34
+ 1: Slave:24:0A:C4:81:CF:A4 [24:0A:C4:81:CF:A5] (-44)
35
+ 3: Slave:30:AE:A4:02:6D:CC [30:AE:A4:02:6D:CD] (-55)
36
+ 2 Slave(s) found, processing..
37
+ Processing: 24:A:C4:81:CF:A5 Status: Already Paired
38
+ Processing: 30:AE:A4:2:6D:CD Status: Already Paired
39
+ Sending: 9
40
+ Send Status: Success
41
+ Last Packet Sent to: 24:0a:c4:81:cf:a5
42
+ Last Packet Send Status: Delivery Success
43
+ Send Status: Success
44
+ Last Packet Sent to: 30:ae:a4:02:6d:cd
45
+ Last Packet Send Status: Delivery Success
46
+
47
+ */
48
+
49
+ #include < esp_now.h>
50
+ #include < WiFi.h>
51
+
52
+ // Global copy of slave
53
+ #define NUMSLAVES 20
54
+ esp_now_peer_info_t slaves[NUMSLAVES] = {};
55
+ int SlaveCnt = 0 ;
56
+
57
+ #define CHANNEL 3
58
+ #define PRINTSCANRESULTS 0
59
+
60
+ // Init ESP Now with fallback
61
+ void InitESPNow () {
62
+ if (esp_now_init () == ESP_OK) {
63
+ Serial.println (" ESPNow Init Success" );
64
+ }
65
+ else {
66
+ Serial.println (" ESPNow Init Failed" );
67
+ // Retry InitESPNow, add a counte and then restart?
68
+ // InitESPNow();
69
+ // or Simply Restart
70
+ ESP.restart ();
71
+ }
72
+ }
73
+
74
+ // Scan for slaves in AP mode
75
+ void ScanForSlave () {
76
+ int8_t scanResults = WiFi.scanNetworks ();
77
+ // reset slaves
78
+ memset (slaves, 0 , sizeof (slaves));
79
+ SlaveCnt = 0 ;
80
+ Serial.println (" " );
81
+ if (scanResults == 0 ) {
82
+ Serial.println (" No WiFi devices in AP Mode found" );
83
+ } else {
84
+ Serial.print (" Found " ); Serial.print (scanResults); Serial.println (" devices " );
85
+ for (int i = 0 ; i < scanResults; ++i) {
86
+ // Print SSID and RSSI for each device found
87
+ String SSID = WiFi.SSID (i);
88
+ int32_t RSSI = WiFi.RSSI (i);
89
+ String BSSIDstr = WiFi.BSSIDstr (i);
90
+
91
+ if (PRINTSCANRESULTS) {
92
+ 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 (" " );
93
+ }
94
+ delay (10 );
95
+ // Check if the current device starts with `Slave`
96
+ if (SSID.indexOf (" Slave" ) == 0 ) {
97
+ // SSID of interest
98
+ 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 (" " );
99
+ // Get BSSID => Mac Address of the Slave
100
+ int mac[6 ];
101
+
102
+ 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 ] ) ) {
103
+ for (int ii = 0 ; ii < 6 ; ++ii ) {
104
+ slaves[SlaveCnt].peer_addr [ii] = (uint8_t ) mac[ii];
105
+ }
106
+ }
107
+ slaves[SlaveCnt].channel = CHANNEL; // pick a channel
108
+ slaves[SlaveCnt].encrypt = 0 ; // no encryption
109
+ SlaveCnt++;
110
+ }
111
+ }
112
+ }
113
+
114
+ if (SlaveCnt > 0 ) {
115
+ Serial.print (SlaveCnt); Serial.println (" Slave(s) found, processing.." );
116
+ } else {
117
+ Serial.println (" No Slave Found, trying again." );
118
+ }
119
+
120
+ // clean up ram
121
+ WiFi.scanDelete ();
122
+ }
123
+
124
+ // Check if the slave is already paired with the master.
125
+ // If not, pair the slave with master
126
+ void manageSlave () {
127
+ if (SlaveCnt > 0 ) {
128
+ for (int i = 0 ; i < SlaveCnt; i++) {
129
+ const esp_now_peer_info_t *peer = &slaves[i];
130
+ const uint8_t *peer_addr = slaves[i].peer_addr ;
131
+ Serial.print (" Processing: " );
132
+ for (int ii = 0 ; ii < 6 ; ++ii ) {
133
+ Serial.print ((uint8_t ) slaves[i].peer_addr [ii], HEX);
134
+ if (ii != 5 ) Serial.print (" :" );
135
+ }
136
+ Serial.print (" Status: " );
137
+ // check if the peer exists
138
+ bool exists = esp_now_is_peer_exist (peer_addr);
139
+ if (exists) {
140
+ // Slave already paired.
141
+ Serial.println (" Already Paired" );
142
+ } else {
143
+ // Slave not paired, attempt pair
144
+ esp_err_t addStatus = esp_now_add_peer (peer);
145
+ if (addStatus == ESP_OK) {
146
+ // Pair success
147
+ Serial.println (" Pair success" );
148
+ } else if (addStatus == ESP_ERR_ESPNOW_NOT_INIT) {
149
+ // How did we get so far!!
150
+ Serial.println (" ESPNOW Not Init" );
151
+ } else if (addStatus == ESP_ERR_ESPNOW_ARG) {
152
+ Serial.println (" Add Peer - Invalid Argument" );
153
+ } else if (addStatus == ESP_ERR_ESPNOW_FULL) {
154
+ Serial.println (" Peer list full" );
155
+ } else if (addStatus == ESP_ERR_ESPNOW_NO_MEM) {
156
+ Serial.println (" Out of memory" );
157
+ } else if (addStatus == ESP_ERR_ESPNOW_EXIST) {
158
+ Serial.println (" Peer Exists" );
159
+ } else {
160
+ Serial.println (" Not sure what happened" );
161
+ }
162
+ delay (100 );
163
+ }
164
+ }
165
+ } else {
166
+ // No slave found to process
167
+ Serial.println (" No Slave found to process" );
168
+ }
169
+ }
170
+
171
+
172
+ uint8_t data = 0 ;
173
+ // send data
174
+ void sendData () {
175
+ data++;
176
+ for (int i = 0 ; i < SlaveCnt; i++) {
177
+ const uint8_t *peer_addr = slaves[i].peer_addr ;
178
+ if (i == 0 ) { // print only for first slave
179
+ Serial.print (" Sending: " );
180
+ Serial.println (data);
181
+ }
182
+ esp_err_t result = esp_now_send (peer_addr, &data, sizeof (data));
183
+ Serial.print (" Send Status: " );
184
+ if (result == ESP_OK) {
185
+ Serial.println (" Success" );
186
+ } else if (result == ESP_ERR_ESPNOW_NOT_INIT) {
187
+ // How did we get so far!!
188
+ Serial.println (" ESPNOW not Init." );
189
+ } else if (result == ESP_ERR_ESPNOW_ARG) {
190
+ Serial.println (" Invalid Argument" );
191
+ } else if (result == ESP_ERR_ESPNOW_INTERNAL) {
192
+ Serial.println (" Internal Error" );
193
+ } else if (result == ESP_ERR_ESPNOW_NO_MEM) {
194
+ Serial.println (" ESP_ERR_ESPNOW_NO_MEM" );
195
+ } else if (result == ESP_ERR_ESPNOW_NOT_FOUND) {
196
+ Serial.println (" Peer not found." );
197
+ } else {
198
+ Serial.println (" Not sure what happened" );
199
+ }
200
+ delay (100 );
201
+ }
202
+ }
203
+
204
+ // callback when data is sent from Master to Slave
205
+ void OnDataSent (const uint8_t *mac_addr, esp_now_send_status_t status) {
206
+ char macStr[18 ];
207
+ snprintf (macStr, sizeof (macStr), " %02x:%02x:%02x:%02x:%02x:%02x" ,
208
+ mac_addr[0 ], mac_addr[1 ], mac_addr[2 ], mac_addr[3 ], mac_addr[4 ], mac_addr[5 ]);
209
+ Serial.print (" Last Packet Sent to: " ); Serial.println (macStr);
210
+ Serial.print (" Last Packet Send Status: " ); Serial.println (status == ESP_NOW_SEND_SUCCESS ? " Delivery Success" : " Delivery Fail" );
211
+ }
212
+
213
+ void setup () {
214
+ Serial.begin (115200 );
215
+ // Set device in STA mode to begin with
216
+ WiFi.mode (WIFI_STA);
217
+ Serial.println (" ESPNow/Multi-Slave/Master Example" );
218
+ // This is the mac address of the Master in Station Mode
219
+ Serial.print (" STA MAC: " ); Serial.println (WiFi.macAddress ());
220
+ // Init ESPNow with a fallback logic
221
+ InitESPNow ();
222
+ // Once ESPNow is successfully Init, we will register for Send CB to
223
+ // get the status of Trasnmitted packet
224
+ esp_now_register_send_cb (OnDataSent);
225
+ }
226
+
227
+ void loop () {
228
+ // In the loop we scan for slave
229
+ ScanForSlave ();
230
+ // If Slave is found, it would be populate in `slave` variable
231
+ // We will check if `slave` is defined and then we proceed further
232
+ if (SlaveCnt > 0 ) { // check if slave channel is defined
233
+ // `slave` is defined
234
+ // Add slave as peer if it has not been added already
235
+ manageSlave ();
236
+ // pair success or already paired
237
+ // Send data to device
238
+ sendData ();
239
+ } else {
240
+ // No slave found to process
241
+ }
242
+
243
+ // wait for 3seconds to run the logic again
244
+ delay (1000 );
245
+ }
0 commit comments