espnow wifi channel setup with connection to lan.
Posted: Mon Nov 04, 2019 10:42 am
arduino-esp32 1.0.4
Arduino ide 1.8.10
Just wondering if this is an acceptable way of finding the common channel
to be used by espnow.
Having used espnow with an earlier arduino-esp32 release, it was sufficient to do:[
However, as I tried this using arduino-esp32 1.0.4 it did not work.
Looking through the error messages and the documentation, I found a solution.
I wanted to let the slave search for the master by changing channel
until a succesfull send response was received.
Using the esp_wifi_set_promiscuous call, I succeded like:
To illustrate how to automatically configure the channel using the channel from the external AP,
below is a 'master' connecting to a local lan, setting the channel of the espnow STA.
And a 'slave' using the esp_wifi_set_channel and a message(token) to search for the 'master'
They are very crude, basic test programs just to show how the 'slave' can find the 'master'.
Long delays are used in order to make the steps easy to follow.
Here is the 'master' code used to test the search for master:
And the 'slave' test code:
Arduino ide 1.8.10
Just wondering if this is an acceptable way of finding the common channel
to be used by espnow.
Having used espnow with an earlier arduino-esp32 release, it was sufficient to do:[
Code: Select all
WiFi.mode(WIFI_STA);
WiFi.disconnect();
uint8_t primaryChan = 6;
wifi_second_chan_t secondChan = WIFI_SECOND_CHAN_NONE;
esp_wifi_set_channel(primaryChan, secondChan);
if (esp_now_init() == ESP_OK)
...
Looking through the error messages and the documentation, I found a solution.
I wanted to let the slave search for the master by changing channel
until a succesfull send response was received.
Using the esp_wifi_set_promiscuous call, I succeded like:
Code: Select all
ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true));
uint8_t primaryChan = 6;
wifi_second_chan_t secondChan = WIFI_SECOND_CHAN_NONE;
esp_wifi_set_channel(primaryChan, secondChan);
ESP_ERROR_CHECK(esp_wifi_set_promiscuous(false));
WiFi.disconnect();
if (esp_now_init() == ESP_OK)
..
To illustrate how to automatically configure the channel using the channel from the external AP,
below is a 'master' connecting to a local lan, setting the channel of the espnow STA.
And a 'slave' using the esp_wifi_set_channel and a message(token) to search for the 'master'
They are very crude, basic test programs just to show how the 'slave' can find the 'master'.
Long delays are used in order to make the steps easy to follow.
Here is the 'master' code used to test the search for master:
- /*
- espnow master
- */
- #include <esp_now.h>
- #include <WiFi.h>
- #include <esp_wifi.h>
- #define WIFI_CHANNEL 10
- #define FIXED_CHANNEL 6
- //Use custom MAC for both master and slave
- uint8_t CustomMac[] = {0xB4, 0xE6, 0x2D, 0xE9, 0xFE, 0x6E};
- uint8_t slaveDeviceMac[] = {0x3C, 0x71, 0xBF, 0x03, 0x3D, 0x30};
- const byte maxDataFrameSize = 200;
- uint8_t dataToSend[maxDataFrameSize];
- byte cnt = 0;
- int dataSent = 0;
- esp_now_peer_info_t slave;
- const esp_now_peer_info_t *peer = &slave;
- /*Put your SSID & Password*/
- const char* ssid = "<SSID>"; // Enter SSID here
- const char* password = "<Password>"; //Enter Password here
- // Set your Static IP address
- IPAddress local_IP(192, 168, xx, xx);
- // Set your Gateway IP address
- IPAddress gateway(192, 168, xx, xx);
- IPAddress subnet(255, 255, 255, 0);
- IPAddress primaryDNS(192, 168, xx, xx); //optional
- void WiFiReset() {
- WiFi.persistent(false);
- WiFi.disconnect();
- WiFi.mode(WIFI_OFF);
- }
- void setup()
- {
- Serial.begin(115200);
- Serial.print("\r\n\r\n");
- WiFiReset();
- WiFi.mode(WIFI_AP_STA );
- esp_wifi_set_mac(ESP_IF_WIFI_AP, &CustomMac[0]);
- if (!WiFi.config(local_IP, gateway, subnet, primaryDNS)) {
- Serial.println("STA Failed to configure");
- }
- Serial.println("Connecting to ");
- Serial.println(ssid);
- //connect to your local wi-fi network
- WiFi.begin(ssid, password, WIFI_CHANNEL);
- int maxTry = 10;
- //check wi-fi is connected to wi-fi network
- while (WiFi.status() != WL_CONNECTED && maxTry > 0 ) {
- delay(1000);
- Serial.print(".");
- maxTry--;
- }
- Serial.println("");
- Serial.println("WiFi connected..!");
- Serial.print("Got IP: "); Serial.println(WiFi.localIP());
- // This is the mac address
- Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress());
- Serial.print("Wifi channel: "); Serial.println(WiFi.channel());
- //Force espnow to use a specific channel
- ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true));
- uint8_t primaryChan = WiFi.channel();
- wifi_second_chan_t secondChan = WIFI_SECOND_CHAN_NONE;
- esp_wifi_set_channel(primaryChan, secondChan);
- ESP_ERROR_CHECK(esp_wifi_set_promiscuous(false));
- //WiFi.disconnect();
- //Serial.print("Wifi Channel: "); Serial.println(WiFi.channel());
- if (esp_now_init() == ESP_OK) {
- Serial.println("ESPNow Init Success!");
- } else {
- Serial.println("ESPNow Init Failed....");
- }
- //Add the slave node to this master node
- memcpy( &slave.peer_addr, &slaveDeviceMac[0], 6 );
- slave.channel = WiFi.channel();
- slave.encrypt = 0;
- slave.ifidx = ESP_IF_WIFI_AP;
- if ( esp_now_add_peer(peer) == ESP_OK) {
- Serial.println("Added Peer!");
- }
- esp_now_register_recv_cb(OnDataRecv);
- esp_now_register_send_cb(OnDataSent);
- }
- void prntmac(const uint8_t *mac_addr) {
- Serial.print("MAC Address: {0x");
- for (byte i = 0; i < 6; ++i) {
- Serial.print(mac_addr[i], HEX);
- if (i < 5)
- Serial.print(",0x");
- }
- Serial.println("};");
- }
- void loop()
- {
- yield();
- }
- void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len)
- {
- if (strncmp((const char *)data, "Calling Master",14) == 0 ) {
- Serial.printf("\r\nReceived\t%d Bytes\t%s\n", data_len, data);
- strcpy((char*)dataToSend, "Greeting from Master");
- esp_err_t sendResult = esp_now_send(slave.peer_addr, dataToSend,sizeof(dataToSend));
- if (sendResult == ESP_OK) {
- Serial.print("Success sendingS response");
- } else if (sendResult == ESP_ERR_ESPNOW_NOT_INIT) {
- // How did we get so far!!
- Serial.println("ESPNOW not Init.");
- } else if (sendResult == ESP_ERR_ESPNOW_ARG) {
- Serial.println("Invalid Argument");
- } else if (sendResult == ESP_ERR_ESPNOW_INTERNAL) {
- Serial.println("Internal Error");
- } else if (sendResult == ESP_ERR_ESPNOW_NO_MEM) {
- Serial.println("ESP_ERR_ESPNOW_NO_MEM");
- } else if (sendResult == ESP_ERR_ESPNOW_NOT_FOUND) {
- Serial.println("Peer not found.");
- }
- else if (sendResult == ESP_ERR_ESPNOW_IF) {
- Serial.println("Interface Error.");
- } else {
- Serial.printf("\r\nNot sure what happened\t%d", sendResult);
- }
- } else {
- Serial.printf("\r\nReceived\t%d Bytes\t%d\n", data_len, data[0]);
- }
- }
- void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
- Serial.print("\r\nLast Packet Send Status:\t");
- Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
- Serial.print("Data sent to ");
- prntmac(mac_addr);
- dataSent = 1; //Sent executed
- }
- /*
- esp32now slave
- */
- #include <esp_now.h>
- #include <WiFi.h>
- #include <esp_wifi.h>
- #define HIGHEST_CHANNEL 13 //Set according to country
- #define LOWEST_CHANNEL 1
- #define FIXED_CHANNEL 6
- //#define USE_FIXED_CHANNEL //Uncomment for no channel search
- //Use custom MAC for both master and slave
- uint8_t masterDeviceMac[] = {0xB4, 0xE6, 0x2D, 0xE9, 0xFE, 0x6E};
- uint8_t CustomMac[] = {0x3C, 0x71, 0xBF, 0x03, 0x3D, 0x30};
- esp_now_peer_info_t master;
- const esp_now_peer_info_t *masterNode = &master;
- esp_err_t sendResult;
- const uint8_t maxDataFrameSize = 200;
- uint8_t dataToSend[maxDataFrameSize];
- byte cnt = 0;
- int dataSent = 0;
- int wifi_channel = 1;
- int ms_sleep = 0;
- void WiFiReset() {
- WiFi.persistent(false);
- WiFi.disconnect();
- WiFi.mode(WIFI_OFF);
- delay(100);
- }
- void setup()
- {
- Serial.begin(115200);
- Serial.print("\r\n\r\n");
- WiFiReset();
- #ifdef USE_FIXED_CHANNEL
- uint8_t primaryChan = FIXED_CHANNEL;
- #else
- for (uint8_t primaryChan = LOWEST_CHANNEL; primaryChan <= HIGHEST_CHANNEL; primaryChan++) {
- #endif
- WiFi.mode(WIFI_STA);
- esp_wifi_set_mac(ESP_IF_WIFI_STA, &CustomMac[0]);
- Serial.print("Current channel no: ");
- Serial.println(primaryChan);
- Serial.println( WiFi.macAddress() );
- ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true));
- wifi_second_chan_t secondChan = WIFI_SECOND_CHAN_NONE;
- ESP_ERROR_CHECK(esp_wifi_set_channel(primaryChan, secondChan));
- ESP_ERROR_CHECK(esp_wifi_set_promiscuous(false));
- WiFi.printDiag(Serial);
- WiFi.disconnect();
- Serial.print("New Wifi channel: "); Serial.println(WiFi.channel());
- if (esp_now_init() == ESP_OK) {
- Serial.println("ESP NOW INIT!");
- }
- else {
- Serial.println("ESP NOW INIT FAILED....");
- }
- memcpy( &master.peer_addr, masterDeviceMac, 6 );
- master.channel = primaryChan;
- master.encrypt = 0;
- master.ifidx = ESP_IF_WIFI_STA;
- #ifdef USE_FIXED_CHANNEL
- if ( esp_now_add_peer(masterNode) == ESP_OK) {
- Serial.println("Added Peer!");
- }
- #else
- //Add node irst time, else replace
- if (primaryChan == LOWEST_CHANNEL) {
- if ( esp_now_add_peer(masterNode) == ESP_OK) {
- Serial.println("Added Peer!");
- }
- } else {
- if (esp_now_mod_peer(masterNode) == ESP_OK) {
- Serial.println("Modified Peer!");
- }
- }
- #endif
- esp_now_register_send_cb(OnDataSent);
- esp_now_register_recv_cb(OnDataRecv);
- dataSent = 0;
- //Send test data
- if ( TestSend() ) {
- //Wait for data sent confirmed
- for (int i = 0; i < 1000; i++, ms_sleep--) {
- delay(1);
- yield();
- if (dataSent != 0 ) {
- break; //No data sent, try another channel
- }
- }
- if (dataSent == 1 ) {
- //Save channel to nvr/RTC mem ?
- Serial.printf("Found Master on channel: %d\n", WiFi.channel());
- #ifndef USE_FIXED_CHANNEL
- break;
- #endif
- }
- }
- #ifndef USE_FIXED_CHANNEL
- delay(500);
- }
- #endif
- }
- void loop()
- {
- for (cnt = 0; cnt < maxDataFrameSize; cnt++) {
- dataToSend[cnt]++;
- }
- esp_err_t sendResult = esp_now_send(master.peer_addr, dataToSend, sizeof(dataToSend)); //maxDataFrameSize);
- if (sendResult == ESP_OK) {
- Serial.println("Send success");
- } else if (sendResult == ESP_ERR_ESPNOW_NOT_INIT) {
- // How did we get so far!!
- Serial.println("ESPNOW not Init.");
- } else if (sendResult == ESP_ERR_ESPNOW_ARG) {
- Serial.println("Invalid Argument");
- } else if (sendResult == ESP_ERR_ESPNOW_INTERNAL) {
- Serial.println("Internal Error");
- } else if (sendResult == ESP_ERR_ESPNOW_NO_MEM) {
- Serial.println("ESP_ERR_ESPNOW_NO_MEM");
- } else if (sendResult == ESP_ERR_ESPNOW_NOT_FOUND) {
- Serial.println("Peer not found.");
- }
- else if (sendResult == ESP_ERR_ESPNOW_IF) {
- Serial.println("Interface Error.");
- } else {
- Serial.printf("\r\nNot sure what happened\t%d", sendResult);
- }
- delay(2000);
- }
- int TestSend() {
- strcpy((char*)dataToSend, "Calling Master");
- esp_err_t sendResult = esp_now_send(master.peer_addr, dataToSend, sizeof(dataToSend));
- if (sendResult == ESP_OK) {
- Serial.println("Send success");
- return 1;
- } else if (sendResult == ESP_ERR_ESPNOW_NOT_INIT) {
- // How did we get so far!!
- Serial.println("ESPNOW not Init.");
- } else if (sendResult == ESP_ERR_ESPNOW_ARG) {
- Serial.println("Invalid Argument");
- } else if (sendResult == ESP_ERR_ESPNOW_INTERNAL) {
- Serial.println("Internal Error");
- } else if (sendResult == ESP_ERR_ESPNOW_NO_MEM) {
- Serial.println("ESP_ERR_ESPNOW_NO_MEM");
- } else if (sendResult == ESP_ERR_ESPNOW_NOT_FOUND) {
- Serial.println("Peer not found.");
- }
- else if (sendResult == ESP_ERR_ESPNOW_IF) {
- Serial.println("Interface Error.");
- } else {
- Serial.printf("\r\nNot sure what happened\t%d", sendResult);
- }
- return 0;
- }
- void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
- Serial.print("\r\nLast Packet Send Status:\t");
- Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
- dataSent = (status == ESP_NOW_SEND_SUCCESS ? 1 : -1);
- }
- void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) {
- //Serial.printf("\r\nReceived\t%d Bytes\t%d\n", data_len, data[0]);
- Serial.printf("\r\nReceived\t%d Bytes\t%s\n", data_len, data);
- }