Go Down

Topic: Fast microSD code modification (Read 929 times) previous topic - next topic

fore4runner

Hello,

I've been modifying code developed by Fat16lib (it can be found here) http://code.google.com/p/beta-lib/downloads/list under fastLoggerBeta20110802.zip 

Basically, I am doing a project where I am looking to write acceleration values from an adxl345 accelerometer to an SD card as fast as possible (at least 1500 samples per second without dropping data points).  The code presented in the link under 'fastlogger.pde' seems to do this quite well.  However, I am having a great deal of trouble modifying the example code to get it to write my data.

So this is what I have (from the example code):

Code: [Select]
// I2C binary logger example

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

SdFat sd;

SdFile file;

#define error(msg) sd.errorHalt_P(PSTR(msg))
//------------------------------------------------------------------------------
bool over = false;
//------------------------------------------------------------------------------
const uint16_t RING_DIM = 600;
uint8_t ring[RING_DIM];
volatile uint16_t head = 0;
volatile uint16_t tail = 0;
uint32_t syncCluster = 0;
//------------------------------------------------------------------------------
// buffer data from I2C
void receiveEvent(int howMany) {
  for (int i = 0; i < howMany; i++) {
    ring[head] = Wire.receive();
    uint16_t next = head < (RING_DIM - 1) ? head + 1 : 0;
    // check for space
    if (next != tail) {
      // space so advance head
      head = next;
    } else {
      // can't advance head so data is dropped
      over = true;
    }
  }
}
//------------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  Serial.println("Type any character to start");
  while (!Serial.available());
  Serial.print("FreeRam: ");
  Serial.println(FreeRam());
 
  if (!sd.init()) sd.initErrorHalt();
  if (!file.open("I2C_TEST.TXT", O_WRITE | O_CREAT | O_TRUNC)) error("open");
  file.print("Start ");
  file.println(millis());
  file.sync();
 
  syncCluster = file.curCluster();
  Serial.println("Started - type any character to stop");
  Serial.flush(); 

  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
}
//------------------------------------------------------------------------------
void loop() {
  uint16_t n;
  uint16_t next;
  // disable interrupts to get 16-bit head
  cli();
  uint16_t h = head;
  sei();
 
  if (h != tail) {
    if (tail < h) {
      // amount to write
      n = h - tail;
      // new tail
      next = h;
    } else {  // h < tail
      // amount to write
      n = RING_DIM - tail;
      // new tail
      next = 0;
    }
    if (file.write(&ring[tail], n) != n) error("write");
    cli();
    tail = next;
    sei();
  }
  if (file.curCluster() != syncCluster) {
    if (!file.sync()) error("sync");
    syncCluster = file.curCluster();
  }
  if (!Serial.available() && !over) return;
  cli();
  file.print("Stop ");
  file.println(millis());
  file.close();
  if (over) error("overrun");
  Serial.println("stoped");
  while(1);
}


And this is my function that I use (in a slower datalogger) to get the data from teh ADXL345:

Code: [Select]
// Reads x,y and z accelerometer registers
void Read_Accel()
{
  int i = 0;
  byte buff[6];
 
  Wire.beginTransmission(AccelAddress);
  Wire.send(0x32);        //sends address to read from
  Wire.endTransmission(); //end transmission
 
  Wire.beginTransmission(AccelAddress); //start transmission to device
  Wire.requestFrom(AccelAddress, 6);    // request 6 bytes from device
 
  while(Wire.available())   // ((Wire.available())&&(i<6))
  {
    buff[i] = Wire.receive();  // receive one byte
    i++;
  }
  Wire.endTransmission(); //end transmission
 
    if (i==6){  // All bytes received?
       accel_x = (((int)buff[1]) << 8) | buff[0];    // X axis (internal sensor x axis)
       accel_y = (((int)buff[3]) << 8) | buff[2];    // Y axis (internal sensor y axis)
       accel_z = (((int)buff[5]) << 8) | buff[4];    // Z axis
     }else{
       Serial.println("!ERR: Error reading accelerometer info!");
     }
}


So I can load my data in, I'm just not sure how to get it into the example code (what variable to assign it as, etc) so that it gets uploaded to the SD card.

Any advice would be greatly appreciated.

Cheers,

Andre
 

fore4runner

I received this reply (hope this might be of help to someone in the future):

"Wire uses interrupts so it won't work well with the fastLogger examples which read data in interrupt routines.... People have logged data from accelerometers at high speed using SdFat but from SPI based devices."

So it looks like I just need to communicate with the adxl345 through SPI to get the higher sampling rates.

Go Up