From a32149c60fe194faf046c4b437f6b02ca63e118d Mon Sep 17 00:00:00 2001 From: Arvind Ravulavaru Date: Tue, 26 Sep 2017 12:49:49 +0530 Subject: [PATCH 1/6] Added ESPNow basic example --- .../ESPNow/examples/Basic/Master/Master.ino | 269 ++++++++++++++++++ .../ESPNow/examples/Basic/Slave/Slave.ino | 90 ++++++ libraries/ESPNow/library.properties | 9 + libraries/ESPNow/src/ESPNow.h | 2 + 4 files changed, 370 insertions(+) create mode 100644 libraries/ESPNow/examples/Basic/Master/Master.ino create mode 100644 libraries/ESPNow/examples/Basic/Slave/Slave.ino create mode 100644 libraries/ESPNow/library.properties create mode 100644 libraries/ESPNow/src/ESPNow.h diff --git a/libraries/ESPNow/examples/Basic/Master/Master.ino b/libraries/ESPNow/examples/Basic/Master/Master.ino new file mode 100644 index 00000000000..01c9362ab55 --- /dev/null +++ b/libraries/ESPNow/examples/Basic/Master/Master.ino @@ -0,0 +1,269 @@ +/** + ESPNOW - Basic communication - Master + Date: 26th September 2017 + Author: Arvind Ravulavaru + 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 +#include + +// 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); +} \ No newline at end of file diff --git a/libraries/ESPNow/examples/Basic/Slave/Slave.ino b/libraries/ESPNow/examples/Basic/Slave/Slave.ino new file mode 100644 index 00000000000..9d670b100e2 --- /dev/null +++ b/libraries/ESPNow/examples/Basic/Slave/Slave.ino @@ -0,0 +1,90 @@ +/** + ESPNOW - Basic communication - Slave + Date: 26th September 2017 + Author: Arvind Ravulavaru + 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 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 +#include + +#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 +} \ No newline at end of file diff --git a/libraries/ESPNow/library.properties b/libraries/ESPNow/library.properties new file mode 100644 index 00000000000..ef2c3986779 --- /dev/null +++ b/libraries/ESPNow/library.properties @@ -0,0 +1,9 @@ +name=ESPNow +version=1.0 +author=Arvind Ravulavaru +maintainer=Arvind Ravulavaru +sentence=ESPNow Communication between ESP32(s) +paragraph= +category=Communication +url= +architectures=esp32 \ No newline at end of file diff --git a/libraries/ESPNow/src/ESPNow.h b/libraries/ESPNow/src/ESPNow.h new file mode 100644 index 00000000000..3e68f81eeaa --- /dev/null +++ b/libraries/ESPNow/src/ESPNow.h @@ -0,0 +1,2 @@ +#ifndef ESPNow_h +#define ESPNow_h \ No newline at end of file From bac4d160fcf2fc6133986f0d9fe43fde41a62890 Mon Sep 17 00:00:00 2001 From: Arvind Ravulavaru Date: Tue, 26 Sep 2017 12:53:08 +0530 Subject: [PATCH 2/6] fixed meta doc for slave --- libraries/ESPNow/examples/Basic/Slave/Slave.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESPNow/examples/Basic/Slave/Slave.ino b/libraries/ESPNow/examples/Basic/Slave/Slave.ino index 9d670b100e2..21e963b8b19 100644 --- a/libraries/ESPNow/examples/Basic/Slave/Slave.ino +++ b/libraries/ESPNow/examples/Basic/Slave/Slave.ino @@ -3,7 +3,7 @@ Date: 26th September 2017 Author: Arvind Ravulavaru Purpose: ESPNow Communication between a Master ESP32 and a Slave ESP32 - Description: This sketch consists of the code for the Master module. + 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/ From 4f25868b6bfb338280d89540cd8e0b21827f6814 Mon Sep 17 00:00:00 2001 From: Arvind Ravulavaru Date: Tue, 26 Sep 2017 14:37:03 +0530 Subject: [PATCH 3/6] refactored folder structure --- .../examples/ESPNow}/Basic/Master/Master.ino | 0 .../examples/ESPNow}/Basic/Slave/Slave.ino | 0 libraries/ESPNow/library.properties | 9 --------- libraries/ESPNow/src/ESPNow.h | 2 -- 4 files changed, 11 deletions(-) rename libraries/{ESPNow/examples => ESP32/examples/ESPNow}/Basic/Master/Master.ino (100%) rename libraries/{ESPNow/examples => ESP32/examples/ESPNow}/Basic/Slave/Slave.ino (100%) delete mode 100644 libraries/ESPNow/library.properties delete mode 100644 libraries/ESPNow/src/ESPNow.h diff --git a/libraries/ESPNow/examples/Basic/Master/Master.ino b/libraries/ESP32/examples/ESPNow/Basic/Master/Master.ino similarity index 100% rename from libraries/ESPNow/examples/Basic/Master/Master.ino rename to libraries/ESP32/examples/ESPNow/Basic/Master/Master.ino diff --git a/libraries/ESPNow/examples/Basic/Slave/Slave.ino b/libraries/ESP32/examples/ESPNow/Basic/Slave/Slave.ino similarity index 100% rename from libraries/ESPNow/examples/Basic/Slave/Slave.ino rename to libraries/ESP32/examples/ESPNow/Basic/Slave/Slave.ino diff --git a/libraries/ESPNow/library.properties b/libraries/ESPNow/library.properties deleted file mode 100644 index ef2c3986779..00000000000 --- a/libraries/ESPNow/library.properties +++ /dev/null @@ -1,9 +0,0 @@ -name=ESPNow -version=1.0 -author=Arvind Ravulavaru -maintainer=Arvind Ravulavaru -sentence=ESPNow Communication between ESP32(s) -paragraph= -category=Communication -url= -architectures=esp32 \ No newline at end of file diff --git a/libraries/ESPNow/src/ESPNow.h b/libraries/ESPNow/src/ESPNow.h deleted file mode 100644 index 3e68f81eeaa..00000000000 --- a/libraries/ESPNow/src/ESPNow.h +++ /dev/null @@ -1,2 +0,0 @@ -#ifndef ESPNow_h -#define ESPNow_h \ No newline at end of file From 81f7da9234d297a82f165574b04bc7861da45cb9 Mon Sep 17 00:00:00 2001 From: Arvind Ravulavaru Date: Tue, 26 Sep 2017 18:36:42 +0530 Subject: [PATCH 4/6] bug fixes --- .../ESP32/examples/ESPNow/Basic/Master/Master.ino | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/libraries/ESP32/examples/ESPNow/Basic/Master/Master.ino b/libraries/ESP32/examples/ESPNow/Basic/Master/Master.ino index 01c9362ab55..0116b543fd2 100644 --- a/libraries/ESP32/examples/ESPNow/Basic/Master/Master.ino +++ b/libraries/ESP32/examples/ESPNow/Basic/Master/Master.ino @@ -55,7 +55,9 @@ void InitESPNow() { // Scan for slaves in AP mode void ScanForSlave() { int8_t scanResults = WiFi.scanNetworks(); + // reset on each scan bool slaveFound = 0; + memset(&slave, 0, sizeof(slave)); Serial.println(""); if (scanResults == 0) { Serial.println("No WiFi devices in AP Mode found"); @@ -128,14 +130,6 @@ bool manageSlave() { // 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); @@ -191,8 +185,6 @@ void deletePeer() { } } - - uint8_t data = 0; // send data void sendData() { From 1c60cb3b4a116fbb6f1b8d7a9471ab81ceff3289 Mon Sep 17 00:00:00 2001 From: Arvind Ravulavaru Date: Tue, 26 Sep 2017 19:14:37 +0530 Subject: [PATCH 5/6] Added Single Master Multi-Slave --- .../ESPNow/Multi-Slave/Master/Master.ino | 245 ++++++++++++++++++ .../ESPNow/Multi-Slave/Slave/Slave.ino | 93 +++++++ 2 files changed, 338 insertions(+) create mode 100644 libraries/ESP32/examples/ESPNow/Multi-Slave/Master/Master.ino create mode 100644 libraries/ESP32/examples/ESPNow/Multi-Slave/Slave/Slave.ino diff --git a/libraries/ESP32/examples/ESPNow/Multi-Slave/Master/Master.ino b/libraries/ESP32/examples/ESPNow/Multi-Slave/Master/Master.ino new file mode 100644 index 00000000000..e66156af841 --- /dev/null +++ b/libraries/ESP32/examples/ESPNow/Multi-Slave/Master/Master.ino @@ -0,0 +1,245 @@ +/** + ESPNOW - Basic communication - Master + Date: 26th September 2017 + Author: Arvind Ravulavaru + 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. + + + // Sample Serial log with 1 master & 2 slaves + Found 12 devices + 1: Slave:24:0A:C4:81:CF:A4 [24:0A:C4:81:CF:A5] (-44) + 3: Slave:30:AE:A4:02:6D:CC [30:AE:A4:02:6D:CD] (-55) + 2 Slave(s) found, processing.. + Processing: 24:A:C4:81:CF:A5 Status: Already Paired + Processing: 30:AE:A4:2:6D:CD Status: Already Paired + Sending: 9 + Send Status: Success + Last Packet Sent to: 24:0a:c4:81:cf:a5 + Last Packet Send Status: Delivery Success + Send Status: Success + Last Packet Sent to: 30:ae:a4:02:6d:cd + Last Packet Send Status: Delivery Success + +*/ + +#include +#include + +// Global copy of slave +#define NUMSLAVES 20 +esp_now_peer_info_t slaves[NUMSLAVES] = {}; +int SlaveCnt = 0; + +#define CHANNEL 3 +#define PRINTSCANRESULTS 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(); + //reset slaves + memset(slaves, 0, sizeof(slaves)); + SlaveCnt = 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(BSSIDstr); Serial.print("]"); 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.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 ) { + slaves[SlaveCnt].peer_addr[ii] = (uint8_t) mac[ii]; + } + } + slaves[SlaveCnt].channel = CHANNEL; // pick a channel + slaves[SlaveCnt].encrypt = 0; // no encryption + SlaveCnt++; + } + } + } + + if (SlaveCnt > 0) { + Serial.print(SlaveCnt); Serial.println(" Slave(s) found, processing.."); + } else { + Serial.println("No Slave 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 +void manageSlave() { + if (SlaveCnt > 0) { + for (int i = 0; i < SlaveCnt; i++) { + const esp_now_peer_info_t *peer = &slaves[i]; + const uint8_t *peer_addr = slaves[i].peer_addr; + Serial.print("Processing: "); + for (int ii = 0; ii < 6; ++ii ) { + Serial.print((uint8_t) slaves[i].peer_addr[ii], HEX); + if (ii != 5) Serial.print(":"); + } + Serial.print(" Status: "); + // check if the peer exists + bool exists = esp_now_is_peer_exist(peer_addr); + if (exists) { + // Slave already paired. + Serial.println("Already Paired"); + } 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"); + } else if (addStatus == ESP_ERR_ESPNOW_NOT_INIT) { + // How did we get so far!! + Serial.println("ESPNOW Not Init"); + } else if (addStatus == ESP_ERR_ESPNOW_ARG) { + Serial.println("Add Peer - Invalid Argument"); + } else if (addStatus == ESP_ERR_ESPNOW_FULL) { + Serial.println("Peer list full"); + } else if (addStatus == ESP_ERR_ESPNOW_NO_MEM) { + Serial.println("Out of memory"); + } else if (addStatus == ESP_ERR_ESPNOW_EXIST) { + Serial.println("Peer Exists"); + } else { + Serial.println("Not sure what happened"); + } + delay(100); + } + } + } else { + // No slave found to process + Serial.println("No Slave found to process"); + } +} + + +uint8_t data = 0; +// send data +void sendData() { + data++; + for (int i = 0; i < SlaveCnt; i++) { + const uint8_t *peer_addr = slaves[i].peer_addr; + if (i == 0) { // print only for first slave + 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"); + } + delay(100); + } +} + +// 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/Multi-Slave/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 (SlaveCnt > 0) { // check if slave channel is defined + // `slave` is defined + // Add slave as peer if it has not been added already + manageSlave(); + // pair success or already paired + // Send data to device + sendData(); + } else { + // No slave found to process + } + + // wait for 3seconds to run the logic again + delay(1000); +} \ No newline at end of file diff --git a/libraries/ESP32/examples/ESPNow/Multi-Slave/Slave/Slave.ino b/libraries/ESP32/examples/ESPNow/Multi-Slave/Slave/Slave.ino new file mode 100644 index 00000000000..f2634df2f83 --- /dev/null +++ b/libraries/ESP32/examples/ESPNow/Multi-Slave/Slave/Slave.ino @@ -0,0 +1,93 @@ +/** + ESPNOW - Basic communication - Slave + Date: 26th September 2017 + Author: Arvind Ravulavaru + Purpose: ESPNow Communication between a Master ESP32 and multiple ESP32 Slaves + 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 found Slaves + + 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 +#include + +#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() { + String Prefix = "Slave:"; + String Mac = WiFi.macAddress(); + String SSID = Prefix + Mac; + String Password = "123456789"; + bool result = WiFi.softAP(SSID.c_str(), Password.c_str(), 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 +} \ No newline at end of file From 4b457a2528acbef7f9719e600d738b973d4e574c Mon Sep 17 00:00:00 2001 From: Arvind Ravulavaru Date: Wed, 27 Sep 2017 08:50:30 +0530 Subject: [PATCH 6/6] updated meta docs --- libraries/ESP32/examples/ESPNow/Multi-Slave/Master/Master.ino | 4 ++-- libraries/ESP32/examples/ESPNow/Multi-Slave/Slave/Slave.ino | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/ESP32/examples/ESPNow/Multi-Slave/Master/Master.ino b/libraries/ESP32/examples/ESPNow/Multi-Slave/Master/Master.ino index e66156af841..87b8c331a1d 100644 --- a/libraries/ESP32/examples/ESPNow/Multi-Slave/Master/Master.ino +++ b/libraries/ESP32/examples/ESPNow/Multi-Slave/Master/Master.ino @@ -2,7 +2,7 @@ ESPNOW - Basic communication - Master Date: 26th September 2017 Author: Arvind Ravulavaru - Purpose: ESPNow Communication between a Master ESP32 and a Slave ESP32 + Purpose: ESPNow Communication between a Master ESP32 and multiple ESP32 Slaves 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 @@ -15,7 +15,7 @@ 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 + Step 5 : Start Transmitting data from Master to Slave(s) Flow: Slave Step 1 : ESPNow Init on Slave diff --git a/libraries/ESP32/examples/ESPNow/Multi-Slave/Slave/Slave.ino b/libraries/ESP32/examples/ESPNow/Multi-Slave/Slave/Slave.ino index f2634df2f83..8837d9c1b8d 100644 --- a/libraries/ESP32/examples/ESPNow/Multi-Slave/Slave/Slave.ino +++ b/libraries/ESP32/examples/ESPNow/Multi-Slave/Slave/Slave.ino @@ -15,7 +15,7 @@ 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 found Slaves + Step 5 : Start Transmitting data from Master to Slave(s) Flow: Slave Step 1 : ESPNow Init on Slave