How to convert byte array to floate

How can I convert the byte array to float?

Code:

void send_data() {
    CCPACKET data;
    data.length=2;

    float lon=26.533255;
    float lat=27.533463;


    data.data[0]=lon;
    data.data[1]=lat;

    if(cc1101.sendData(data)){
    Serial.println(data.data[0]);
    Serial.println(data.data[1]);

    Serial.println(" sent ok ");
    return true;
    }else{
    Serial.println("sent failed ");
    return false;
    }

 }

The problem is when I print those two variables it just prints lon 26.00 and lat 27.00 but not lon 26.533255 lat 27.533463 as I expected.

Here is the header file for CCPACKET i use:

#ifndef _CCPACKET_H
#define _CCPACKET_H

#include "Arduino.h"

/**
 * Buffer and data lengths
 */
#define CC1101_BUFFER_LEN        64
#define CC1101_DATA_LEN          CC1101_BUFFER_LEN - 3

/**
 * Class: CCPACKET
 * 
 * Description:
 * CC1101 data packet class
 */
class CCPACKET
{
  public:
    /**
     * Data length
     */
    byte length;

    /**
     * Data buffer
     */
    byte data[CC1101_DATA_LEN];

    /**
     * CRC OK flag
     */
    boolean crc_ok;

    /**
     * Received Strength Signal Indication
     */
    byte rssi;

    /**
     * Link Quality Index
     */
    byte lqi;
};

#endif

I was trying to fix it by this part of code, but without success:

float lon=26.533543;

*((float *)data.data[0]) = lon;

Can someone help me to convert the byte array to float?

It would help if you could just post your entire code. From the results you're getting it looks like data.data is an array of integers or bytes. Since you're using data.data, this means you are using a member of an incidence of a class of some kind. Since I can't see where this is being defined, I don't know what it holds.

No problem, I can do that. I'm implementing a transceiver and therefore you will see functions, defines etc. in the code witch are not relevant for this question. I use the panStamp library in this link: Arduino : use a Texas CC1101 – Erwan's Blog

I will appreciate your help.

#include <Wire.h>
#include <EEPROM.h>
#include "cc1101.h"
 
 
// The connection to the hardware chip CC1101 the RF Chip
CC1101 cc1101;

int j;
byte x; 
byte b;
byte i;
byte syncWord = 199;
long counter = 0;
byte chan = 0;
 
// a flag that a wireless packet has been received
boolean packetAvailable = false;
 
 
/* Handle interrupt from CC1101 (INT0) gdo0 on pin2 */
void cc1101signalsInterrupt(void) {
  // set the flag that a package is available
  packetAvailable = true;
}
 
void setup()
{
  
  Wire.begin();  
  Serial.begin(9600);
  Serial.println("start");
   
 
  // setup the blinker output
  //pinMode(LEDOUTPUT, OUTPUT);
 // digitalWrite(LEDOUTPUT, LOW);
 
  // blink once to signal the setup
  //blinker();
  // initialize the RF Chip
  cc1101.init();
 
  cc1101.setSyncWord(&syncWord, false);
  cc1101.setCarrierFreq(CFREQ_433);
  cc1101.disableAddressCheck(); //if not specified, will only display "packet received"
  //cc1101.setTxPowerAmp(PA_LowPower);
 
  Serial.print("CC1101_PARTNUM "); //cc1101=0
  Serial.println(cc1101.readReg(CC1101_PARTNUM, CC1101_STATUS_REGISTER));
  Serial.print("CC1101_VERSION "); //cc1101=4
  Serial.println(cc1101.readReg(CC1101_VERSION, CC1101_STATUS_REGISTER));
  Serial.print("CC1101_MARCSTATE ");
  Serial.println(cc1101.readReg(CC1101_MARCSTATE, CC1101_STATUS_REGISTER) & 0x1f);
 
  attachInterrupt(0, cc1101signalsInterrupt, FALLING);
 
  Serial.println("device initialized");
  
}
 
