Skip to content

I2C issue with BNO055 from Adafruit #81

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
hngmihai opened this issue Dec 6, 2016 · 37 comments
Closed

I2C issue with BNO055 from Adafruit #81

hngmihai opened this issue Dec 6, 2016 · 37 comments

Comments

@hngmihai
Copy link

hngmihai commented Dec 6, 2016

Tried to connect the ESP32 with the sensor BNO055 from adafruit (https://learn.adafruit.com/adafruit-bno055-absolute-orientation-sensor/wiring-and-test).

Used the latest commit of arduino-esp32, downloaded the libraries from adafruit, and used their code as well:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
  
Adafruit_BNO055 bno = Adafruit_BNO055(55);
 
void setup(void) 
{
  Serial.begin(9600);
  Serial.println("Orientation Sensor Test"); Serial.println("");
  
  /* Initialise the sensor */
  if(!bno.begin())
  {
    /* There was a problem detecting the BNO055 ... check your connections */
    Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
    while(1);
  }
  
  delay(1000);
    
  bno.setExtCrystalUse(true);
}
 
void loop(void) 
{
  /* Get a new sensor event */ 
  sensors_event_t event; 
  bno.getEvent(&event);
  
  /* Display the floating point data */
  Serial.print("X: ");
  Serial.print(event.orientation.x, 4);
  Serial.print("\tY: ");
  Serial.print(event.orientation.y, 4);
  Serial.print("\tZ: ");
  Serial.print(event.orientation.z, 4);
  Serial.println("");
  
  delay(100);
}

I get the following error message on serial: "Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!" and if I check the SCL / SDA with the scope I get the following result:

15354241_1473509246009757_1195612445_o

Mention: I double checked the wiring!

I don't know what the issue might be, any help would be great.

@me-no-dev
Copy link
Member

it seems as the device is first holding SCL and then SDA (I presume SDA is above) what is the frequency of I2C?

@hngmihai
Copy link
Author

hngmihai commented Dec 7, 2016

Your presumption is right.
The frequency is default, I haven't changed it:
Wire.h: void begin(int sda=-1, int scl=-1, uint32_t frequency=100000);

Here are two more screens from the scope:

  1. This is when I connect the BNO055 to an Arduino UNO and it works
    15369765_1474621799231835_159935084_o

  2. This is when I connect the BNO055 to the ESP32
    15387466_1474621479231867_509258048_o

Mention: the same application is loaded on both boards.

@me-no-dev
Copy link
Member

Interesting... what is that single clock and data pulses before transmission begins? Other than that you can see the same data being sent to your device, but the device does not release SDA after the last byte in the case of ESP32, so that initial pulse is probably screwing something up... it might be a pinInit pulse, so why not add some delay after Wire.begin?

@hngmihai
Copy link
Author

hngmihai commented Dec 7, 2016

Ok so I've tried what you've suggested, added a delay(100); after Wire.begin(); and that pulse before transmission begin was eliminated but everything else is the same (still not working, the only difference is that the pulse is not present anymore).

Meanwhile I've also stumbled upon this:

  // BNO055 clock stretches for 500us or more!
#ifdef ESP8266
  Wire.setClockStretchLimit(1000); // Allow for 1000us of clock stretching
#endif

Could this be the issue? I tried removing the if instruction so that Wire.setClockStretchLimit(1000); should happend on ESP32 as well but the method is not recognized by the compiler. The method does not exist in the driver.

I also printed on serial the return from the Wire.endTransmission(); which is "3" => that is "I2C_ERROR_TIMEOUT". So the driver error is a timeout on the bus.

Hope all of this will suggest something that leads you to a solution :D.

@me-no-dev
Copy link
Member

you are probably correct. I will look for such setting and let you know on what could be done :)

@silentviper
Copy link

I'm also trying to get the Sparkfun ESP32 Thing to communicate with the BNO055, I have a saleae logic analyzer as well, and when using the arduino i2c scanner code i receive "No I2C devices found" repeatedly, and the logic analyzer sees the device hunt through only even address devices, while the BNO055 is at address 0x28 by default according to the datasheet, but the ESP32 it still isn't seeing a response on the device. An arduino Uno running the same code successfully sees the device at 0x28.
Here's a csv export of the Saleae dump Saleae-export.csv.txt and
associated screenshot of the signals screen shot 2016-12-08 at 5 12 35 pm as compared to
screen shot 2016-12-08 at 5 13 38 pm which is captured from the Arduino Uno.

I've never used i2c in a project so i'm less than confident in my knowledge but if i had to guess, I think @Devilish1208 is correct that it's related to clock stretching, and setClockStretchLimit is not defined, nor did it seem easy to port to me.

Please let me know if I can be any help in testing/debugging a solution.

