ADXL355 Data Acquisition Question (ODR)

Hi everyone,

I'm currently working on a research project where I am using the ADXL355 accelerometer. I have carefully followed the instructions in the datasheet and other helpful posts on the forum to write my main source code.

#define DEVID_AD                 0x00
#define DEVID_MST                0x01
#define PARTID                   0x02
#define REVID                    0x03
#define STATUS                   0x04
#define FIFO_ENTRIES             0x05
#define TEMP2                    0x06
#define TEMP1                    0x07
#define XDATA3                   0x08
#define XDATA2                   0x09
#define XDATA1                   0x0A
#define YDATA3                   0x0B
#define YDATA2                   0x0C
#define YDATA1                   0x0D
#define ZDATA3                   0x0E
#define ZDATA2                   0x0F
#define ZDATA1                   0x10
#define FIFO_DATA                0x11
#define OFFSET_X_H               0x1E
#define OFFSET_X_L               0x1F
#define OFFSET_Y_H               0x20
#define OFFSET_Y_L               0x21
#define OFFSET_Z_H               0x22
#define OFFSET_Z_L               0x23
#define ACT_EN                   0x24
#define ACT_THRESH_H             0x25
#define ACT_THRESH_L             0x26
#define ACT_COUNT                0x27
#define FILTER                   0x28
#define FIFO_SAMPLES             0x29
#define INT_MAP                  0x2A
#define SYNC                     0x2B
#define RANGE                    0x2C
#define POWER_CTL                0x2D
#define SELF_TEST                0x2E
#define RESET                    0x2F

#define ADXL355_CS_PIN    10
#define ADXL355_MOSI_PIN  11
#define ADXL355_MISO_PIN  12
#define ADXL355_SCK_PIN   13

#include <Arduino.h>
//#include <SD.h>
#include "SdFat.h"
#include <Wire.h>
#include <SPI.h>
#include <led.h>

//const int SD_CS = 8;
const int acc_CS = 10; //
long values[20],t[9];
double x, y, z, c;

volatile uint8_t ADXL355_DRDY;
volatile int ADXL355_DATA_COUNTER;

void acc_data();
byte readRegister (byte thisRegister);
void writeRegister (byte thisRegister, byte value);

SdFat SDO;
File myFile;

void GPIO7_IRQHandler(void) {
    if (1) {
        ADXL355_DRDY = 1;
        ADXL355_DATA_COUNTER += 1;
    }
}

void setup() { 
  delay(1000);
  Serial.begin(115200);
  
  SPI.setMOSI(ADXL355_MOSI_PIN);
  SPI.setSCK(ADXL355_SCK_PIN);
  SPI.setMISO(ADXL355_MISO_PIN);
  SPI.setCS(ADXL355_CS_PIN);
  SPI.begin();

  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);

  pinMode(41, OUTPUT);
  digitalWrite(41, HIGH);

  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);

  pinMode(6, INPUT);
  attachInterrupt(digitalPinToInterrupt(6), GPIO7_IRQHandler, RISING);

  digitalWrite(3, HIGH);
  digitalWrite(10, HIGH);
//  digitalWrite(23, HIGH);
  
  writeRegister(POWER_CTL, 0x00);
  writeRegister(RANGE, 0xC1);
  writeRegister(SELF_TEST, 0x00);  // writing 0 to to enable sensor // 0x06?
  writeRegister(SYNC, 0x00);
  writeRegister(FILTER, 0x05); // 1000 Hz
  delay(500);

  ADXL355_DRDY = 0;
  ADXL355_DATA_COUNTER = 0;

  SDO.begin(SdioConfig(FIFO_SDIO));

  LED_Init();
  LED_Off();
}
void loop() {
  
  ADXL355_DRDY = 0;
  ADXL355_DATA_COUNTER = 0;

  for (int i=0; i<4000*60*10; i++) {
    while (!ADXL355_DRDY) {}
        ADXL355_DRDY = 0;
        acc_data();
        if (i%10 == 0){
            Serial.print(ADXL355_DATA_COUNTER);
            Serial.print(',');
            Serial.print(x,7);
            Serial.print(',');
            Serial.print(y,7);
            Serial.print(',');
            Serial.print(z,7);
            Serial.println();
        }
        if (i%1000 == 0){
            LED_Gtoggle();
        }
  }
//   acc_data();
  
//   delay(3000);
}

