1

I am currently struggling to apply Majenkos solution to read binary data from an sd card. I am writing data as floats from a 3-axis accelerometer via a struct this way:

struct data {
    float acc_x;
    float acc_y;
    float acc_z;
};
void take_measure(){
    struct data myData;
    myData.acc_x = get_accel_MMA8451(X);
    myData.acc_y = get_accel_MMA8451(Y);
    myData.acc_z = get_accel_MMA8451(Z);
    myFile.write((const uint8_t *)&myData, sizeof(myData));
    Serial.println(myData.acc_x, 2);
    Serial.println(myData.acc_y, 2);
    Serial.println(myData.acc_z, 2);
}
  1. The data that I take and display are correct via the serial monitor.
  2. Each component of my struct is a float of size 4 so sizeof(myData) is 12.
  3. I chose Majenkos solution to be able to get more data acquisition from my data logger.
  4. So first I write a binary file via the previous function called in a loop,
  5. and then I want to create a file readable by a human by reading the data from the binary file,
  6. and converting them back through my arduino mega 2560.

    • The problem is that I get nonsense values from my reading:

Values read from file (accel_x;accel_y, accel_z)

The code to read the data is as follow :

void loop() {
  if (myFile.available()) {
    struct data myData_read;
    myFile.read((uint8_t *)&myData_read, sizeof(myData_read));
    Serial.print(myData_read.acc_x,2);
    Serial.print(";");
    Serial.print(myData_read.acc_y,2);
    Serial.print(";");
    Serial.print(myData_read.acc_z,2);
    Serial.println(";");
    myFile.flush();
    delay(50);
    Serial.println("END");
}
}

Does anyone have an idea about what I am doing wrong ? Is this link with little and big endian ?

Here is the whole code for writing on the sd after one demand in the comment :

#include <SdFat.h>
#include <SPI.h>
#include <DS3231.h>
#include <RTClib.h>
#include <Wire.h>
#include "MMA8451.h"
#include "rtc.h"
#include <Adafruit_MMA8451.h>

const byte CS_pin = 48;
const byte pin= A0;
unsigned long start, finished, elapsed;

/* Nom du fichier csv */
const char* FILE_NAME= "binary_accel.bin";
const unsigned long DELAY_MEASURES = 10;
SdFat SD;
File myFile;


struct data {
    float acc_x;
    float acc_y;
    float acc_z;
};

/**  Delete file if exists */
void deleteFile(const char* filename) {
  if(SD.exists(filename)) {
    if(!SD.remove (filename)) {
      Serial.println(F("Error deleting file"));
      for(;;); // Wait for RESET button
    }
  }
}

void setup() {
  Serial.begin(9600);
  pinMode(53,OUTPUT);
  init_MMA8451(); // initialize the accelerometer
  set_ODR(800); // ouput data rate 800 Hz = 1,25ms
  /* init SD */
  Serial.println(F("Initialisation of sd card"));
  if (!SD.begin(CS_pin)){
    Serial.println(F("Impossible to initialize..."));
    Serial.println(F("Check for sd card and press RESET"));
    for(;;); // boucle infinie (wait for RESET)
  }

  /* Create a file for writing */
  Serial.println(F("Opening a file"));
  deleteFile(FILE_NAME);
  myFile = SD.open(FILE_NAME, O_WRITE | O_CREAT);
  if(!myFile){
    Serial.println(F("Impossible to open"));
    Serial.println(F("Check for sd card and press RESET"));
    for(;;);
  }

  /* Head of file */
  if(myFile.size()==0){
    Serial.println(F("File head"));
    myFile.println(F("accel_x;accel_y;accel_z"));
    //myFile.flush(); // Ensures that any bytes written to the file are physically saved to the SD card. This is done automatically when the file is closed.
  }
}



void loop() {
  static unsigned long prev_measure = 0;
  unsigned long start=millis();  // 10s timer
  unsigned long curr_measure = millis();
  // Measure
  if (start<10000){
    if (curr_measure - prev_measure >= DELAY_MEASURES){
       prev_measure = curr_measure;
       take_measure();
    }
    }
  else{
    myFile.close();
    Serial.println("Done");
  }
}

void take_measure(){
  struct data myData;
  myData.acc_x = get_accel_MMA8451(X);
  myData.acc_y = get_accel_MMA8451(Y);
  myData.acc_z = get_accel_MMA8451(Z);
  myFile.write((const uint8_t *)&myData, sizeof(myData));
  Serial.println(myData.acc_x, 2);
  Serial.println(myData.acc_y, 2);
  Serial.println(myData.acc_z, 2);
  }

And here is the code for reading the file :

#include <SdFat.h>
#include <SPI.h>
#include <Wire.h>

const byte CS_pin = 48;
unsigned long start, finished, elapsed, beginning;

const char* FILE_NAME_READ= "binary_accel.bin";
const char* FILE_NAME_WRITE= "binary_accel.csv";
File myFile;
File myFile2;
SdFat SD;

const unsigned long DELAY_MEASURES = 10;

struct data { // structure pour stocker date et 3 accélérations
    float acc_x;
    float acc_y;
    float acc_z;
};

void deleteFile(const char* filename) {
  if(SD.exists(filename)) {
    if(!SD.remove (filename)) {
      Serial.println(F("Error deleting file"));
      for(;;);
    }
  }
}


void setup() {
  Wire.begin();
  Serial.begin(9600);
  pinMode(53,OUTPUT);
  /* init carte SD */
  Serial.println(F("Initialisation of sd card "));
  if (!SD.begin(CS_pin)){
    Serial.println(F("Impossible to initialize"));
    Serial.println(F("Check for sd and press RESET"));
    for(;;);
  }


  Serial.println(F("Opening file"));
  deleteFile(FILE_NAME_WRITE);
  myFile = SD.open(FILE_NAME_READ, O_READ);
  myFile2 = SD.open(FILE_NAME_WRITE, O_WRITE | O_CREAT);
  if(!myFile2){
    Serial.println(F("Impossible to open file"));
    Serial.println(F("Check for sd and press RESET"));
    for(;;);
  }

  /* Head of file */
  if(myFile2.size()==0){
    Serial.println(F("Writing file head"));
    myFile.println(F("accel_x; accel_y; accel_z"));
    myFile.flush(); // Ensures that any bytes written to the file are physically saved to the SD card. This is done automatically when the file is closed.
  }
}

void loop() {
  if (myFile.available()) {
    struct data myData_read;
    myFile.read((uint8_t *)&myData_read, sizeof(myData_read));
    Serial.print(myData_read.acc_x,2);
    Serial.print(";");
    Serial.print(myData_read.acc_y,2);
    Serial.print(";");
    Serial.print(myData_read.acc_z,2);
    Serial.println(";");
    myFile.flush();
    delay(50);
    Serial.println("END");
}
}

Thanks a lot for your help !

12
  • do you close the file after writing and open it for reading before reading? – Juraj Jul 26 '19 at 8:30
  • 1
    Hi ! After writing in the file I flush it and yes I open the file before reading. I tried by closing it instead of flushing it (sdFat library calls flush when it closes anyway) but still the same problem in reading... – JamesONeil Jul 26 '19 at 9:05
  • 1
    Yes I do the writing and reading on the same Arduino mega 2560 – JamesONeil Jul 26 '19 at 9:20
  • 1
    And in the second sketch you are trying to write the same thing to the binary file (which is fortunately opened read only). I think you mean to try and write to myFile2. – Majenko Jul 26 '19 at 13:56
  • 1
    Ok thanks I will try it as soon as possible and let you know if it worked ! – JamesONeil Jul 28 '19 at 15:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.