void ReadLQI()
{
  byte lqi = 0;
  byte value = 0;
  lqi = (cc1101.readReg(CC1101_LQI, CC1101_STATUS_REGISTER));
  value = 0x3F - (lqi & 0x3F);
  Serial.print("CC1101_LQI ");
  Serial.println(value);
}
 
void ReadRSSI()
{
  byte rssi = 0;
  byte value = 0;
 
  rssi = (cc1101.readReg(CC1101_RSSI, CC1101_STATUS_REGISTER));
 
  if (rssi >= 128)
  {
    value = 255 - rssi;
    value /= 2;
    value += 74;
  }
  else
  {
    value = rssi / 2;
    value += 74;
  }
  Serial.print("CC1101_RSSI ");
  Serial.println(value);
}
 
 void send_data() {
CCPACKET data;
data.length=2;

float lon=26.533543;
float lat=27.532343;


data.data[0]=lon;
data.data[1]=lat;

if(cc1101.sendData(data)){
Serial.println(data.data[0]);
Serial.println(data.data[1]);
//Serial.println(data.data[1]);
//Serial.println(" sent ok :)");
return true;
}else{
Serial.println("sent failed :(");
return false;
}

 }
 
void loop()
{
  send_data();
delay(1000);
  if (packetAvailable) {
    Serial.println("packet received");
    // Disable wireless reception interrupt
    detachInterrupt(0);
 
    ReadRSSI();
    ReadLQI();
    // clear the flag
    packetAvailable = false;
 
    CCPACKET packet;
 
    if (cc1101.receiveData(&packet) > 0) {
      if (!packet.crc_ok) {
        Serial.println("crc not ok");
        
      }
      
      else if (packet.crc_ok){ 
      if (packet.length > 0) {
        Serial.print("packet: len ");
        Serial.print(packet.length);
        Serial.print(" data: ");

        j = 0;
        x = packet.data[j];
          Serial.print(x);
          Serial.print(" ");
           
        Serial.println(".");
        
      }
    }
    }
    // Enable wireless reception interrupt
    attachInterrupt(0, cc1101signalsInterrupt, FALLING);
  }

  
}

and the source code for send data/ receive data:

boolean CC1101::sendData(CCPACKET packet)
{
  byte marcState;
  bool res = false;

  // Declare to be in Tx state. This will avoid receiving packets whilst
  // transmitting
  rfState = RFSTATE_TX;

  // Enter RX state
  setRxState();

  // Check that the RX state has been entered
  while (((marcState = readStatusReg(CC1101_MARCSTATE)) & 0x1F) != 0x0D)
  {
    if (marcState == 0x11)        // RX_OVERFLOW
      flushRxFifo();              // flush receive queue
  }

  delayMicroseconds(500);

  // Set data length at the first position of the TX FIFO
  writeReg(CC1101_TXFIFO,  packet.length);
  // Write data into the TX FIFO
  writeBurstReg(CC1101_TXFIFO, packet.data, packet.length);

  // CCA enabled: will enter TX state only if the channel is clear
  setTxState();

  // Check that TX state is being entered (state = RXTX_SETTLING)
  marcState = readStatusReg(CC1101_MARCSTATE) & 0x1F;
  if((marcState != 0x13) && (marcState != 0x14) && (marcState != 0x15))
  {
    setIdleState();       // Enter IDLE state
    flushTxFifo();        // Flush Tx FIFO
    setRxState();         // Back to RX state

    // Declare to be in Rx state
    rfState = RFSTATE_RX;
    return false;
  }

  // Wait for the sync word to be transmitted
  wait_GDO0_high();

  // Wait until the end of the packet transmission
  wait_GDO0_low();

  // Check that the TX FIFO is empty
  if((readStatusReg(CC1101_TXBYTES) & 0x7F) == 0)
    res = true;

  setIdleState();       // Enter IDLE state
  flushTxFifo();        // Flush Tx FIFO

  // Enter back into RX state
  setRxState();

  // Declare to be in Rx state
  rfState = RFSTATE_RX;

  return res;
}


