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
/* | |
// | |
// 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