adxl345 calibration

Hello
I don't understand how to calibrate adxl345 to get z=1g
i try many code in internet any one can help me ?
my connection is i2c
vcc-->3.3v
GND-->GND
SDA-->A4
SCL-->A5

#include <ADXL345.h>

#include <Wire.h>

byte DEVICE_ADDRESS = 0x53; //This address is fixed for the board we use because pin 12 is fixed to GND

byte DATA_FORMAT = 0x31;   //Data Format & Measurement Range Register
byte POWER_CTRL = 0x2D;    //Power Control Register
byte INT_ENABLE = 0x2E;    //Enable Data Ready Interrupt

byte OFSTX = 0x1E;         //X_CALIB
byte OFSTY = 0x1F;         //Y_CALIB
byte OFSTZ = 0x20;         //Z_CALIB

byte DATAX0 = 0x32;        //X-Axis Data 0
byte DATAX1 = 0x33;        //X-Axis Data 1
byte DATAY0 = 0x34;        //Y-Axis Data 0
byte DATAY1 = 0x35;        //Y-Axis Data 1
byte DATAZ0 = 0x36;        //Z-Axis Data 0
byte DATAZ1 = 0x37;        //Z-Axis Data 1

byte values[6];
ADXL345 accel;
int x,y,z;                 //For storing the raw value
double xg, yg, zg;         //For storing the G value

float x_bound[3] = {-9999, -9999, -9999};            //Upper, Lower, Middle
float y_bound[3] = {-9999, -9999, -9999};            //Upper, Lower, Middle
float z_bound[3] = {-9999, -9999, -9999};            //Upper, Lower, Middle

int calibrate = -1;
int CAL_DELAY = 400;      //Calibration Delay - waiting time for user to make response

void setup() {
  Wire.begin();    //Initiate the Wire library and join the I2C bus as a master. This is called only once.
  Serial.begin(9600);

  //Minimum initialization sequance according to the application note.
  writeRegister(DEVICE_ADDRESS, DATA_FORMAT, 0x0B); //Put the ADXL345 into Measurement Mode with full resolution (13-bit) and +/-16G range.
  writeRegister(DEVICE_ADDRESS, POWER_CTRL, 0x08); //Start Measurement.
  writeRegister(DEVICE_ADDRESS, INT_ENABLE, 0x80); //Enable Data Ready Interrupt.

  pinMode(2, INPUT_PULLUP);     //Pin2 (LOW) -> Calibration Mode, Pin2(HIGH, DEFAULT) -> Normal Mode
}

void loop() {

  int calibration_mode = digitalRead(2);

  if (calibration_mode == HIGH) {
//    Serial.println("Normal Mode");
    normalMode();
  
    //Converting the raw accelerometer values to g's.

    xg = x * 0.0039;
    yg = y * 0.0039;
    zg = z * 0.0039;

    //Display the results

    Serial.print(x, DEC);
    Serial.print(", ");
    Serial.print(y, DEC);
    Serial.print(", ");
    Serial.print(z, DEC);
    Serial.print(" | ");

    Serial.print(x_bound[0]);
    Serial.print(", ");
    Serial.print(x_bound[1]);
    Serial.print(", ");
    Serial.print(x_bound[2]);
    Serial.print(" | ");   
  
    Serial.print(y_bound[0]);
    Serial.print(", ");
    Serial.print(y_bound[1]);
    Serial.print(", ");
    Serial.print(y_bound[2]);
    Serial.print(" | ");   

    Serial.print(z_bound[0]);
    Serial.print(", ");
    Serial.print(z_bound[1]);
    Serial.print(", ");
    Serial.print(z_bound[2]);
    Serial.println();
  

    Serial.print((float)xg, 2);
    Serial.print("'g, ");
    Serial.print((float)yg, 2);
    Serial.print("g, ");
    Serial.print((float)zg, 2);
    Serial.println("g");
delay(4000);
  }

  if (calibration_mode == LOW) {
    Serial.println("Calibration Mode");
    if ((x_bound[0] == -9999) || (y_bound[0] == -9999) || (z_bound[0] == -9999)) {
        Serial.println("Please release pin 2 from logic LOW position");
        while (digitalRead(2) == LOW) {
        }     
        //delay(CAL_DELAY);
        calibrationMode();
   }
   else {
     Serial.println("Module already calibrated. Do you want to calibrate again? (0 = No, 1 = Yes) ");
     while (calibrate == -1) {
       calibrate = Serial.read();
     }
     if (calibrate == '1') {     
       calibrationMode();
       calibrate = -1;
     }
     else {
       calibrate = -1;
     }
   } 
  }
}

void calibrationMode() {

//Get y-axis boundries
//----------------------------------------------------------------------------
  Serial.println("Place module to position 1 before count down reaches 0");
  for (int i = 25; i >= 0; i--) {
    Serial.println(i);
    delay(CAL_DELAY);
  }
  Serial.println();
  for (int count = 1; count < 100; count++) {
    normalMode();
    y_bound[0] = y_bound[0] + y; 
  }
  y_bound[0] = y_bound[0] / 100;
  Serial.print("Y Low Bound = ");
  Serial.println(y_bound[0]);

  Serial.println();
  Serial.println("Place module to position 2 before count down reaches 0");
  for (int i = 25; i >= 0; i--) {
    Serial.println(i);
    delay(CAL_DELAY);
  }
  for (int count = 1; count < 100; count++) {
    normalMode();
    y_bound[1] = y_bound[1] + y; 
  }
  y_bound[1] = y_bound[1] / 100;
  Serial.print("Y High Bound = ");
  Serial.println(y_bound[1]);
  y_bound[2] = (y_bound[0] + y_bound[1]) / 2;
  Serial.print("Y Mid Point = ");
  Serial.println(y_bound[2]);

//Get x-axis boundries
//----------------------------------------------------------------------------
  Serial.println("Place module to position 3 before count down reaches 0");
  for (int i = 25; i >= 0; i--) {
    Serial.println(i);
    delay(CAL_DELAY);
  }
  Serial.println();
  for (int count = 1; count < 100; count++) {
    normalMode();
    x_bound[0] = x_bound[0] + x; 
  }
  x_bound[0] = x_bound[0] / 100;
  Serial.print("X Low Bound = ");
  Serial.println(x_bound[0]);

  Serial.println();
  Serial.println("Place module to position 4 before count down reaches 0");
  for (int i = 25; i >= 0; i--) {
    Serial.println(i);
    delay(CAL_DELAY);
  }
  for (int count = 1; count < 100; count++) {
    normalMode();
    x_bound[1] = x_bound[1] + x; 
  }
  x_bound[1] = x_bound[1] / 100;
  Serial.print("X High Bound = ");
  Serial.println(x_bound[1]);
  x_bound[2] = (x_bound[0] + x_bound[1]) / 2;
  Serial.print("X Mid Point = ");
  Serial.println(x_bound[2]); 

//Get z-axis boundries
//----------------------------------------------------------------------------
  Serial.println("Place module to position 5 before count down reaches 0");
  for (int i = 25; i >= 0; i--) {
    Serial.println(i);
    delay(CAL_DELAY);
  }
  Serial.println();
  for (int count = 1; count < 100; count++) {
    normalMode();
    z_bound[0] = z_bound[0] + z; 
  }
  z_bound[0] = z_bound[0] / 100;
  Serial.print("Z Low Bound = ");
  Serial.println(z_bound[0]);

  Serial.println();
  Serial.println("Place module to position 6 before count down reaches 0");
  for (int i = 25; i >= 0; i--) {
    Serial.println(i);
    delay(CAL_DELAY);
  }
  for (int count = 1; count < 100; count++) {
    normalMode();
    z_bound[1] = z_bound[1] + z; 
  }
  z_bound[1] = z_bound[1] / 100;
  Serial.print("Z High Bound = ");
  Serial.println(z_bound[1]);
  z_bound[2] = (z_bound[0] + z_bound[1]) / 2;
  Serial.print("Z Mid Point = ");
  Serial.println(z_bound[2]); 

}

void normalMode() {

  readRegister(DEVICE_ADDRESS, DATAX0, 6, values); 

  //The ADXL345 gives 10-bit or 13-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
  //The X value is stored in values[0] and values[1].
  x = ((int)values[1]<<8)|(int)values[0];
  //The Y value is stored in values[2] and values[3].
  y = ((int)values[3]<<8)|(int)values[2];
  //The Z value is stored in values[4] and values[5].
  z = ((int)values[5]<<8)|(int)values[4];
  
  delay(15);
}

void writeRegister(byte device, byte registerAddress, byte value) {
  Wire.beginTransmission(device);    //Start transmission to device
  Wire.write(registerAddress);       //Specify the address of the register to be written to
  Wire.write(value);                 //Send the value to be writen to the register
  Wire.endTransmission();            //End transmission 
}

void readRegister(byte device, byte registerAddress, int numBytes, byte *values) {

  byte address = registerAddress;

  Wire.beginTransmission(device);
  Wire.write(address);
  Wire.endTransmission();

  Wire.beginTransmission(device);     
  Wire.requestFrom(device, numBytes);  //Request 6 bytes from device

  int i = 0;
  while (Wire.available() && i < numBytes) {        //Device may send less than requested
    values[i] = Wire.read();                        //Receive a byte from device and put it into the buffer
    i++;
 }
  
  Wire.endTransmission(); 
}

i try many code in internet any one can help me ?

