├── LICENSE ├── README.md ├── master.ino └── slave.ino /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 aaronnewcomb 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # simple_espnow_esp8266 2 | A simple example of using esp-now protocol between two ESP8266 boards (not ESP32) 3 | 4 | You will need to run the slave.ino file first and check the serial monitor to get the MAC address. Update the line in the master.ino file with that MAC address in order for the two ESPs to communicate. 5 | 6 | I found that esp-now is not very reliable on the ESP8266, so the master.ino script checks for a successful transmission and retries every 100 milliseconds until it gets a success. After 10 seconds, it tries again. 7 | -------------------------------------------------------------------------------- /master.ino: -------------------------------------------------------------------------------- 1 | //master/sender ESP-8266 2 | 3 | //#include 4 | #include 5 | //#include 6 | extern "C" { 7 | #include 8 | #include 9 | } 10 | 11 | typedef struct esp_now_peer_info { 12 | u8 peer_addr[6]; /**< ESPNOW peer MAC address that is also the MAC address of station or softap */ 13 | uint8_t channel; /**< Wi-Fi channel that peer uses to send/receive ESPNOW data. If the value is 0, 14 | use the current channel which station or softap is on. Otherwise, it must be 15 | set as the channel that station or softap is on. */ 16 | } esp_now_peer_info_t; 17 | 18 | #define CHANNEL 0 19 | 20 | uint8_t remoteMac[] = {0xA0, 0x20, 0xA6, 0x00, 0xF1, 0xCC}; // Replace with the AP MAC address of the slave/receiver 21 | uint8_t data = 1; 22 | bool retry = true; 23 | 24 | void printMacAddress(uint8_t* macaddr) { 25 | Serial.print("{"); 26 | for (int i = 0; i < 6; i++) { 27 | Serial.print("0x"); 28 | Serial.print(macaddr[i], HEX); 29 | if (i < 5) Serial.print(','); 30 | } 31 | Serial.println("};"); 32 | } 33 | 34 | // Init ESP Now with fallback 35 | void InitESPNow() { 36 | if (esp_now_init() == 0) { 37 | Serial.println("ESPNow Init Success"); 38 | } 39 | else { 40 | Serial.println("ESPNow Init Failed"); 41 | ESP.restart(); 42 | } 43 | esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER); 44 | } 45 | 46 | void sendData() { 47 | data++; 48 | int result = esp_now_send(remoteMac, &data, sizeof(data)); 49 | Serial.print("Send Command: "); 50 | if (result ==0) { 51 | Serial.println("Success " + String(result)); 52 | } else { 53 | Serial.println("Failed " + String(result)); 54 | } 55 | delay(100); 56 | } 57 | 58 | // callback when data is sent from Master to Slave 59 | esp_now_send_cb_t OnDataSent(const uint8_t *mac_addr, u8 status) { 60 | char macStr[18]; 61 | snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", 62 | mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); 63 | Serial.print("Last Packet Sent to: "); Serial.println(macStr); 64 | Serial.print("Last Packet Send Status: "); Serial.println(status == 0 ? "Delivery Success" : "Delivery Fail"); 65 | } 66 | 67 | void setup() { 68 | Serial.begin(115200); 69 | delay(2000); 70 | //Set device in STA mode to begin with 71 | WiFi.mode(WIFI_STA); 72 | Serial.println("ESPNow Basic Master Example"); 73 | // This is the mac address of the Master in Station Mode 74 | Serial.print("STA MAC: "); Serial.println(WiFi.macAddress()); 75 | // Init ESPNow with a fallback logic 76 | InitESPNow(); 77 | // Once ESPNow is successfully Init, we will register for Send CB to 78 | // get the status of Trasnmitted packet 79 | // esp_now_register_send_cb(OnDataSent); 80 | esp_now_register_send_cb([](uint8_t* macaddr, uint8_t status) { 81 | printMacAddress(macaddr); 82 | static uint32_t ok = 0; 83 | static uint32_t fail = 0; 84 | if (status == 0) { 85 | Serial.println("ESPNOW: ACK_OK"); 86 | ok++; 87 | retry = false; 88 | } 89 | else { 90 | Serial.println("ESPNOW: SEND_FAILED"); 91 | fail++; 92 | } 93 | Serial.printf("[SUCCESS] = %lu/%lu \r\n", ok, ok+fail); 94 | }); 95 | int addStatus = esp_now_add_peer((u8*)remoteMac, ESP_NOW_ROLE_CONTROLLER, CHANNEL, NULL, 0); 96 | if (addStatus == 0) { 97 | // Pair success 98 | Serial.println("Pair success"); 99 | } else { 100 | Serial.println("Pair failed"); 101 | } 102 | } 103 | 104 | void loop() { 105 | while (retry) { 106 | sendData(); 107 | delay(100); 108 | } 109 | retry = true; 110 | delay(10000); 111 | } 112 | -------------------------------------------------------------------------------- /slave.ino: -------------------------------------------------------------------------------- 1 | //slave/receiver ESP-8266 2 | 3 | extern "C" { 4 | #include 5 | } 6 | #include 7 | 8 | #define CHANNEL 0 9 | 10 | unsigned long timeout = millis(); 11 | void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len); 12 | 13 | // Init ESP Now with fallback 14 | void InitESPNow() { 15 | if (esp_now_init() == 0) { 16 | Serial.println("ESPNow Init Success"); 17 | } 18 | else { 19 | Serial.println("ESPNow Init Failed"); 20 | ESP.restart(); 21 | } 22 | } 23 | 24 | void setup() { 25 | Serial.begin(115200); 26 | delay(2000); 27 | Serial.println("ESPNow Basic Slave Example"); 28 | 29 | //Set device in AP mode to begin with 30 | WiFi.mode(WIFI_AP_STA); 31 | // This is the mac address of the Slave in AP Mode 32 | Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress()); 33 | 34 | // Init ESPNow with a fallback logic 35 | InitESPNow(); 36 | // Once ESPNow is successfully Init, we will register for recv CB to 37 | // get recv packer info. 38 | esp_now_register_recv_cb(OnDataRecv); 39 | } 40 | 41 | // callback when data is recv from Master 42 | void OnDataRecv(uint8_t *mac_addr, uint8_t *data, uint8_t len) { 43 | char macStr[18]; 44 | snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", 45 | mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); 46 | Serial.print("Last Packet Recv from: "); Serial.println(macStr); 47 | Serial.print("Last Packet Recv Data: "); Serial.println(*data); 48 | Serial.println(""); 49 | } 50 | 51 | void loop() { 52 | if (millis() - timeout > 3000) { 53 | Serial.println("Waiting for data ..."); 54 | timeout = millis(); 55 | } 56 | } 57 | --------------------------------------------------------------------------------