Added ESPNow basic example (#667)
* Added ESPNow basic example * fixed meta doc for slave * refactored folder structure
This commit is contained in:
		
							parent
							
								
									d27d297195
								
							
						
					
					
						commit
						4c36e03381
					
				
							
								
								
									
										269
									
								
								libraries/ESP32/examples/ESPNow/Basic/Master/Master.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										269
									
								
								libraries/ESP32/examples/ESPNow/Basic/Master/Master.ino
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,269 @@ | ||||
| /**
 | ||||
|    ESPNOW - Basic communication - Master | ||||
|    Date: 26th September 2017 | ||||
|    Author: Arvind Ravulavaru <https://github.com/arvindr21>
 | ||||
|    Purpose: ESPNow Communication between a Master ESP32 and a Slave ESP32 | ||||
|    Description: This sketch consists of the code for the Master module. | ||||
|    Resources: (A bit outdated) | ||||
|    a. https://espressif.com/sites/default/files/documentation/esp-now_user_guide_en.pdf
 | ||||
|    b. http://www.esploradores.com/practica-6-conexion-esp-now/
 | ||||
| 
 | ||||
|    << This Device Master >> | ||||
| 
 | ||||
|    Flow: Master | ||||
|    Step 1 : ESPNow Init on Master and set it in STA mode | ||||
|    Step 2 : Start scanning for Slave ESP32 (we have added a prefix of `slave` to the SSID of slave for an easy setup) | ||||
|    Step 3 : Once found, add Slave as peer | ||||
|    Step 4 : Register for send callback | ||||
|    Step 5 : Start Transmitting data from Master to Slave | ||||
| 
 | ||||
|    Flow: Slave | ||||
|    Step 1 : ESPNow Init on Slave | ||||
|    Step 2 : Update the SSID of Slave with a prefix of `slave` | ||||
|    Step 3 : Set Slave in AP mode | ||||
|    Step 4 : Register for receive callback and wait for data | ||||
|    Step 5 : Once data arrives, print it in the serial monitor | ||||
| 
 | ||||
|    Note: Master and Slave have been defined to easily understand the setup. | ||||
|          Based on the ESPNOW API, there is no concept of Master and Slave. | ||||
|          Any devices can act as master or salve. | ||||
| */ | ||||
| 
 | ||||
| #include <esp_now.h> | ||||
| #include <WiFi.h> | ||||
| 
 | ||||
| // Global copy of slave
 | ||||
| esp_now_peer_info_t slave; | ||||
| #define CHANNEL 3 | ||||
| #define PRINTSCANRESULTS 0 | ||||
| #define DELETEBEFOREPAIR 0 | ||||
| 
 | ||||
| // Init ESP Now with fallback
 | ||||
| void InitESPNow() { | ||||
|   if (esp_now_init() == ESP_OK) { | ||||
|     Serial.println("ESPNow Init Success"); | ||||
|   } | ||||
|   else { | ||||
|     Serial.println("ESPNow Init Failed"); | ||||
|     // Retry InitESPNow, add a counte and then restart?
 | ||||
|     // InitESPNow();
 | ||||
|     // or Simply Restart
 | ||||
|     ESP.restart(); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Scan for slaves in AP mode
 | ||||
| void ScanForSlave() { | ||||
|   int8_t scanResults = WiFi.scanNetworks(); | ||||
|   bool slaveFound = 0; | ||||
|   Serial.println(""); | ||||
|   if (scanResults == 0) { | ||||
|     Serial.println("No WiFi devices in AP Mode found"); | ||||
|   } else { | ||||
|     Serial.print("Found "); Serial.print(scanResults); Serial.println(" devices "); | ||||
|     for (int i = 0; i < scanResults; ++i) { | ||||
|       // Print SSID and RSSI for each device found
 | ||||
|       String SSID = WiFi.SSID(i); | ||||
|       int32_t RSSI = WiFi.RSSI(i); | ||||
|       String BSSIDstr = WiFi.BSSIDstr(i); | ||||
| 
 | ||||
|       if (PRINTSCANRESULTS) { | ||||
|         Serial.print(i + 1); | ||||
|         Serial.print(": "); | ||||
|         Serial.print(SSID); | ||||
|         Serial.print(" ("); | ||||
|         Serial.print(RSSI); | ||||
|         Serial.print(")"); | ||||
|         Serial.println(""); | ||||
|       } | ||||
|       delay(10); | ||||
|       // Check if the current device starts with `Slave`
 | ||||
|       if (SSID.indexOf("Slave") == 0) { | ||||
|         // SSID of interest
 | ||||
|         Serial.println("Found a Slave."); | ||||
|         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(""); | ||||
|         // Get BSSID => Mac Address of the Slave
 | ||||
|         int mac[6]; | ||||
|         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] ) ) { | ||||
|           for (int ii = 0; ii < 6; ++ii ) { | ||||
|             slave.peer_addr[ii] = (uint8_t) mac[ii]; | ||||
|           } | ||||
|         } | ||||
| 
 | ||||
|         slave.channel = CHANNEL; // pick a channel
 | ||||
|         slave.encrypt = 0; // no encryption
 | ||||
| 
 | ||||
|         slaveFound = 1; | ||||
|         // we are planning to have only one slave in this example;
 | ||||
|         // Hence, break after we find one, to be a bit efficient
 | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   if (slaveFound) { | ||||
|     Serial.println("Slave Found, processing.."); | ||||
|   } else { | ||||
|     Serial.println("Slave Not Found, trying again."); | ||||
|   } | ||||
| 
 | ||||
|   // clean up ram
 | ||||
|   WiFi.scanDelete(); | ||||
| } | ||||
| 
 | ||||
| // Check if the slave is already paired with the master.
 | ||||
| // If not, pair the slave with master
 | ||||
| bool manageSlave() { | ||||
|   if (slave.channel == CHANNEL) { | ||||
|     if (DELETEBEFOREPAIR) { | ||||
|       deletePeer(); | ||||
|     } | ||||
| 
 | ||||
|     Serial.print("Slave Status: "); | ||||
|     const esp_now_peer_info_t *peer = &slave; | ||||
|     const uint8_t *peer_addr = slave.peer_addr; | ||||
|     // check if the peer exists
 | ||||
|     bool exists = esp_now_is_peer_exist(peer_addr); | ||||
|     if ( exists) { | ||||
|       // Slave already paired.
 | ||||
|       Serial.println("Already Paired"); | ||||
|       return true; | ||||
|     } else if (exists == ESP_ERR_ESPNOW_NOT_INIT) { | ||||
|       // How did we get so far!!
 | ||||
|       Serial.println("ESPNOW Not InitESP_ERR_ESPNOW_NOT_INIT"); | ||||
|       return false; | ||||
|     } else if (exists == ESP_ERR_ESPNOW_ARG) { | ||||
|       // Invalid Argument
 | ||||
|       Serial.println("Invalid Argument"); | ||||
|       return false; | ||||
|     } else { | ||||
|       // Slave not paired, attempt pair
 | ||||
|       esp_err_t addStatus = esp_now_add_peer(peer); | ||||
|       if (addStatus == ESP_OK) { | ||||
|         // Pair success
 | ||||
|         Serial.println("Pair success"); | ||||
|         return true; | ||||
|       } else if (addStatus == ESP_ERR_ESPNOW_NOT_INIT) { | ||||
|         // How did we get so far!!
 | ||||
|         Serial.println("ESPNOW Not Init"); | ||||
|         return false; | ||||
|       } else if (addStatus == ESP_ERR_ESPNOW_ARG) { | ||||
|         Serial.println("Invalid Argument"); | ||||
|         return false; | ||||
|       } else if (addStatus == ESP_ERR_ESPNOW_FULL) { | ||||
|         Serial.println("Peer list full"); | ||||
|         return false; | ||||
|       } else if (addStatus == ESP_ERR_ESPNOW_NO_MEM) { | ||||
|         Serial.println("Out of memory"); | ||||
|         return false; | ||||
|       } else if (addStatus == ESP_ERR_ESPNOW_EXIST) { | ||||
|         Serial.println("Peer Exists"); | ||||
|         return true; | ||||
|       } else { | ||||
|         Serial.println("Not sure what happened"); | ||||
|         return false; | ||||
|       } | ||||
|     } | ||||
|   } else { | ||||
|     // No slave found to process
 | ||||
|     Serial.println("No Slave found to process"); | ||||
|     return false; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void deletePeer() { | ||||
|   const esp_now_peer_info_t *peer = &slave; | ||||
|   const uint8_t *peer_addr = slave.peer_addr; | ||||
|   esp_err_t delStatus = esp_now_del_peer(peer_addr); | ||||
|   Serial.print("Slave Delete Status: "); | ||||
|   if (delStatus == ESP_OK) { | ||||
|     // Delete success
 | ||||
|     Serial.println("Success"); | ||||
|   } else if (delStatus == ESP_ERR_ESPNOW_NOT_INIT) { | ||||
|     // How did we get so far!!
 | ||||
|     Serial.println("ESPNOW Not Init"); | ||||
|   } else if (delStatus == ESP_ERR_ESPNOW_ARG) { | ||||
|     Serial.println("Invalid Argument"); | ||||
|   } else if (delStatus == ESP_ERR_ESPNOW_NOT_FOUND) { | ||||
|     Serial.println("Peer not found."); | ||||
|   } else { | ||||
|     Serial.println("Not sure what happened"); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| uint8_t data = 0; | ||||
| // send data
 | ||||
| void sendData() { | ||||
|   data++; | ||||
|   const uint8_t *peer_addr = slave.peer_addr; | ||||
|   Serial.print("Sending: "); Serial.println(data); | ||||
|   esp_err_t result = esp_now_send(peer_addr, &data, sizeof(data)); | ||||
|   Serial.print("Send Status: "); | ||||
|   if (result == ESP_OK) { | ||||
|     Serial.println("Success"); | ||||
|   } else if (result == ESP_ERR_ESPNOW_NOT_INIT) { | ||||
|     // How did we get so far!!
 | ||||
|     Serial.println("ESPNOW not Init."); | ||||
|   } else if (result == ESP_ERR_ESPNOW_ARG) { | ||||
|     Serial.println("Invalid Argument"); | ||||
|   } else if (result == ESP_ERR_ESPNOW_INTERNAL) { | ||||
|     Serial.println("Internal Error"); | ||||
|   } else if (result == ESP_ERR_ESPNOW_NO_MEM) { | ||||
|     Serial.println("ESP_ERR_ESPNOW_NO_MEM"); | ||||
|   } else if (result == ESP_ERR_ESPNOW_NOT_FOUND) { | ||||
|     Serial.println("Peer not found."); | ||||
|   } else { | ||||
|     Serial.println("Not sure what happened"); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // callback when data is sent from Master to Slave
 | ||||
| void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) { | ||||
|   char macStr[18]; | ||||
|   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.print("Last Packet Sent to: "); Serial.println(macStr); | ||||
|   Serial.print("Last Packet Send Status: "); Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail"); | ||||
| } | ||||
| 
 | ||||
| void setup() { | ||||
|   Serial.begin(115200); | ||||
|   //Set device in STA mode to begin with
 | ||||
|   WiFi.mode(WIFI_STA); | ||||
|   Serial.println("ESPNow/Basic/Master Example"); | ||||
|   // This is the mac address of the Master in Station Mode
 | ||||
|   Serial.print("STA MAC: "); Serial.println(WiFi.macAddress()); | ||||
|   // Init ESPNow with a fallback logic
 | ||||
|   InitESPNow(); | ||||
|   // Once ESPNow is successfully Init, we will register for Send CB to
 | ||||
|   // get the status of Trasnmitted packet
 | ||||
|   esp_now_register_send_cb(OnDataSent); | ||||
| } | ||||
| 
 | ||||
| void loop() { | ||||
|   // In the loop we scan for slave
 | ||||
|   ScanForSlave(); | ||||
|   // If Slave is found, it would be populate in `slave` variable
 | ||||
|   // We will check if `slave` is defined and then we proceed further
 | ||||
|   if (slave.channel == CHANNEL) { // check if slave channel is defined
 | ||||
|     // `slave` is defined
 | ||||
|     // Add slave as peer if it has not been added already
 | ||||
|     bool isPaired = manageSlave(); | ||||
|     if (isPaired) { | ||||
|       // pair success or already paired
 | ||||
|       // Send data to device
 | ||||
|       sendData(); | ||||
|     } else { | ||||
|       // slave pair failed
 | ||||
|       Serial.println("Slave pair failed!"); | ||||
|     } | ||||
|   } | ||||
|   else { | ||||
|     // No slave found to process
 | ||||
|   } | ||||
| 
 | ||||
|   // wait for 3seconds to run the logic again
 | ||||
|   delay(3000); | ||||
| } | ||||
							
								
								
									
										90
									
								
								libraries/ESP32/examples/ESPNow/Basic/Slave/Slave.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								libraries/ESP32/examples/ESPNow/Basic/Slave/Slave.ino
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,90 @@ | ||||
| /**
 | ||||
|    ESPNOW - Basic communication - Slave | ||||
|    Date: 26th September 2017 | ||||
|    Author: Arvind Ravulavaru <https://github.com/arvindr21>
 | ||||
|    Purpose: ESPNow Communication between a Master ESP32 and a Slave ESP32 | ||||
|    Description: This sketch consists of the code for the Slave module. | ||||
|    Resources: (A bit outdated) | ||||
|    a. https://espressif.com/sites/default/files/documentation/esp-now_user_guide_en.pdf
 | ||||
|    b. http://www.esploradores.com/practica-6-conexion-esp-now/
 | ||||
| 
 | ||||
|    << This Device Slave >> | ||||
| 
 | ||||
|    Flow: Master | ||||
|    Step 1 : ESPNow Init on Master and set it in STA mode | ||||
|    Step 2 : Start scanning for Slave ESP32 (we have added a prefix of `slave` to the SSID of slave for an easy setup) | ||||
|    Step 3 : Once found, add Slave as peer | ||||
|    Step 4 : Register for send callback | ||||
|    Step 5 : Start Transmitting data from Master to Slave | ||||
| 
 | ||||
|    Flow: Slave | ||||
|    Step 1 : ESPNow Init on Slave | ||||
|    Step 2 : Update the SSID of Slave with a prefix of `slave` | ||||
|    Step 3 : Set Slave in AP mode | ||||
|    Step 4 : Register for receive callback and wait for data | ||||
|    Step 5 : Once data arrives, print it in the serial monitor | ||||
| 
 | ||||
|    Note: Master and Slave have been defined to easily understand the setup. | ||||
|          Based on the ESPNOW API, there is no concept of Master and Slave. | ||||
|          Any devices can act as master or salve. | ||||
| */ | ||||
| 
 | ||||
| #include <esp_now.h> | ||||
| #include <WiFi.h> | ||||
| 
 | ||||
| #define CHANNEL 1 | ||||
| 
 | ||||
| // Init ESP Now with fallback
 | ||||
| void InitESPNow() { | ||||
|   if (esp_now_init() == ESP_OK) { | ||||
|     Serial.println("ESPNow Init Success"); | ||||
|   } | ||||
|   else { | ||||
|     Serial.println("ESPNow Init Failed"); | ||||
|     // Retry InitESPNow, add a counte and then restart?
 | ||||
|     // InitESPNow();
 | ||||
|     // or Simply Restart
 | ||||
|     ESP.restart(); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // config AP SSID
 | ||||
| void configDeviceAP() { | ||||
|   char* SSID = "Slave_1"; | ||||
|   bool result = WiFi.softAP(SSID, "Slave_1_Password", CHANNEL, 0); | ||||
|   if (!result) { | ||||
|     Serial.println("AP Config failed."); | ||||
|   } else { | ||||
|     Serial.println("AP Config Success. Broadcasting with AP: " + String(SSID)); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void setup() { | ||||
|   Serial.begin(115200); | ||||
|   Serial.println("ESPNow/Basic/Slave Example"); | ||||
|   //Set device in AP mode to begin with
 | ||||
|   WiFi.mode(WIFI_AP); | ||||
|   // configure device AP mode
 | ||||
|   configDeviceAP(); | ||||
|   // This is the mac address of the Slave in AP Mode
 | ||||
|   Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress()); | ||||
|   // Init ESPNow with a fallback logic
 | ||||
|   InitESPNow(); | ||||
|   // Once ESPNow is successfully Init, we will register for recv CB to
 | ||||
|   // get recv packer info.
 | ||||
|   esp_now_register_recv_cb(OnDataRecv); | ||||
| } | ||||
| 
 | ||||
| // callback when data is recv from Master
 | ||||
| void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) { | ||||
|   char macStr[18]; | ||||
|   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.print("Last Packet Recv from: "); Serial.println(macStr); | ||||
|   Serial.print("Last Packet Recv Data: "); Serial.println(*data); | ||||
|   Serial.println(""); | ||||
| } | ||||
| 
 | ||||
| void loop() { | ||||
|   // Chill
 | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user