Without seeing any of the code? Without seeing exactly how the device is connected? Without seeing what output you currently see?

No! And starting another damned thread is not going to change the answer.

Adafruit has a nice tutorial on calibrating accelerometers.

Sorry for not set the code
code :

#include <ADXL345.h>

#include <Wire.h>

byte DEVICE_ADDRESS = 0x53; //This address is fixed for the board we use because pin 12 is fixed to GND

byte DATA_FORMAT = 0x31; //Data Format & Measurement Range Register
byte POWER_CTRL = 0x2D; //Power Control Register
byte INT_ENABLE = 0x2E; //Enable Data Ready Interrupt

byte OFSTX = 0x1E; //X_CALIB
byte OFSTY = 0x1F; //Y_CALIB
byte OFSTZ = 0x20; //Z_CALIB

byte DATAX0 = 0x32; //X-Axis Data 0
byte DATAX1 = 0x33; //X-Axis Data 1
byte DATAY0 = 0x34; //Y-Axis Data 0
byte DATAY1 = 0x35; //Y-Axis Data 1
byte DATAZ0 = 0x36; //Z-Axis Data 0
byte DATAZ1 = 0x37; //Z-Axis Data 1

byte values[6];
ADXL345 accel;
int x,y,z; //For storing the raw value
double xg, yg, zg; //For storing the G value

float x_bound[3] = {-9999, -9999, -9999}; //Upper, Lower, Middle
float y_bound[3] = {-9999, -9999, -9999}; //Upper, Lower, Middle
float z_bound[3] = {-9999, -9999, -9999}; //Upper, Lower, Middle

int calibrate = -1;
int CAL_DELAY = 400; //Calibration Delay - waiting time for user to make response

void setup() {
Wire.begin(); //Initiate the Wire library and join the I2C bus as a master. This is called only once.
Serial.begin(9600);

//Minimum initialization sequance according to the application note.
writeRegister(DEVICE_ADDRESS, DATA_FORMAT, 0x0B); //Put the ADXL345 into Measurement Mode with full resolution (13-bit) and +/-16G range.
writeRegister(DEVICE_ADDRESS, POWER_CTRL, 0x08); //Start Measurement.
writeRegister(DEVICE_ADDRESS, INT_ENABLE, 0x80); //Enable Data Ready Interrupt.

pinMode(2, INPUT_PULLUP); //Pin2 (LOW) -> Calibration Mode, Pin2(HIGH, DEFAULT) -> Normal Mode
}

void loop() {

int calibration_mode = digitalRead(2);

if (calibration_mode == HIGH) {
// Serial.println("Normal Mode");
normalMode();

//Converting the raw accelerometer values to g's.

xg = x * 0.0039;
yg = y * 0.0039;
zg = z * 0.0039;

//Display the results

Serial.print(x, DEC);
Serial.print(", ");
Serial.print(y, DEC);
Serial.print(", ");
Serial.print(z, DEC);
Serial.print(" | ");

Serial.print(x_bound[0]);
Serial.print(", ");
Serial.print(x_bound[1]);
Serial.print(", ");
Serial.print(x_bound[2]);
Serial.print(" | ");

Serial.print(y_bound[0]);
Serial.print(", ");
Serial.print(y_bound[1]);
Serial.print(", ");
Serial.print(y_bound[2]);
Serial.print(" | ");

Serial.print(z_bound[0]);
Serial.print(", ");
Serial.print(z_bound[1]);
Serial.print(", ");
Serial.print(z_bound[2]);
Serial.println();

Serial.print((float)xg, 2);
Serial.print("'g, ");
Serial.print((float)yg, 2);
Serial.print("g, ");
Serial.print((float)zg, 2);
Serial.println("g");
delay(4000);
}

if (calibration_mode == LOW) {
Serial.println("Calibration Mode");
if ((x_bound[0] == -9999) || (y_bound[0] == -9999) || (z_bound[0] == -9999)) {
Serial.println("Please release pin 2 from logic LOW position");
while (digitalRead(2) == LOW) {
}
//delay(CAL_DELAY);
calibrationMode();
}
else {
Serial.println("Module already calibrated. Do you want to calibrate again? (0 = No, 1 = Yes) ");
while (calibrate == -1) {
calibrate = Serial.read();
}
if (calibrate == '1') {
calibrationMode();
calibrate = -1;
}
else {
calibrate = -1;
}
}
}
}