byte readRegister (byte thisRegister) {
  byte inByte = 0 ;
  digitalWrite(acc_CS, LOW); 
  SPI.transfer((thisRegister << 1) | 1);
  inByte = SPI.transfer(0x00);
  digitalWrite(acc_CS, HIGH);
  return inByte;
}
void writeRegister (byte thisRegister, byte value) {
  digitalWrite(acc_CS, LOW);
  SPI.transfer(thisRegister << 1);
  SPI.transfer(value);
  digitalWrite(acc_CS, HIGH);
}
void acc_data(){
  values[0] = readRegister(XDATA3);
  values[1] = readRegister(XDATA2);
  values[2] = readRegister(YDATA3);
  values[3] = readRegister(YDATA2);
  values[4] = readRegister(ZDATA3);
  values[5] = readRegister(ZDATA2);

  values[6] = readRegister(XDATA1);
  values[7] = readRegister(YDATA1);
  values[8] = readRegister(ZDATA1);

  t[0] = readRegister(TEMP2);
  t[1] = readRegister(TEMP1);

  x = (values[0] << 12) + (values[1]<<4) + (values[6]>>4);
  y = (values[2] << 12) + (values[3]<<4) + (values[7]>>4);
  z = (values[4] << 12) + (values[5]<<4) + (values[8]>>4);

//  Serial.print(x);Serial.print(",");
//  Serial.print(y);Serial.print(",");
//  Serial.print(z);Serial.println();
   
  if (x >= 0x80000) {
    x = x-(2*0x80000);
  }
  if (y >= 0x80000) {
    y = y-(2*0x80000);
  }
  if (z >= 0x80000) {
    z = z-(2*0x80000);
  }
 
  c=(t[0]<<8)+t[1];
  c=((1852 - c)/9.05)+25.7;
 
  x=x*0.0000039;
  y=y*0.0000039;
  z=z*0.0000039;
  }

However, I have encountered an issue with the ADXL355 ODR settings. Despite setting the ODR correctly in my code, I have observed through an oscilloscope that the DRDY pin does not reflect the expected output.


Similarly, when I change ODR from 4000Hz(Addr:0x28->Val:0x00) to 125Hz(Addr:0x28->Val:0x05), each output doesn't give its exact setting value..

ODR=0 : (ideal) 4000Hz <-> (measured) 3968Hz~4098Hz
ODR=1 : (ideal) 2000Hz <-> (measured) 2000Hz~2032Hz
ODR=2 : (ideal) 1000Hz <-> (measured) 1012Hz~1016Hz
ODR=3 : (ideal) 500Hz <-> (measured) 502.5Hz~507.6Hz
ODR=4 : (ideal) 250Hz <-> (measured) 126.6Hz~252.5Hz
ODR=5 : (ideal) 125Hz <-> (measured) ~126.3Hz

Low odr even gives high difference..
Also It seems that data lost breaks out

I wanted to ask if anyone else has experienced a similar problem with the ADXL355 accelerometer. If so, I would appreciate any insights or solutions you have discovered to address this issue.

Thank you in advance for your help and suggestions.

Best regards,

Why do you expect the rate to be "exact"? The sensor does not have a precision crystal clock.

Check the data sheet for information about using an external clock for synchronization.

1 Like

Thank you for your reply

I have also read the datasheet and I understand that using a 1.024MHz external clock can improve accuracy. However, I expected the accelerometer to provide reasonably accurate values at a sampling rate of 1000Hz since it doesn't require super-high requirement in my point of view.

But last night, I succeeded to match the sampling time precisely by changing the attachinginterrupt setting from RISING to HIGH.

I also tested the ADXL355 accelerometer by exciting a 3Hz sinusoidal signal using a shaking table and comparing its performance with a reference sensor. The ADXL355 accurately captured the signal's frequency without any noticeable changes.

But there is still one problem left.. that is its absolute value differs with reference sensor
Although ADXL355 is digital sensor, it is so noisy more than i expected

I suspect that there is wrong with my source code or there could be a conversion mistake occurred
If you or anyone have any insights or guidance regarding this issue, please let me know

Here's the source code now i'm using

#define DEVID_AD                 0x00
#define DEVID_MST                0x01
#define PARTID                   0x02
#define REVID                    0x03
#define STATUS                   0x04
#define FIFO_ENTRIES             0x05
#define TEMP2                    0x06
#define TEMP1                    0x07
#define XDATA3                   0x08
#define XDATA2                   0x09
#define XDATA1                   0x0A
#define YDATA3                   0x0B
#define YDATA2                   0x0C
#define YDATA1                   0x0D
#define ZDATA3                   0x0E
#define ZDATA2                   0x0F
#define ZDATA1                   0x10
#define FIFO_DATA                0x11
#define OFFSET_X_H               0x1E
#define OFFSET_X_L               0x1F
#define OFFSET_Y_H               0x20
#define OFFSET_Y_L               0x21
#define OFFSET_Z_H               0x22
#define OFFSET_Z_L               0x23
#define ACT_EN                   0x24
#define ACT_THRESH_H             0x25
#define ACT_THRESH_L             0x26
#define ACT_COUNT                0x27
#define FILTER                   0x28
#define FIFO_SAMPLES             0x29
#define INT_MAP                  0x2A
#define SYNC                     0x2B
#define RANGE                    0x2C
#define POWER_CTL                0x2D
#define SELF_TEST                0x2E
#define RESET                    0x2F

