Accelerometer Shield and Code

FWETP1JH82UHLAH.RECTANGLE1Screen Shot 2012-12-04 at 11.29.18 AMDuring a physics class we were preforming a physics experiment to measure the accleration due to graivty – 9.8m/s^2 and while we did not make any new discoveries, I had an idea for improving the experiment. The way the experiment worked was to drop a NXT with an attached acclerometer off of a balcony and some one below would catch it. The problem was that if they missed it $200 would hit the ground and shatter. After some research I found that for < $20 you can build a Shield with an accelerometer that works just as well and has less signal noise.

A few benefits to the MMA7361 Acceleromter are that it can be set to detect +/- 1.5g or +/-6g. It also has a very low power consumption and its small size even with the breakout board makes it an ideal fit for any project.

Materials

1x Arduino Uno (a Mega will allow you to store more data, but it is also bigger and more expensive)1x MMA7361 Acceleromter – Sparkfun has one with a breakout board
1x Proto shield/perf board

Soldering Iron and solder

Headers
Wire
LEDs
Push buttonsResistors
On/Off switch

Connection

Solder all of the pins on the accelerometer to their appropriate header pin.

Sleep – 13
SelfTest/STP – 12
ZeroG/0G – 11
Gselect/GSel – 10
X axis – A0
Y axis – A1
Z axis – A2VDD – 3.3 V

Then hookup 2 LEDs to any two pins and 2 pushbuttons to any other two pins.

FLO3N9SH82UHLAM.MEDIUM

FK46TNXH82UHLB2.MEDIUM

Programming

There are only a few variables that you need to change based on what you want to record.

You will also need to add the accelerometer library. If you have not added a library before create a folder called “libraries” in your Arduino sketch folder and then drop the accelerometer folder inside of the “libraries” folder.

total_points – controls the number of recorded data points

const unsigned long loop_time – controls how often data is recorded ex. 5 corresponds to 5ms between each recording.

The maximum number of data points that can be collected on the Arduino SRAM is roughly 700. Additional data points may be collected with a SD card.

The scaling factor for the values found “x” is: ((x/100)-1) * acceleration due to gravity). Acceleration to gravity roughly equals 9.8 . The scaled values are in units of m/s^2.

Ex. in free fall it will read 0 so (0-1)*9.8 = -9.8m/s^s. At rest it will read 1 so (1-1) * 9.8 = 0.

The LEDs correspond to each of the buttons and the following action. The button farthest from the accelerometer turns the green LED on and records values. The LED will turn off when pressed again and values will stop being collected. The red LED corresponds to the button closest to the accelerometer and lights up when values are being transmitted to the serial monitor.

The red LED will flash twice at the beginning to indicate that the start up loop and calibration has completed and data can now now be collected. When calibrating make sure that the accelerometer does not move and is on a relatively flat surface.

The most basic code for this to make sure everything is working is the first program below.
When rested flat on something the Z axis should read roughly 1 and the X and Y axis 0 each. This is because there is no acceleration in the x/y directions and gravity is pulling down in the Z direction.

Sample Code:

int x;
int y;
int z;
void setup()
{
Serial.begin(9600);
accelero.begin(13, 12, 11, 10, A0, A1, A2);
accelero.setARefVoltage(5); //sets the AREF voltage to 3.3V
accelero.setSensitivity(LOW); //sets the sensitivity to +/-6G
accelero.calibrate();
}
void loop()
{
x = accelero.getXAccel();
y = accelero.getYAccel();
z = accelero.getZAccel();
Serial.print("\nx: ");
Serial.print(x);
Serial.print(" \ty: ");
Serial.print(y);
Serial.print(" \tz: ");
Serial.print(z);
Serial.print("\tG*10^-2");
delay(500); //make it readable
}

Program Code

</div></pre>
<div>
<pre><div>

