As has been noted by @Majenko, you are reading voltages with your analogRead()
as a ratio of the A/D reference voltage specified for the Arduino you are using rather than true accelerations. For example, your first pass readings of x=9, y=8, z=8 were really saying x = Vref * 9 / 1023 volts. The datasheet for your accelerometer sensor will specify a calibration factor to be applied in terms of Volts/g.
Therefore, if you wish to read in terms of actual acceleration g. then you will need to first convert the value read from the A/D to volts and then convert the voltage to g by applying the datasheet sensitivity factor.
You can brute force this conversion calculation if you wish by using variables of type float
. If you wish to avoid floating point arithmetic and use fixed point calculations, you can consider defining the result as being multiplied by 10 or 100. (Example: a reading of 1.0g might be reported as 10 if using 10x reporting or it might be reported as 100 if using 100x reporting.
Additionally, if you suspect some jitter in your measurements, you can read multiple times to average and smooth the readings. You can then divide the total of the readings to get an average.
Example Code for Single Axis Using Integer Variables (Untested)
#define AXIS_PIN A0
void setup() {
// Insert Setup Code Here
}
void loop()
{
int reading;
reading = 0;
// Read the sensor axis value 4 times
// Use a short delay between reads if you might exceed
// the read frequency of the sensor.
// Use millis() for non-blocking aspects if needed
for (int readLoop = 0; readLoop < 4; readLoop++)
{
reading += analogRead(AXIS_PIN);
delay(2);
}
// Map the reading to a voltage using a 100x multiplier
// The raw reading has a range of (0 to 1023) * 4
// The mapped reading has a range of (0 to 3300) * 4
// (assuming a 3.3v reference voltage)
// (Use 0 to 4 * 5000 if required by the choice of sensor and
// Arduino used.)
reading = map(reading, 0, 4 * 1023, 0, 4 * 3300);
// Find the average by now dividing by 4
reading = reading >> 2;
Serial.print(F("Average axis reading (x100) is: "));
Serial.println(reading);
// Read the axis once per second
// Use millis() for non-blocking aspects, if needed
delay(1000);
}
EDIT NOTE: I see you have now specified an Adafruit ADXL345 sensor. Be aware that this sensor references 3.3v (offset ratio-metric, ie +/- 1.65v) even though it runs off of a 5v power source. Depending on which Arduino you are using, you may have to adjust the map() function input above to account for the proper output. You can try something like map(reading, 0, 4 * 1023, -2 * 3300, 2 * 3300);
.
ADDED EDIT: The above will output a converted voltage. If you would like to output directly in units of g (x100), then you can change the map()
function to something like map(reading, 0, 4 * 1023, -2 * 300, 2 * 300)
assuming the Adafruit ADXL345 (PRODUCT ID: 163) which reads to +/- 3g.