(Fast?) 50ms Datalogger SD card

Hi,

i'm working on a project that involves a MMA8451 3-axis accelerometer, a Arduino MEGA and a 3.2TFT Shield with SD card.
I only use the SD card part of the TFT screen.

I like to measure the sensors data every 50ms and write that to a text file on the SD Card.
For now i made a sketch but it's not working at 50ms, i think the opening an closing the file takes the longest so i need to figure something out to get it working. I read some on the net about alternative writing to the SD card using FIFO Buffers and such. Really like to implement that but don't know exactly how.

What i also need is since it is a portable solution, i have no serial output and i can not close the sketch on a nice way. I can only pull out the power, so i need the data not to get corrupt when losing power. I can loose some data but als long it is not 2minutes of data i don't care much.

The project is going to measure a couple of hours, 3 values (x,y,z) at 50ms. So there's not a lot of data, only one line: indexnumber (value), X(value), Y(value), Z(value).

Powered by a large powerbank.

#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <Adafruit_MMA8451.h>
#include <Adafruit_Sensor.h>

Adafruit_MMA8451 mma = Adafruit_MMA8451();
File myFile;
  int Counter = 0;
  
void setup() {
Serial.begin(9600);
 while (!Serial) {
   ; // wait for serial port to connect. Needed for native USB port only
 }

  if (! mma.begin()) {
 Serial.println("Couldnt start");
   while (1);
  }
 Serial.println("MMA8451 found!");
  
  mma.setRange(MMA8451_RANGE_4_G);
  
 Serial.print("Range = "); Serial.print(2 << mma.getRange());  
 Serial.println("G");
  
 Serial.print("Initializing SD card...");

SD.begin(53);

  }



void loop() {
  mma.read();
Serial.print(Counter);
Serial.print("\tX:\t"); Serial.print(mma.x); 
Serial.print("\tY:\t"); Serial.print(mma.y); 
Serial.print("\tZ:\t"); Serial.print(mma.z); 
Serial.println();
  
  myFile = SD.open("test.txt", FILE_WRITE);

    // if the file opened okay, write to it:
  if (myFile) {

    myFile.print(Counter);
  
    myFile.print("\tX:\t");
    myFile.print(mma.x);
    
    myFile.print("\tY:\t");
    myFile.print(mma.y);
    
    myFile.print("\tZ:\t");
    myFile.println(mma.z);
    
    Counter ++;
    myFile.close();
            sensors_event_t event; 
            mma.getEvent(&event);

  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
  delay(50);
 
}

Kind regards hopefully someone give me a solution to do this on a nice and clean way.

Read this (by fat16lib):

Try this super fast analog pin logger

You can achieve 25.000 samples per second, that is 40uS interval.

yes thanks i saw those, but they are kind of hard to understand for me.
All i need is when i power onmy Mega it starts logging immediately and save the data to SD card.
Because the code is so big i do not know where to implement my part of reading the sensor data.

void loop() {
  mma.read();
Serial.print(Counter);
Serial.print("\tX:\t"); Serial.print(mma.x); 
Serial.print("\tY:\t"); Serial.print(mma.y); 
Serial.print("\tZ:\t"); Serial.print(mma.z); 
Serial.println();

that's all i need for this project.
power on --> stat logging --> power off --> sd in PC and data collecting.

delchrys:
The project is going to measure a couple of hours, 3 values (x,y,z) at 50ms. So there's not a lot of data, only one line: indexnumber (value), X(value), Y(value), Z(value).

When counting up " int Counter = 0;" each 50 milliseconds, the counter will overflow after 32767*50ms=1638 seconds.

If you want your program to run for hours, you maybe better use 'long' data type for counting the samples.

Besides of that: SD cards are organized in "sectors" of 512 bbytes each:

To achieve a hgh write rate, you sould collect your data in a buffer with a size of 512 bytes, and each time you have 512 bytes ready in the write buffer, then write a whole sector (512 bytes) at once to the SD card!

So one digit like for Instance "x" is one byte? So "x: 1209" is 7 byte including the space?
Or am I wrong?

And thank you for the heads up on the overflow of the counter. Forgot about that should have used long in the first place. :slight_smile:

I really like the lowlatencylogger but I see a lot of code that uses serial monitor input and I don't know a workaround for it. The buffer thingy is quite clever, but have to figure out how to do it. Seems I have a lot of reading to do.