0

I am trying to build a door sensor that, as soon as the door opens, will activate a reed switch and send the value to an ESP-NOW SLAVE which will then connect to WiFi, and then MQTT.

So my sender device can send the value continuously with an interval of 2 seconds, but most of the time my messages fail, even when the devices are kept next to each other.

When I do WiFi.disconnect(); it works very well, very few packets fail and the range is also good.

Here is what my code looks like right now for the receiver side:

Receiver.ino

#include "WifiSetup.h"
#include <espnow.h>

//##################################################
//##################################################
    
// Change this!!
char* ssid = "RANDOM";
char* password = "123455";
    
char* deviceAP_name = "RANDOM"; //
char* deviceAP_password = "RANDOM";
   
char mqttServer[40] = "192.168.1.20";
int mqttPort = 1883;
char mqttUser[40] = "username";
char mqttPassword[40] = "password";
    
//##################################################
//##################################################
    
boolean wifiConnected = false;
boolean clientConnected = false;
   
typedef struct struct_message {
  char dt[50]; // device topic
  char dstate[5];
  char bt[50]; // battery topic
  float bvolt;
} struct_message;
    
// Init ESP Now with fallback
void InitESPNow() {
  //  WiFi.disconnect();
  if (esp_now_init() == 0) {
    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();
  }
}
    
// Create a struct_message called myData
struct_message myData;
   
// Callback function that will be executed when data is received
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
  memcpy(&myData, incomingData, sizeof(myData));  

  Serial.print("Bytes received: ");
  Serial.println(len);
  Serial.print("char: ");
  Serial.println(myData.dt);
  Serial.print("char: ");
  Serial.println(myData.dstate);
  Serial.println();
}
    
void setup() {
  Serial.begin(115200);

  wifiConnected = connectWifi();

  if (!wifiConnected) {
    reconnectWifiSetup();
  }

  InitESPNow();
      
  // Once ESPNow is successfully Init, we will register for recv CB to
  // get recv packer info
  esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
  esp_now_register_recv_cb(OnDataRecv);  
}
     
void loop() {
  wifiReconnectLoop();
  yield();
}

Here is what my WifiConnectivity program looks like:

WifiSetup.h

#include <ESP8266WiFi.h>
    
//##################################################
//##################################################
// Change this!!
extern char* ssid;
extern char* password;
    
extern char* deviceAP_name;
extern char* deviceAP_password;
    
//##################################################
//##################################################
    
boolean connectWifi() {
  Serial.println("############    Connecting to Wifi   #################");
      
  boolean state = true;
  int i = 0;
  //  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");
  Serial.println("Connecting to WiFi");
  wifiConnected = false;
 
  // Wait for connection
  Serial.print("Connecting...");

  while (WiFi.status() != WL_CONNECTED) {
    delay(50);
    wifiConnected = false;
    Serial.print(".");
    if (i > 150) {
      state = false;
      break;
    }
    i++;
  }
  Serial.println("");
  if (state) {
    digitalWrite(2, HIGH);
    wifiConnected = true;
    Serial.print("Connected to ");
    Serial.println(ssid);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
    Serial.print("ESP8266 Board MAC Address:  ");
    Serial.println(WiFi.macAddress());
    Serial.println("############    Connected to Wifi   #################");
  } else {
    Serial.println("Connection failed.");
    Serial.println("############    Failed Wifi Connection   #################");
  }  
      
  return state;
}
    
// check wifi connection if not connected then set the timmer and start the connection after every 2 minutes (120 sec): 
int total_wifi_check_count;
unsigned long overallStartTime_wifi;
unsigned long overallPeriod_wifi = 120000;
unsigned long currentTime_wifi;
    
void reconnectWifiSetup() {
  Serial.println("Cannot connect to WiFi. Please check data and reset the ESP.");
  currentTime_wifi = millis();
  overallStartTime_wifi = currentTime_wifi;
  total_wifi_check_count++;
}
    
void wifiReconnectLoop() {
  if (WiFi.status() != WL_CONNECTED) {
    currentTime_wifi = millis();
    if (currentTime_wifi - overallStartTime_wifi >= overallPeriod_wifi) {
      if (total_wifi_check_count >= 15) { 
        ESP.reset();
      }
      if (!connectWifi()) {
        total_wifi_check_count++;
        Serial.println(total_wifi_check_count);
        overallStartTime_wifi = currentTime_wifi;
      }
    }
  } else {
    currentTime_wifi = millis();
    overallStartTime_wifi = currentTime_wifi;
  }
}

To improve the battery life and the response time I am using ESP-NOW, but due to less range and non-consistent message delivery in near range I am also not sure how I can get this done.

Any suggestions will be helpful.

Thank you!

5
  • you can't use wifi and espnow on the same thing at the same time, as you've seen. That said, wifi does seem to somehow affect espnow. I've gotten the quickest espnow sendoffs by first pre-configuring a chip for my wifi, booting it, then disabling wifi, including calling disconnect() in the espnow sketch, which I then flash over the wifi-having sketch. Why I need to flash twice? Not sure, but i think it has something to do with the channel cached by the ESP. – dandavis Jan 27 at 18:35
  • I have a setup like what you describe, and it takes 100-220ms to boot and get a message out and go to deepsleep. – dandavis Jan 27 at 19:23
  • I find I need to use 3 ESP-01 boards to do this. It is not clear if this is what you are doing. The 1st is at the door and is sleeping 90+% of the time (do disconnect the power LED). The next is always listening for ESP-NOW messages. This is connected over a serial port to the 3rd which is always connected to the WIFI network. I'm sure it happens, but I don't think I have ever seen a missed message. This is operating at about 20 feet through a wall. – st2000 Jan 27 at 20:40
  • What is the WiFi for? ESP-NOW is a peer-to-peer communication WITHOUT WiFi connection, so you need the WiFi.disconnect() to make sure that the WiFi is not connected. – hcheung Jan 28 at 13:36
  • @hcheung WiFi is for MQTT server connection. – user3201500 Jan 28 at 14:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.