Adafruit_CircuitPython_BNO055 icon indicating copy to clipboard operation
Adafruit_CircuitPython_BNO055 copied to clipboard

-92 degrees celsius randomly returned from imu's temperature field

Open snowpuppy opened this issue 4 years ago • 9 comments

While graphing this data, it was noticed that there were arbitrary dips to a negative value in the range of -92 degrees Celsius. Upon writing a simple test script, it was noticed that the library is indeed returning these large negative temperature values.

Sample Script:

!/bin/python

import board
import busio
import adafruit_bno055
i2c = busio.I2C(board.SCL, board.SDA)
sensor = adafruit_bno055.BNO055_I2C(i2c)

for i in range(1000):
    print('Temperature: {} degrees C'.format(sensor.temperature))
    print('Accelerometer: (m/s^2): {}'.format(sensor.acceleration))
    print('Magnetometer (microteslas): {}'.format(sensor.magnetic))
    print('Gyroscope (deg/sec): {}'.format(sensor.gyro))
    print('Euler angle: {}'.format(sensor.euler))
    print('Quaternion: {}'.format(sensor.quaternion))
    print('Linear acceleration (m/s^2): {}'.format(sensor.linear_acceleration))
    print('Gravity (m/s^2): {}'.format(sensor.gravity))

The output was redirected to a file like so: python3 imu_test.py > read_imu.txt Then ran grep for Temperature values: cat read_imu.txt | grep Temperature The output shows that temperature arbitrarily drops to -92/-93 degrees:

Temperature: 35 degrees C
Temperature: 35 degrees C
Temperature: 35 degrees C
Temperature: 35 degrees C
Temperature: 35 degrees C
Temperature: 35 degrees C
Temperature: 35 degrees C
Temperature: 35 degrees C
Temperature: -93 degrees C
Temperature: 35 degrees C
Temperature: 35 degrees C
Temperature: 35 degrees C
Temperature: 35 degrees C
Temperature: 35 degrees C
Temperature: -93 degrees C
Temperature: 35 degrees C
Temperature: 35 degrees C

snowpuppy avatar Oct 23 '20 00:10 snowpuppy

@snowpuppy Does it always return the same wrong value? From what you're saying it seems like it will sometimes return -92, sometimes -93; is that correct?

siddacious avatar Oct 26 '20 22:10 siddacious

@siddacious That's correct. I've only observed the same wrong values of -92 and -93. It's interesting to note though that the transition of random spikes from -93 to -92 aligns with the transition of the normal temperature reading from 35 to 36 degrees.

Output filtering out 35 and 36 degrees celsius: $ cat read_imu.txt | grep Temperature | egrep -v "(36|35)"

Temperature: -93 degrees C
Temperature: -93 degrees C
Temperature: -93 degrees C
Temperature: -93 degrees C
Temperature: -93 degrees C
Temperature: -93 degrees C
Temperature: -93 degrees C
Temperature: -93 degrees C
Temperature: -93 degrees C
Temperature: -93 degrees C
Temperature: -93 degrees C
Temperature: -93 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C
Temperature: -92 degrees C

snowpuppy avatar Oct 26 '20 23:10 snowpuppy

So, I tested this and was able to replicate it. I'm pretty sure the issue has something to do with reading the buffer.

35 in binary is: 00100011 -93 in (signed) binary is: 10100011

Not entirely sure what the best way to fix this mathematically is (I could always just do a check for a temperature change of more than n degrees since the last reading but I really don't want to do that) but I'm working on it.

evaherrada avatar Nov 25 '20 17:11 evaherrada

Looks like it could have something to do with clock stretching: https://community.bosch-sensortec.com/t5/MEMS-sensors-forum/BNO055-Temperature-fluctuation/td-p/13142 I have enabled software clock stretching, but it won't work if it's below 10kHz and the bad values still happen at 10kHz.

@siddacious Any thoughts on what strategy I should take?

I'm currently thinking it could make sense to make an overriding __get__ method for ROUnaryStruct (called _ReadOnlyUnaryStruct() in adafruit_bno055.py) that only runs when it detects it's running on a Pi. If the last 6 bits of the current byte and previous bytes are the same, then it would return that instead. I'm not a huge fan of this solution, but I don't think there's a way to do it purely mathematically while still allowing for negative numbers.

evaherrada avatar Nov 25 '20 17:11 evaherrada

Another thing I'm thinking of would be to just throw an error when the last and current temperatures are exactly 128 apart and then have the user handle it.

evaherrada avatar Nov 25 '20 18:11 evaherrada

@dherrada I think you're likely correct that this has to do with clock stretching, however I don't think that the Register lib is the place to address the issue, since it's shared by every platform and this issue only pertains to one.

I think https://github.com/adafruit/Adafruit_Blinka is a more appropriate place, as it is the glue between code written to the CircuitPython API and the hardware, so it would probably be the place to fix discrepancies between the two.

siddacious avatar Nov 27 '20 18:11 siddacious

@siddacious Sounds good. Do you think I should close the PR I made (#64)?

evaherrada avatar Nov 30 '20 20:11 evaherrada

@siddacious ^

evaherrada avatar Dec 16 '20 19:12 evaherrada

@dherrada I think so, yes.

siddacious avatar Dec 18 '20 17:12 siddacious

Closing. Most likely related to clock stretching and nominal fix is here: https://learn.adafruit.com/adafruit-bno055-absolute-orientation-sensor/python-circuitpython#python-computer-wiring-i2c-2998129

More info and options here: https://learn.adafruit.com/raspberry-pi-i2c-clock-stretching-fixes

caternuson avatar Nov 04 '22 16:11 caternuson