Project: Arduino Accelerometer Logging Sheild
Alright this is my first time posting a full project, so be gentle if i make any mistakes. Also the project is still ongoing but a few people emailed me asking for details and schematics. So I will be making updates and I will note any updates.
Concept: I had received a few MMA7260 3-Axis Accelerometers as samples and wanted to do something cool with them. The project started out as a interface just to play with the Accelerometers, but then I realized I had a Micro SD socket that I had got from Molex and a 512MB Micro SD card that I was not using.
Hardware: OK so first I started off with a 3.3V Arudino Pro from Sparkfun.com . Its important to note that all of the devices I use for this project are 3.3v logic and power if you are using a 5v Arduino then you must take this into account, it will affect the way that you interface and power the chip and the SD card and will require a different schematic.
Parts Used:
4x 10K Resistors
4x 4.7K Resistors
4x 0.1uf Capacitors
1x MMA7260 3-Axis Accelerometer
1x MicroSD Socket
1x Pushbutton Switch
Schematic:
Firmware: The firmware is not totally finished at the moment and may have a few bugs. First of to compile my code in the Arduino IDE your going to have to download the fat16lib library and put it in your “\arduino-0015\hardware\libraries” folder, it is a really a great library and makes logging to a .txt file very simple.
/*
* Accelerometer data logger
* with LCD and MicroSD
* Curtis F.
*
*/
#include <EEPROM.h>
// SD Card includes
#include "Fat16.h"
#include "SdCard.h"
SdCard card;
Fat16 file;
// end
#include <avr/io.h>
#include <avr/wdt.h>
#define Reset_AVR() wdt_enable(WDTO_30MS); while(1) {}
int buttonPin = 5; //button Pin
int GS1Pin = 2; //Gravity Select Pin 1
int GS2Pin = 3; //Gravity Select Pin 2
int AccSleepPin = 4; // Accelorometer sleep pin for enable/disable
int X, Y, Z; // Raw ADC values for XYZ
int sendtoserial = 0;
int samplestaken = 0;
int isLoggingData = 1;
int val = 0;
void setup()
{
pinMode(buttonPin, INPUT);
pinMode(GS1Pin, OUTPUT);
pinMode(GS2Pin, OUTPUT);
pinMode(AccSleepPin, OUTPUT);
Serial.begin(19200);
Serial.println("Accelerometer data logger");
analogReference(EXTERNAL); // ser ADC voltage ref to 3.3 external
digitalWrite(GS1Pin, LOW); // set inital 1.5G sensitiviy
digitalWrite(GS2Pin, LOW);
digitalWrite(AccSleepPin, HIGH); // turn on Accelorometer
sendtoserial = EEPROM.read(1);
//SD card Int
intcardfunction();
// End
if (sendtoserial == 0) Serial.println("MicroSD Log");
}
void loop()
{
while (1) {
X = analogRead(2); // store values
Y = analogRead(1);
Z = analogRead(0);
if (sendtoserial == 1) {
Serial.print(40, BYTE); // print "(" charcater
Serial.print(X); // send raw values out serial port
Serial.print(Y);
Serial.print(Z);
Serial.println(41, BYTE); // print ")" charcater
delay(5);
val = digitalRead(buttonPin); // read input value
if (val == HIGH) { // check if the input is HIGH
while (digitalRead(buttonPin) == HIGH){}
Serial.println("Reset_AVR();");
EEPROM.write(1, 0);
Reset_AVR(); //reset to load to default MicroSD logging mode
}
}
if (sendtoserial == 0) {
logtosdcard();
val = digitalRead(buttonPin); // read input value
if (val == HIGH) { // check if the input is HIGH
EEPROM.write(1, 1);
while (digitalRead(buttonPin) == HIGH){}
Serial.println("Reset_AVR();");
Reset_AVR(); //reset to load to default MicroSD logging mode
}
}
serbPollSerialPort(); // listen on serial port for commands
}
delay(1);
}
void intcardfunction()
{
if (!card.init()) error("card.init"); // initialize
if (!Fat16::init(card, 1)) {
// try super floppy
if (!Fat16::init(card, 0)) error("Fat16::init");
}
}
void logtosdcard()
{
char name[] = "LOG-00.TXT";
for (uint8_t i = 0; i < 254; i++) {
name[4] = i/10 + '0';
name[5] = i%10 + '0';
if (file.create(name)) break;
}
if (!file.isOpen()) error ("file.create");
file.print(millis());
file.print(":");
file.print(40, BYTE);// print "(" charcater
file.print(X, DEC);
file.print(",");
file.print(Y, DEC);
file.print(",");
file.print(Z, DEC);
file.println(41, BYTE);// print ")" charcater
samplestaken++ ;
if (samplestaken > 15)
{
file.sync();
samplestaken = 0;
}
}
void serbPollSerialPort()
{
int dta; //variable to hold the serial byte
if ( Serial.available() >= 5) { //if 5 bytes are in the buffer (length pf a full request)
dta = Serial.read();
if ( dta = 65){ //Checks for first check byte "A"
dta = Serial.read();
if ( dta = 65){ //Checks for second check byte "A"
dta = Serial.read();
if ( dta = 65){ //Checks for third check byte "A"
int command = Serial.read(); //Fourth byte is the command
int param1 = Serial.read(); //Fifth byte is param1
interpretCommand(command, param1); //sends the parsed request to it's handler
}
}
}
}
}
void interpretCommand(int command, int param1)
{
if (command == 83){ // If command = "S" then
switch (param1) {
case 49: // case command parameter = "1"
digitalWrite(AccSleepPin, LOW); // turn off Accelorometer
delay(100);
digitalWrite(GS1Pin, LOW); // change to 1.5G sensitivity
digitalWrite(GS2Pin, LOW);
delay(400);
Serial.flush(); // clear buffer
digitalWrite(AccSleepPin, HIGH); // turn on Accelorometer
break;
case 50: // case command parameter = "2"
digitalWrite(AccSleepPin, LOW);
delay(100);
digitalWrite(GS1Pin, LOW);// change to 2G sensitivity
digitalWrite(GS2Pin, HIGH);
delay(400);
Serial.flush(); // clear buffer
digitalWrite(AccSleepPin, HIGH); // turn on Accelorometer
break;
case 51: // case command parameter = "3"
digitalWrite(AccSleepPin, LOW);
delay(100);
digitalWrite(GS1Pin, HIGH);// change to 4G sensitivity
digitalWrite(GS2Pin, LOW);
delay(400);
Serial.flush(); // clear buffer
digitalWrite(AccSleepPin, HIGH); // turn on Accelorometer
break;
case 52: // case command parameter = "4"
digitalWrite(AccSleepPin, LOW);
delay(100);
digitalWrite(GS1Pin, HIGH);// change to 6G sensitivity
digitalWrite(GS2Pin, HIGH);
delay(400);
Serial.flush(); // clear buffer
digitalWrite(AccSleepPin, HIGH); // turn on Accelorometer
break;
}
}
if (command == 69){ // if command = "E" then
switch (param1) {
case 69: // case command parameter = "E"
digitalWrite(AccSleepPin, HIGH);
Serial.flush();
break;
case 68: // case command parameter = "D"
digitalWrite(AccSleepPin, LOW);
Serial.flush();
break;
}
}
}
void error(char *str)
{
sendtoserial = 1;
Serial.print("error: ");
Serial.println(str);
}
Software: Here is a quick VB6 program I threw together to visualize the data. Im working on making it read log files and play them back but that feature is not done yet. Please beware this program was written fast and without comments its sloppy and hard to read. Its just for debugging. Here is the Source.
Function: The Device has 2 modes logging and streaming. To Enter serial mode to allow for use of the PC program and streaming data you hold the push button for 2 seconds during power on. Otherwise the device will automatically start logging a *.txt file to a MicroSD card with the time(in milliseconds since power on) and XYZ values. The text file can easily be parsed in or some other spreadsheet program and made into line graphs. If no MicroSD card for 30 seconds or so(not my control) it will start to send serial data. You can change the mode while logging or streaming by pressing the button once this will put it into the opposite mode.
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Thanks for the useful info. It’s so interesting
Do you think can I connect one of these accelerometers to arduino without any additional circuitry? I don’t need precise reading, just need to detect move for anti-theft putrpose.
http://it.farnell.com/stmicroelectronics/lis302dl/accelerometro-3-assi-lga-14-302/dp/1435588
http://it.farnell.com/memsic/mxc62020jv/accelerometro-2-assi-2-0g-i2c/dp/1365602
http://it.farnell.com/freescale-semiconductor/mma7341lt/accelerometer-3g-xyz-14lga/dp/1659489
The first 2 you linked are serial type accelerometers. The 3rd, MMA7341LT one can be used like i did with minimal extra hardware. That data sheet just shows some caps on the XYZ lines but you could probly get away without them if you dont need it to be accurate and are useing it for only anti-theft type setup.