Skip to content

Instantly share code, notes, and snippets.

@nataliefreed
Last active December 30, 2015 10:28
Show Gist options
  • Save nataliefreed/7815633 to your computer and use it in GitHub Desktop.
Save nataliefreed/7815633 to your computer and use it in GitHub Desktop.
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