Post Go back to editing

ADXL375Z Shock Threshold False Triggering

Thread Summary

The user was experiencing incorrect shock detection with the ADXL375 accelerometer when interfacing with Arduino UNO via I2C. The solution involved resetting the trigger mode by entering bypass mode in the initial setup and after each shock event, and reading all 10 FIFO samples to capture the shock values. The user configured the shock threshold to 31.2g, ODR to 3200Hz, and enabled XYZ-axis shock detection.
AI Generated Content
Category: Hardware
Product Number: ADXL375

Hello, 

I am working on ADXL375 and interfacing it with Arduino UNO using I2C protocol. I get the values of X, Y, Z axis as mentioned in the datasheet, i.e., when placed horizontally I get x=0g, y=0g, z=1g (approx. calibrated). I have enabled trigger mode and mapped interrupt to INT2. My Shock Threshold is set to 0x28 = 31.2g, and I am detecting for single shock event 

When I tap the module on table, interrupt triggers even though the threshold is 31.2g, but the values I get are unchanged (around x= 0, y=0, z=1). How to get the values of X, Y, Z during the shock? When I tilt the module, I can see the values change accordingly. but these values hardly go beyond 3g. what am I doing wrong?

Here is my code setup:

/*START Set Shock Threshold*/
  Wire.beginTransmission(Device_Address);
  Wire.write(0x1D); //Shock Duration Register Address
  Wire.write(0x28); //Scale Factor is 780mg/LSB, hence 0x28 = 31.2g
  Wire.endTransmission();
  /*END Set Shock Threshold*/

  /*START Set DUR Thresh_SHOCK*/
  Wire.beginTransmission(Device_Address);
  Wire.write(0x21); //Shock Duration Register Address
  Wire.write(0x50); //Scale Factor is 625us/LSB, hence 0x50 = 50ms
  Wire.endTransmission();
  /*END Set DUR Thresh_SHOCK*/

  /*START Set Latency*/
  Wire.beginTransmission(Device_Address);
  Wire.write(0x22); //Latent Register Address
  Wire.write(0x20); //Scale Factor is 1.25ms/LSB, hence 0x20 = 400ms
  Wire.endTransmission();
  /*END Set Latency*/

  /*START Set Shock Window to 300ms*/
  Wire.beginTransmission(Device_Address);
  Wire.write(0x23); //Window Register Address
  Wire.write(0xF0); //Scale Factor is 1.25ms/LSB, hence 0xF0 = 300ms
  Wire.endTransmission();
  /*END Set Shock Window to 300ms*/

  /*START Enable XYZ-Axis Shock Detection START*/
  Wire.beginTransmission(Device_Address);
  Wire.write(0x2A); //SHOCK_AXES Register
  Wire.write(0x07); //Enable SHOCK_X, SHOCK_Y, SHOCK_Z
  Wire.endTransmission();
  /*END Enable XYZ-Axis Shock Detection END*/

  /*START Set Out-Data-Rate(ODR) to 3200Hz*/
  Wire.beginTransmission(Device_Address);
  Wire.write(0x2C); //BW_RATE Register Address
  Wire.write(0x0F); //3200 Hz Output Data Rate
  Wire.endTransmission();
  /*END Set Out-Data-Rate(ODR) to 3200Hz */

  /*START Enable Single Shock Interrupt*/
  Wire.beginTransmission(Device_Address);
  Wire.write(0x2E); //INT_Enable Register Address
  Wire.write(0x40); //Enable Single Shock Int
  Wire.endTransmission();
  /*END Enable Single Shock Interrupt*/
 
  /*START Assign Single Shock Interrupt*/
  Wire.beginTransmission(Device_Address);
  Wire.write(0x2F); //INT_Map Register Address
  Wire.write(0x40); //Assign Single Shock Int
  Wire.endTransmission();
  /*END Assign Single Shock Interrupt*/  
  
  /*START Data Format*/
  Wire.beginTransmission(Device_Address);
  Wire.write(0x31); //DATA_FORMAT Reg
  Wire.write(0x0B); 
  Wire.endTransmission();
  /*END Data Format*/

  /*START Enable Trigger Mode*/
  Wire.beginTransmission(Device_Address);
  Wire.write(0x38); //FIFO_CTL Register Address
  Wire.write(0xEA); //Enable Trigger Mode, set samples = 10
  Wire.endTransmission();
  /*END Enable Trigger Mode*/

  /*START Offset Calibration*/
  // Scale Factor = 0.196g/MSB
  Wire.beginTransmission(Device_Address);
  Wire.write(0x1E); //OFSX Address
  Wire.write(0xFA); //OFSX offset 
  Wire.endTransmission();

  Wire.beginTransmission(Device_Address);
  Wire.write(0x1F); //OFSY Address
  Wire.write(0xFB); //OFSY offset
  Wire.endTransmission();

  Wire.beginTransmission(Device_Address);
  Wire.write(0x20); //OFSZ Address
  Wire.write(0xFF); //OFSZ offset
  Wire.endTransmission();
  /*END Offset Calibration*/

  /*Start Enable Measuring*/
  Wire.beginTransmission(Device_Address);
  Wire.write(0x2D); //POWER_CTL Register
  Wire.write(0x08); //Enable Measuring
  Wire.endTransmission();
  /*END Enable Measuring*/
  
  /*Attach Interrupt to Digital pin 2*/
  attachInterrupt(digitalPinToInterrupt(2), ISR_Func, RISING);

