1

For my data logger project I'm logging data to a SD card. Here I'm storing the data in binary format. I'm logging accelerometer and temp&humidity sensors. I could read data byte by byte. Hence to print ADXL data (two bytes), I combine each two byte data. Hence four bytes has to be combined to get temparature data. Unfortunately for temparature I failed to print actual data. There is some conversion problem. I'm looking some help regarding how to convert data to floats.

Code to read and print binary to uint16_t ( accelerometer data): working

while ((nr = fgetc(logFile)) != EOF){
         pc.printf(" \r\n %d ",nr);
          acc_con[i] = nr;
          if (i == 1){ 
          acc = (acc_con[1]<<8) | acc_con[0];
          pc.printf(" \r\n %i ",acc);
          i = 0;} 
          else i++; 
         }

Code to read and print binary to float ( temparature data): Not working

while ((nr = fgetc(logFile)) != EOF){
         pc.printf(" \r\n %d ",nr);
           humicon[i] = nr;
           if (i == 3){
            hum = (humicon[0] << 24) | (humicon[1] << 16) | (humicon[2] << 8) | humicon[3];
            pc.printf(" \r\n %f ",hum);
            i = 0;}
            else i++;
            }

The byte by byte raw data from variable nr is: 24, 58, 46, 66, and the output from variable hum is: 406466112.000000.

I could read humidity or temparature (floats) with fread. Unfortunatly to use fread I must know th no of bytes stored in the file. With below code I could print floats also. int main() {

int nr;
FILE *fp = fopen("/sd/PCE000.bin", "rb");
float read[1];
fread(read,sizeof(float),1,fp);
pc.printf("\r\n %f",read[0]);
  fclose(fp); 

}

I would like to know the formula for the conversion like (acc_con[1]<<8) | acc_con[0]. Thank you.

3
  • 2
    See struct Commented Dec 14, 2016 at 9:41
  • 1
    Is this a python or C question? Commented Dec 14, 2016 at 9:46
  • It is C. Done as below answer. Commented Dec 14, 2016 at 10:06

3 Answers 3

2

If you want to do this in Python, it sounds like a job for the struct module:

>>> struct.unpack("f", "".join([chr(x) for x in [24, 58, 46, 66]]))
(43.556732177734375,)

This assumes little-endian byte-order.

In C, you can use memcpy():

float x;
const unsigned char bytes[] = { 24, 58, 46, 66 };
memcpy(&x, bytes, sizeof x);
printf("%f\n", x);
Sign up to request clarification or add additional context in comments.

Comments

0

With

unsigned int hum;
....
hum = (humicon[0] << 24) | (humicon[1] << 16) | (humicon[2] << 8) | humicon[3];

You are converting 8 bit data to 32 bit integer data. You can store this data directly. Or if you absolutely want to store in floats, you can use.

float hum_f;
....
hum_f = hum;

Comments

0

Yap, is not simple function, transform an array of bytes to a floating point function. I am lookin also to implement it to avoid portable reasons. There are differences also between little endian and big endian machines. But there are several hacks to this problem. First the file size, you have to include "sys/stat.h", with small differences is also portable. But is not required. Read it as buffer of char :

char f[sizeof(float)];
if (fread(f,1,sizeof(float), yourfile) ==sizeof(float))
{
    float *flt_ptr=f;
    printf("%f\n",*flt_ptr);
}

C is wonderful for those things, there is also no need to cast everithing.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.