IMUs for Espressif ESP32: BNO085 or LSM9DS1?

Breakout boards, sensors, other Adafruit kits, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
natee
 
Posts: 6
Joined: Tue Apr 18, 2023 11:54 am

IMUs for Espressif ESP32: BNO085 or LSM9DS1?

Post by natee »

Hello everyone,

I'm wondering which of these two IMUs is better suited for the Espressif ESP32.

What appeals to me about the BNO085 is the onboard fusion.
However, according to this site https://learn.adafruit.com/adafruit-9-d ... 85/arduino, there are (or were?) communication problems between the BNO085 and the Espressif ESP32 via I2C.

Here viewtopic.php?f=19&p=845213 is a suggested solution though. Does this fix the problem for sure? Can I use connect other sensors via I2C with the ESP32 even though I redefined the I2C pins for the BNO085 according to this suggested solution?
The original thread from 2020 is unfortunately closed, so I would appreciate a hint from someone who has tried it.

This data sheet from 2021 https://www.mouser.de/datasheet/2/737/a ... 489934.pdf does not refer to the bug anymore at all. That makes me a little bit puzzled now.

Or do I have to switch to the LSM9DS1 and go for data fusion following this tutorial?: https://learn.adafruit.com/how-to-fuse- ... algorithms?

I would be very grateful for a suggestion!

Have a great weekend!

User avatar
gammaburst
 
Posts: 1015
Joined: Thu Dec 31, 2015 12:06 pm

Re: IMUs for Espressif ESP32: BNO085 or LSM9DS1?

Post by gammaburst »

If it was my decision, I would try the BNO085 first. Here's why ...

I wish Adafruit would identify the timing violation mentioned in their orange warning box. It may or may not be the same violation that I discovered several years ago:

From my investigation, the BNO055 and BNO085 occasionally violate I2C's SDA-high to SCL-high setup-time requirement during some clock-stretching cycles. The amount of violation seems jittery/random, and depends upon the previous data bit. When the violation is strongest, it causes the I2C transfer to be on the verge of failure. Small electrical variations (your wiring capacitance, your microcontroller's I/O pin characteristics, your finger touching the I2C pins, etc) nudge the situation towards either success or failure. The overall result: many folks don't notice any problem, some folks see occasional mysterious I2C failure, and a few folks see severe I2C failure. If I attach a short bare wire to SDA and grab it with two fingers (finger capacitance slows the signal's rise-time), I usually see severe I2C failure no matter which microcontroller I'm using. My suggested workaround is to simply add one extra pullup resistor (about 2K to 3K ohms) to SDA. That speeds-up SDA's rise-time relative to SCL, pushing the situation towards "success". The extra resistor doesn't eliminate the timing violation, but it reduces the violation sufficiently to stabilize all the BNO projects that I've seen, including ESP32.

Or, Adafruit could be referring to some other timing violation that I don't know about.

User avatar
natee
 
Posts: 6
Joined: Tue Apr 18, 2023 11:54 am

Re: IMUs for Espressif ESP32: BNO085 or LSM9DS1?

Post by natee »

Thank you for your helpful suggestion, Gammaburst!

Both my ESP32 board and the Adafruit BNO085 have a STEMMA QT / Qwiic connector. With the pullup resistor it will be a bit of a pity not to be able to use this option, but at least the use of the IMU in general would (hopefully) be a bit more uncomplicated.

User avatar
gammaburst
 
Posts: 1015
Joined: Thu Dec 31, 2015 12:06 pm

Re: IMUs for Espressif ESP32: BNO085 or LSM9DS1?

Post by gammaburst »

The BNO085 is a nice sensor for the price.