void calibrationMode() {

//Get y-axis boundries
//----------------------------------------------------------------------------
Serial.println("Place module to position 1 before count down reaches 0");
for (int i = 25; i >= 0; i--) {
Serial.println(i);
delay(CAL_DELAY);
}
Serial.println();
for (int count = 1; count < 100; count++) {
normalMode();
y_bound[0] = y_bound[0] + y;
}
y_bound[0] = y_bound[0] / 100;
Serial.print("Y Low Bound = ");
Serial.println(y_bound[0]);

Serial.println();
Serial.println("Place module to position 2 before count down reaches 0");
for (int i = 25; i >= 0; i--) {
Serial.println(i);
delay(CAL_DELAY);
}
for (int count = 1; count < 100; count++) {
normalMode();
y_bound[1] = y_bound[1] + y;
}
y_bound[1] = y_bound[1] / 100;
Serial.print("Y High Bound = ");
Serial.println(y_bound[1]);
y_bound[2] = (y_bound[0] + y_bound[1]) / 2;
Serial.print("Y Mid Point = ");
Serial.println(y_bound[2]);

//Get x-axis boundries
//----------------------------------------------------------------------------
Serial.println("Place module to position 3 before count down reaches 0");
for (int i = 25; i >= 0; i--) {
Serial.println(i);
delay(CAL_DELAY);
}
Serial.println();
for (int count = 1; count < 100; count++) {
normalMode();
x_bound[0] = x_bound[0] + x;
}
x_bound[0] = x_bound[0] / 100;
Serial.print("X Low Bound = ");
Serial.println(x_bound[0]);

Serial.println();
Serial.println("Place module to position 4 before count down reaches 0");
for (int i = 25; i >= 0; i--) {
Serial.println(i);
delay(CAL_DELAY);
}
for (int count = 1; count < 100; count++) {
normalMode();
x_bound[1] = x_bound[1] + x;
}
x_bound[1] = x_bound[1] / 100;
Serial.print("X High Bound = ");
Serial.println(x_bound[1]);
x_bound[2] = (x_bound[0] + x_bound[1]) / 2;
Serial.print("X Mid Point = ");
Serial.println(x_bound[2]);

//Get z-axis boundries
//----------------------------------------------------------------------------
Serial.println("Place module to position 5 before count down reaches 0");
for (int i = 25; i >= 0; i--) {
Serial.println(i);
delay(CAL_DELAY);
}
Serial.println();
for (int count = 1; count < 100; count++) {
normalMode();
z_bound[0] = z_bound[0] + z;
}
z_bound[0] = z_bound[0] / 100;
Serial.print("Z Low Bound = ");
Serial.println(z_bound[0]);

Serial.println();
Serial.println("Place module to position 6 before count down reaches 0");
for (int i = 25; i >= 0; i--) {
Serial.println(i);
delay(CAL_DELAY);
}
for (int count = 1; count < 100; count++) {
normalMode();
z_bound[1] = z_bound[1] + z;
}
z_bound[1] = z_bound[1] / 100;
Serial.print("Z High Bound = ");
Serial.println(z_bound[1]);
z_bound[2] = (z_bound[0] + z_bound[1]) / 2;
Serial.print("Z Mid Point = ");
Serial.println(z_bound[2]);

}

void normalMode() {

readRegister(DEVICE_ADDRESS, DATAX0, 6, values);

//The ADXL345 gives 10-bit or 13-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
//The X value is stored in values[0] and values[1].
x = ((int)values[1]<<8)|(int)values[0];
//The Y value is stored in values[2] and values[3].
y = ((int)values[3]<<8)|(int)values[2];
//The Z value is stored in values[4] and values[5].
z = ((int)values[5]<<8)|(int)values[4];

delay(15);
}

void writeRegister(byte device, byte registerAddress, byte value) {
Wire.beginTransmission(device); //Start transmission to device
Wire.write(registerAddress); //Specify the address of the register to be written to
Wire.write(value); //Send the value to be writen to the register
Wire.endTransmission(); //End transmission
}

void readRegister(byte device, byte registerAddress, int numBytes, byte *values) {

byte address = registerAddress;

Wire.beginTransmission(device);
Wire.write(address);
Wire.endTransmission();

Wire.beginTransmission(device);
Wire.requestFrom(device, numBytes); //Request 6 bytes from device

int i = 0;
while (Wire.available() && i < numBytes) { //Device may send less than requested
values = Wire.read(); //Receive a byte from device and put it into the buffer

  • i++;*
    }

  • Wire.endTransmission();*
    }
    the result :
    -43, 51, 648 | -142.06, -142.25, -142.16 | -49.94, -49.79, -49.86 | 541.17, 541.31, 541.24
    -0.17'g, 0.20g, 2.53g
    i pose the adxl345 in 6 position but not give me z=1g

You didn't mean for the last few lines to be italic. Go back and put [ code ] tags around it.

the code is insert in the question in top

  if (calibration_mode == HIGH) {
 }

  if (calibration_mode == LOW) {

What other modes are you planning for? How do you intend to accomplish having a digital pin return those values?

Please edit your post and add code tags ("</>" button).