Hello.
I'm trying to create an accelerometer logger for my R/C bikes (and cars, why not?).
The project will consists of an Arduino Nano, an ADXL345, a RTC, a GPS and a SD card module.
It will log the acceleration (in Gs) on X/Y/Z axis and the angle (in degrees) on X & Y axis (to see how much it leans at the corners, what was the maximum lean before crash etc). Also it will log the long/latt data from GPS and will be saved on SD card as KML (for Google Earth review). Power will be supplied either from the ESC's BEC or from a channel of the RX (with a 7805 voltage regulator and a diode for protection).
So far it looks that works OK, but there are two problems related with the accelerometer.
First problem is that when I'm trying to move it left/right/front/back on a table (keeping the Z axis steady), the acceleration changes, but it changes the angle too. Is it normal?
Second problem is that I don't know too much about accelerometers, and I'm not sure if it counts the G forces OK. It looks good, but when I'm accelerating for example, it changes the angle a lot, and I'm not leaning.
Here is my code so far. If I have any errors in calculations (I'm totally newbie to accelerometers), please help! Oh, and please contribute if you like

#include <Time.h>
#include "Wire.h"
#include "ADXL345.h"
#include <DS1307RTC.h>
#include <EEPROM.h>
#define GreenLed 13
#define RedLed 12
#define ButtonWrite 11
int x,y,z;
int xx, yy;
int defaultXX, defaultYY, defaultZZ;
double xyz[3];
double calibratedAccelXYZ[3];
double currentAccelX, currentAccelY, currentaccelz;
double differencexx, differenceyy, differencezz;
int CurrentFront = 0;
int CurrentBack = 0;
int CurrentLeft = 0;
int CurrentRight = 0;
double maxX = 0;
double maxY = 0;
double maxZ = 0;
int maxAngleLeft = 0;
int maxAngleRight = 0;
int maxAngleFront = 0;
int maxAngleBack = 0;
ADXL345 accel;
#define debug 1
void setup(void)
{
pinMode(RedLed, OUTPUT);
pinMode(GreenLed, OUTPUT);
// Turn on the red led to define that calibration
// process will be started
pinMode(ButtonWrite, INPUT);
digitalWrite(GreenLed, HIGH);
digitalWrite(RedLed, HIGH);
setSyncProvider(RTC.get); // Get the time from RTC
delay(100);
if (debug==1)
{
Serial.begin(9600);
Serial.println("Begin");
}
accel.powerOn(); // Power On the Accelerator
accel.setRangeSetting(8); // Set maximum range to 8G
digitalWrite(GreenLed, LOW);
digitalWrite(RedLed, LOW);
delay(100);
digitalWrite(RedLed, HIGH);
delay(100);
digitalWrite(RedLed, LOW);
delay(100);
digitalWrite(RedLed, HIGH);
delay(100);
digitalWrite(RedLed, LOW);
delay(100);
digitalWrite(RedLed, HIGH);
delay(100);
// Read acceleration data and store them as default/inactive values
accel.readAccel(&x, &y, &z);
defaultXX = (atan2(y,z)+3.14)*RAD_TO_DEG;
defaultYY = (atan2(x,z)+3.14)*RAD_TO_DEG;
accel.get_Gxyz(xyz);
calibratedAccelXYZ[0] = xyz[0];
calibratedAccelXYZ[1] = xyz[1];
calibratedAccelXYZ[2] = xyz[2];
// Turn on the green led - ready to start
delay(250);
digitalWrite(RedLed, LOW);
digitalWrite(GreenLed, HIGH);
// Display previous records from EEPROM
ReadFromEEPROM();
// zero the variables to store the new maximum values
maxX = 0;
maxY = 0;
maxZ = 0;
maxAngleLeft = 0;
maxAngleRight = 0;
maxAngleFront = 0;
maxAngleBack = 0;
if (debug==1)
Serial.println("Ready!");
}
void loop()
{
if (digitalRead(ButtonWrite) == HIGH)
WriteToEEPROM();
if (debug==1)
{
Serial.print(TimeDate());
Serial.print(" | ");
}
accel.readAccel(&x, &y, &z);
xx = (atan2(y,z)+3.14)*RAD_TO_DEG;
yy = (atan2(x,z)+3.14)*RAD_TO_DEG;
accel.get_Gxyz(xyz);
currentAccelX=abs(calibratedAccelXYZ[0]-xyz[0]);
currentAccelY=abs(calibratedAccelXYZ[1]-xyz[1]);
currentaccelz=abs(calibratedAccelXYZ[2]-xyz[2]);
if (currentAccelX>maxX)
maxX = currentAccelX;
if (currentAccelY>maxY)
maxY = currentAccelY;
if (currentaccelz>maxZ)
maxZ = currentaccelz;
if (debug==1)
{
Serial.print("Acceleration X: ");
Serial.print(currentAccelX, 1);
Serial.print(" - Y: ");
Serial.print(currentAccelY, 1);
Serial.print(" - Z: ");
Serial.print(currentaccelz, 1);
Serial.print(" | ");
}
differencexx = defaultXX-xx;
if (differencexx < -180)
differencexx += 180;
if (differencexx > 180)
differencexx -= 180;
if (differencexx<0)
CurrentLeft=abs(differencexx);
else
CurrentRight=differencexx;
differenceyy = defaultYY-yy;
if (differenceyy < -180)
differenceyy += 180;
if (differenceyy > 180)
differenceyy -= 180;
if (differenceyy<0)
CurrentFront=abs(differenceyy);
else
CurrentBack=differenceyy;
if (CurrentFront>maxAngleFront)
maxAngleFront=CurrentFront;
if (CurrentBack>maxAngleBack)
maxAngleBack=CurrentBack;
if (CurrentLeft>maxAngleLeft)
maxAngleLeft=CurrentLeft;
if (CurrentRight>maxAngleRight)
maxAngleRight=CurrentRight;
if (debug==1)
{
Serial.print("Front: ");
Serial.print(CurrentFront);
Serial.print(" - Back: ");
Serial.print(CurrentBack);
Serial.print(" - Left: ");
Serial.print(CurrentLeft);
Serial.print(" - Right: ");
Serial.print(CurrentRight);
Serial.println("");
delay(50);
}
}
String TimeDate()
{
String datetime;
if (hour()<10)
datetime=String("0");
else
datetime=String(hour());
if (minute()<10)
datetime += String(":0");
datetime += String(":")+String(minute())+String(":");
if (second()<10)
datetime += String("0");
datetime += String(second())+String(" / ");
if (day()<10)
datetime += String("0");
datetime += String(day())+String("/");
if (month()<10)
datetime += String("0");
datetime += String(month())+String("/")+String(year());
return datetime;
}
void WriteToEEPROM()
{
digitalWrite(RedLed, HIGH);
digitalWrite(GreenLed, LOW);
Serial.println("");
Serial.println("Write to EEPROM");
int foo;
foo = maxX*100;
EEPROM.write(0,foo);
foo = maxY*100;
EEPROM.write(1,foo);
foo = maxZ*100;
EEPROM.write(2,foo);
EEPROM.write(3,maxAngleFront);
EEPROM.write(4,maxAngleBack);
EEPROM.write(5,maxAngleLeft);
EEPROM.write(6,maxAngleRight);
delay(500);
digitalWrite(RedLed, LOW);
digitalWrite(GreenLed, HIGH);
Serial.println("Done!");
}
void ReadFromEEPROM()
{
Serial.println("");
Serial.println("");
Serial.println("Reading EEPROM");
maxX = EEPROM.read(0);
maxY = EEPROM.read(1);
maxZ = EEPROM.read(2);
maxAngleFront = EEPROM.read(3);
maxAngleBack = EEPROM.read(4);
maxAngleLeft = EEPROM.read(5);
maxAngleRight = EEPROM.read(6);
Serial.println("");
double foo = 0;
Serial.print("Max X Acceleration: ");
foo = maxX/100;
Serial.println(foo, 2);
Serial.print("Max Y Acceleration: ");
foo = maxY/100;
Serial.println(foo, 2);
Serial.print("Max Z Acceleration: ");
foo = maxZ/100;
Serial.println(foo, 2);
Serial.println("");
Serial.print("Max Angle Front: ");
Serial.println(maxAngleFront);
Serial.print("Max Angle Back: ");
Serial.println(maxAngleBack);
Serial.print("Max Angle Left: ");
Serial.println(maxAngleLeft);
Serial.print("Max Angle Right: ");
Serial.println(maxAngleRight);
Serial.println("");
Serial.println("");
delay(2000);
}
PS 1: I haven't receive the GPS & the SD card module yet, so it only displays the data on screen (and saves the max values @ EEPROM when button is pressed).
PS 2: I want to log the crashes (don't forget it's a RC Bike, it has lot of crashes). I guess that's possible with the tap detection. Any ideas how to do that?
Thank you,
Antonis.