ESPNow and connection to WiFi AP
If ESPNow is used to transfer data from several ESP32’s (Slaves) to another ESP32 (Master) that then forward the data over WiFi to a server (e.g. a MQTT broker) this configuration works only if the channel used for ESPNow is the same channel used for the WiFi connection. If ESPNow channel and WiFi AP channel are different, the ESPNow connection is not working. Example code for Slaves in ESPNow examples – Slave And here an example (adapted from ESPNow examples – Master) for an ESP32 master that receives data from slaves and forwards them to an MQTT broker:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
/** ESPNOW - Basic communication - Slave Date: 26th September 2017 Author: Arvind Ravulavaru <https://github.com/arvindr21> */ #include <esp_now.h> #include <WiFi.h> #include <MQTTClient.h> #define CHANNEL 1 /** MQTT client class to access mqtt broker */ MQTTClient mqttClient(2560); /** MQTT broker URL */ static const char * mqttBroker = "xx.xx.xx.xx"; /** MQTT connection id */ static const char * mqttID = "ESP32"; /** MQTT user name */ static const char * mqttUser = "esp32"; /** MQTT password */ static const char * mqttPwd = "PASSWORD"; /** WiFi client class to receive messages from mqtt broker */ WiFiClient mqttReceiver; void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len); // Init ESP Now with fallback void InitESPNow() { if (esp_now_init() == ESP_OK) { Serial.println("ESPNow Init Success"); } else { Serial.println("ESPNow Init Failed"); 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_STA); WiFi.begin("MYWIFI", "MYWIFIPW"); // configure device AP mode configDeviceAP(); // This is the mac address of the Slave in AP Mode Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress()); // Start connection to MQTT broker // Connect to MQTT broker mqttClient.begin(mqttBroker, mqttReceiver); Serial.println("Connecting to MQTT broker"); int connectTimeout = 0; while (!mqttClient.connect(mqttID, mqttUser, mqttPwd)) { delay(100); connectTimeout++; if (connectTimeout > 10) { // Wait for 1 seconds to connect Serial.println("Can't connect to MQTT broker"); ESP.restart(); } } Serial.println("Connected to MQTT"); // 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(""); mqttClient.publish("/debug","[INFO] Last Packet Recv from: " + tftMsg); mqttClient.publish("/debug","[INFO] Last Packet Recv Data: " + tftMsg); recvMsgNum++; } void loop() { // Chill } |







00:06
I’m afraid I don’t see how the sample code solves the problem – it does not attempt to set the channel for the ESPNow to match that of the WiFi connection. Presumably this was the point of the work around. I have ecountered the exact same issue described and have been able to resolve it. Please could you amend the code or explain how you actually resolved the issue.
Thank you
20:47
I never solved it. You had to connect to a WiFi AP that uses channel 1.
There is a workaround somewhere in the ESP-IDF sources, but I never tested it. Specially, because I tried a mixed ESPnow network with ESP32 and ESP8266. And on ESP8266 there is no work around.
I switched to painlessMesh which was easier to use, is not channel dependent and works on both ESP32 and ESP8266 the same way.
21:37
so if i want to connect a esp32 to a esp8266 and send data from esp32 to esp8266. Simultaneously connect esp32 to WiFi to send data to a server i should use painless mesh?
22:00
That’s what I use now. It works fine with mixed ESP32 and ESP8266 devices in the Mesh.
04:01
Hi
I have resolved this problem in another way, I have define two modes: espnow mode or “wifi-client + mqtt” mode/code, when esp32 reboots, it reads a eeprom variable, this tells it what code must execute. So first it boots in espnow slave mode, then, when it receives a message, burns it in eeprom and change the state variable also in eeprom, and reboots.
Then it wakes up and execute “wifi-client + mqtt” mode/code, reads info from eeprom and sends it. Resets eeprom state variable and reboots again.
Cons: Lost of espnow RX during this period of time; only integer values due to eeprom
Pros: Only a chip; it works!; it’s amazing to view the output from this gateway switching 🙂
08:40
Nice way to solve the channel problem. But, as you mentioned, packages will be lost.