Arduino MMA7361 accelerometer (Sparkfun breakout https://www.sparkfun.com/products/9652)Implementation of the math from this excellent guide: http://www.starlino.com/imu_guide.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
// | |
// Code for MMA7361 accelerometer (Sparkfun breakout https://www.sparkfun.com/products/9652) | |
// Natalie Freed | |
// 12-5-2013 | |
// | |
// Implementation of the math from this excellent guide: http://www.starlino.com/imu_guide.html | |
// | |
// | |
*/ | |
/***********************************************************/ | |
/****************** Accelerometer ****************ar******/ | |
/***********************************************************/ | |
int x, y, z; //raw analog values | |
float x_avg, y_avg, z_avg; //smoothed values | |
float rx, ry, rz; //smoothed value in number of gs (one g = 9.8 m/s^2) | |
float tiltAngle; | |
float vref; | |
float vzerog; | |
float sensitivity; | |
void initAcc() | |
{ | |
vref = 5.0; //voltage reference | |
vzerog = 1.65; //voltage at zero g, as specified by accelerometer datasheet | |
sensitivity = 0.8; //output voltage produced by a certain force, as specified in datasheet | |
} | |
/***********************************************************/ | |
void setup() | |
{ | |
delay(1000); | |
initAcc(); | |
Serial.begin(9600); | |
pinMode(12, INPUT_PULLUP); | |
} | |
void loop() | |
{ | |
updateAcc(); | |
delay(500); | |
} | |
void updateAcc() | |
{ | |
//raw accelerometer values | |
x = analogRead(A0); | |
y = analogRead(A1); | |
z = analogRead(A2); | |
Serial.print(x); | |
Serial.print('\t'); | |
Serial.print(y); | |
Serial.print('\t'); | |
Serial.print(z); | |
Serial.print('\t'); | |
Serial.println(); | |
//smoothed values | |
x_avg = expMovingAvg(x, 0.1, x_avg); | |
y_avg = expMovingAvg(y, 0.1, y_avg); | |
z_avg = expMovingAvg(z, 0.1, z_avg); | |
//smoothed values in number of gs (one g = 9.8 m/s^2) | |
rx = (x_avg*vref/1023-vzerog) / sensitivity; | |
ry = (y_avg*vref/1023-vzerog) / sensitivity; | |
rz = (z_avg*vref/1023-vzerog) / sensitivity; | |
//angle accelerometer is tilted from vertical, in radians (exact only if it is at rest) | |
tiltAngle = acos( (rx*0 + ry*0 + rz*-1) / (sqrt(sq(rx) + sq(ry) + sq(rz)) * sqrt(sq(0) + sq(0) + sq(-1))) ); | |
Serial.print("tilt angle: "); | |
Serial.println(tiltAngle); | |
} | |
//Exponential moving average, weight on new value | |
float expMovingAvg(float new_val, float weight_on_new, float avg) | |
{ | |
return avg + weight_on_new*(new_val - avg); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment