[SOLVED] Accelerometer ADXL355 'moved' values

Hi, I'm new to the forum and I have a problem with my project. I'm using an Analog Devices EVAL-ADXL355Z accelerometer on an Arduino UNO.

The accelerometer is using I2C to communicate with the Arduino UNO.
It looks like it's returing the right values to the serial monitor, but the values that I'm getting back aren't in the right order. If i turn my accelerometer 90 degrees to the left, I get the values from where it was in the first place according to the attachment.

For example: The top is pointing upwards and i'm turning it 90 degrees to the left. Now the top is pointing to the left, but it gives me the values I should have when the top is pointing upwards.

This is my code:

/*
  Description: EVAL_ADXL355Z Accelerometer

  Revision: V1.3

  Rev update: V1.0   November  3, 2020
  Rev update: V1.1   November 10, 2020
  Rev update: V1.2   November 19, 2020
  Rev update: V1.3   November 24, 2020
*/
 
// include libraries
#include <Wire.h>                       // Wire library - used for I2C communication
#include <math.h>                       // Math library - used for math calculations

// ------------------------- Declare Constants ------------------------- //
#define STATUS        0x04              // define STATUS as 0x04
#define XDATA3        0x08              // define XDATA3 as 0x08
#define XDATA2        0x09              // define XDATA2 as 0x09
#define XDATA1        0x0A              // define XDATA1 as 0x0A
#define YDATA3        0x0B              // define YDATA3 as 0x0B
#define YDATA2        0x0C              // define YDATA2 as 0x0C
#define YDATA1        0x0D              // define YDATA1 as 0x0D
#define ZDATA3        0x0E              // define ZDATA3 as 0x0E
#define ZDATA2        0x0F              // define ZDATA2 as 0x0F
#define ZDATA1        0x10              // define ZDATA1 as 0x10

#define RANGE         0x2C              // define RANGE as 0x2C
#define POWER_CTL     0x2D              // define POWER_CTL as 0x2D, power_register address
#define RANGE_2G      2.048             // define RANGE_2G as decimal 2.048
#define RANGE_4G      4.096             // define RANGE_3G as decimal 4.096
#define RANGE_8G      8.192             // define RANGE_8G as decimal 8.192

// ------------------------- Declare Global Variables ------------------------- // 
int ADXL355 = 0x53;                     // ADXL355 I2C address - 0x53
float x,y,z;                            // x,y,z initiated as float
float range;                            // range initiated as float
float rollF,pitchF=0;                   // rollF,pitchF initiated as float
uint8_t enable(uint8_t);                // enable initiated as an unidentified integer

// Setup
void setup() 
{   
  Serial.begin(9600);                   // Initiate serial communication
  Wire.begin();                         // Initiate the Wire library
  Serial.println("Started");            // Print "Started" on the serial monitor
  enable(0x00);

}

// Main loop
void loop() 
{ 
  // put your main code here, to run repeatedly:
  Serial.println();
  Serial.print("Accelerometer ADXL (x,y,z): ");
  Serial.print(readX()); Serial.print(",");
  Serial.print(readY()); Serial.print(",");
  Serial.print(readZ()); 
  Serial.println();  
}


float readX() {
  Wire.beginTransmission(ADXL355);
  Wire.write(XDATA3);
  Wire.endTransmission();
  Wire.requestFrom((int)ADXL355,3);
  uint32_t x1 = Wire.available()?Wire.read():0;   // read wire x1 if wire is available
  uint32_t x2 = Wire.available()?Wire.read():0;   // read wire x2 if wire is available
  uint32_t x3 = Wire.available()?Wire.read():0;   // read wire x3 if wire is available
  uint32_t data = (x1<<16)|(x2<<8)|x3;
  data = data>>4;
  float value = (float)data;
  value = data>0X7FFFF?value-0XFFFFE:value;
  return value/0X7FFFF*2.048;
}

float readY() {
  Wire.beginTransmission(ADXL355);
  Wire.write(YDATA3);
  Wire.endTransmission();
  Wire.requestFrom((int)ADXL355,3);
  uint32_t y1 = Wire.available()?Wire.read():0;   // read wire y1 if wire is available
  uint32_t y2 = Wire.available()?Wire.read():0;   // read wire y2 if wire is available
  uint32_t y3 = Wire.available()?Wire.read():0;   // read wire y3 if wire is available
  uint32_t data = (y1<<16)|(y2<<8)|y3;
  data = data>>4;
  float value = (float)data;
  value = data>0X7FFFF?value-0XFFFFE:value;
  return value/0X7FFFF*2.048;
}

float readZ() {
  Wire.beginTransmission(ADXL355);
  Wire.write(ZDATA3);
  Wire.endTransmission();
  Wire.requestFrom((int)ADXL355,3);
  uint32_t z1 = Wire.available()?Wire.read():0;   // read wire z1 if wire is available
  uint32_t z2 = Wire.available()?Wire.read():0;   // read wire z2 if wire is available
  uint32_t z3 = Wire.available()?Wire.read():0;   // read wire z3 if wire is available
  uint32_t data = (z1<<16)|(z2<<8)|z3;
  data = data>>4;
  float value = (float)data;
  value = data>0X7FFFF?value-0XFFFFE:value;
  return value/0X7FFFF*2.048;
}

