01-10-2021 06:05 PM
Hello
I am trying to implement inline self-test of the BMA250 accelerometer, mounted on a board at our product. It is calibrated to measure up to 2g. As you point out at the datasheet at table 10, I should see difference of at least 0.8g between +x and -x g values - i.e. difference of 256*0.8=204.8 beteween the values.
Unfotrunately I checked in 2 different accelerometers and on x dimention the difference is never larger than 120, so it is not even close. The other 2 axis pass the self-test fine. I put 300 ms sleep between every measure and reading.
What do you think is the problem?
Kind reagrds
Eli
Solved! Go to Solution.
01-12-2021 03:49 AM
Hi,
I haven't BMA250 datasheet, only refer page 20 self-test of bst-bma253-ds000.pdf .
One suggestion, when you active each axis, please wait for at least 50 msec, then read register data.
Or, You could upload this datasheet and code here, I could double check if any problem.
Best regards.
01-12-2021 09:55 AM
Hi
I also don't have the latest datasheet and I use this one from muser: https://www.mouser.com/datasheet/2/783/BST-BMA250-DS002-05-786487.pdf
It is revision 1.15 so maybe there are typos there... Please check if you have access to the most updated datasheet.
Regarding the code, please see it here in python:
def selftest(self):
self.bus.write_byte_data(self.address, 0x14, 0xB6)
time.sleep(0.3)
self.bus.write_byte_data(self.address, 0x32, 0x01)
time.sleep(0.3)
data_x_pos = self.bus.read_i2c_block_data(self.address, 0x02, 2)
# Convert the data to 10 bits
Accl_x_pos = (data_x_pos[1] * 256 + (data_x_pos[0] & 0xC0)) / 64
if Accl_x_pos > 511 :
Accl_x_pos -= 1024
self.bus.write_byte_data(self.address, 0x14, 0xB6)
time.sleep(0.3)
self.bus.write_byte_data(self.address, 0x32, 0x05)
time.sleep(0.3)
data_x_neg = self.bus.read_i2c_block_data(self.address, 0x02, 2)
# Convert the data to 10 bits
Accl_x_neg = (data_x_neg[1] * 256 + (data_x_neg[0] & 0xC0)) / 64
if Accl_x_neg > 511 :
Accl_x_neg -= 1024
self.bus.write_byte_data(self.address, 0x14, 0xB6)
time.sleep(0.3)
self.bus.write_byte_data(self.address, 0x32, 0x02)
time.sleep(0.3)
data_y_pos = self.bus.read_i2c_block_data(self.address, 0x04, 2)
# Convert the data to 10 bits
Accl_y_pos = (data_y_pos[1] * 256 + (data_y_pos[0] & 0xC0)) / 64
if Accl_y_pos > 511 :
Accl_y_pos -= 1024
self.bus.write_byte_data(self.address, 0x14, 0xB6)
time.sleep(0.3)
self.bus.write_byte_data(self.address, 0x32, 0x06)
time.sleep(0.3)
data_y_neg = self.bus.read_i2c_block_data(self.address, 0x04, 2)
# Convert the data to 10 bits
Accl_y_neg = (data_y_neg[1] * 256 + (data_y_neg[0] & 0xC0)) / 64
if Accl_y_neg > 511 :
Accl_y_neg -= 1024
self.bus.write_byte_data(self.address, 0x14, 0xB6)
time.sleep(0.3)
self.bus.write_byte_data(self.address, 0x32, 0x03)
time.sleep(0.3)
data_z_pos = self.bus.read_i2c_block_data(self.address, 0x06, 2)
# Convert the data to 10 bits
Accl_z_pos = (data_z_pos[1] * 256 + (data_z_pos[0] & 0xC0)) / 64
if Accl_z_pos > 511 :
Accl_z_pos -= 1024
self.bus.write_byte_data(self.address, 0x14, 0xB6)
time.sleep(0.3)
self.bus.write_byte_data(self.address, 0x32, 0x07)
time.sleep(0.3)
data_z_neg = self.bus.read_i2c_block_data(self.address, 0x06, 2)
# Convert the data to 10 bits
Accl_z_neg = (data_z_neg[1] * 256 + (data_z_neg[0] & 0xC0)) / 64
if Accl_z_neg > 511 :
Accl_z_neg -= 1024
self.bus.write_byte_data(self.address, 0x14, 0xB6)
time.sleep(0.3)
return Accl_x_pos, Accl_x_neg, Accl_y_pos, Accl_y_neg, Accl_z_pos, Accl_z_neg
the output of the function is:
selftest acc results:
-59.0
86.0
-218.0
285.0
146.0
359.0
as you can see, both x axis values are with much smaller difference then needed. The IMU lays stable on the table with z axis looking downwards.
01-12-2021 01:30 PM
Hi,
Two suggestion, please try.
1 After softreset, add 10 mec delay.
2 adjust x/y/z Self-test sequence, maybe result is different.
01-12-2021 05:45 PM
Unfortunately it does not seem to help...
I changed the seqence of the test to z-y-x and changed the delay after every softreset to 0.01:
def selftest(self):
self.bus.write_byte_data(self.address, 0x14, 0xB6)
time.sleep(0.01)
self.bus.write_byte_data(self.address, 0x32, 0x03)
time.sleep(0.3)
data_z_pos = self.bus.read_i2c_block_data(self.address, 0x06, 2)
# Convert the data to 10 bits
Accl_z_pos = (data_z_pos[1] * 256 + (data_z_pos[0] & 0xC0)) / 64
if Accl_z_pos > 511 :
Accl_z_pos -= 1024
self.bus.write_byte_data(self.address, 0x14, 0xB6)
time.sleep(0.01)
self.bus.write_byte_data(self.address, 0x32, 0x07)
time.sleep(0.3)
data_z_neg = self.bus.read_i2c_block_data(self.address, 0x06, 2)
# Convert the data to 10 bits
Accl_z_neg = (data_z_neg[1] * 256 + (data_z_neg[0] & 0xC0)) / 64
if Accl_z_neg > 511 :
Accl_z_neg -= 1024
self.bus.write_byte_data(self.address, 0x14, 0xB6)
time.sleep(0.01)
self.bus.write_byte_data(self.address, 0x32, 0x02)
time.sleep(0.3)
data_y_pos = self.bus.read_i2c_block_data(self.address, 0x04, 2)
# Convert the data to 10 bits
Accl_y_pos = (data_y_pos[1] * 256 + (data_y_pos[0] & 0xC0)) / 64
if Accl_y_pos > 511 :
Accl_y_pos -= 1024
self.bus.write_byte_data(self.address, 0x14, 0xB6)
time.sleep(0.01)
self.bus.write_byte_data(self.address, 0x32, 0x06)
time.sleep(0.3)
data_y_neg = self.bus.read_i2c_block_data(self.address, 0x04, 2)
# Convert the data to 10 bits
Accl_y_neg = (data_y_neg[1] * 256 + (data_y_neg[0] & 0xC0)) / 64
if Accl_y_neg > 511 :
Accl_y_neg -= 1024
self.bus.write_byte_data(self.address, 0x14, 0xB6)
time.sleep(0.01)
self.bus.write_byte_data(self.address, 0x32, 0x01)
time.sleep(0.03)
data_x_pos = self.bus.read_i2c_block_data(self.address, 0x02, 2)
# Convert the data to 10 bits
Accl_x_pos = (data_x_pos[1] * 256 + (data_x_pos[0] & 0xC0)) / 64
if Accl_x_pos > 511 :
Accl_x_pos -= 1024
self.bus.write_byte_data(self.address, 0x14, 0xB6)
time.sleep(0.01)
self.bus.write_byte_data(self.address, 0x32, 0x05)
time.sleep(0.03)
data_x_neg = self.bus.read_i2c_block_data(self.address, 0x02, 2)
# Convert the data to 10 bits
Accl_x_neg = (data_x_neg[1] * 256 + (data_x_neg[0] & 0xC0)) / 64
if Accl_x_neg > 511 :
Accl_x_neg -= 1024
self.bus.write_byte_data(self.address, 0x14, 0xB6)
time.sleep(0.01)
return Accl_x_pos, Accl_x_neg, Accl_y_pos, Accl_y_neg, Accl_z_pos, Accl_z_neg
the results of the few runs I did for +x, -x, +y, -y, +z, -z order (in many seqences) are as follows:
nvidia@tegra-ubuntu:~/Downloads$ sudo python3 imu.py
IMU operation - Please choose CALIB or SELFTEST or READ
SELFTEST
selftest acc results:
-59.0
85.0
-220.0
283.0
146.0
356.0
nvidia@tegra-ubuntu:~/Downloads$ sudo python3 imu.py
IMU operation - Please choose CALIB or SELFTEST or READ
SELFTEST
selftest acc results:
-59.0
84.0
-219.0
286.0
147.0
359.0
nvidia@tegra-ubuntu:~/Downloads$ sudo python3 imu.py
IMU operation - Please choose CALIB or SELFTEST or READ
SELFTEST
selftest acc results:
-61.0
84.0
-221.0
285.0
147.0
359.0
nvidia@tegra-ubuntu:~/Downloads$
Same type of results is for another BMA250 accelerometer I tried... what do you suggest?