byte CC1101::receiveData(CCPACKET * packet)
{
  byte val;
  byte rxBytes = readStatusReg(CC1101_RXBYTES);

  // Any byte waiting to be read and no overflow?
  if (rxBytes & 0x7F && !(rxBytes & 0x80))
  {
    // Read data length
    packet->length = readConfigReg(CC1101_RXFIFO);
    // If packet is too long
    if (packet->length > CC1101_DATA_LEN)
      packet->length = 0;   // Discard packet
    else
    {
      // Read data packet
      readBurstReg(packet->data, CC1101_RXFIFO, packet->length);
      // Read RSSI
      packet->rssi = readConfigReg(CC1101_RXFIFO);
      // Read LQI and CRC_OK
      val = readConfigReg(CC1101_RXFIFO);
      packet->lqi = val & 0x7F;
      packet->crc_ok = bitRead(val, 7);
    }
  }
  else
    packet->length = 0;

  setIdleState();       // Enter IDLE state
  flushRxFifo();        // Flush Rx FIFO
  //cmdStrobe(CC1101_SCAL);

  // Back to RX state
  setRxState();

  return packet->length;
}

strtod() or atof() will do this conversion. See
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga5ee4d110a3bb55d2eadda05e3ebedf8a
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga689c9d3c4c04463aa31d329937789d06

CCPACKET data;
data.length=2;

float lon=26.533543;
float lat=27.532343;


data.data[0]=lon;
data.data[1]=lat;

What is the definition for CCPACKET? It appears to be a struct, containing a member called data. Your assumption, and I am not at all convinced that it is right, is that data is an array of floats.

PaulS:

CCPACKET data;

data.length=2;

float lon=26.533543;
float lat=27.532343;

data.data[0]=lon;
data.data[1]=lat;



What is the definition for CCPACKET? It appears to be a struct, containing a member called data. Your assumption, and I am not at all convinced that it is right, is that data is an array of floats.

It is an array like in the example below, the header file for CCPACKET.

#ifndef _CCPACKET_H
#define _CCPACKET_H

#include "Arduino.h"

/**
 * Buffer and data lengths
 */
#define CC1101_BUFFER_LEN        64
#define CC1101_DATA_LEN          CC1101_BUFFER_LEN - 3

/**
 * Class: CCPACKET
 * 
 * Description:
 * CC1101 data packet class
 */
class CCPACKET
{
  public:
    /**
     * Data length
     */
    byte length;

    /**
     * Data buffer
     */
    byte data[CC1101_DATA_LEN];

    /**
     * CRC OK flag
     */
    boolean crc_ok;

    /**
     * Received Strength Signal Indication
     */
    byte rssi;

    /**
     * Link Quality Index
     */
    byte lqi;
};

#endif[code]

It is an array

CCPACKET is NOT an array.

data is an instance of the CCPACKET class. The class contains an array called data, which is NOT an array of floats, so you are going to be sorely disappointed by what you get on the other end, since you are assuming that you can store floats in the data array.

Your buffer if an array of bytes, not floats. You're going to have trouble storing a float in a single byte. As far as converting a byte array to a float, assuming you're dealing with a 32bit float on a little-endian system, you could use a union or just use memcpy:

float lat;
byte lat_bytes[4] = { buffer[3], buffer[2], buffer[1], buffer[0] };
memcpy(&lat, &lat_bytes, sizeof lat);

If on big-endian, reverse the order of the bytes.

Alternatively, if you're receiving it over serial, use atof() as previously pointed out, since it will be a string.

If you just want to coerce a float into a binary byte sequence, then these ungainly casts will do the job.

float f, g;
char s[12];

/* Stick a float into the char[]
 */
f = 3.14159;
*(float *)s = f;                // either of these options will work.
*(float *)(&s[0]) = f;       // another way to do the same thing

/* Suck a float back out of the char[]
 */
g = *(float *)s;
Serial.println(g);

g = *(float *)(&s[0]);
Serial.println(g);