uint8_t enable(uint8_t c = 0X00) {
  Wire.beginTransmission(ADXL355);
  if (Wire.endTransmission()==0) {
    Wire.beginTransmission(ADXL355);
    Wire.write(0X00);
    Wire.endTransmission(); 
    Wire.requestFrom((int)ADXL355,1);
    if (Wire.available()) {
      if (Wire.read()==0XAD) {
        Serial.println("Device found");
      }
      else {
        return 1;
      }
    }
  }
  else {
    return 0;
  }
  Wire.beginTransmission(ADXL355);
  Wire.write(POWER_CTL);
  Wire.write(c);
  Wire.endTransmission();
  range = RANGE_2G;
  return 1;
}


uint8_t readData() {
  while(dataReady()==0);
  uint32_t d3,d2,d1,data;
  float value;
  Wire.beginTransmission(ADXL355);
  Wire.write(XDATA3);
  Wire.endTransmission();
  Wire.requestFrom(ADXL355,9);
  
  d3 = Wire.available()?Wire.read():0;
  d2 = Wire.available()?Wire.read():0;
  d1 = Wire.available()?Wire.read():0;
  data = (d3<<16)|(d2<<8)|d1;
  data = data>>4;
  value = (float)data;
  value = data>0X7FFFF?value-0XFFFFE:value;
  x = value/0X7FFFF*range;
  
  d3 = Wire.available()?Wire.read():0;
  d2 = Wire.available()?Wire.read():0;
  d1 = Wire.available()?Wire.read():0;
  data = (d3<<16)|(d2<<8)|d1;
  data = data>>4;
  value = (float)data;
  value = data>0X7FFFF?value-0XFFFFE:value;
  y = value/0X7FFFF*range;
  
  d3 = Wire.available()?Wire.read():0;
  d2 = Wire.available()?Wire.read():0;
  d1 = Wire.available()?Wire.read():0;
  data = (d3<<16)|(d2<<8)|d1;
  data = data>>4;
  value = (float)data;
  value = data>0X7FFFF?value-0XFFFFE:value;
  z = value/0X7FFFF*range;
  
  return 0;
}

uint8_t dataReady() {
  Wire.beginTransmission(ADXL355);
  Wire.write(STATUS);
  Wire.endTransmission();
  Wire.requestFrom(ADXL355,1);
  return Wire.available()?Wire.read()&0X01:0X00;
}

The code works, but I think my calculations aren't right.

The link from the (left) image in the attachment:

I was wondering if anyone knows how to 'fix' this problem or if they know if this isn't a big of a deal that all the values are 'moved' 90 degrees.

Thanks in advance.

It looks like You and the device designer use differently oriented coordinate systems.

uint32_t y1 = Wire.available()?Wire.read():0;   // read wire y1 if wire is available

The question mark looks odd to me as well as the colon after Wire.read():

Railroader:
It looks like You and the device designer use differently oriented coordinate systems.

uint32_t y1 = Wire.available()?Wire.read():0;   // read wire y1 if wire is available

The question mark looks odd to me as well as the colon after Wire.read():

Ternary operator. Nothing wrong that I can see (apart from "how do you tell the difference between a read zero and nothing to read?")

Thanks! I looked into the Ardiuno reference and didn't find out.

all the values are 'moved' 90 degrees.

I suspect that either the code has an indexing problem, or you are misinterpreting the orientation.

The code to read out the data is most unusual in the way it was written, which confuses the issue. The author obviously does not completely understand how the Arduino Wire library works. For example, there is no reason to use Wire.available() with Wire.requestFrom().

Is there some particular reason to use that rather complex accelerometer?

jremington:
I suspect that either the code has an indexing problem, or you are misinterpreting the orientation.

The code to read out the data is most unusual in the way it was written, which confuses the issue. The author obviously does not completely understand how the Arduino Wire library works. For example, there is no reason to use Wire.available() with Wire.requestFrom().

Is there some particular reason to use that rather complex accelerometer?

Hi, thanks for your reply.
Yes, we're using this accelerometer on our redesigned product for ASML. They want to measure the speed and they want to know in which direction the machine is going. They chose this accelerometer, because it's quite precise and has a long-term stability enabling precision with minimal calibration. I'm not very familiar to use an accelerometer, especially this one, because it's indeed rather complex.
I have a code in processing 3.5.4, which reads the data written on the serial monitor. I'm using this data to display a 3D model of the accelerometer, so you can see how the accelerometer is turning. I've a small calculation error in that part, but it shouldn't be that hard to solve the equation. It looks like the 'moved' values doesn't make a big difference, but it made me quite confused seeing different values than expected. I just wanted to make sure there aren't any errors when the products are being shipped.
Kind regards

Hard to see how you can have any confidence in the sensor, if you can't tell for sure which direction it is pointing.

jremington:
Hard to see how you can have any confidence in the sensor, if you can't tell for sure which direction it is pointing.

I personally wouldn't choose this accelerometer to use in my projects either, but with the right calculations it seems like it's doing its job. I've found another picture where de data is also different from what I've shown before. The customer is king and they wanted this accelerometer, now it's my job to see how this thing works and how we can implement it in our redesigned product.

The link to the image: Simple angle meter using ADXL335 accelerometer [Arduino] | electronicsblog.net
The image

First a happy new year to everyone.

I've solved it. The changed values didn't matter in the calculations.
I've posted the whole code to GitHub.
You can find the full repository here

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.