Closed DandrewsDev closed 1 year ago
Yep, it's def a clock stretcher, which never plays nice on a Pi.
Before giving up I2C, try software based I2C using the i2c-gpio overlay. https://github.com/raspberrypi/firmware/blob/5f40391c32ca871c8491b4d78c1e60f0c28120f5/boot/overlays/README#L1731
Okay so I gave software I2c a shot, and ran into a totally different issue.
Traceback (most recent call last):
File "/home/pi/accTest/acc.py", line 18, in <module>
bno.enable_feature(BNO_REPORT_ROTATION_VECTOR)
File "/usr/local/lib/python3.9/dist-packages/adafruit_bno08x/__init__.py", line 985, in enable_feature
raise RuntimeError("Was not able to enable feature", feature_id)
RuntimeError: ('Was not able to enable feature', 5)
import adafruit_bitbangio
i2c = adafruit_bitbangio.I2C(board.D19, board.D26)
bno = BNO08X_I2C(i2c)
bno.enable_feature(BNO_REPORT_ROTATION_VECTOR)
So to check, I tried an i2c scan, using that same bitbang I2c connection. I2C addresses found: ['0x4a']. Which is correct. So the connection is working and seeing the device, but data to and from seems to be a problem.
I went ahead and wired up my sensor for SPI, and am running into a different issue.
Sample code Im running
from time import sleep
import board
import busio
from digitalio import DigitalInOut, Direction
from adafruit_bno08x.spi import BNO08X_SPI
spi = busio.SPI(board.SCK, MISO=board.MISO, MOSI=board.MOSI)
cs = DigitalInOut(board.D5)
cs.direction = Direction.OUTPUT
int_pin = DigitalInOut(board.D13)
int_pin.direction = Direction.INPUT
wake_pin = DigitalInOut(board.D6)
wake_pin.direction = Direction.INPUT
reset_pin = DigitalInOut(board.D6)
reset_pin.direction = Direction.INPUT
bno = BNO08X_SPI(spi, cs, int_pin, wake_pin, reset_pin, debug=True)
while True:
print("getting quats")
quat = bno.quaternion # pylint:disable=no-member
print("Rotation Vector Quaternion:")
print(
"I: %0.6f J: %0.6f K: %0.6f Real: %0.6f" % (quat.i, quat.j, quat.k, quat.real)
)
print("")
sleep(0.5)
And error message.
DBG:: ********** __init__ *************
Hard resetting...
Done!
Traceback (most recent call last):
File "/home/pi/accTest/spiAcc.py", line 23, in <module>
bno = BNO08X_SPI(spi, cs, int_pin, wake_pin, reset_pin, debug=True)
File "/usr/local/lib/python3.9/dist-packages/adafruit_bno08x/spi.py", line 40, in __init__
super().__init__(resetpin, debug)
File "/usr/local/lib/python3.9/dist-packages/adafruit_bno08x/__init__.py", line 513, in __init__
self.initialize()
File "/usr/local/lib/python3.9/dist-packages/adafruit_bno08x/__init__.py", line 518, in initialize
self.hard_reset()
File "/usr/local/lib/python3.9/dist-packages/adafruit_bno08x/spi.py", line 56, in hard_reset
self._read_packet()
File "/usr/local/lib/python3.9/dist-packages/adafruit_bno08x/spi.py", line 103, in _read_packet
self._read_header()
File "/usr/local/lib/python3.9/dist-packages/adafruit_bno08x/spi.py", line 98, in _read_header
spi.readinto(self._data_buffer, end=4, write_value=0x00)
File "/usr/local/lib/python3.9/dist-packages/busio.py", line 390, in readinto
return self._spi.readinto(buf, start, end, write_value=write_value)
File "/usr/local/lib/python3.9/dist-packages/adafruit_blinka/microcontroller/generic_linux/spi.py", line 101, in readinto
self._spi.max_speed_hz = self.baudrate
File "/usr/local/lib/python3.9/dist-packages/Adafruit_PureIO/spi.py", line 323, in max_speed_hz
self._ioctl(SPI._IOC_WR_MAX_SPEED_HZ, max_speed_hz)
File "/usr/local/lib/python3.9/dist-packages/Adafruit_PureIO/spi.py", line 223, in _ioctl
arg = struct.pack("=" + structure, data)
struct.error: required argument is not an integer
I've checked my wiring vs the spec 3 or 4 times now and everything looks good.
I saw a comment somewhere "# need to limit clock to 3Mhz" for this SPI device. But not mention of where or how to se that clock speed limit. So that might be my issue there. But I've now tried I2c, software I2c, and SPI and am unable to get it to spit back data at anything more than 20 samples a second.
How about the suggestion here: https://learn.adafruit.com/adafruit-9-dof-orientation-imu-fusion-breakout-bno085?view=all#python-computer-wiring-3072324 to go back to hardware I2C and up the clock speed to 400kHz?
Well thats something I had tried before I started lowering the I2C clock speed. It was throwing basically identical errors to those I had reported initially of UNKNOWN Report Type.
I however tried that exact setup again. And then ran into the same issues. But I had a handful of these sensors sitting around so I tried another on I2C with the same settings, and setup as the first. And no problems. Able to get around 250 samples per second of full data without issue.
Closing for now as its currently working fairly well over hardware I2C at 400kHz, with a second sensor.
I am seeing a number of issues working with this library and sensor when reading over I2c. Seems that there is some serious clock stretching issues with this sensor.
Here is some example of the code I am working with.
I have been getting good measurements when its not throwing errors. To help fix these errors I've adjust the I2c bus speed in /boot/config.txt. Currently its set to 20khz.
dtparam=i2c_arm_baudrate=20000
The more I lower that speed, the less and less I see errors. However it is having a massive impact on the rate at which I can poll the sensor. At the 20khz I am now limited to around 18 samples per second for Acc/Gyro/Quat data.
I am unable to use a UART here as the 1 hardware UART is already in use. And doing a software UART seems to have very similar issues with errors being thrown.
Is SPI my best option here? Will it suffer the same issues as I2c and UART? Most of the examples and documentation I've seen for this sensor show I2c. I'd like to get around 100 samples a second for Acc/Gyro/Quat data. Is there anything I can try where that sort of data rate seems likely?