Gateway_NodeMCU & NRF24L01_Wrong data coming

Hello Everybody!

I need your support to resolve the below mysterious phenomena:
I am building a Node and Gateway to measure temperature, humidity & CO2.
The Node is Arduino MEGA. The transmitter and the receiver: NRF24L01
When the Gateway is Arduino UNO, then the sketch is working perfectly.
When I change the Gateway to NodeMCU ESP 8266MOD, then
I am getting only one, totally wrong data: 8438000

Instead of:
Node ID: 255
Air temp: 24.5
Humidity: 85.4
CO2: 212.0

What am I doing wrongly?


NODES's sketch:

//NODE:
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <EEPROM.h>
#include "DHT.h"
#include <MQ2.h>

#define CSN_PIN 45   
#define CE_PIN 47     
const byte slaveAddress[5] = { 'R', 'x', 'A', 'A', 'A' };
RF24 radio(CE_PIN, CSN_PIN);  // Create a Radio
struct package {
  int id = 1;
  float airtemp = 0;
  float humid   = 0;
  float CO2     = 0;
};
typedef struct package Package;
Package dataToSend;   
int nodeID = EEPROM.read(0);
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
float humidity, temperature;  
int CO2pin = A0;  
float CO2;
MQ2 mq2(CO2pin);
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000;  
void setup() {
  dht.begin();
  mq2.begin();  // calibrate the device
  Serial.begin(9600);
  Serial.println("NODE Starting");
  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.setRetries(3, 5);  // delay, count
  radio.openWritingPipe(slaveAddress);
  radio.setPALevel(RF24_PA_MAX);  
  radio.setChannel(127); 
  pinMode(10, OUTPUT);  // Just keep SPI working
}

void loop() {
  humidity = dht.readHumidity();
  temperature = dht.readTemperature();
  float* values= mq2.read(true); 
  CO2 = values[1];  //0 : LPG in ppm   1 : CO2 in ppm   2 : SMOKE in ppm
  if (isnan(humidity) || isnan(temperature)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }
  dataToSend.id       = nodeID;
  dataToSend.airtemp  = temperature; // C
  dataToSend.humid    = humidity;       // %
  dataToSend.CO2      = 1000*CO2;       // mppm
  Serial.println("------------- Measurements -------------");
  Serial.print("Node ID:         ");  Serial.println(dataToSend.id);
  Serial.print("Air temperature: ");  Serial.println(dataToSend.airtemp);
  Serial.print("Humidity [%]:    ");  Serial.println(dataToSend.humid);
  Serial.print("CO2 [mppm\]:     ");  Serial.println(dataToSend.CO2);
  Serial.println("Sending to GATEWAY");
  currentMillis = millis();
  if (currentMillis - prevMillis >= txIntervalMillis) {
    send();
    prevMillis = millis();
  }
  delay(2000);
}

void send() {
  bool rslt;
  rslt = radio.write(&dataToSend, sizeof(dataToSend));
  Serial.print("Data Sent ");
 
  if (rslt) {
    Serial.println("  Acknowledge received");
  } else {
    Serial.println("  Tx failed. No acknowledgement received!");
  }
}

GATEWAY's sketch:

