Arduino + ADXL362

Hello,

I try to use the ADXL362 to get a precise orientation in 3D of my board to earth.

I corrected the ADXL362 Library so that it passes the values correctly, and I think my problem is a math one. just for completeness here is my whole project :

[ADXL362_lib.zip

#include <SPI.h>
#include <ADXL362.h>

ADXL362 xl;

//2014-02-16 	1° 33' 5" E changing by  6.9' E per year
// http://rumkin.com/tools/gps/degrees.php
// 1.551389 degree = 0.027076846 radians
#define declinaison 0.027076846

void setup()   
{                
  Serial.begin(115200);
  Serial.println("Setup");

  delay(2000);

  xl.begin();                   // Setup SPI protocol, issue device soft reset
  xl.beginMeasure();            // Switch ADXL362 to measure mode  
  xl.checkAllControlRegs();     // Burst Read all Control Registers, to check for proper setup
}


void loop() 
{
  int XValue, YValue, ZValue, Temperature;

  xl.readXYZTData(XValue, YValue, ZValue, Temperature);
  
  Serial.print("x : ");
  Serial.println(XValue);
  Serial.print("y : ");
  Serial.println(YValue);
  Serial.print("z : ");
  Serial.println(ZValue);
  Serial.print("t : ");
  Serial.println(float(Temperature)/16);

  float a = atan2(XValue, sqrt(YValue*YValue+ZValue*ZValue));
  a += declinaison;
  a = a * 180/M_PI; 
  
  float b = atan2(YValue, sqrt(XValue*XValue+ZValue*ZValue));
  b = b * 180/M_PI; 

  float c = atan2(sqrt(XValue*XValue+YValue*YValue),ZValue);
  c = c * 180/M_PI; 

  Serial.print("alpha : ");
  Serial.println(a);
  Serial.print("beta  : ");
  Serial.println(b);
  Serial.print("gamma : ");
  Serial.println(c);
  Serial.println("");

  delay(250);
}

and here is a sample output when rotating the board around :

x : 243
y : 65169
z : 1958
t : 25.19
alpha : 0.00
beta  : 88.27
gamma : 0.00

x : 65311
y : 334
z : 152
t : 25.06
alpha : 91.23
beta  : 0.00
gamma : 0.00

x : 65051
y : 688
z : 65342
t : 25.19
alpha : 0.00
beta  : 0.00
gamma : 0.00

x : 64951
y : 775
z : 65099
t : 25.19
alpha : 0.00
beta  : 0.00
gamma : 0.00

x : 64599
y : 44
z : 771
t : 25.19
alpha : 90.87
beta  : 0.00
gamma : 0.00

x : 135
y : 64743
z : 359
t : 25.44
alpha : 0.00
beta  : 89.66
gamma : 0.00

x : 751
y : 611
z : 1390
t : 25.19
alpha : 27.87
beta  : 21.14
gamma : 34.86

x : 65288
y : 1246
z : 65374
t : 25.19
alpha : 0.00
beta  : 0.00
gamma : 0.00

x : 64999
y : 174
z : 65107
t : 25.19
alpha : 0.00
beta  : 0.00
gamma : 0.00

x : 64967
y : 1127
z : 65500
t : 25.37
alpha : 0.00
beta  : 0.00
gamma : 0.00

x : 65056
y : 64719
z : 1024
t : 25.00
alpha : 0.00
beta  : 0.00
gamma : 0.00

x : 65390
y : 64436
z : 396
t : 25.00
alpha : 0.00
beta  : 0.00
gamma : 0.00

x : 65284
y : 64502
z : 65292
t : 25.19
alpha : 0.00
beta  : 0.00
gamma : 0.00

x : 65241
y : 64515
z : 380
t : 25.37
alpha : 0.00
beta  : 0.00
gamma : 0.00

x : 64921
y : 112
z : 1209
t : 25.19
alpha : 90.48
beta  : 0.00
gamma : 0.00

x : 64974
y : 896
z : 65206
t : 25.00
alpha : 0.00
beta  : 0.00
gamma : 0.00

x : 65142
y : 673
z : 65120
t : 25.06
alpha : 0.00
beta  : 0.00
gamma : 0.00

x : 60
y : 172
z : 1070
t : 25.19
alpha : 4.72
beta  : 9.12
gamma : 9.66

x : 65531
y : 65351
z : 1011
t : 25.19
alpha : 0.00
beta  : 89.47
gamma : 0.00

x : 103
y : 39
z : 1084
t : 25.19
alpha : 6.98
beta  : 2.05
gamma : 5.80

x : 65519
y : 65523
z : 1169
t : 25.37
alpha : 0.00
beta  : 0.00
gamma : 0.00

As you can see the alpha,beta and gamma angle make no sense.

I took the trig function from the Analog Device AN-1057 p7 : [AN-1057.pdf](AN-1057: Using an Accelerometer for Inclination Sensing | Analog Devices)](http://stuff.knackes.com/dld/201402/ADXL362_lib_F255EF24.zip)

Progress indication :

the ADXL362 reports if values as 12bits in 2x8 bits registers (for each of the XValue, YValue, ZValue and Temperature) like this :

http://stuff.knackes.com/dld/201402/Scr … C520F0.png

Which means that when the number is negative I have to do some filtering :

int wordstomg(word value)
{
  int r = value & 0x07FF; 
  if ( value & 0X0800 )
  {
    r = value - 65536;
  }
  return r;
}

now the values from the ADXL362 at least made sense.

The next error was to use ints in my trig function Where I needed floats.

float rho = atan2(float(x), sqrt(pow(float(y),2)+pow(float(z),2)));
  rho += declinaison;
  rho = rho * 180/M_PI; 
  
  float phi = atan2(float(y), sqrt(pow(float(x),2)+pow(float(z),2)));
  phi = phi * 180/M_PI; 

  float theta = atan2(sqrt(pow(float(x),2)+pow(float(y),2)),float(z));
  theta = theta * 180/M_PI;

I then added some function to the library to set the accelerometer for maximum accuracy.

Here is the final Sketch :

#include <SPI.h>
#include <ADXL362.h>

ADXL362 xl;

// http://www.ngdc.noaa.gov/geomag-web/#declination
// Strasbourg 2014-02-16 	1° 33' 5" E changing by  6.9' E per year
// Belmont    2014-02-22 	1.42° E changing by  0.12° E per year 
// http://rumkin.com/tools/gps/degrees.php
// 1.551389 degree = 0.027076846 radians
// 1.42 degree     = 0.0247836754 radians

#define declinaison 0.027076846

void setup()   
{                
  Serial.begin(115200);
  Serial.println("Setup");

  delay(2000);

  xl.begin();                   // Setup SPI protocol, issue device soft reset
  xl.setupAccurateMode();
  xl.checkAllControlRegs();     // Burst Read all Control Registers, to check for proper setup
}

int wordstomg(word value)
{
  int r = value & 0x07FF; 
  if ( value & 0X0800 )
  {
    r = value - 65536;
  }
  return r;
}

void loop() 
{
  char line[80];
  word XValue, YValue, ZValue, Temperature;
  int x = 0;
  int y = 0;
  int z = 0;
  int t = 0;

  delay(80); // (1 / 12,5Hz) * 1000
  xl.readXYZTData(XValue, YValue, ZValue, Temperature);
  x = wordstomg(XValue);
  y = wordstomg(YValue);
  z = wordstomg(ZValue);
  t = wordstomg(Temperature);    

  sprintf(line,"x : %5d", x);
  Serial.println(line);
  sprintf(line,"y : %5d", y);
  Serial.println(line);
  sprintf(line,"z : %5d", z);
  Serial.println(line);
  Serial.print("t : ");
  Serial.println(float(t)/16);

  float rho = atan2(float(x), sqrt(pow(float(y),2)+pow(float(z),2)));
  rho += declinaison;
  rho = rho * 180/M_PI; 

  float phi = atan2(float(y), sqrt(pow(float(x),2)+pow(float(z),2)));
  phi = phi * 180/M_PI; 

  float theta = atan2(sqrt(pow(float(x),2)+pow(float(y),2)),float(z));
  theta = theta * 180/M_PI; 

  Serial.print("rho   : ");
  Serial.println(rho,3);
  Serial.print("phi   : ");
  Serial.println(phi,3);
  Serial.print("theta : ");
  Serial.println(theta,3);
  Serial.println();
}

I’ll add this into the library and release it ASAP

Thank you for posting this up and continuing updating your progress. Pretty sure this will help someone in the future.

I forked the original library here : https://github.com/pixelk0/ADXL362

I saw many answers to similar problem online, but none adressed my needs, I hope it will be usefull for anybody trying to use their accelerometer as an inclinometer.