@andrei-ivanov
Copy link

Maybe this will help? http://esp32.com/viewtopic.php?f=19&t=632&p=2832#p2801

me-no-dev added a commit that referenced this issue Dec 9, 2016
wait for data to be latched and increase timeout in attempt to fix clock stretch issues
Connected issues:
http://esp32.com/viewtopic.php?f=19&t=632&p=2832#p2801
#81
#53
#11
@me-no-dev
Copy link
Member

try the latest commit please :)

@hngmihai
Copy link
Author

hngmihai commented Dec 9, 2016

Glad you guys came up with this, it gave me some hope:))
Pulled your latest commit and tried it out, it brings some improvement but something is still not good and I'm also quite confused now.

If I load the application from here: http://playground.arduino.cc/Main/I2cScanner (which scans the I2C bus for devices and outputs on serial the address at which it found it) the ESP32 finds the device at address 0x28 (which is the default address of the BNO055 according to its documentation). So this is the improvement because previously not even the scan was working. This improved because you increased this value: i2c->dev->timeout.tout = 400000;//clocks max=1048575

If I load the example application from adafruit website: https://learn.adafruit.com/adafruit-bno055-absolute-orientation-sensor/wiring-and-test which should output on serial some values from the sensor, it seems that the ESP32 finds the BNO055 (because I don-t get the error message that says not found) but after that it hangs (gets stuck). I've also found out by using Serial.print messages that it might be hanging in the while loop you introduced: while(i2c->dev->fifo_st.tx_fifo_end_addr == fifotail) {}; (not 100% sure about this though).

Some mentions:

  1. In the while loop you introduced shouldn't you compare "fifotail" variable with the start address in the structure? (you are now comparing it with: "fifo_st.tx_fifo_end_addr")
  2. While running the scanner app I scoped the SDA and SCL again and this is what I get (There are some bus conflicts, that half amplitude spike there)
    15387529_1478590662168282_1576128350_o

2.2. While running the Adafruit sample app I scoped SDL and SCL again and this is the only thing I get (I don't understand this, some initialisation phase probably):
15419466_1478590542168294_606718898_o

@me-no-dev
Copy link
Member

the loop is checking supposedly the last byte address of the fifo and waiting for it to change (increment) after we added the byte. Surely it could be some magic going on... try removing it and see how things are

@me-no-dev
Copy link
Member

address was detected probably due to the increased timeout ;)

@hngmihai
Copy link
Author

hngmihai commented Dec 9, 2016

@me-no-dev: I'm gonna try that on monday with a scope near and provide what I find out

@tolson2000
Copy link

I have a mod to the I2Cscanner sketch. There should be something between an beginTransmission and endTransmission, else some devices won't respond. See below snippet.

