No, each count measures 5/1024 = 4.88mV.
Oops, right. A reciprocal brain slip. And thanks for the correction of my analysis. I see now.
In other words, a tilt of 1 degree from horizontal will give a reading change of 2 counts.
Five degrees gives 12 counts.
It seems that should be good enough for my app.
I have noticed that you haven't posted any of your code yet. Taking a look at that might help us figure out why your noise filtering code isn't working they way you expect.
My test program is below. All critique appreciated. I ran it and have put a file with the serial output here.
I had the accelerometer breakout board plugged into a small breadboard not mounted on the Arduino board. I let it just run without touching it, then towards the end picked it up and rotated it around and set it back down.
The noise, with the averaging, seems to be +/- 1 count, which is pretty good I think, since that is less than 1 degree of tilt. To be expected? Should I not worry about trying to filter the data to be perfectly flat?
Thanks to all for all the generous advice. Now on to the real math to actually do stuff with the data!
.ad
/* ADXL335test6
Test of ADXL335 accelerometer
Andy Davidson
*/
const boolean debugging = true; // whether to print debugging to serial output
const boolean showBuffer = false; // whether to dump details of ring buffer at each read
const int xPin = 3; // analog: X axis output from accelerometer
const int yPin = 1; // analog: Y axis output from accelerometer
const int zPin = 2; // analog: Z axis output from accelerometer
const int led = 13; // just to blink a heartbeat while running
const int totalAxes = 3; // for XYZ arrays: 0=x, 1=y, 2=z
const int baseSamples = 1000; // number of samples to average for establishing zero g base
const int bufferSize = 16; // number of samples for buffer of data for running average
const int loopBlink = 100; // number of trips through main loop to blink led
// array of pin numbers for each axis, so the constants above can be chnaged with impunity
const int pin [totalAxes] = {
xPin, yPin, zPin};
// base value for each axis - zero g offset (at rest when sketch starts)
int base [totalAxes];
// ring buffer for running average of data, one for each axis, each with <bufferSize> samples
int buffer [totalAxes] [bufferSize];
// index into ring buffer of next slot to use, for each axis
int next [totalAxes] = {
0,0,0};
// current values from each axis of accelerometer
int curVal [totalAxes];
// count of trips through main loop, modulo blink rate
int loops = 0;
void setup() {
long sum [totalAxes]= { // accumulator for calculating base value of each axis
0,0,0 };
Serial.begin (9600);
Serial.println ("***");
// initialize all pins
pinMode (led, OUTPUT);
for (int axis=0; axis<totalAxes; axis++)
pinMode (pin [axis], INPUT); // not necessary for analog, really
// read all axes a bunch of times and average the data to establish zero g offset
// chip should be at rest during this time
for (int i=0; i<baseSamples; i++)
for (int axis=0; axis<totalAxes; axis++)
sum [axis] += analogRead (pin [axis]);
for (int axis=0; axis<totalAxes; axis++)
base [axis] = round (sum [axis] / baseSamples);
// and display them
Serial.print ("*** base: ");
for (int axis=0; axis<totalAxes; axis++) {
Serial.print (base [axis]);
Serial.print ("\t");
}
Serial.println ();
Serial.println ("***");
// initialize the ring buffer with these values so the averaging starts off right
for (int axis=0; axis<totalAxes; axis++)
for (int i=0; i<bufferSize; i++)
buffer [axis] [i] = base [axis];
// light up the led and wait til the user is ready to start (sends anything on serial)
// so that the base values don't immediately shoot off the top of the serial window
digitalWrite (led, HIGH);
while (!Serial.available())
/* wait for <RETURN> */ ;
digitalWrite (led, LOW);
}
void loop() {
//increment the loop counter and blink the led periodically
loops = (loops + 1) % loopBlink;
digitalWrite (led, loops == 0);
// get new data from each axis by calling a routine that returns
// the running average, instead of calling analogRead directly
for (int axis=0; axis<totalAxes; axis++) {
curVal [axis] = getVal (axis, showBuffer);
if (debugging) {
Serial.print (curVal [axis]);
Serial.print ("\t");
}
}
if (debugging)
Serial.println ();
// here we will do all of the real work with curVals
}
int getVal (int axis, boolean show) {
// returns the current value on <axis>, averaged across the previous <bufferSize> reads
// print details if <show> is true
long sum; // to hold the total for aaveraging all values in the buffer
// read the data into the next slot in the buffer and stall for a short time
// to make sure the ADC can cleanly finish multiplexing to another pin
buffer [axis] [next [axis]] = analogRead (pin [axis]);
delay (10); // probably not necessary given the stuff below
// display the buffer if requested
if (show) {
for (int i=0; i<bufferSize; i++) {
if (i == next [axis]) Serial.print ("*");
Serial.print (buffer [axis] [i]);
Serial.print (" ");
}
Serial.println ();
}
// bump up the index of the next available slot, wrapping around
next [axis] = (next [axis] + 1) % bufferSize;
// add up all the values and return the average,
// taking into account the offset for zero g base
sum = 0;
for (int i=0; i<bufferSize; i++)
sum += buffer [axis] [i];
return (round (sum / bufferSize) - base [axis]);
}