Report
2 years, 8 months ago.

output data with fgetc(File)) != EOFEOF function is not 100% readable

Hello all, I am trying to read the binary data from an SD card. I have two methods to do it. In First method by using fread. Here I must know the no of bytes that binary file consist of. This method is not useful for my application as we can not predict how much bytes we store. This method goes like below: Let's consider file has 350 bytes of data.

int main() {
    
    int readings[3] = {0, 0, 0};
    accelerometer.setPowerControl(0x00);
    wait_ms(1.1);
    accelerometer.setDataFormatControl(0x0B);
    accelerometer.setPowerControl(0x08);
    accelerometer.setDataRate(0x08);
    accelerometer.setFifoControl(0x80);
    accelerometer.setInterruptEnableControl(0x80);
  
    FILE *fp = fopen("/sd/test001.bin", "rb");
    int16_t read[350]; // I know the file has 350 bytes of data
    fread(read,sizeof(int16_t),350,fp);
    for (int i = 0; i<350; i++) 
    pc.printf("\r\n %i",read[i]);
   
    fclose(fp); 
  }

Second method: using End of File (EOF) The problem with second method is for negative data for example: -16...It is printing as 240 255 In case of positive data : for exaple for value 92..it is printing as 92 0 This is how it is representing each data as set of two values. The code is :

int main() {
    
    int readings[3] = {0, 0, 0};
    accelerometer.setPowerControl(0x00);
    wait_ms(1.1);
    accelerometer.setDataFormatControl(0x0B);
    accelerometer.setPowerControl(0x08);
    accelerometer.setDataRate(0x08);
    accelerometer.setFifoControl(0x80);
    accelerometer.setInterruptEnableControl(0x80);
  
    FILE *fp = fopen("/sd/PCE001.bin", "rb");
   if (!logFile)  
      pc.puts("FAILED TO OPEN FILE"); 
      else { 
      
      while((nr = fgetc(logFile)) != EOF) 
      pc.printf("%i \n\r",nr);
    fclose(fp); 
  }

. The above method is reading file till its end but output data is not readable. Above methos is useful for my application when data shown is 100% readable.

Thank you for your time. Any suggestions would be appreciated.

Comment on this question

1 Answer

2 years, 8 months ago.

Two options: Option 1: You could use fgetc() twice to read 2 bytes and then reassemble the 16 bit number. This has the advantage that you could cope with files written by a system with a different endianness to the mbed.

Option 2: You read one int16 at a time until the end of the file. This is probably the easier option.

int main() {
    
    FILE *fp = fopen("/sd/test001.bin", "rb");
    int16_t readData;

    while (!feof(fp)) {                                // while we haven't hit the end of the file
      int len = fread(&readData,sizeof(int16_t),1,fp); // read an int16_t
      if (len == sizeof(int16_t))                     // check we got the required amount of data
        pc.printf("\r\n %i",readData);                 // print it.
    }  
    fclose(fp); 
  }

Dear Andy, Thank you. I worked out option 1. However getting an error for option 2. undefined symbol feof.

posted by Mohan gandhi Vinnakota 12 Dec 2016

feof() is a standard c library function and compiles fine for me. if you are getting that error then either you spelt it wrong or there is something wrong with your compiler setup.

posted by Andy A 12 Dec 2016

Thank you. I will check that. one more doubt.

This is how I combine two bytes to make uint16_t data.

 while ((c = fgetc(logFile)) != EOF){
              p = fgetc(logFile);
            cp = (p<<8) | c;
            pc.printf(" \r\n %i ",cp);}

Now I must read float data temparature . I am doing it like below. Unfortunately getting wrong data.

while ((nr = fgetc(logFile)) != EOF){
                ta = fgetc(logFile);
                tb = fgetc(logFile);
                tc = fgetc(logFile);
                td = fgetc(logFile);
                f1 = (ta << 24) | (tb << 16) | (tc << 8) | td;
                pc.printf(" \r\n %f ",f1);}

is above process of combining float data is right?.

posted by Mohan gandhi Vinnakota 12 Dec 2016