Go Down

Topic: [solved] Can't receive float from nRF24L01 with ESP8266 (Read 218 times) previous topic - next topic

HookUpWire

I have one Arduino Pro Mini that is sending DS18B20 temperature with nRF24L01. Then I have Arduino Uno receiving that data and putting it to serial. Works Great. Serial output "Radio 1, 27.44 °C".

When I try to receive that data with nRF24L01 + ESP8266 the serial output is  "Radio 1, 0.00 °C". If I change the temp data from float to int8_t I can receive the data. Serial output "Radio 1, 27 °C".

Code: [Select]

struct TempPacket // Any packet up to 32 bytes can be sent.
{
    uint8_t FromRadioId;
    float Temp;
};

to

Code: [Select]
struct TempPacket // Any packet up to 32 bytes can be sent.
{
    uint8_t FromRadioId;
    int8_t Temp;
};


Only uint8_t and int8_t works with ESP8266. If I try to send int16_t or float the temperature is 0 °C. With Uno float and int16_t works fine.

I'm using this library for nRF24L01. https://github.com/dparson55/NRFLite


Pro mini send code:
Code: [Select]
#include <SPI.h>
#include <NRFLite.h>

#include <OneWire.h>
#include <DallasTemperature.h>

//DS18B20
#define ONE_WIRE_BUS 4 //Pin to which is attached a temperature sensor + 4k7 resistor to 3V3
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

const static uint8_t RADIO_ID = 1;             // Our radio's id.
const static uint8_t DESTINATION_RADIO_ID = 0; // Id of the radio we will transmit to.
const static uint8_t PIN_RADIO_CE = 9;
const static uint8_t PIN_RADIO_CSN = 10;

struct TempPacket // Any packet up to 32 bytes can be sent.
{
    uint8_t FromRadioId;
    float Temp;        //Only uint8_t and int8_t works with ESP8266
};

NRFLite _radio;
TempPacket _tempData;


void setup() {
    Serial.begin(115200);
    if (!_radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN))
    {
        Serial.println("Cannot communicate with radio");
        while (1); // Wait here forever.
    }
   
    _tempData.FromRadioId = RADIO_ID;
    sensors.begin();

}

void loop() {
    sensors.requestTemperatures();
    _tempData.Temp = sensors.getTempCByIndex(0);
   
    Serial.print("Sending temperature");

    if (_radio.send(DESTINATION_RADIO_ID, &_tempData, sizeof(_tempData))) // Note how '&' must be placed in front of the variable name.
    {
        Serial.println("...Success");
    }
    else
    {
        Serial.println("...Failed");
    }

    delay(1000);
}


Uno receiver:
Code: [Select]

Radio    Arduino
CE    -> 9
CSN   -> 10 (Hardware SPI SS)
MOSI  -> 11 (Hardware SPI MOSI)
MISO  -> 12 (Hardware SPI MISO)
SCK   -> 13 (Hardware SPI SCK)
IRQ   -> No connection
VCC   -> No more than 3.6 volts
GND   -> GND

*/

#include <SPI.h>
#include <NRFLite.h>

const static uint8_t RADIO_ID = 0;       // Our radio's id.  The transmitter will send to this id.
const static uint8_t PIN_RADIO_CE = 9;
const static uint8_t PIN_RADIO_CSN = 10;


struct TempPacket // Any packet up to 32 bytes can be sent.
{
    uint8_t FromRadioId;
    float Temp;
};


NRFLite _radio;
TempPacket _tempData;

void setup()
{
    Serial.begin(115200);
    if (!_radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN))
    {
        Serial.println("Cannot communicate with radio");
        while (1); // Wait here forever.
    }
}

void loop()
{
    while (_radio.hasData())
    {
        _radio.readData(&_tempData); // Note how '&' must be placed in front of the variable name.

        String msg = "Radio ";
        msg += _tempData.FromRadioId;
        msg += ", ";
        msg += _tempData.Temp;
        msg += " °C ";
        Serial.println(msg);
    }
}


ESP8266 receiver:
Code: [Select]

#include <SPI.h>
#include <NRFLite.h>

const static uint8_t RADIO_ID = 0;       // Our radio's id.  The transmitter will send to this id.
const static uint8_t PIN_RADIO_CE = D8;
const static uint8_t PIN_RADIO_CSN = D4;


struct TempPacket // Any packet up to 32 bytes can be sent.
{
    uint8_t FromRadioId;
    int8_t Temp;        //Only uint8_t and int8_t works with ESP8266
};


NRFLite _radio;
TempPacket _tempData;

void setup()
{
    Serial.begin(115200);
    if (!_radio.init(RADIO_ID, PIN_RADIO_CE, PIN_RADIO_CSN))
    {
        Serial.println("Cannot communicate with radio");
        while (1); // Wait here forever.
    }
}

void loop()
{
    while (_radio.hasData())
    {
        _radio.readData(&_tempData); // Note how '&' must be placed in front of the variable name.

        String msg = "Radio ";
        msg += _tempData.FromRadioId;
        msg += ", ";
        msg += _tempData.Temp;
        msg += " °C ";
        Serial.println(msg);
    }
}

Robin2

I suspect the problem is with differences in the way that different datatypes are defined on the different microprocessors. "float" on an ESP8266 may not be the same as on an Arduino.

Keep in mind that an nRF24 just sends the bytes that make up the struct, it has no idea what they represent.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

davetcc

I'm not 100% sure but Another possibility is packing on the struct.

I'm assuming one side was AVR which is 8bit and the other ESP8266 which is 32 bit and probably has even alignment on bytes. There's normally a compiler pragma option to set to 8 bit packing. Remember to set it back after the struct.

Also are they both using the same endian? IE high byte first or low byte first. If not you need to rearrange them yourself.

I've done lots of comms stuff in the past between different architectures and the usual first suspects are the two above.
Long time Arduino user who enjoys DIY audio and AV equipment.

swe-dude

I had the same problem on esp8266 and changing the struct on the esp side like this helped me.(yes davetcc are right its a packing problem)
Code: [Select]
struct __attribute__((__packed__)) dataStruct6 {
  int16_t tmp;
  int16_t hum;
  uint32_t counter;
  int16_t volt;
} myData_SI7021;


Another tip if this are a battery powered transmitter, consider using a thermistor instead, DS18B20 start behaving strange below 3v-+, the nrf will work down to 1,6v so depending on the clock on the mcu you can get a lot better battery life.

HookUpWire

Thank you swe-dude. I got int16_t and float working.

I have battery powered DS18B20 (2xAA). I might try to make it solar powered some day. Just startet to play with these. Thanks for the tip.

I'm receiving that temperature with ESP and then I publish MQTT message of it. I can read it with my phone and planning to do some ESP+display to show that temperature.

max_esp8266

Hello every body,

Can you provide complete pin out of nrf24 for esp8266


thanks in advance

Go Up