espnow wifi channel setup changed?

ardcp32
Posts: 4
Joined: Thu Oct 31, 2019 8:10 pm

espnow wifi channel setup changed?

Postby ardcp32 » Fri Nov 01, 2019 11:39 am

arduino-esp32 1.0.4
Arduino ide 1.8.10

esp32: WEMOS D1 MINI ESP32 plus LOLIN D32

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)
...
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:

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)
...

Is there an easier or better solution to do this?
Does it have any side effects ?

I have two simple, quickly put together sketches to illustrate how a slave can search
for the master (intended to be connected to a local lan ) looping through
the channels.
It is very crude, basic test programs just to show how to find the master on a specific channel.
The slave tries to send a token to the master after each channel change and stop when a response
is received.
Then it continues to send to the master using the found channel.

Here is the slave code used to test the search for master:

Code: Select all

/*
     esp32now slave 
*/

#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>

#define HIGHEST_CHANNEL	11
#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");
 
#ifdef USE_FIXED_CHANNEL
  uint8_t primaryChan = FIXED_CHANNEL;
#else
  for (uint8_t primaryChan = LOWEST_CHANNEL; primaryChan <= HIGHEST_CHANNEL; primaryChan++) {
#endif
  WiFiReset();
  WiFi.mode(WIFI_STA);
  
  delay(100);
  
 esp_wifi_set_mac(ESP_IF_WIFI_STA, &CustomMac[0]);
 
  delay(250);
 
  Serial.print("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("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("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(1500);
}

int TestSend() {
  
  strcpy((char*)dataToSend, "Calling Master");

	esp_err_t sendResult = esp_now_send(master.peer_addr, dataToSend, sizeof(dataToSend)); //maxDataFrameSize);
	if (sendResult == ESP_OK) {
		Serial.println("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);
}

And the master test code:

Code: Select all

/*
     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;

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_STA, &CustomMac[0]);
  
  Serial.print("Connecting to ");
  Serial.println( WiFi.softAPmacAddress() );

  Serial.println( WiFi.macAddress() );

  //Force espnow to use a specific channel
  ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true));
  
  uint8_t primaryChan = FIXED_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 = FIXED_CHANNEL;
  slave.encrypt = 0;
  slave.ifidx = ESP_IF_WIFI_STA;

  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)); // maxDataFrameSize);
    if (sendResult == ESP_OK) {
      Serial.print("Success delivering 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
}

ardcpesp32

Who is online

Users browsing this forum: No registered users and 36 guests