Hi to all.
I made a 3 axis accelerometer/datalogger. This is very useful in physics class, - you can do the Gallilean dilution of gravity on a ramp experiment, and compare your raw adc counts to the angle of your slope. You can play with centripetal force and circular motion, and you can show that a falling object experiences no weight force (just like NASAs Vomit Comet). But best of all, duct taped onto a skateboard with an Estes rocket motor ....... XD
The SD card was from RobotBase via ebay (Arduino SD read-write memory module Mass Storage card),
and the accelerometer was also from ebay (MMA7260 Accelerometer Sensor Module 3-Axis Arduino AVR ).
Please enjoy, and I hope this is useful to someone.
The veroboard layout is here:
And the code is here:
/*
Datalogging accelerometer
Version: 0.2
Status: Incomplete
Last Modified: 19/04/2013
Author: Leon Harris
Description:
This circuit is designed to measure acceleration in the x,y, and z
axis, and to store them onto a micro-SD drive.
The user interface consists of a button to start and stop logging
data, and two leds to indicate status.
Two modules, both purchased from ebay, were incorporated into this design:
MMA7260 Accelerometer Sensor Module 3-Axis Arduino AVR
Arduino SD read-write memory module Mass Storage card (www.robobase.cn)
User Instructions.
The red led lights when the unit is in "halt" mode. To make it log
data, press the button once. The red led will extinguish, and the
white led will come on. The arduino will then open a file for
logging called "Basename" + N (where N is the number of the file it is up to).
Logging will then commence, once every ( int interval) milliseconds until the button is again pressed.
The file will be closed, the white led will flash the number of times that the
datafile ends in (to let the user know the number of that run), and then the
red led will be relit.
Action Red led White led status
- lit - halted
press button - lit recording data to file
press button lit flashing stop recording, flash file number to user
- lit - halted
*/
/*
Pin assignments
Analog pins
A1: y-axis
A2: x-axis
A0: z-axis
A4: ground //not used as analogue but rewired as digital gnd with pinMode()
A5: vcc //not used as analogue but rewired as digital vcc with pinMode()
Digital pins:
D2: Red led ("paused")
D3: White LED ("running")
D4: SS (chip select) for SD
D6: Button pin
D10: reserved, but not used, needed for SD library (do not use for anything else)
SPI Bus:
D11: MOSI for SD
D12: MISO for SD
D13: sck clock for SD
*/
//Includes
#include <SD.h> // library for using sd cards on SPI bus
#include <FlexiTimer2.h> // library for interrupts
// Code to define pins
const int groundpin = 18; // analog input pin 4 -- ground
const int powerpin = 19; // analog input pin 5 -- voltage
const int xpin = A2; // x-axis of the accelerometer
const int ypin = A1; // y-axis
const int zpin = A0; // z-axis (only on 3-axis models)
const int runningledpin = 3; // White led, used to indicate running
const int pauseledpin = 2; // Red led, used to indicate logging
const int buttonpin = 6; // test for now - will reassign pin
const int chipselect = 4; // ss pin for SD card
// set up runmode for program control/ led indication
boolean runmode = false;
// accelerometer variables
int x;
int y;
int z;
// Timer variables
long int logtime=0; // start time is zero
bool logflag=true;
int interval=100; //read sensors 100/1000 times per second
char BASEFILENAME[6] = "accel"; // this is the base filename for logging
char filename[14]; // this is the actual filename, which we will build later
int fcounter = 0; // this is the used to store the current filenumber
String dataString = ""; // a string to build output data into
void setup()
{
BASEFILENAME[5] = 0; // null terminate the name so sprintf can work
fcounter=1; // file counter
// initialize the serial communications:
Serial.begin(9600);
// Provide ground and power by using the analog inputs as normal
// digital pins. Think of it as ghetto current limitting to a 3.3v accelerometer !
pinMode(groundpin, OUTPUT);
pinMode(powerpin, OUTPUT);
digitalWrite(groundpin, LOW);
digitalWrite(powerpin, HIGH);
//set the leds to off
pinMode(runningledpin, OUTPUT);
pinMode(pauseledpin, OUTPUT);
digitalWrite(pauseledpin, HIGH);
digitalWrite(runningledpin, LOW);
//initialise the button
pinMode(buttonpin, INPUT);
digitalWrite(buttonpin, HIGH); // turn on internal pullup resistor
// set up the SD card
Sd2Card card;
SD.begin(chipselect);
pinMode(10, OUTPUT); // even if not used by the card, sd library breaks if 10 is not output
if (!card.init(SPI_HALF_SPEED, chipselect)) {
flashError();
}
}
// int readAccel(int* x, int* y, int* z) {
// *x=analogRead(xpin);
// *y=analogRead(ypin);
// *z=analogRead(zpin);
// return(*x,*y,*z);
//}
void pollbutton() {
if (digitalRead(buttonpin)== LOW) {
runmode = !runmode;
delay(200); // debounce the switch for 200 msec
}
return;
}
void flashError(){
// this function flashes to signal a missing, damaged
// or write protected SD card
for (int i=0; i < 4; i++) {
digitalWrite(pauseledpin,LOW);
digitalWrite(runningledpin,LOW);
delay(250);
digitalWrite(pauseledpin,HIGH);
digitalWrite(runningledpin,HIGH);
delay (250);
}
digitalWrite(pauseledpin,LOW);
}
void flashFilenumber(int suffix) {
// this function flashes the white led a number of times
// corresponding to the file number that has just been written
while (suffix >= 0) {
digitalWrite(runningledpin, HIGH);
delay (250);
digitalWrite(runningledpin, LOW);
delay(250);
suffix--;
}
return;
}
void readAccel() {
// interupt routine
// Increase logtime by Interval
logtime += interval;
logflag=true;
//readAccel(&x, &y, &z);
x=analogRead(xpin);
y=analogRead(ypin);
z=analogRead(zpin);
}
void loop()
{
pollbutton();
if (runmode){
sprintf(filename, "%s%02i.txt", BASEFILENAME, fcounter);
File dataFile = SD.open(filename, FILE_WRITE);
if (! dataFile){
Serial.println("Gaaaah, cant open File");
}
// set up an interval timer to trigger every interval * 1000 mseconds.
// when interupt triggers, fire off readAccel subroutine.
FlexiTimer2::set(interval, 1.0/1000, readAccel);
FlexiTimer2::start();
while (runmode) {
pollbutton();
digitalWrite(pauseledpin,LOW);
digitalWrite(runningledpin,HIGH);
// readAccel(&x, &y, &z);
if (logflag) {
logflag=false;
dataString = String(logtime);
dataString += "\t";
dataString += String(x);
dataString += "\t";
dataString += String(y);
dataString += "\t";
dataString += String(z);
Serial.println(dataString);
dataFile.println(dataString);
if (! dataFile) {
Serial.println("CANT WRITE TO FILE !!!!!!!");
}
}
}
FlexiTimer2::stop(); // disable interupts until a new run
logtime=0; // reset clock for new run
logflag=true;
dataFile.close(); // close the file
flashFilenumber(fcounter); // done at the end of file writing to make timing easier for the user
fcounter++;
}
digitalWrite(pauseledpin,HIGH);
digitalWrite(runningledpin,LOW);
}