If the extra pullup resistor is the appropriate workaround for you, then an ordinary quarter-watt or eighth-watt leaded resistor can be easily soldered between the VIN and SDA pads on the BNO breakout. (The breakout's PCB connects those two pads to STEMMA connector pins 2 and 3.)

Or perhaps solder the resistor to a spare STEMMA cable, and then plug the cable into the BNO's other STEMMA connector.

Would be helpful if an Adafruit support person stepped-in here and clarified whether or not Adafruit's orange warning box is the same problem as my above long-winded description.

User avatar
jps2000
 
Posts: 811
Joined: Fri Jun 02, 2017 4:12 pm

Re: IMUs for Espressif ESP32: BNO085 or LSM9DS1?

Post by jps2000 »

@gammaburst
Vin might be higher than 3V. Hence I suggest to add resistor between 3V and sda.

User avatar
gammaburst
 
Posts: 1015
Joined: Thu Dec 31, 2015 12:06 pm

Re: IMUs for Espressif ESP32: BNO085 or LSM9DS1?

Post by gammaburst »

Hi jps2000,
I understand your point, but here's my rationale:

1. Whatever voltage the controller outputs on its STEMMA power pin, it should tolerate that much voltage coming back on the I2C pins. Otherwise it's asking for trouble.

2. If the extra pullup is tied to the BNO breakout's 3.3V (3Vo) pin, and if the breakout is then connected to a 5V microcontroller, the I2C signal may not rise high enough to satisfy the microcontroller's I2C Vin_high_minimum (0.7 * VDD).

The definitive answer should be in the official STEMMA spec. But where is the spec? Who created it? What does "STEMMA" even mean?

User avatar
natee
 
Posts: 6
Joined: Tue Apr 18, 2023 11:54 am

Re: IMUs for Espressif ESP32: BNO085 or LSM9DS1?

Post by natee »

Thank you all very much for your help!

I have now purchased the Adafruit BNO085 board and connected it to my ESP32 board (Sparkfun smol ESP32 https://learn.sparkfun.com/tutorials/sm ... okup-guide) via I2C using a "header board"(https://learn.sparkfun.com/tutorials/sm ... okup-guide).

The first example sketch of the Adafruit BNO085 library did not even compile.

I got the following error message:
Arduino: 1.8.19 (Windows 10), Board: "SparkFun ESP32 Thing, 80MHz, Default, 921600, None"

C:\Users\Blau\Documents\Arduino\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp: In member function 'bool Adafruit_SPIDevice::write(const uint8_t*, size_t, const uint8_t*, size_t)':

C:\Users\Blau\Documents\Arduino\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp:352:61: error: invalid conversion from 'const uint8_t* {aka const unsigned char*}' to 'uint8_t* {aka unsigned char*}' [-fpermissive]

_spi->transferBytes(prefix_buffer, nullptr, prefix_len);

^

In file included from C:\Users\Blau\Documents\Arduino\libraries\Adafruit_BusIO\Adafruit_SPIDevice.h:9:0,

from C:\Users\Blau\Documents\Arduino\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp:1:

C:\Users\Blau\AppData\Local\Arduino15\packages\SparkFun\hardware\esp32\1.0.1\libraries\SPI\src/SPI.h:73:10: note: initializing argument 1 of 'void SPIClass::transferBytes(uint8_t*, uint8_t*, uint32_t)'

void transferBytes(uint8_t * data, uint8_t * out, uint32_t size);

^

C:\Users\Blau\Documents\Arduino\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp:355:47: error: invalid conversion from 'const uint8_t* {aka const unsigned char*}' to 'uint8_t* {aka unsigned char*}' [-fpermissive]

_spi->transferBytes(buffer, nullptr, len);

^

In file included from C:\Users\Blau\Documents\Arduino\libraries\Adafruit_BusIO\Adafruit_SPIDevice.h:9:0,

from C:\Users\Blau\Documents\Arduino\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp:1:

C:\Users\Blau\AppData\Local\Arduino15\packages\SparkFun\hardware\esp32\1.0.1\libraries\SPI\src/SPI.h:73:10: note: initializing argument 1 of 'void SPIClass::transferBytes(uint8_t*, uint8_t*, uint32_t)'

void transferBytes(uint8_t * data, uint8_t * out, uint32_t size);

^

C:\Users\Blau\Documents\Arduino\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp: In member function 'bool Adafruit_SPIDevice::write_then_read(const uint8_t*, size_t, uint8_t*, size_t, uint8_t)':

C:\Users\Blau\Documents\Arduino\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp:446:59: error: invalid conversion from 'const uint8_t* {aka const unsigned char*}' to 'uint8_t* {aka unsigned char*}' [-fpermissive]

_spi->transferBytes(write_buffer, nullptr, write_len);

^

In file included from C:\Users\Blau\Documents\Arduino\libraries\Adafruit_BusIO\Adafruit_SPIDevice.h:9:0,

from C:\Users\Blau\Documents\Arduino\libraries\Adafruit_BusIO\Adafruit_SPIDevice.cpp:1:

C:\Users\Blau\AppData\Local\Arduino15\packages\SparkFun\hardware\esp32\1.0.1\libraries\SPI\src/SPI.h:73:10: note: initializing argument 1 of 'void SPIClass::transferBytes(uint8_t*, uint8_t*, uint32_t)'

void transferBytes(uint8_t * data, uint8_t * out, uint32_t size);

^

exit status 1

Error compiling for board SparkFun ESP32 Thing.

(Unfortunately, I can't update to Arduino IDE 2.x, since then another board connected to the Sparkfun smol ESP32 won't work. I hope this is not the main problem here, but if anyone knows better, please let me know, too.)

After that I tried it with the Sparkfun BNO08x library.

The first BNO08x Sparkfun example sketch also suggests to add this code when working with an ESP:

Code: Select all

 
//Are you using a ESP? Check this issue for more information: https://github.com/sparkfun/SparkFun_BNO080_Arduino_Library/issues/16
//  //=================================
//  delay(100); //  Wait for BNO to boot
//  // Start i2c and BNO080
//  Wire.flush();   // Reset I2C
//  IMU.begin(BNO080_DEFAULT_ADDRESS, Wire);
//  Wire.begin(4, 5);
//  Wire.setClockStretchLimit(4000);
//  //=================================


However, that won't work with the ESP32, since it doesn't support Wire.setClockStretchLimit(); (and Arduino IDE won't compile).
So I have left this one line commented out and adjusted the remaining lines as follows:

Code: Select all

//  //=================================
delay(100); //  Wait for BNO to boot
//  // Start i2c and BNO080
Wire.flush();   // Reset I2C
IMU.begin(0x4A, Wire);
Wire.begin(21, 22);  //also tried it vice versa (22, 21) just for "fun"
//  Wire.setClockStretchLimit(4000);
//  //=================================
Compiling and uploading the first example of this library worked this way, but the error code then is:
BNO080 Read Example
BNO080 not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...
Sometimes I even only get the second line, missing
BNO080 Read Example
.

The ESP32 board and the BNO085 board are connected using a Qwiic cable.
I put 2-3 kOhm in the SDA line between ESP32 and BNO085 board as suggested (or as I understood at least). This did not work. I thought maybe I had it wrong and put 3kOhm between SDA and VIN on the BNO085 board instead.
Both variants did not lead to any improvement. I hope I did not hurt the board too much.

I've felt like I'm close to a solution several times over two days now, but am getting frustrated. Does anyone else have a slight idea what to do, or is it just hopeless with this setup? I would be very grateful for hints in both directions.

Thank you.

User avatar
gammaburst
 
Posts: 1015
Joined: Thu Dec 31, 2015 12:06 pm

Re: IMUs for Espressif ESP32: BNO085 or LSM9DS1?

Post by gammaburst »

I understand your frustration. A lot of little things can go wrong with these projects (Murphy's Law), especially when I mix products from different companies. Maybe one of these tips will help you.

I'm unfamiliar with mixing a SparkFun microcontroller support package with Adafruit libraries/examples. I would try using only SparkFun libraries/examples. If you still get compile-time errors, then talk to SparkFun support.

Be sure to properly select the BNO085 I2C address, because SparkFun and Adafruit use opposite defaults. Change the address either in your code, or jumper the address pin on the BNO085 breakout. I sometimes run an I2C bus scan sketch to help automatically find the addresses of connected I2C devices.

Or perhaps your microcontroller has two I2C ports and of course defaults to the one that you aren't using. That has happened to me with an Adafruit ESP32 board.

You have a "SparkFun smol ESP32" board, but the first error message mentions "SparkFun ESP32 Thing". That's suspicious.

I successfully use an old version 1.8.5 Arduino IDE with my various old and new Adafruit boards, including several ESP32 types. I keep the board support packages updated using Arduino's "Boards Manager". I keep the libraries updated using Arduino's "Manage Libraries". Be sure yours are updated too.

A "pullup" resistor goes between the power pin and signal pin, such as between pins VIN and SDA on the BNO085 breakout. Don't cut the SDA wire and insert the resistor in series, but if you did, no harm done, simply undo it.
https://en.wikipedia.org/wiki/Pull-up_resistor

User avatar
natee
 
Posts: 6
Joined: Tue Apr 18, 2023 11:54 am

Re: IMUs for Espressif ESP32: BNO085 or LSM9DS1?

Post by natee »

Hi Gammaburst,

thank you very much for your tips and your emotional support :)

I have now run an I2C bus scan sketch. With this, the board is at least detected at address 0x4A.

The board is shown as "SparkFun ESP32 Thing", because Sparkfun says in the manual for my board that it should be declared as such in the Aurduino IDE. So that should be correct.
And it also has only one I2C port.

I also soldered the resistor (just under 3kOhm) between SDA and Vin. However, that did not help either. Should I perhaps also solder one between SCL and Vin, or would it then no longer work at all, even if I remove other sources of error bit by bit at the same time?

By the way, my ESP32-board already has a 10k-Ohm resistor between SDA and Vin and SCL and Vin. I have now deactivated these resistors. But it still does not work.

If someone still has a suggestion, I would be very grateful!

User avatar
gammaburst
 
Posts: 1015
Joined: Thu Dec 31, 2015 12:06 pm

Re: IMUs for Espressif ESP32: BNO085 or LSM9DS1?

Post by gammaburst »

The I2C scan works! That's an important result.

The pullup resistor trick helps workaround a specific I2C timing violation. That violation usually causes intermittent/erratic I2C communication. But you see no communication at all except during the I2C bus scan. That seems like a different problem. The pullup resistor trick probably won't help that problem. (By the way, don't add a similar extra pullup resistor to SCL, because the trick relies on SDA and SCL having unequal pullups. And don't remove any original pullup resistors - the I2C bus could stop working.)

Which BNO085 library are you now using, Adafruit's or Sparkfun's?
What error message or failure are you now seeing when the BNO085 doesn't work?

Be sure you've configured the BNO085 library and BNO085 breakout to the same I2C address. Your I2C scan found the BNO085 breakout at 0x4A, so be sure the BNO085 library is also set to 0x4A. The Adafruit BNO085 library defaults to 0x4A. I think the Sparkfun BNO085 library defaults to 0x4B.

This type of problem is difficult to solve via back-and-forth text communication.

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Products from Adafruit”