NodeMCU ESP8266 doesn't send data via ESPNOW

I'm trying to send temperature and humidity data from 3 terminal nodes to a central node (many to one), all my devices are NodeMCU ESP8266. All the connections are good, there is no shorted component or anything electrical related as far as I've observed. Yesterday everything went fine, all the data was sent as per code (see below). As of now, none of the terminals send anything, but the local readings are working.

Here is the sender code (there are 3 different devices):

#include <ESP8266WiFi.h>
#include <espnow.h>

#include <Adafruit_Sensor.h>
#include <DHT.h>

// REPLACE WITH THE MAC Address of your receiver 
uint8_t broadcastAddress[] = {0x40, 0xF5, 0x20, 0x2E, 0x7D, 0xCD};//send to main station

// Digital pin connected to the DHT sensor
#define DHTPIN 2    

// Uncomment the type of sensor in use:
//#define DHTTYPE    DHT11     // DHT 11
#define DHTTYPE    DHT22     // DHT 22 (AM2302)
//#define DHTTYPE    DHT21     // DHT 21 (AM2301)
#define LED 12

DHT dht(DHTPIN, DHTTYPE);

// Define variables to store DHT readings to be sent
float temperature;
float humidity;

//// Define variables to store incoming readings
//float incomingTemp;
//float incomingHum;

// Updates DHT readings every 30 seconds
const long interval = 30000; 
unsigned long previousMillis = 0;    // will store last time DHT was updated 

// Variable to store if sending data was successful
String success;

//Structure example to send data
//Must match the receiver structure
//typedef struct struct_message {
//    float temp;
//    float hum;
//} struct_message;

typedef struct Data{
  int id;
  float temperature;
  float humidity;
} Data;

// Create a struct_message called DHTReadings to hold sensor readings
Data myData;

// Create a struct_message to hold incoming sensor readings
//struct_message incomingReadings;



// Callback when data is sent
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
  Serial.print("Last Packet Send Status: ");
  if (sendStatus == 0){
    Serial.println("Delivery success");
  }
  else{
    Serial.println("Delivery fail");
  }
  
}

// Callback when data is received
//void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
//  memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
//  Serial.print("Bytes received: ");
//  Serial.println(len);
//  incomingTemp = incomingReadings.temp;
//  incomingHum = incomingReadings.hum;
//}

void getReadings(){
  // Read Temperature
  temperature = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  //float t = dht.readTemperature(true);
  if (isnan(temperature)){
    Serial.println("Failed to read from DHT");
    temperature = 0.0;
  }
  humidity = dht.readHumidity();
  if (isnan(humidity)){
    Serial.println("Failed to read from DHT");
    humidity = 0.0;
  }
}

//void printIncomingReadings(){
//  // Display Readings in Serial Monitor
//  Serial.println("INCOMING READINGS");
//  Serial.print("Temperature: ");
//  Serial.print(incomingTemp);
//  Serial.println(" ÂșC");
//  Serial.print("Humidity: ");
//  Serial.print(incomingHum);
//  Serial.println(" %");
//}
 
void setup() {
  // Init Serial Monitor
  Serial.begin(115200);

  // Init DHT sensor
  dht.begin();
 
  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();

  // Init ESP-NOW
  if (esp_now_init() != 0) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // Set ESP-NOW Role
  esp_now_set_self_role(ESP_NOW_ROLE_COMBO);

  // Once ESPNow is successfully Init, we will register for Send CB to
  // get the status of Trasnmitted packet
  esp_now_register_send_cb(OnDataSent);
  
  // Register peer
  esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_COMBO, 1, NULL, 0);
  
  // Register for a callback function that will be called when data is received
  //esp_now_register_recv_cb(OnDataRecv);

  pinMode(LED, OUTPUT);
}
 
void loop() {
  unsigned long currentMillis = millis();
  digitalWrite(LED, HIGH);
  myData.id=2;
  if (currentMillis - previousMillis >= interval) {
    // save the last time you updated the DHT values
    previousMillis = currentMillis;

    //Get DHT readings
    getReadings();

    //Set values to send
    myData.temperature = temperature;
    myData.humidity = humidity;

    // Send message via ESP-NOW
    esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
    Serial.println(temperature);
    Serial.println(humidity);
    // Print incoming readings
    //printIncomingReadings();
  }
}

This is the receiver:

#include <ESP8266WiFi.h>
#include <espnow.h>
#include <SoftwareSerial.h>
#include <Firebase_ESP_Client.h>
#include "addons/TokenHelper.h"
#include "addons/RTDBHelper.h"

#define WIFI_SSID "Doom"
#define WIFI_PASSWORD "Andrei1999"

#define API_KEY "APIKEY"
#define DATABASE_URL "URL"

FirebaseData fbdo;

FirebaseAuth auth;
FirebaseConfig config;

bool signupOK = false;

String incomingData;
char serialData;

String gateway_temperature;
String gateway_humidity;
String gateway_gas;

SoftwareSerial ESPserial(4, 5); // RX, TX

//#include <Adafruit_Sensor.h>
//#include <DHT.h>

// REPLACE WITH THE MAC Address of your receiver 
// this is the receiver

// Digital pin connected to the DHT sensor
#define DHTPIN 2    

// Uncomment the type of sensor in use:
//#define DHTTYPE    DHT11     // DHT 11
//#define DHTTYPE    DHT22     // DHT 22 (AM2302)
//#define DHTTYPE    DHT21     // DHT 21 (AM2301)

//DHT dht(DHTPIN, DHTTYPE);

// Define variables to store DHT readings to be sent
//float temperature;
//float humidity;

// Define variables to store incoming readings
//float incomingTemp_D98F;
//float incomingHum_D98F;
//float incomingTemp_A942;
//float incomingHum_A942;
//float incomingTemp_15B5;
//float incomingHum_15B5;

// Updates DHT readings every 30 seconds
const long interval = 30000; 
unsigned long previousMillis = 0;    // will store last time DHT was updated 

// Variable to store if sending data was successful
//String success;

//Structure example to send data
//Must match the receiver structure
//typedef struct struct_message {
//    float temp;
//    float hum;
//} struct_message;
//

typedef struct Data{
  int id;
  float temperature;
  float humidity;
} Data;

Data myData;

Data nodeMCU_D98F;
Data nodeMCU_A942;
Data nodeMCU_15B5;

Data nodeMCUStruct[3] = {nodeMCU_D98F, nodeMCU_A942, nodeMCU_15B5};

String str;

// Callback when data is sent
//void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
//  Serial.print("Last Packet Send Status: ");
//  if (sendStatus == 0){
//    Serial.println("Delivery success");
//  }
//  else{
//    Serial.println("Delivery fail");
//  }
//}

// Callback when data is received
void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) {
  char macStr[18];
  //Serial.print("Packet received from: ");
  //snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", 
  //mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  //Serial.println(macStr);
  
  memcpy(&myData, incomingData, sizeof(myData));
  nodeMCUStruct[myData.id-1].temperature = myData.temperature;
  nodeMCUStruct[myData.id-1].humidity = myData.humidity;
}

//void getReadings(){
//  // Read Temperature
//  temperature = dht.readTemperature();
//  // Read temperature as Fahrenheit (isFahrenheit = true)
//  //float t = dht.readTemperature(true);
//  if (isnan(temperature)){
//    Serial.println("Failed to read from DHT");
//    temperature = 0.0;
//  }
//  humidity = dht.readHumidity();
//  if (isnan(humidity)){
//    Serial.println("Failed to read from DHT");
//    humidity = 0.0;
//  }
//}

void printIncomingReadings(){
  
  Serial.println(nodeMCUStruct[0].temperature);
  Serial.println(nodeMCUStruct[0].humidity);
  Serial.println(nodeMCUStruct[1].temperature);
  Serial.println(nodeMCUStruct[1].humidity);
  Serial.println(nodeMCUStruct[2].temperature);
  Serial.println(nodeMCUStruct[2].humidity);
  ESPserial.println(nodeMCUStruct[0].temperature);
  ESPserial.println(nodeMCUStruct[0].humidity); 
  ESPserial.println(nodeMCUStruct[1].temperature);
  ESPserial.println(nodeMCUStruct[1].humidity);
  ESPserial.println(nodeMCUStruct[2].temperature);
  ESPserial.println(nodeMCUStruct[2].humidity);
}
 
void setup() {
  // Init Serial Monitor
  Serial.begin(115200);
  ESPserial.begin(9600);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  // Init DHT sensor
  //dht.begin();
 
  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);
  //WiFi.disconnect();

  // Init ESP-NOW
  if (esp_now_init() != 0) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // Set ESP-NOW Role
  esp_now_set_self_role(ESP_NOW_ROLE_COMBO);

  // Once ESPNow is successfully Init, we will register for Send CB to
  // get the status of Trasnmitted packet
  //esp_now_register_send_cb(OnDataSent);
  
  // Register peer
  //esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_COMBO, 1, NULL, 0);
  
  // Register for a callback function that will be called when data is received
  esp_now_register_recv_cb(OnDataRecv);

  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED){
    Serial.print(".");
    delay(1000);
  }
  Serial.println();
  Serial.print("Connected with IP: ");
  Serial.println(WiFi.localIP());
  Serial.println();

  auth.user.email = "esp8266@gmail.com";
  auth.user.password = "Tintenpatronen1&";

  /* Assign the api key (required) */
  config.api_key = API_KEY;

  /* Assign the RTDB URL (required) */
  config.database_url = DATABASE_URL;

  /* Sign up */
  if (Firebase.signUp(&config, &auth, "", "")){
    Serial.println("ok");
    signupOK = true;
  }
  else{
    Serial.printf("%s\n", config.signer.signupError.message.c_str());
  }

  /* Assign the callback function for the long running token generation task */
  config.token_status_callback = tokenStatusCallback; //see addons/TokenHelper.h
  
  Firebase.begin(&config, &auth);
  Firebase.reconnectWiFi(true);
}
 
void loop() {
  unsigned long currentMillis = millis();
  
  printIncomingReadings();
  
  if (Firebase.ready() && signupOK && Firebase.authenticated())
  {
//    Firebase.RTDB.setFloat(&fbdo, "test/kitchentemperature",atof(gateway_temperature));
//    Firebase.RTDB.setFloat(&fbdo, "test/kitchenhumidity",atof(gateway_humidity));
//    Firebase.RTDB.setFloat(&fbdo, "test/kitchenGAS",atof(gateway_gas));
    Firebase.RTDB.setFloat(&fbdo, "test/bedroom1temperature",nodeMCUStruct[0].temperature);
    Firebase.RTDB.setFloat(&fbdo, "test/bedroom1humidity",nodeMCUStruct[0].humidity);
    Firebase.RTDB.setFloat(&fbdo, "test/bedroom2temperature",nodeMCUStruct[1].temperature);
    Firebase.RTDB.setFloat(&fbdo, "test/bedroom2humidity",nodeMCUStruct[1].humidity);
    Firebase.RTDB.setFloat(&fbdo, "test/bathroomtemperature",nodeMCUStruct[2].temperature);
    Firebase.RTDB.setFloat(&fbdo, "test/bathroomhumidity",nodeMCUStruct[2].humidity);
  }
  
  
  
  delay(30000);
}

I'm reading/sending/receiving data each 30 seconds.

gateway
terminal

Attached I have the console output for a terminal node (Delivery fail), and the central node which in case no readings are sent, it will show 0.00 on the output.

IMPORTANT: Ignore firebase references as they are not related to the question.

Does anyone have an approach on this problem? I appreciate any help and I'll do my best to answer all questions if need be.

Thank you.

Are breadboards involved?
Have You made any code changes that could possibly be the reaso?

Yes, I have breadboards
I made very minor code changes but they shouldn't disrupt the flow of data. For example I changed Data nodeMCUStruct[3] to Data nodeMCUStruct[4]. Nothing happened and then I changed it back

I also changed the uint8_t broadcastAddress[] to a different MAC address to test on a different device, nothing changed and I reversed the code to the version I posted

There are no minor, small, changes that can't go wrong.
Change back to the version working and analyse what the each change really is doing. Having no possibility to test the code it's hopeless to dive down in Your code.

Breadboards do add uncertainty. The clamping capacity, clamping the component, cable.... is not very precise. Components having too tiny legs might lose the contact.
A usual failure of remote controls is oxide, dirt, dust between the battery and the contacting thing. Often rotating the battery reestablish the contact.

I'm running my hardware directly from household power plugs (output is 5V). I don't have any batteries. This exact same code worked yesterday just fine, and the issue is strictly the WiFi via ESPNOW. The terminal nodes fail to send data to the receiver. The receiver knows it must receive data but instead shows 0 because there were no readings sent

I will however attempt to retry this version of code, look at all minor sections of code which could possibly change the output. However I doubt it since I ran several tests previous time

After a bit of browsing, I identified that ESPNOW and WiFi are interfering with eachother. See this link: ESP8266 - ESP-Now Delivery Failure, but only sometimes - #4 by chrismast

After removing the lines of code where I attempt to connect to my hotspot, including WiFi.begin(WIFI_SSID, WIFI_PASSWORD); , the receiver shows the correct data. The problem might in fact reside in the channel used by ESPNOW being different than WiFi channel, hence the sender fails to push the data to the receiver. I will attempt adapting the code in the link I posted to my project and see if the 2 technologies can run under the same channel without disrupting the data flow

have a look at esp32-esp-now-wi-fi-web-server - there are some guidelines on using ESP-NOW and WiFi concurrently

I ultimately fixed the issue. All I had to do was connect everything on the same network and now the dataflow is synchronized, shows up and is accurate.

Thank you everyone who helped me in this topic

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.