#include <AcceleroMMA7361.h> // accelerometer library
AcceleroMMA7361 accelero; // initialize library
unsigned long lastTime; // used to compare time
const unsigned long loop_time = 5; // how many times a second does it collect data ex. 50 equals every 50ms
boolean startup; // test w/ true or false
int x; // x axis
int y;
int z;
int magnitude = 0;

int record = 0; // record the data
int bite_size = 0; //not use right now
int pushButton1 = 2; // button 1
int prevState1 = LOW; // comparer to state of button 1
int pushButton2 = 3;
int prevState2 = LOW;
int printer = 0; // does it send the data to serial monitor or not

int myStrings[700]={};
int counter = 0;
int total_values = 0;

int total_points = 700;

void setup()
{
 Serial.begin(9600);
 accelero.begin(13, 12, 11, 10, A0, A1, A2); // pins used for accelerometer
 accelero.setARefVoltage(5); //sets the AREF voltage to 3.3V
 accelero.setSensitivity(LOW); //sets the sensitivity to +/-6G
 accelero.calibrate(); // calibrate the sensor
 sum = 0;
 pinMode(A5,OUTPUT); // pin A5 connected to LED
 pinMode(pushButton1, INPUT); // voltage increase when pins is pressed so pins detect HIGH or LOW
 pinMode(pushButton2, INPUT);
 pinMode(7,OUTPUT);
 delay(50);

}
void loop()
{
if(startup == false){ // has the startup function been run
startsup(); // blink A5 twice to signal that everything is ready and setup has completed
}
int currState1 = digitalRead(pushButton1); // read the state of push button 1
int currState2 = digitalRead(pushButton2);
if (currState1 != prevState1){
 record = record + 1; // add 1 to record
 delay(350); // wait until push is competed so it does not record change twice
}
if (currState2 != prevState2){ // test whether state of pushbutton has changed
 printer = printer + 1;
 delay(350);
}
if (record == 1){
 collect();
 digitalWrite(7,HIGH); // light up 7 to indicate that data is being collected
}
if (record == 2){ //set record back to 0 so that record does not go 3,4,5....
 record = 0;
 digitalWrite(7,LOW);// turn off indicator light
lastTime = millis() - loop_time; // make sure that lastTime keeps up with the time so that it does not record the entire time
}
if (record == 0){
 digitalWrite(7,LOW);
 lastTime = millis() - loop_time;
}
if (printer == 1){
 send_data();
}
if (printer == 2){
 printer = 0;
}
if (printer == 0 ){
 digitalWrite(A5,LOW);
}

} // end of main loop

&nbsp;

void collect(){ // function that collects the data
if(millis() - lastTime > loop_time){ //has it been x ms and time to run loop agian
x = accelero.getXAccel(); // collect on x axis
y = accelero.getYAccel();
z = accelero.getZAccel();
magnitude = sqrt((x*x)+(y*y)+(z*z)); // magnitude of the 3 axis
if (counter <= total_points){
myStrings[counter] = magnitude;
counter = counter + 1;
total_values = total_values + 1;
}
else{
 counter = total_points;
 total_values = total_points;
}

lastTime += loop_time; // add time so that loop does not run forever
}
}

void startsup(){ // function that blinks A5 twice to signal everything is ready
digitalWrite(A5,HIGH);
delay(500);
digitalWrite(A5,LOW);
delay(500);
digitalWrite(A5,HIGH);
delay(500);
digitalWrite(A5,LOW);
startup = true;
}

void send_data(){ // function to send the data
delay(100);
digitalWrite(A5,HIGH);
Serial.print("Here it is: "); // start of data
for (counter = 0; counter < total_values; counter = counter + 1) {
 Serial.println(myStrings[counter]);
}
Serial.println("# of Data points:");
Serial.println(total_values);
delay(100);
digitalWrite(A5,LOW);
printer = 0; // reset all values meanin all data wiped and ready to run agian
sum = 0;
magnitude = 0;
counter = 0;
total_values = 0;
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s