BNO08x on a QT Py ESP32 Pico not working
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- adafruit2
- Posts: 22148
- Joined: Fri Mar 11, 2005 7:36 pm
Re: BNO08x on a QT Py ESP32 Pico not working
gary, wanna try that code kindly donated by gamma?
- argonblue
- Posts: 93
- Joined: Wed Apr 25, 2012 12:18 am
Re: BNO08x on a QT Py ESP32 Pico not working
Interesting. I think that breakout board comes with pullup resistors installed? Do you still need the additional pullup if you lower the I2C clock speed to 100kHz?Be sure to add the extra pullup resistor to SDA (about 2K to 3K ohms).
- gammaburst
- Posts: 1015
- Joined: Thu Dec 31, 2015 12:06 pm
Re: BNO08x on a QT Py ESP32 Pico not working
Hi argonblue,
The timing problem is independent of I2C clock frequency, so slowing the clock won't help.
Here's a simple test to see if your BNO055/BNO085 project has the I2C timing problem: Connect a short wire to SDA and grab its bare end with two fingers. If your project stutters/crashes, it has the problem.
Details: The extra pullup resistor is a tricky fix that helps overcome an SDA-to-SCL setup-time violation caused by the BNO055/BNO085 chip during clock-stretching. The symptom is occasional or frequent I2C corruption. By adding an extra resistor (roughly 2K or 3K ohms) that pulls-up SDA more strongly than SCL, SDA now rises more quickly than SCL, thereby providing additional nanoseconds of setup time. That doesn't eliminate the timing violation, but it reduces the violation sufficiently to avoid malfunction.
Hi adafruit2 and other folks,
This is my understanding/opinion:
Lots of folks call that .inf file a "driver", but it's merely a text file that helps Windows identify your new gadget as a USB Communications Device Class (CDC) gadget. Windows already has the required CDC driver (executable code).
Basically, you use Device Manager to discover your new CDC gadget's PID and VID identifier strings, then carefully copy the strings into a generic CDC .inf file, then optionally modify the product name strings, and then use Device Manager with the .inf file to "update" your gadget. Beware, the modified .inf file has no signature credentials, so you need to click through a red warning message. After that, you'll find a copy of your .inf file in \Windows\inf.
If you want to undo your .inf installation, use Device Manager to "uninstall" your gadget, and tell it to "delete the driver software". The .inf copy will disappear from \Windows\inf.
I've done those steps several times on my Win7 with two different Adafruit ESP32 boards.
I have a Win10 machine too.
The timing problem is independent of I2C clock frequency, so slowing the clock won't help.
Here's a simple test to see if your BNO055/BNO085 project has the I2C timing problem: Connect a short wire to SDA and grab its bare end with two fingers. If your project stutters/crashes, it has the problem.
Details: The extra pullup resistor is a tricky fix that helps overcome an SDA-to-SCL setup-time violation caused by the BNO055/BNO085 chip during clock-stretching. The symptom is occasional or frequent I2C corruption. By adding an extra resistor (roughly 2K or 3K ohms) that pulls-up SDA more strongly than SCL, SDA now rises more quickly than SCL, thereby providing additional nanoseconds of setup time. That doesn't eliminate the timing violation, but it reduces the violation sufficiently to avoid malfunction.
Hi adafruit2 and other folks,
This is my understanding/opinion:
Lots of folks call that .inf file a "driver", but it's merely a text file that helps Windows identify your new gadget as a USB Communications Device Class (CDC) gadget. Windows already has the required CDC driver (executable code).
Basically, you use Device Manager to discover your new CDC gadget's PID and VID identifier strings, then carefully copy the strings into a generic CDC .inf file, then optionally modify the product name strings, and then use Device Manager with the .inf file to "update" your gadget. Beware, the modified .inf file has no signature credentials, so you need to click through a red warning message. After that, you'll find a copy of your .inf file in \Windows\inf.
If you want to undo your .inf installation, use Device Manager to "uninstall" your gadget, and tell it to "delete the driver software". The .inf copy will disappear from \Windows\inf.
I've done those steps several times on my Win7 with two different Adafruit ESP32 boards.
I have a Win10 machine too.
- garyrkey
- Posts: 13
- Joined: Fri Feb 07, 2014 8:14 pm
Re: BNO08x on a QT Py ESP32 Pico not working
Thanks, gammaburst! You got me where I wanted to go.
I'm talking to the BNO08x, and it is telling everything I want to hear!
I'm talking to the BNO08x, and it is telling everything I want to hear!
- gammaburst
- Posts: 1015
- Joined: Thu Dec 31, 2015 12:06 pm
Re: BNO08x on a QT Py ESP32 Pico not working
Yay!
Have fun with your project.
Have fun with your project.
- gammaburst
- Posts: 1015
- Joined: Thu Dec 31, 2015 12:06 pm
Re: BNO08x on a QT Py ESP32 Pico not working
Hi adafruit2,
Regarding the problem: "Plain" ESP32 and Adafruit BNO08x library seem to not work together:
A few days ago I too saw that problem when I switched from a QT Py ESP32-S2 (Adafruit 5348) to a Feather32 HUZZAH (Adafruit 3619).
I may have fixed it. I connected an I2C analyzer and saw message problems after the attempted BNO soft reset. I edited library file "Adafruit_BNO08x.cpp" and replaced function "i2chal_open()" with the following code. The Feather32 now works fine for me.
That inspired me to improve the soft reset code in my 28-June-2022 example sketch:
My 26-June-2022 example sketch contains this line of code:
bno08x.enableReport(SH2_ROTATION_VECTOR,100);
The value needs to be microseconds, so 100 is bogus. It should be 10000 (for 100 Hz messages) or 100000 (for 10 Hz messages). Sorry if I messed up anyone with that!
Regarding the problem: "Plain" ESP32 and Adafruit BNO08x library seem to not work together:
A few days ago I too saw that problem when I switched from a QT Py ESP32-S2 (Adafruit 5348) to a Feather32 HUZZAH (Adafruit 3619).
I may have fixed it. I connected an I2C analyzer and saw message problems after the attempted BNO soft reset. I edited library file "Adafruit_BNO08x.cpp" and replaced function "i2chal_open()" with the following code. The Feather32 now works fine for me.
Code: Select all
#warning Experimental BNO08x soft reset
static int i2chal_open(sh2_Hal_t *self)
{
uint8_t softreset_pkt[] = {5, 0, 1, 0, 1};
while (!i2c_dev->write(softreset_pkt, 5)) // send soft reset until success
delay(30);
delay(300); // allow plenty of time for BNO to reboot
return 0;
}
Code: Select all
#include <Wire.h>
#define I2C_PORT 2 // 1 selects first I2C port, 2 selects second I2C port
#define BNO_ADDR 0x4A // I2C address of BNO085 (0x4A if SA0=0, 0x4B if SA0=1)
//#define pinRST A0 // comment-out this line to soft-reset BNO with a command, uncomment this line to output a hard-reset pulse to BNO's RST pin
#define I2C_CLOCK 200000L // I2C clock rate
#define SERIAL_BAUD 115200L // serial port baud rate
#define SENSOR_US 10000L // time between sensor reports, microseconds, 10000L is 100 Hz, 20000L is 50 Hz, etc.
// *******************
// ** Output data **
// *******************
int16_t iqw, iqx, iqy, iqz; // quaternion, integer
static void output_data()
{
// my BNO08x orientation dot is towards left rear, rotate BNO08x quaternion to NED conventions
float q0 = iqw+iqz;
float q1 = iqx+iqy;
float q2 = iqx-iqy;
float q3 = iqw-iqz;
float norm = 1 / sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);
q0 *= norm;
q1 *= norm;
q2 *= norm;
q3 *= norm;
Serial.print("Quaternion: ");
Serial.print(q0, 4); Serial.print(" ");
Serial.print(q1, 4); Serial.print(" ");
Serial.print(q2, 4); Serial.print(" ");
Serial.print(q3, 4); Serial.println();
}
#if I2C_PORT == 1 // use first I2C port
#define WIRE Wire
#define SELECT_I2C_PINS()
#elif I2C_PORT == 2 // use second I2C port
#define WIRE Wire1
#define SELECT_I2C_PINS() WIRE.setPins(SDA1,SCL1) // Adafruit advises this for QT Py ESP32-S2
#endif
// *******************************
// ** Request desired reports **
// *******************************
#define QUAT_REPORT 0x05 // quaternion report, see 6.5.18
#define TIME_REPORT 0xFB // time report, see 7.2.1
static void request_reports(void)
{
// request quaternion reports, see 6.5.4
static const uint8_t cmd_quat[] = {21, 0, 2, 0, 0xFD, QUAT_REPORT, 0, 0, 0, (SENSOR_US>>0)&255, (SENSOR_US>>8)&255, (SENSOR_US>>16)&255, (SENSOR_US>>24)&255, 0, 0, 0, 0, 0, 0, 0, 0};
WIRE.beginTransmission(BNO_ADDR); WIRE.write(cmd_quat, sizeof(cmd_quat)); WIRE.endTransmission();
// at 10ms rate, BNO08x outputs most reports in one burst, Gyro-Quat-Lac-Mag, however Acc is asynchronous and a few percent faster. Situation may vary with SENSOR_US and maximum sensor rates.
}
// ******************************************
// ** Check for and parse sensor reports **
// ******************************************
static void ensure_read_available(int16_t length) // ensure a read byte is available, if necessary reread and discard 4-byte SHTP header, then read as much length as possible
{
if (!WIRE.available())
WIRE.requestFrom(BNO_ADDR,4+length), WIRE.read(), WIRE.read(), WIRE.read(), WIRE.read();
}
static void check_report()
{
int16_t length;
uint8_t channel __attribute__((unused));
uint8_t seqnum __attribute__((unused));
WIRE.requestFrom(BNO_ADDR,4+1); // read 4-byte SHTP header and first byte of cargo
length = WIRE.read(); // length LSB
length |= (WIRE.read() & 0x7F) << 8; // length MSB (ignore continuation flag)
channel = WIRE.read(); // channel number
seqnum = WIRE.read(); // sequence number (ignore)
length -= 4; // done reading SHTP Header
if (length <= 0 || length > 1000) // if null/bad/degenerate SHTP header
return;
while (length) // while more reports in cargo
{
uint8_t buf[20]; // report buffer, big enough for longest interesting report (uninteresting reports will be ignored)
uint16_t n = 0; // index into report buffer
ensure_read_available(length);
buf[n++] = WIRE.read(); // first byte of report
length--;
// known reports
if (channel==3 && buf[0]==TIME_REPORT && length >= 5-1)
{
for (uint8_t n=1; n<5; n++) // read remainder of report
{
ensure_read_available(length);
buf[n] = WIRE.read();
length--;
}
continue;
}
if (channel==3 && buf[0]==QUAT_REPORT && length >= 14-1)
{
for (uint8_t n=1; n<14; n++) // read remainder of report
{
ensure_read_available(length);
buf[n] = WIRE.read();
length--;
}
iqw = *(int16_t*)&buf[10];
iqx = *(int16_t*)&buf[4];
iqy = *(int16_t*)&buf[6];
iqz = *(int16_t*)&buf[8];
output_data();
continue;
}
// unknown reports
while (length) // discard remainder of cargo (shouldn't happen very often)
{
ensure_read_available(length);
WIRE.read();
length--;
}
continue;
}
return;
}
// **********************
// ** Setup and Loop **
// **********************
void setup()
{
Serial.begin(SERIAL_BAUD); // initialize serial
Serial.println("\nRunning...");
#ifdef pinRST // hard reset BNO by pulsing its RST pin
//hard_reset();
pinMode(pinRST,OUTPUT);
digitalWrite(pinRST,LOW);
delay(2); // because 1 sometimes gets truncated
digitalWrite(pinRST,HIGH);
delay(300); // let BNO reboot, about 150 works marginally, so let's double it
#endif
// pinMode(A1,OUTPUT); digitalWrite(A1,HIGH); delayMicroseconds(10); digitalWrite(A1,LOW); delayMicroseconds(10); // scope trigger for debugging
SELECT_I2C_PINS();
WIRE.begin(); // initialize I2C
WIRE.setClock(I2C_CLOCK);
// clear I2C bus, just in case
WIRE.beginTransmission(BNO_ADDR);
WIRE.endTransmission();
#ifndef pinRST // if no hard reset, soft reset BNO by sending SHTP "reset" command, see 1.3.1
do
{
static const uint8_t cmd_reset[] = {5, 0, 1, 0, 1};
delay(30);
WIRE.beginTransmission(BNO_ADDR);
WIRE.write(cmd_reset, sizeof(cmd_reset));
} while (WIRE.endTransmission()); // if failed to send reset command, try again
delay(300); // let BNO reboot, about 150 works marginally, so let's double it
#endif
request_reports(); // request desired reports
do // wait until BNO outputs non-zero quaternions
check_report();
while (!iqw && !iqx && !iqy && !iqz);
}
void loop()
{
check_report(); // check for reports
}
bno08x.enableReport(SH2_ROTATION_VECTOR,100);
The value needs to be microseconds, so 100 is bogus. It should be 10000 (for 100 Hz messages) or 100000 (for 10 Hz messages). Sorry if I messed up anyone with that!
- gammaburst
- Posts: 1015
- Joined: Thu Dec 31, 2015 12:06 pm
Re: BNO08x on a QT Py ESP32 Pico not working
Hi adafruit2,
Good news! After a long UPS shipping delay, I received some QT Py ESP32 Pico modules (Adafruit 5395).
I tested one with my soft-reset library modification (previous message).
The QT Py ESP32 Pico now seems to work fine with BNO085.
Can you confirm this adafruit2?
I had trouble following the instruction for installing the Windows driver for the Pico.
These two pages link to driver CH341SER.ZIP:
https://www.adafruit.com/product/5395
https://learn.adafruit.com/adafruit-qt- ... -ide-setup
But that didn't work - my Device Manager showed "USB Single Serial" with yellow exclamation mark.
I noticed the CH9102F on my Pico requires USB\VID_1A86&PID_55D4 which is in this driver:
http://www.wch-ic.com/downloads/CH343SER_ZIP.html
I installed CH343SER_ZIP using Adafuit's above instructions (unzip, run SETUP.EXE).
The Pico serial port now detects as "USB-Enhanced-SERIAL CH9102" and works fine.
QT Py. Oh now I get it. Cutie pie.
Good news! After a long UPS shipping delay, I received some QT Py ESP32 Pico modules (Adafruit 5395).
I tested one with my soft-reset library modification (previous message).
The QT Py ESP32 Pico now seems to work fine with BNO085.
Can you confirm this adafruit2?
I had trouble following the instruction for installing the Windows driver for the Pico.
These two pages link to driver CH341SER.ZIP:
https://www.adafruit.com/product/5395
https://learn.adafruit.com/adafruit-qt- ... -ide-setup
But that didn't work - my Device Manager showed "USB Single Serial" with yellow exclamation mark.
I noticed the CH9102F on my Pico requires USB\VID_1A86&PID_55D4 which is in this driver:
http://www.wch-ic.com/downloads/CH343SER_ZIP.html
I installed CH343SER_ZIP using Adafuit's above instructions (unzip, run SETUP.EXE).
The Pico serial port now detects as "USB-Enhanced-SERIAL CH9102" and works fine.
QT Py. Oh now I get it. Cutie pie.
- adafruit2
- Posts: 22148
- Joined: Fri Mar 11, 2005 7:36 pm
Re: BNO08x on a QT Py ESP32 Pico not working
:) can you submit a PR for that fix to github? that's the best way for us to test it - and if it works, merge it into the library!
- adafruit_support_carter
- Posts: 29168
- Joined: Tue Nov 29, 2016 2:45 pm
Re: BNO08x on a QT Py ESP32 Pico not working
@gammaburst I tested but could not recreate your success with getting this working on a QT Py ESP32 Pico:
https://github.com/adafruit/Adafruit_BN ... 1182127608
The latest ESP32 BSP turns on some compiler flags that cause previous warns to now be errors:
https://github.com/adafruit/Adafruit_BNO08x/issues/19
I did a quick patch for all those locally to get things to compile. So I'm not 100% same as current library code. I doubt that has anything to do with this.
What ESP32 BSP version were you using when you ran your test?
https://github.com/adafruit/Adafruit_BN ... 1182127608
The latest ESP32 BSP turns on some compiler flags that cause previous warns to now be errors:
https://github.com/adafruit/Adafruit_BNO08x/issues/19
I did a quick patch for all those locally to get things to compile. So I'm not 100% same as current library code. I doubt that has anything to do with this.
What ESP32 BSP version were you using when you ran your test?
- gammaburst
- Posts: 1015
- Joined: Thu Dec 31, 2015 12:06 pm
Re: BNO08x on a QT Py ESP32 Pico not working
Hi adafruit_support_carter,
Let's see if I can provide enough info to help you reproduce what I'm doing...
QT Py ESP32 Pico (Adafruit 5395) connected to BNO08x (Adafruit 4754).
Notice extra SDA pullup resistor:
My build environment:
- Win7 64-bit running on i7 processor
- Arduino IDE 1.8.5
- ESP32 support - not sure how to tell, Library Manager shows "ESP32 Built-In by Gochkov and Grokhtkov version 2.0.0"
- Library Adafruit_bno08x version 1.2.1, modified with my aforementioned soft reset patch.
My sketch:I've selected board "Adafruit QT Py ESP32". I click Upload button, wait a while (I don't see your compile errors), see "Hard resetting via RTS pin", then I press Ctrl+Shift+M to see nice Quaternion data scrolling in serial monitor window (set to 115200 baud).
Remember to install the extra SDA pullup resistor, or else you're asking for trouble.
Let's see if I can provide enough info to help you reproduce what I'm doing...
QT Py ESP32 Pico (Adafruit 5395) connected to BNO08x (Adafruit 4754).
Notice extra SDA pullup resistor:
My build environment:
- Win7 64-bit running on i7 processor
- Arduino IDE 1.8.5
- ESP32 support - not sure how to tell, Library Manager shows "ESP32 Built-In by Gochkov and Grokhtkov version 2.0.0"
- Library Adafruit_bno08x version 1.2.1, modified with my aforementioned soft reset patch.
My sketch:
Code: Select all
#include <Adafruit_BNO08x.h>
#define I2C_PORT 2 // 1 selects first I2C port, 2 selects second I2C port
Adafruit_BNO08x bno08x(-1);
void setup(void)
{
Serial.begin(115200);
#if I2C_PORT == 1 // use first I2C port
bno08x.begin_I2C();
#elif I2C_PORT == 2 // use second I2C port
Wire1.setPins(SDA1, SCL1); // Adafruit 5348 QT Py ESP32-S2: Qwiic connector uses second I2C port
bno08x.begin_I2C(BNO08x_I2CADDR_DEFAULT, &Wire1);
#endif
Wire.setClock(200000L); // I2C speed, 400 kHz is a little fast for default pullups
bno08x.enableReport(SH2_ROTATION_VECTOR, 10000); // report rate, microseconds
}
void loop()
{
sh2_SensorValue_t sensorValue;
if (!bno08x.getSensorEvent(&sensorValue))
return;
switch (sensorValue.sensorId)
{
case SH2_ROTATION_VECTOR:
Serial.print("Quaternion: ");
Serial.print(sensorValue.un.rotationVector.real,4); Serial.print(" ");
Serial.print(sensorValue.un.rotationVector.i,4); Serial.print(" ");
Serial.print(sensorValue.un.rotationVector.j,4); Serial.print(" ");
Serial.print(sensorValue.un.rotationVector.k,4); Serial.println();
break;
}
}
Remember to install the extra SDA pullup resistor, or else you're asking for trouble.
- gammaburst
- Posts: 1015
- Joined: Thu Dec 31, 2015 12:06 pm
Re: BNO08x on a QT Py ESP32 Pico not working
Hi adafruit_support_carter,
Sounds like you had some trouble building the project.
I'm not sure what is "latest ESP32 BSP".
I just noticed that my Boards Manager includes: "esp32 by Expressif Systems version 2.0.3 INSTALLED". That sounds vaguely familiar. I may have recently "updated" it. I occasionally walk through all my "Updatable" Board Manager and Library Manager items and "Update" them (a tedious and slow process).
I haven't encountered "I2C address not found" during my experiments with this issue.
Back on June 24, adafruit2 mentioned "esp32 is not getting correct data and its getting confused", which sounds like it's getting further than your "I2C address not found", so maybe you can examine that build environment?
viewtopic.php?f=19&t=191933#p930175
Sounds like you had some trouble building the project.
I'm not sure what is "latest ESP32 BSP".
I just noticed that my Boards Manager includes: "esp32 by Expressif Systems version 2.0.3 INSTALLED". That sounds vaguely familiar. I may have recently "updated" it. I occasionally walk through all my "Updatable" Board Manager and Library Manager items and "Update" them (a tedious and slow process).
I haven't encountered "I2C address not found" during my experiments with this issue.
Back on June 24, adafruit2 mentioned "esp32 is not getting correct data and its getting confused", which sounds like it's getting further than your "I2C address not found", so maybe you can examine that build environment?
viewtopic.php?f=19&t=191933#p930175
- adafruit_support_carter
- Posts: 29168
- Joined: Tue Nov 29, 2016 2:45 pm
Re: BNO08x on a QT Py ESP32 Pico not working
Sorry for the delay. This sort of got lost and had at least one other pull request that needed to be taken care of prior. Just revisited this and have submitted a pull request to hopefully fix:
https://github.com/adafruit/Adafruit_BNO08x/pull/21
And here's the related issue thread:
https://github.com/adafruit/Adafruit_BNO08x/issues/18
https://github.com/adafruit/Adafruit_BNO08x/pull/21
And here's the related issue thread:
https://github.com/adafruit/Adafruit_BNO08x/issues/18
Please be positive and constructive with your questions and comments.