Go Down

Topic: Accelerometer and datalogger (Read 1 time) previous topic - next topic

Harristotle

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:

Code: [Select]
/*
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);
   

       
   
 }

dtokez

Thanks for sharing! Looks cool, I will certainly be looking into this when I have finished some other projects :)

Go Up