#define ADXL355_CS_PIN    10
#define ADXL355_MOSI_PIN  11
#define ADXL355_MISO_PIN  12
#define ADXL355_SCK_PIN   13

#include <Arduino.h>
//#include <SD.h>
#include "SdFat.h"
#include <Wire.h>
#include <SPI.h>
#include <led.h>

//const int SD_CS = 8;
const int acc_CS = 10; //
long values[20],t[9];
double x, y, z, c;

volatile uint8_t ADXL355_DRDY;
volatile int ADXL355_DATA_COUNTER;

String fileName;
int fileCount = 1;

void acc_data();
byte readRegister (byte thisRegister);
void writeRegister (byte thisRegister, byte value);

SdFat SDO;
File myFile;

void GPIO7_IRQHandler(void) {
    if (1) {
        ADXL355_DRDY = 1;
        ADXL355_DATA_COUNTER += 1;
    }
}

void setup() { 
  delay(1000);
  Serial.begin(115200);
  
  SPI.setMOSI(ADXL355_MOSI_PIN);
  SPI.setSCK(ADXL355_SCK_PIN);
  SPI.setMISO(ADXL355_MISO_PIN);
  SPI.setCS(ADXL355_CS_PIN);
  SPI.begin();

  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);

  pinMode(41, OUTPUT);
  digitalWrite(41, HIGH);

  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);

  pinMode(6, INPUT);
  attachInterrupt(digitalPinToInterrupt(6), GPIO7_IRQHandler, HIGH);

  digitalWrite(3, HIGH);
  digitalWrite(10, HIGH);
//  digitalWrite(23, HIGH);
  
  writeRegister(POWER_CTL, 0x00);
  writeRegister(RANGE, 0xC1);
  writeRegister(SELF_TEST, 0x00);  // writing 0 to to enable sensor // 0x06?
  writeRegister(SYNC, 0x00);
  writeRegister(FILTER, 0x02); // 1000 Hz
  delay(500);

  ADXL355_DRDY = 0;
  ADXL355_DATA_COUNTER = 0;

  SDO.begin(SdioConfig(FIFO_SDIO));

  LED_Init();
  LED_Off();
}
void loop() {
  
  ADXL355_DRDY = 0;
  ADXL355_DATA_COUNTER = 0;
 
  fileName = String(fileCount) + ".txt";
  myFile = SDO.open(fileName, O_WRITE | O_CREAT | O_APPEND) ;

  for (int i=0; i<1000*60*1; i++) {
    while (!ADXL355_DRDY) {}
        ADXL355_DRDY = 0;
        acc_data();
        if (i%10 == 0){
            myFile.print(i);
            myFile.print(',');
            myFile.print(x,7);
            myFile.print(',');
            myFile.print(y,7);
            myFile.print(',');
            myFile.print(z,7);
            myFile.println();
        }
        if (i%1000 == 0){
            LED_Gtoggle();
        }
  }
  myFile.close();
  fileCount++;
//   acc_data();
  
//   delay(3000);
}

byte readRegister (byte thisRegister) {
  byte inByte = 0 ;
  digitalWrite(acc_CS, LOW); 
  SPI.transfer((thisRegister << 1) | 1);
  inByte = SPI.transfer(0x00);
  digitalWrite(acc_CS, HIGH);
  return inByte;
}
void writeRegister (byte thisRegister, byte value) {
  digitalWrite(acc_CS, LOW);
  SPI.transfer(thisRegister << 1);
  SPI.transfer(value);
  digitalWrite(acc_CS, HIGH);
}
void acc_data(){
  values[0] = readRegister(XDATA3);
  values[1] = readRegister(XDATA2);
  values[2] = readRegister(YDATA3);
  values[3] = readRegister(YDATA2);
  values[4] = readRegister(ZDATA3);
  values[5] = readRegister(ZDATA2);

  values[6] = readRegister(XDATA1);
  values[7] = readRegister(YDATA1);
  values[8] = readRegister(ZDATA1);

  t[0] = readRegister(TEMP2);
  t[1] = readRegister(TEMP1);

  x = (values[0] << 12) + (values[1]<<4) + (values[6]>>4);
  y = (values[2] << 12) + (values[3]<<4) + (values[7]>>4);
  z = (values[4] << 12) + (values[5]<<4) + (values[8]>>4);

//  Serial.print(x);Serial.print(",");
//  Serial.print(y);Serial.print(",");
//  Serial.print(z);Serial.println();
   
  if (x >= 0x80000) {
    x = x-(2*0x80000);
  }
  if (y >= 0x80000) {
    y = y-(2*0x80000);
  }
  if (z >= 0x80000) {
    z = z-(2*0x80000);
  }
 
  c=(t[0]<<8)+t[1];
  c=((1852 - c)/9.05)+25.7;
 
  x=x*0.0000039;
  y=y*0.0000039;
  z=z*0.0000039;
  }

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