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);
}
- The data that I take and display are correct via the serial monitor.
- Each component of my struct is a float of size
4
sosizeof(myData)
is12
. - I chose Majenkos solution to be able to get more data acquisition from my data logger.
- So first I write a binary file via the previous function called in a loop,
- and then I want to create a file readable by a human by reading the data from the binary file,
and converting them back through my arduino mega 2560.
- The problem is that I get nonsense values from my reading:
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 !