for(address` = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire2.beginTransmission(address);
Wire2.write(0x00); // Really needs this for reliability <<<---------------
error = Wire2.endTransmission();

@Mat-Alm
Copy link

Mat-Alm commented Dec 9, 2016

I think that I2C drivers have bugs related with fifo! (If we can disable fifo for test )Because when you write only one request to the slave device it only act with behaviour that Devilish1208 show in figure 2.2. Also for read BME280 you need a restart condition after writting request to read the registers and is not done in the current I2C implementation. If we have a better docs on the I2C would be nice!

@me-no-dev
Copy link
Member

Please try the latest commit. I tested with 6 devices at the same time. I hope we can close this :)

@hngmihai
Copy link
Author

tried it now, still not working with the BNO055. It seems to be even worst than before because running the I2C scanner software prints on serial that it finds devices at several adresses (the BNO is the only device connected).
For example if I scan adresses from 30 to 50: for (address = 30; address < 50; address++) { I get the following output:

I2C device found at address 0x1F  !
I2C device found at address 0x21  !
I2C device found at address 0x25  ! 
I2C device found at address 0x27  ! 
I2C device found at address 0x28  !
I2C device found at address 0x2A  !
I2C device found at address 0x2C  !
I2C device found at address 0x2E  ! 
I2C device found at address 0x30  !

This is what I catch on the logic analyzer:
2016-12-14_11h03_48

@me-no-dev
Copy link
Member

do you guys have pull up resistors on SDA and SCL? I have 1K on my board and without them I2C will not work

@me-no-dev
Copy link
Member

I have 6 devices connected at the same time and I have no problems. Scan is working as expected also

@hngmihai
Copy link
Author

The BNO055 breakout has pullups of 10k on it

@me-no-dev
Copy link
Member

ok, now what are you doing exactly? are you scanning or are you trying to communicate with that device? if scanning is your answer, have you tried communicating with it with the latest version?
If it's locking your bus, you might want to look here

@Mat-Alm
Copy link

Mat-Alm commented Dec 14, 2016

Hello! I found a solution! for read BME280 it will also works for BNO055! After you issue a read command you need to send a nack after the numbers of read that you done! So you need to mod this line in esp32-hal-i2c.c in (line 270) or the read command field change it to i2cSetCmd(i2c, cmdIdx++, I2C_CMD_READ, willRead, true, false, true); And you will be able work fine with this devices!
Also some times is needed to increase the main stack size on maic.c or you can get only single pulses like in figure 2.2 that Devilish1208 posted!

@me-no-dev
Copy link
Member

Holly Cow!!!! What A find!
Stack size?

@me-no-dev
Copy link
Member

breaks all other devices though :(

@hngmihai
Copy link
Author

@me-no-dev I was scanning the bus for I2C devices, tired again with latest commit, same behaviour.
If I try to communicate with it, it gets stuck somewhere.
@Mat-Alm tried to modify line 270 like you said => It seems to connect to the device because I don't get the error message that BNO055 was not detected but I than get that same value over and over again "from the device" (I'm not sure it really sends anything because this is what I catch on logic analyzer):

2016-12-14_16h44_00

@torntrousers
Copy link
Contributor

FYI I've tried @Mat-Alm 's line 270 change and it gets a BME280 working for me.

@me-no-dev
Copy link
Member

but breaks many (all of mine) other I2C devices

@Mat-Alm
Copy link

Mat-Alm commented Dec 14, 2016

Delvish check if your code / library send the stop conditions right? like Wire.endTransmission(true);
Scan works fine to me! I also have 10k pulls near the device.

@Mat-Alm
Copy link

Mat-Alm commented Dec 14, 2016

me-no-dev but my changes are like I2C specs for read ex:
image

@me-no-dev
Copy link
Member

@Mat-Alm you just brought an idea in my head... let me see what I can do. Signaling is OK, there is something totally else that is going on.

@me-no-dev
Copy link
Member

ok try the commit now

@Mat-Alm
Copy link

Mat-Alm commented Dec 14, 2016

For my device BME280 it's working! You had changed the behaviour of multiple and single reads? And what about the : `/*

  • index - command index (0 to 15)
  • op_code - is the command
  • byte_num - This register is to store the amounts of data that is read and written. byte_num in RSTART, STOP, END is null.
  • ack_val - Each data byte is terminated by an ACK bit used to set the bit level.
  • ack_exp - This bit is to set an expected ACK value for the transmitter.
  • ack_check - This bit is to decide whether the transmitter checks ACK bit. 1 means yes and 0 means no.
  • */`

What are exactly ack fields behaviour?

@Mat-Alm
Copy link

Mat-Alm commented Dec 14, 2016

Tested with tmp006 it also works!
But the max30100 does not work and I get only single pulses of death!

@me-no-dev
Copy link
Member

ack_val sets the level of the ack bit when you are reading from a slave. If you set it to true, it will actually send NACK.
ack_exp sets the level of the ack bit that you are expecting to get when you are writing to a slave
ack_check sets wether correct ack level should be checked and error bit set if it fails

@silentviper
Copy link

@me-no-dev I just tested on a BNO055, and it works!! Address scanning and data pulling, without any extra pull-up resistors.

1 catch, i'm not entirely sure why sensorapi.ino does not work but bunny.ino does. I didn't dig into it just yet.

Thank you!!

@hngmihai
Copy link
Author

@me-no-dev you did your magic good. Seems to work now, first tests. Congrats m8.

@me-no-dev
Copy link
Member

that's good news guys! Thank you all for the help! I'll keep this open a bit more because I need to make scanning work better (writing only the address to the bus) and would like you to test the result against your devices to make sure I do not break something along the way :)

@me-no-dev
Copy link
Member

alright was chasing ghosts (did not pull the latest change in my working branch) closing this now :)
Thank you all for the help!

blue-2357 pushed a commit to blue-2357/arduino-esp32 that referenced this issue Jul 17, 2024
wait for data to be latched and increase timeout in attempt to fix clock stretch issues
Connected issues:
http://esp32.com/viewtopic.php?f=19&t=632&p=2832#p2801
espressif/arduino-esp32#81
espressif/arduino-esp32#53
espressif/arduino-esp32#11
brentru pushed a commit to adafruit/arduino-esp32 that referenced this issue Oct 22, 2024
dash0820 added a commit to dash0820/arduino-esp32-stripped that referenced this issue Mar 10, 2025
wait for data to be latched and increase timeout in attempt to fix clock stretch issues
Connected issues:
http://esp32.com/viewtopic.php?f=19&t=632&p=2832#p2801
espressif/arduino-esp32#81
espressif/arduino-esp32#53
espressif/arduino-esp32#11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants