ESP-NOW Multiple sensors error in received data

Hi everyone

First I hope this is posted in the right topic section as it is a programming question, and appologies if ESP8266 devices are not meant to be posted here

So I have been mixing and matching code that I have found across the internet and came up with a rather nice project, however I have one silly error that I can not work out how to fix.

My project is simple, I have an esp8266 configured for ESP-NOW transmiter, its set up to send the temperatures of 2 DS18B20 sensors.

I have 3 of these transmitters, each sending 2 temperature readings, so far so good.

On the receiver side I am reciving the signals of all 6 temperature sensors, again great, but when printing off the reading via the serial monitor it should read something like this

WiFi connected, IP address: 192.168.1.242
This node AP mac: 3E:71:BF:29:21:32, STA mac: 3C:71:BF:29:21:32

Sensor = No1
Fridge Temperature = 5.87
Freezer Temperature = -12.00

Sensor = No2
Fridge Temperature = -12.00
Freezer Temperature = -18.50

Sensor = No3
Fridge Temperature = 5.87
Freezer Temperature = -15.00

But what I`m getting is

Sensor = No3
Fridge Temperature = 5.87
Freezer Temperature = -12.00

Sensor = No3
Fridge Temperature = -12.00
Freezer Temperature = -18.50

Sensor = No3
Fridge Temperature = 5.87
Freezer Temperature = -15.00

All the readings say sensor No3 and for the life of me I can not figure out why.

My receiver code is attached, any help greatfully appreciated.

Cheers Alan

#include <ESP8266WiFi.h>

extern "C" {
#include <espnow.h>
}
const char* ssid = "Ozric Network";
const char* password = "Hawkwind69!";

#define WIFI_CHANNEL 1

struct SENSOR_DATA_DS18B20_1 {
  String name1_ds18b20_1;
  String name2_ds18b20_1;
  float temp1_ds18b20_1;
  float temp2_ds18b20_1;
  float t_ds18b20_1;
};

struct SENSOR_DATA_DS18B20_2 {
  String name1_ds18b20_2;
  String name2_ds18b20_2;
  float temp1_ds18b20_2;
  float temp2_ds18b20_2;
  float t_ds18b20_2;
};

struct SENSOR_DATA_DS18B20_3 {
  String name1_ds18b20_3;
  String name2_ds18b20_3;
  float temp1_ds18b20_3;
  float temp2_ds18b20_3;
  float t_ds18b20_3;
};

void setup() {
  Serial.begin(115200); Serial.println();

  initWifi();

  if (esp_now_init() != 0) {
    Serial.println("*** ESP_Now init failed");
    ESP.restart();
  }

  Serial.print("This node AP mac: "); Serial.print(WiFi.softAPmacAddress());
  Serial.print(", STA mac: "); Serial.println(WiFi.macAddress());

  esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);

  esp_now_register_recv_cb([](uint8_t *mac, uint8_t *data_ds18b20_1, uint8_t len) {

    getReading_DS18B20_1(data_ds18b20_1, len);
  });

  esp_now_register_recv_cb([](uint8_t *mac, uint8_t *data_ds18b20_2, uint8_t len) {

    getReading_DS18B20_2(data_ds18b20_2, len);
  });

  esp_now_register_recv_cb([](uint8_t *mac, uint8_t *data_ds18b20_3, uint8_t len) {

    getReading_DS18B20_3(data_ds18b20_3, len);
  });
}

void loop() {
}

void getReading_DS18B20_1(uint8_t *data_ds18b20_1, uint8_t len) {
  SENSOR_DATA_DS18B20_1 tmp_ds18b20_1;
  memcpy(&tmp_ds18b20_1, data_ds18b20_1, sizeof(tmp_ds18b20_1));
  
  Serial.print("Sensor = No1"); Serial.println();
  Serial.print(tmp_ds18b20_1.name1_ds18b20_1); Serial.print(" Temperature = "); Serial.println(tmp_ds18b20_1.temp1_ds18b20_1);
  Serial.print(tmp_ds18b20_1.name2_ds18b20_1); Serial.print(" Temperature = "); Serial.println(tmp_ds18b20_1.temp2_ds18b20_1);
  Serial.println(); 
}

void getReading_DS18B20_2(uint8_t *data_ds18b20_2, uint8_t len) {
  SENSOR_DATA_DS18B20_2 tmp_ds18b20_2;
  memcpy(&tmp_ds18b20_2, data_ds18b20_2, sizeof(tmp_ds18b20_2));
  
  Serial.print("Sensor = No2"); Serial.println();
  Serial.print(tmp_ds18b20_2.name1_ds18b20_2); Serial.print(" Temperature = "); Serial.println(tmp_ds18b20_2.temp1_ds18b20_2);
  Serial.print(tmp_ds18b20_2.name2_ds18b20_2); Serial.print(" Temperature = "); Serial.println(tmp_ds18b20_2.temp2_ds18b20_2);
  Serial.println(); 
}

void getReading_DS18B20_3(uint8_t *data_ds18b20_3, uint8_t len) {
  SENSOR_DATA_DS18B20_3 tmp_ds18b20_3;
  memcpy(&tmp_ds18b20_3, data_ds18b20_3, sizeof(tmp_ds18b20_3));
  
  Serial.print("Sensor = No3"); Serial.println();
  Serial.print(tmp_ds18b20_3.name1_ds18b20_3); Serial.print(" Temperature = "); Serial.println(tmp_ds18b20_3.temp1_ds18b20_3);
  Serial.print(tmp_ds18b20_3.name2_ds18b20_3); Serial.print(" Temperature = "); Serial.println(tmp_ds18b20_3.temp2_ds18b20_3);
  Serial.println();
}

void initWifi() {
  WiFi.mode(WIFI_AP_STA);
  WiFi.softAP("MyGateway", "12345678", WIFI_CHANNEL, 1);
  Serial.print("Connecting to "); Serial.print(ssid);
  if (strcmp (WiFi.SSID().c_str(), ssid) != 0) {
    WiFi.begin(ssid, password);
  }
  int retries = 20; // 10 seconds
  while ((WiFi.status() != WL_CONNECTED) && (retries-- > 0)) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  if (retries < 1) {
    Serial.print("*** WiFi connection failed");
    ESP.restart();
  }
  Serial.print("WiFi connected, IP address: "); Serial.println(WiFi.localIP());
}

you call esp_now_register_recv_cb () 3 times with 3 different callback functions. wouldn’t the callback be whatever the last call to this function set it to?

in other words, shouldn’t there only be 1 callback?

(if the above is allowed, how many callback functions are allowed and when does it call them)?

In addition to gcjr's (correct) concern about registering 3 callbacks, only the last of which will be called, you do NOT need three structs to contain data, when all the structs are the same.

You need one instance of one struct to contain the data just received. You might want three instances, if you want to share data between functions.

The senders MUST include something in the data that they send that will allow the receiver to know which one sent the data. The ONE callback function will use that data to decide which instance of the struct to put the data in, or to decide what to print.

Hi everyone

Sorry for the late reply.

I managed to get it working so am posting the code here if its of help to anyone.

cheers

#include <ESP8266WiFi.h>
extern "C" {
#include <espnow.h>
#include "user_interface.h"
}
uint8_t mac[] = {0x36, 0x33, 0x33, 0x33, 0x33, 0x33};

struct __attribute__((packed)) SENSOR_DATA {
  float station;
  float temp1;
  float temp2;
} sensorData;

void setup() {

  WiFi.mode(WIFI_AP);
  wifi_set_macaddr(SOFTAP_IF, &mac[0]);

  Serial.begin(115200); Serial.println();
  Serial.print("This node AP mac: "); Serial.println(WiFi.softAPmacAddress());
  Serial.print("This node STA mac: "); Serial.println(WiFi.macAddress());

  delay(1000);
  Serial.println();

  initEspNow();
}

int heartBeat;

void loop() {
  if (millis() - heartBeat > 30000) {
    heartBeat = millis();
  }
  ESP.wdtFeed(); 
}

void initEspNow() {
  if (esp_now_init() != 0) {
    Serial.println("*** ESP_Now init failed");
    ESP.restart();
  }

  esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
  esp_now_register_recv_cb([](uint8_t *mac, uint8_t *data, uint8_t len) {

    char macStr[18];
    snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    //Serial.print("Sensor Station MAC address is: ");  Serial.println(macStr);
    memcpy(&sensorData, data, sizeof(sensorData));
    Serial.println();

    if (sensorData.station == 1) {
      
      Serial.print("Kitchen"); Serial.println();
      Serial.print("Temperature1 is: ");  Serial.println(sensorData.temp1);
      Serial.print("Temperature2 is: ");  Serial.println(sensorData.temp2);
      Serial.println();
    }

    if (sensorData.station == 2) {
      
      Serial.print("Fridge 1"); Serial.println();
      Serial.print("Temperature1 is: ");  Serial.println(sensorData.temp1);
      Serial.print("Temperature2 is: ");  Serial.println(sensorData.temp2);
      Serial.println();
    }
    
    if (sensorData.station == 3) {
      
      Serial.print("Garden"); Serial.println();
      Serial.print("Temperature1 is: ");  Serial.println(sensorData.temp1);
      Serial.print("Temperature2 is: ");  Serial.println(sensorData.temp2);     
      Serial.println();
    }

    if (sensorData.station == 4) {

      Serial.print("Fridge 2"); Serial.println();
      Serial.print("Temperature1 is: ");  Serial.println(sensorData.temp1);
      Serial.print("Temperature2 is: ");  Serial.println(sensorData.temp2);
      Serial.println();
}  
  });
}