Here is how I am receiving the values:

int16_t data_x = 0, data_x_lsb = 0; 
int16_t data_y = 0, data_y_lsb = 0; 
int16_t data_z = 0, data_z_lsb = 0;

Wire.beginTransmission(Device_Address);
Wire.write(0x32); //read LSB
Wire.endTransmission();

    Wire.requestFrom(Device_Address, 6);   
    while (Wire.available()) {
      data_x_lsb = Wire.read();
      data_x = Wire.read();
      data_y_lsb = Wire.read();
      data_y = Wire.read();
      data_z_lsb = Wire.read();
      data_z = Wire.read();

       data_x = (data_x << 8) | (data_x_lsb);
       data_y = (data_y << 8) | (data_y_lsb);
       data_z = (data_z << 8) | (data_z_lsb);
    }
    
data_x = (double)data_x*49/1000
data_y = (double)data_y*49/1000
data_z = (double)data_z*49/1000

Sample output:

14:36:51.120 -> -0.072	-0.067	0.977
14:36:51.221 -> -0.087	-0.096	0.949
14:36:51.325 -> 0.010	-0.191	0.988
14:36:51.427 -> -0.062	-0.162	1.071
14:36:51.536 -> -0.010	-0.088	1.071
14:36:51.614 -> -0.015	-0.037	1.052
14:36:51.725 -> -0.022	-0.047	1.044
14:36:51.837 -> 0.062	-0.043	1.012
14:36:52.025 -> FIFO STATUS REG: A0
14:36:52.025 -> Shock Occured
14:36:52.062 -> ACT STATUS SHOCK REG: 1
14:36:52.062 -> INT_SOURCE: C3
14:36:52.137 -> 0.055	-0.081	0.997
14:36:52.252 -> 0.024	0.031	1.033
14:36:52.354 -> 0.011	-0.072	1.079
14:36:52.455 -> 0.022	-0.031	0.973
14:36:52.547 -> 0.014	-0.042	1.041
14:36:52.654 -> -0.062	-0.036	1.018
14:36:52.770 -> -0.080	-0.003	1.003
14:36:52.880 -> -0.081	-0.118	1.084
14:36:52.972 -> -0.080	-0.039	1.046
14:36:53.079 -> -0.109	-0.016	0.930

Edit Notes

edited code
[edited by: RajT at 1:29 PM (GMT -5) on 24 Jan 2023]
  • Update:

    I am able to get the output values. All I had to do was resetting the trigger mode by entering into bypass mode in the initial setup.

    and resetting again after each shock event.  

    This is the code section I added in my setup and calling after each shock event:

      /*START Disable Trigger Mode/enable Bypass Mode*/
      Wire.beginTransmission(Device_Address);
      Wire.write(0x38); //FIFO_CTL Register Address
      Wire.write(0x2A); //Disable Trigger Mode, set samples = 10
      Wire.endTransmission();
      /*END Disable Trigger Mode/enable Bypass Mode*/
    
      /*START Enable Trigger Mode*/
      Wire.beginTransmission(Device_Address);
      Wire.write(0x38); //FIFO_CTL Register Address
      Wire.write(0xEA); //Enable Trigger Mode, set samples = 10
      Wire.endTransmission();
      /*END Enable Trigger Mode*/

    As for the values remaining constant even after shock, I was resetting trigger mode after reading only the output FIFO [0]), when there are 10 FIFOs to collect data, as I have configured in register 0x38(samples = 10). So, the shock values were being stored in the later stages of FIFOs and not in FIFO [0]. Reading FIFO more than 10 times after shock event and then resetting the trigger mode solved the problem.

    Sample Output(X Y Z in g):

    0.000   0.000   0.196
    -0.490  0.098   0.000
    0.098   -0.392  0.980
    Shock Occured
    FIFO STATUS REG: A0
    ACT STATUS SHOCK REG: 1
    INT_SOURCE: C3
    0.490   -0.098  2.156
    0.490   -0.098  2.156
    0.392   0.098   1.960
    0.392   0.294   2.254
    0.294   0.098   1.960
    -0.784  -0.882  1.470
    -0.686  -0.980  1.274
    10.976  13.524  59.290
    27.342  17.934  36.358
    -13.034 -6.566  -1.666
    -0.098  0.098   1.078
    0.000   0.294   0.686
    0.098   0.098   1.470