Accelerometer Data to be Stored on SD card

Status
Not open for further replies.

Mike_B

New member
Hi Everyone,

I'm currently working on a small project to measure movement around the human foot.
I'm using the MMA8452Q accelerometer module off sparkfun to get raw data. It's 12 bits of resolution and i'm using it as +- 8g. so every bit is worth 3.9mg.

I'm using a Teensy 3.1 to store the data but i want to store it on SD. This is where i came across an SD Storage module on the Teensy website.
https://www.pjrc.com/store/sd_adaptor.html

I set the SD storage module up like that shown in:
https://forum.pjrc.com/threads/16758-Teensy-3-MicroSD-guide

I got the SD card to work for a simple program (read/write on Arduinos sample programs) but i'm finding it hard to incorporate it into my accelerometer code. (Code below)
All I'm looking for it the data from the accelerometer to be saved onto the SD so it can be put into another device and then you can do some analysis on it.
I was wondering would anybody have any ideas on how I can get the both to work together?
Any help will be greatly appreciated.

Regards,
Mike

Results from Accelerometer:

Accelerometer Readings.png

Accelerometer with Teensy:

Teensy plus Accle.png



Code for Accelerometer Working:

Code:
#include <Wire.h> // Used for I2C

// The SparkFun breakout board defaults to 1, set to 0 if SA0 jumper on the bottom of the board is set
#define MMA8452_ADDRESS 0x1D  // 0x1D if SA0 is high, 0x1C if low

//Define a few of the registers that we will be accessing on the MMA8452
#define OUT_X_MSB 0x01
#define XYZ_DATA_CFG  0x0E
#define WHO_AM_I   0x0D
#define CTRL_REG1  0x2A

#define GSCALE 8 // Sets full-scale range to +/-2, 4, or 8g. Used to calc real g values.
int led = 13;


void setup()
{
  pinMode(led, OUTPUT);
    
  Serial.begin(9600);

  Serial.println("MMA8452 Basic Example");

  Wire.begin(); //Join the bus as a master
 
  initMMA8452(); //Test and intialize the MMA8452
 
}

void loop()
{  
  uint8_t rawData[6];  // x/y/z accel register data stored here

  readRegisters(OUT_X_MSB, 6, rawData);  // Read the six raw data registers into data array
 
  
  
  int16_t x_value = ((rawData[0] << 8) | rawData[1]);       // shifts the value of the high value of x by 8 bits to the left then "or"s it with the low value of x 
  int16_t y_value = ((rawData[2] << 8) | rawData[3]);       // shifts the value of the high value of y by 8 bits to the left then "or"s it with the low value of y
  int16_t z_value = ((rawData[4] << 8) | rawData[5]);       // shifts the value of the high value of z by 8 bits to the left then "or"s it with the low value of z
  
  x_value = x_value / 0x10;
  y_value = y_value / 0x10;
  z_value = z_value / 0x10;
  
  Serial.print(x_value);      // Prints the value of x but because the shifting we need to divide by 0x10 i.e 16 in hex to get the values back to near 0.
  Serial.print(",");
  Serial.print(y_value);
  Serial.print(",");
  Serial.print(z_value);
  Serial.println();
  delay(100);  //Delay here for visibility
}



// Initialize the MMA8452 registers 
void initMMA8452()
{
  byte c = readRegister(WHO_AM_I);  // Read WHO_AM_I register
  
  if (c == 0x2A) // WHO_AM_I should always be 0x2A
  {  
    Serial.println("MMA8452Q is online...");
  }
  else
  {
    Serial.print("Could not connect to MMA8452Q: 0x");
    Serial.println(c, HEX);
    while(1) ; // Loop forever if communication doesn't happen
  }

  MMA8452Standby();  // Must be in standby to change registers

  // Set up the full scale range to 2, 4, or 8g.
  byte fsr = GSCALE;
  if(fsr > 8) fsr = 8; //Easy error check
  fsr >>= 2; // Neat trick, see page 22. 00 = 2G, 01 = 4A, 10 = 8G
  writeRegister(XYZ_DATA_CFG, fsr);

  //The default data rate is 800Hz and we don't modify it in this example code

  MMA8452Active();  // Set to active to start reading
}

// Sets the MMA8452 to standby mode. It must be in standby to change most register settings
void MMA8452Standby()
{
  byte c = readRegister(CTRL_REG1);
  writeRegister(CTRL_REG1, c & ~(0x01)); //Clear the active bit to go into standby
}

// Sets the MMA8452 to active mode. Needs to be in this mode to output data
void MMA8452Active()
{
  byte c = readRegister(CTRL_REG1);
  writeRegister(CTRL_REG1, c | 0x01); //Set the active bit to begin detection
}

// Read bytesToRead sequentially, starting at addressToRead into the dest byte array
void readRegisters(byte addressToRead, int bytesToRead, byte * dest)
{
  Wire.beginTransmission(MMA8452_ADDRESS);
  Wire.write(addressToRead);
  Wire.endTransmission(false); //endTransmission but keep the connection active

  Wire.requestFrom(MMA8452_ADDRESS, bytesToRead); //Ask for bytes, once done, bus is released by default

  while(Wire.available() < bytesToRead); //Hang out until we get the # of bytes we expect

  for(int x = 0 ; x < bytesToRead ; x++)
    dest[x] = Wire.read();    
}

// Read a single byte from addressToRead and return it as a byte
byte readRegister(byte addressToRead)
{
  Wire.beginTransmission(MMA8452_ADDRESS);
  Wire.write(addressToRead);
  Wire.endTransmission(false); //endTransmission but keep the connection active
     digitalWrite(led, HIGH);
  Wire.requestFrom(MMA8452_ADDRESS, 1); //Ask for 1 byte, once done, bus is released by default

  while(!Wire.available()) ; //Wait for the data to come back
  return Wire.read(); //Return this one byte
}

// Writes a single byte (dataToWrite) into addressToWrite
void writeRegister(byte addressToWrite, byte dataToWrite)
{
  Wire.beginTransmission(MMA8452_ADDRESS);
  Wire.write(addressToWrite);
  Wire.write(dataToWrite);
  Wire.endTransmission(); //Stop transmitting
}
 
Last edited:
Status
Not open for further replies.
Back
Top