Converting a float to uint8_t for LoRa radio 433MHz

Hello all, I’m working on a new module, Radio Lora Grove to send data between 2 arduino nano.
Indeed i wand to send some float value from a censor by this module.

I currently use 2 NRF and it works really good but i want to try and test new technologies such as LoRa.

http://wiki.seeedstudio.com/Grove_LoRa_Radio/ Here is module i use combined with an INA219 (current sensor).

So it works fine with the example given by the library Radio Lora Grove 433MHz.

But it has work only for a String. And when i want to send a float, the arduino IDE shows me some errors because the send function use to send a message take 2 parameters : uint8_t*, len uint8_t

Here is a part from the code of the Transmitter:

void loop()
{
    ShowSerial.println("Sending to rf95_server");
    // Send a message to rf95_server
    uint8_t data[] = "Hello World";

    rf95.send(data, sizeof(data));

What i want to do is to replace this “hello world” by a float. I have been trying for many hours now, Unions, cast, reinterpret_cast etc but maybe i just can’t simply send a float by this module.
I thought i could transform a float type to an uint8_t but it is not that easy.

And here is the Receiver code:

uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
       uint8_t len = sizeof(buf);
if(rf95.recv(buf, &len))
        {
            ShowSerial.print("got reply: ");
            ShowSerial.println((char*)buf);
        }

I have been looking where is this send function on headerfiles to understand how it works, i put it there.

template <typename T>
bool RH_RF95<T>::send(uint8_t* data, uint8_t len)
{
    if (len > RH_RF95_MAX_MESSAGE_LEN)
	return false;

    this->waitPacketSent(); // Make sure we dont interrupt an outgoing message
    setModeIdle();

    // Position at the beginning of the FIFO
    this->write(RH_RF95_REG_0D_FIFO_ADDR_PTR, 0);
    
    // The headers
    this->write(RH_RF95_REG_00_FIFO, this->_txHeaderTo);
    this->write(RH_RF95_REG_00_FIFO, this->_txHeaderFrom);
    this->write(RH_RF95_REG_00_FIFO, this->_txHeaderId);
    this->write(RH_RF95_REG_00_FIFO, this->_txHeaderFlags);
    
    // The message data
    this->burstWrite(RH_RF95_REG_00_FIFO, data, len);
    this->write(RH_RF95_REG_22_PAYLOAD_LENGTH, len + RH_RF95_HEADER_LEN);

    setModeTx(); // Start the transmitter
    // when Tx is done, interruptHandler will fire and radio mode will return to STANDBY
    
    //this->write(RH_RF95_REG_12_IRQ_FLAGS, 0xff); // Clear all IRQ flags
    return true;
}

and his prototype:

    /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().
    /// Then loads a message into the transmitter and starts the transmitter. Note that a message length
    /// of 0 is permitted. 
    /// \param[in] data Array of data to be sent
    /// \param[in] len Number of bytes of data to send
    /// \return true if the message length was valid and it was correctly queued for transmit
    virtual bool send(uint8_t* data, uint8_t len);

Link of the githbug module : https://github.com/Seeed-Studio/Grove_LoRa_433MHz_and_915MHz_RF
Any idea?

Thanks

  float myFloat = 3.14159;
  rf95.send((uint8_t *)(&myFloat), sizeof(myFloat));

Thank you for your help,

I tried,

Here is the result :

It compile without warning and errors but.. I think it's a type casting problem..

Img of the result

Quentin78:
Thank you for your help,

I tried,

Here is the result :

It compile without warning and errors but.. I think it's a type casting problem..

Img of the result

you need to cast the receive buffer back to a float, and print the float, not the buffer itself, or cast the buffer pointer to a float pointer, and print the dereferenced pointer..

Ok, i read what you said like 25 times,

But i don't understand where i can do this on those lines :

if(rf95.available())
  {
    // Should be a message for us now   
    uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
    uint8_t len = sizeof(buf);
    if(rf95.recv(buf, &len))
    {
//        digitalWrite(led, HIGH);
        //float x = *(float *)&buf;
        ShowSerial.print("got request: ");
        ShowSerial.println((char*)buf);

I tried to change the last line by ShowSerial.println((float*)buf);
and get this error no matching function for call to 'println(float*)

You need to dereference the pointer*(float*)buf

Similarly:

float x = *((float *)buf);

Thank you for your help! It works well ! :slight_smile: :slight_smile: :slight_smile: :slight_smile:

BUT

I don't really understand what you mean here :

You need to dereference the pointer

And I'd like to better understand what my code does, especially this pointer thing!

thanks again

float val = 3.1412; // a variable
float* pVal = &val;          // a pointer to the variable
float anotherVal = *pVal; // dereference the pointer to the first variable, and assign the value to a new variable. "anotherVal" now has the value 3.1412
*pVal = 2.718;   // "val" now has the value 2.718, but "anotherVal" still has the value 3.1412

Ok thanks for the reply, i understood!

My questions is more difficult now,

How about sending many float numbers, not just one? (My current sensor send power, voltage and current as float numbers)

Now if we don't send only one float, i think i have to send an array of float Or a String with my numbers in, or a structure
I don't know what is the best. What do you advise me?

I would send it as an array of floats.

float data[5], this way you can send all values at once and not have to deal with stirng processing on both sides.