2025-02-14 3:52 AM
Hi, I’m working with the IIS3DWB accelerometer to acquire single-axis data (Z-axis) using the following setup:
I have attempted different methods to read the Z-axis data. First, I tried reading the Z-axis high (0x2D) and low (0x2C) registers using a timer with auto-increment. I also tried using 1AX_TO_3REGOUT mode and reading all 6 registers (0x28 to 0x2D) using a timer with auto-increment.
I then configured the sensor with the following register settings:
write_register(IIS3DWB_CTRL1_XL, 0x00); // Power Down
write_register(IIS3DWB_CTRL6_C, 0x03); // Single Axis Mode (Z-Axis)
write_register(IIS3DWB_CTRL1_XL, 0xA4); // Power On, Full Scale 16g, 26.667 kHz ODR write_register(IIS3DWB_CTRL3_C, 0x44); // BDU and Auto Increment Enabled write_register(IIS3DWB_CTRL8_XL, 0xF4); // High-pass and Low-pass Filters
write_register(IIS3DWB_CTRL4_C, 0x01); // 6 Consecutive Single Axis Values
write_register(IIS3DWB_CTRL5_C, 0x20); // Wraparound Rounding
After setting up the above configuration, I attempted burst reading of the registers to acquire data.
I noticed that the RMS values are accurate at lower frequencies but start to become inaccurate at higher frequencies above 800 Hz. Additionally, even when the input amplitude remains constant, the output RMS values differ across different frequencies.
I suspect that using FIFO might help in achieving more accurate RMS calculations at higher frequencies, but I am unsure how to configure it correctly in single-axis mode.
Has anyone faced similar issues or successfully implemented high-frequency RMS calculations using IIS3DWB? Any insights on optimal FIFO settings or alternative approaches would be greatly appreciated!
Thanks in advance!
Solved! Go to Solution.
2025-02-17 10:27 AM
First recommendation is to use the official drivers to get the output from IIS3DWB, look here:
Reason is that combining two bytes in one signed int value and scaling with correct sensitivity may sometime be done in the wrong way, and we want to rule out coding errors. Also, as you have notices, at 26kHz ODR it should take 1second to get 26k samples. You can get all the samples, or you can poll the sensor fewer times, effectively down-sampling
Second recommendation is to know what to expect: in steady conditions, only gravity acts on the sensor, the datasheet says that bandwidth is 6.3kHz and MAX noise density is 190ug/sqrtHz in 3-axes mode, and 130ug/sqrtHz in 1-axis mode; the formula to compute the expected RMS noise is RMS = noise density * sqrt(bandwidth)
190ug/sqrtHz * sqrt(6300Hz) = 15.1mg and 130ug/sqrtHz * sqrt(6300Hz) = 10.3mg, this is what you should expect, less if you enable the embedded low-pass filter which reduces the bandwidth and rejects out-of-band noise.
The RMS will be the same when computed on all samples read out, or on a subset of those samples. So, if you see different values, then for sure there is a problem with the data read out. Can you confirm you get this or better numbers in steady conditions?
Third, if you are computing the RMS not in static conditions, but when the accelerometer is subject to some specific stimulus, then we would need to know more about the stimulus, how it is generated and how many harmonics does it have. IIS3DWB includes an anti-alias filter before the ADC that attenuates anything above 6.3kHz, for example at 10kHz attenuation is 10dB, which means that something is still folded in the available bandwidth, the roll-off is sharp and attenuation is 70-90dB for higher frequencies). Also, sensitivity is defined +/-2% so you can expect this variability in the RMS output.
2025-02-14 9:59 AM
Can you share more details?
What is the RMS that you expect and what is the RMS that you are getting?
If I understand correctly, you are polling the sensor, therefore downsampling? Example polling at 800Hz?
Is the device in steady conditions? (if not please try to measure the RMS in steady conditions)
2025-02-16 8:22 PM
Sorry for the late reply.
I am calculating RMS by storing 26,667 values in an array using the following method:
z_accel_value = (int16_t)((z_high << 8) | z_low);
input[i] = z_accel_value * 0.000488;
I am then calculating RMS using arm_rms_f32().
I tried different configurations as mentioned before, where it took approximately 0.854, 1.204, and 1.588 seconds to capture the array. I suspect that I am missing some values due to this.
For example, when I apply 0.8 g to the accelerometer at different frequencies, I get varying RMS values:
I tried correcting this using a moving average filter with window sizes of 3, 5, and 7. This improved accuracy at 1500 Hz (e.g., at 0.8 g, I got 0.91 g), but at 2000 Hz, the RMS dropped to 0.2 g. Even when increasing the amplitude to 1 g or 1.5 g, the RMS increased very slowly at 2000 Hz.
I observed similar behavior with weighted moving average and exponential moving average filters.
Can you guide me on how to get consecutive values through FIFO for single-axis (Z-axis) acquisition? I suspect that using the FIFO buffer might help in obtaining more accurate RMS values, especially at higher frequencies.
2025-02-17 10:27 AM
First recommendation is to use the official drivers to get the output from IIS3DWB, look here:
Reason is that combining two bytes in one signed int value and scaling with correct sensitivity may sometime be done in the wrong way, and we want to rule out coding errors. Also, as you have notices, at 26kHz ODR it should take 1second to get 26k samples. You can get all the samples, or you can poll the sensor fewer times, effectively down-sampling
Second recommendation is to know what to expect: in steady conditions, only gravity acts on the sensor, the datasheet says that bandwidth is 6.3kHz and MAX noise density is 190ug/sqrtHz in 3-axes mode, and 130ug/sqrtHz in 1-axis mode; the formula to compute the expected RMS noise is RMS = noise density * sqrt(bandwidth)
190ug/sqrtHz * sqrt(6300Hz) = 15.1mg and 130ug/sqrtHz * sqrt(6300Hz) = 10.3mg, this is what you should expect, less if you enable the embedded low-pass filter which reduces the bandwidth and rejects out-of-band noise.
The RMS will be the same when computed on all samples read out, or on a subset of those samples. So, if you see different values, then for sure there is a problem with the data read out. Can you confirm you get this or better numbers in steady conditions?
Third, if you are computing the RMS not in static conditions, but when the accelerometer is subject to some specific stimulus, then we would need to know more about the stimulus, how it is generated and how many harmonics does it have. IIS3DWB includes an anti-alias filter before the ADC that attenuates anything above 6.3kHz, for example at 10kHz attenuation is 10dB, which means that something is still folded in the available bandwidth, the roll-off is sharp and attenuation is 70-90dB for higher frequencies). Also, sensitivity is defined +/-2% so you can expect this variability in the RMS output.