//GATEWAY:
/* For Arduino UNO:
#define CE_PIN   9   //D4
#define CSN_PIN 10   //D2
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <EEPROM.h>
const byte thisSlaveAddress[5] = { 'R', 'x', 'A', 'A', 'A' };
// Set up nRF24L01 radio on pins D4 & D2 of Nodemcu
RF24 radio(4, 2);  //CE, CSN 
bool newData = false;
int gatewayID = EEPROM.read(0);
struct package {
  int   id      = 0;
  float airtemp = 0;
  float humid   = 0;
  float CO2     = 0;
};
typedef struct package Package;
Package dataReceived;  // this must match dataToSend in the TX (trasmitter/master)

void setup() {
  Serial.begin(9600);
  Serial.println("");
  Serial.println("***** GATEWAY Starting *****");
  radio.begin();
  radio.setDataRate(RF24_250KBPS);
  radio.openReadingPipe(1, thisSlaveAddress);
  radio.setPALevel(RF24_PA_MAX);  //RF24_PA_MAX   RF24_PA_MIN //_MIN _LOW _HIGH _MAX
  radio.setChannel(127); //select a channel (in which there is no noise! 127 == 0x7F
  radio.startListening();
}

void loop() {
  getData();
  showData();
  delay(1000);
}

void getData() {
  if (radio.available()) {
    radio.read(&dataReceived, sizeof(dataReceived));
    newData = true;
  }
}
void showData() {
  if (newData == true) {
    Serial.println("---- Data received ----");
    //Serial.println(dataReceived);
    Serial.print("Node ID:         ");    Serial.println(dataReceived.id);
    Serial.print("Air temperature: ");    Serial.println(dataReceived.airtemp);
    Serial.print("Humidity [%]:    ");    Serial.println(dataReceived.humid);
    Serial.print("CO2 [mppm]:      ");    Serial.println(dataReceived.CO2);
    newData = false;
  }
}

probably due to different data sizes on the Mega and ESP8266 and possibly byte packing
e..g. esp8266 int is 32 bits on Mega is 16 bits
try

struct __attribute__((packed))  package {
  int16_t   id      = 0;
  float airtemp = 0;
  float humid   = 0;
  float CO2     = 0;
};

define id as a 16bit int so same on both systems

Thank You horace for the very quick feedback. I change the sketch as You porosed:
I changed in Gateway & Node this:

struct package {
  int   id      = 0;
  float airtemp = 0;
  float humid   = 0;
  float CO2     = 0;
};

To this:

struct __attribute__((packed))  package {
  int16_t   id      = 0;
  float airtemp = 0;
  float humid   = 0;
  float CO2     = 0;
};

Result:
---- Data received ----
Node ID: -32544
Air temperature: 0.00
Humidity [%]: 0.00
CO2 [mppm]: 0.00


Additional to the proposal: If I am defining only this:
On the NODE side:

char testString[100] = "text";
rslt = radio.write(&testString, sizeof(testString));

On the GATEWAY side:

char testString[100] = "text";
radio.read(&testString, sizeof(testString));
Serial.print("Test string:      ");   Serial.println(testString);

Result:
image

the name of an array is a pointer to the first element , try without the &, e.g.

char testString[100] = "text";
rslt = radio.write(testString, sizeof(testString));

EDIT: seem to remember the maximum NRF24L01 packet size is 32bytes

Thank You very much for your guidance.
I changed the following:
Node:

char testString[10] = "text";
rslt = radio.write(testString, sizeof(testString));

Gateway:

char testString[10] = "";
radio.read(testString, sizeof(testString));
Serial.print("Test string:      ");   Serial.println(testString);

Result:
image

ran a simple test transmitting text array
RP2040 transmitter

//  ESP32 > NRF24L01 transmitter test using a text string

// RP2040 connections
// RP2040 SPIO_SCK pin GP18 goes to NRF24L10_pin SCK
// RP2040 SPIO_RX pin GP16 goes to NRF24L10_pin MISO
// RP2040 SPIO_TX pin GP19 goes to NRF24L10_pin MOSI
// RP2040 pin SPIO_CSn GP17 to NRF24L10 CSN
// RP2040 pin GP20 to NRF24L10 CE
// RP2040 GND and 3.3V to NRF24L10  GND and VCC

#include <SPI.h>
#include "RF24.h"

#define CE_PIN 20
#define CSN_PIN 17

bool radioNumber = 0;
RF24 radio(CE_PIN, CSN_PIN);

byte addresses[][6] = { "1Node", "2Node" };

void setup() {
  Serial.begin(115200);
  Serial.println("\n\nRP2040 > NRF24L01 transmit text");
  radio.begin();
  if (radio.isChipConnected())
    Serial.println("\n\nTransmitter NF24 connected to SPI");
  else Serial.println("\n\nNF24 is NOT connected to SPI");
  radio.setChannel(125);
  radio.setPALevel(RF24_PA_MIN);
  radio.powerUp();
  radio.setDataRate(RF24_1MBPS);
  //radio.setDataRate(RF24_250KBPS);
  if (radioNumber) {
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1, addresses[0]);
  } else {
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1, addresses[1]);
  }
  radio.stopListening();
  //radio.setPayloadSize(sizeof(Struct1));
}

// loop transmiting data packet
void loop() {
  static char testString[10] = "text 0";
  radio.write(testString, sizeof(testString));
  Serial.print("transmit ");
  Serial.println(testString);
  delay(1000);
  testString[5]++;
}

nano receiver

//  Nano > NRF24L01 receiver test using a text string

// UNO/Nano connections
// arduino SCK pin 11 goes to NRF24L10_pin SCK
// arduino MISO pin 12 goes to NRF24L10_pin MI
// arduino MOSI pin 13 goes to NRF24L10_pin MO
// NRF24L10 CE to arduino pin 9
// NRF24L10 CSN to arduino pin10

#include <SPI.h>
#include <RF24.h>

#define CE_PIN 9
#define CSN_PIN 10

bool radioNumber = 1;
const uint8_t pipes[][6] = { "1Node", "2Node" };

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10];  // this must match dataToSend in the TX
bool newData = false;

//===========

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("Nano > NRF24L01 Receive text");
  radio.begin();
  if (radio.isChipConnected())
    Serial.println("Receiver NF24 connected to SPI");
  else {
    Serial.println("NF24 is NOT connected to SPI");
    while (1)
      ;
  }
  radio.setChannel(125);
  radio.setDataRate(RF24_1MBPS);
  //radio.setDataRate(RF24_250KBPS);
  radio.printDetails();
  if (!radioNumber) {
    radio.openWritingPipe(pipes[0]);
    radio.openReadingPipe(1, pipes[1]);
  } else {
    radio.openWritingPipe(pipes[1]);
    radio.openReadingPipe(1, pipes[0]);
  }
  radio.startListening();
  // radio.setPayloadSize(sizeof(Struct1));
}

//=============

void loop() {
  if (radio.available()) {
    char testString[10] = "";
    radio.read(testString, sizeof(testString));
    Serial.print("Test string:      ");
    Serial.println(testString);
  }
}

RP2040 serial monitor

RP2040 > NRF24L01 transmit text
Transmitter NF24 connected to SPI
transmit text 0
transmit text 1
transmit text 2
transmit text 3
transmit text 4
transmit text 5

nano serial monitor

Nano > NRF24L01 Receive text
Receiver NF24 connected to SPI
Test string:      text 0
Test string:      text 1
Test string:      text 2
Test string:      text 3
Test string:      text 4

looks OK

EDIT: are you attempting to transmit/receive packets with different contents and of different sizes
if so how do you tell which packet is which?