[英]ADXL375Z Shock Threshold False Triggering
I am working on ADXL375 and interfacing it with Arduino UNO using I2C protocol.我正在研究 ADXL375 并使用 I2C 协议将其与 Arduino UNO 连接。 I get the values of X, Y, Z axis as mentioned in the datasheet, ie, when placed horizontally I get x=0g, y=0g, z=1g(approx. calibrated).我得到数据表中提到的 X、Y、Z 轴的值,即,当水平放置时,我得到 x=0g、y=0g、z=1g(近似校准)。 I have enabled trigger mode and mapped interrupt to INT2.我已启用触发模式并将中断映射到 INT2。 My Shock Threshold is set to 0x28 = 31.2g.我的冲击阈值设置为 0x28 = 31.2g。
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).当我点击桌子上的模块时,即使阈值是 31.2g,中断也会触发,但我得到的值没有改变(大约 x= 0,y=0,z=1)。 How to get the values of X, Y, Z during the shock?冲击过程中如何得到X、Y、Z的值? When I tilt the module, I can see the values change accordingly.当我倾斜模块时,我可以看到值相应地发生变化。 but these values hardly go beyond 3g.但这些值几乎没有超过 3g 的 go。 what am I doing wrong?我究竟做错了什么?
Here is my code setup for registers:这是我的寄存器代码设置:
/*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*/
//Used for Double Shock Detection Only**
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:样本 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
According to datasheet, it says that we need to reset trigger mode after each triggering event.根据数据表,它说我们需要在每次触发事件后重置触发模式。 I tried doing that but to no avail.我尝试这样做但无济于事。
I am doing multibyte read using I2C and implemented moving average filter with the span of 4.我正在使用 I2C 进行多字节读取,并实现了跨度为 4 的移动平均滤波器。
Update: I am able to get the output values.更新:我能够获得 output 值。 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).至于即使在冲击后仍保持不变的值,我在仅读取 output FIFO [0] 后重置触发模式,当有 10 个 FIFO 收集数据时,正如我在寄存器 0x38(样本 = 10)中配置的那样。 So, the shock values were being stored in the later stages of FIFOs and not in FIFO [0].因此,冲击值存储在 FIFO 的后期,而不是 FIFO [0]。 Reading FIFO more than 10 times after shock event and then resetting the trigger mode solved the problem.冲击事件后读取 FIFO 超过 10 次,然后重置触发模式解决了问题。
Sample Output(XYZ in g):样本输出(XYZ,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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.