Esp32 feather v2 can’t find bno08x over i2c

Please tell us which board you are using.
For CircuitPython issues, ask in the Adafruit CircuitPython forum.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
christophersheffield90
 
Posts: 5
Joined: Sun Jan 29, 2023 5:18 pm

Esp32 feather v2 can’t find bno08x over i2c

Post by christophersheffield90 »

Connected a bno08x to a esp32 feather v2 using stemma qt. Uploaded the bno08x example and I get

I2c address not found
Failed to find bno08x chip

Other sensors work just fine such as bmp388 and tsl2591

User avatar
mikeysklar
 
Posts: 13936
Joined: Mon Aug 01, 2016 8:10 pm

Re: Esp32 feather v2 can’t find bno08x over i2c

Post by mikeysklar »

Arduino or CircuitPython code? Can you link me to the example you are running?

User avatar
christophersheffield90
 
Posts: 5
Joined: Sun Jan 29, 2023 5:18 pm

Re: Esp32 feather v2 can’t find bno08x over i2c

Post by christophersheffield90 »

Arduino ide…

Code: Select all

 #include <Arduino.h>
// This demo explores two reports (SH2_ARVR_STABILIZED_RV and SH2_GYRO_INTEGRATED_RV) both can be used to give 
// quartenion and euler (yaw, pitch roll) angles.  Toggle the FAST_MODE define to see other report.  
// Note sensorValue.status gives calibration accuracy (which improves over time)
#include <Adafruit_BNO08x.h>

// For SPI mode, we need a CS pin
#define BNO08X_CS 10
#define BNO08X_INT 9


// #define FAST_MODE

// For SPI mode, we also need a RESET 
//#define BNO08X_RESET 5
// but not for I2C or UART
#define BNO08X_RESET -1

struct euler_t {
  float yaw;
  float pitch;
  float roll;
} ypr;

Adafruit_BNO08x  bno08x(BNO08X_RESET);
sh2_SensorValue_t sensorValue;

#ifdef FAST_MODE
  // Top frequency is reported to be 1000Hz (but freq is somewhat variable)
  sh2_SensorId_t reportType = SH2_GYRO_INTEGRATED_RV;
  long reportIntervalUs = 2000;
#else
  // Top frequency is about 250Hz but this report is more accurate
  sh2_SensorId_t reportType = SH2_ARVR_STABILIZED_RV;
  long reportIntervalUs = 5000;
#endif
void setReports(sh2_SensorId_t reportType, long report_interval) {
  Serial.println("Setting desired reports");
  if (! bno08x.enableReport(reportType, report_interval)) {
    Serial.println("Could not enable stabilized remote vector");
  }
}

void setup(void) {

  Serial.begin(115200);
  while (!Serial) delay(10);     // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("Adafruit BNO08x test!");

  // Try to initialize!
  if (!bno08x.begin_I2C()) {
  //if (!bno08x.begin_UART(&Serial1)) {  // Requires a device with > 300 byte UART buffer!
  //if (!bno08x.begin_SPI(BNO08X_CS, BNO08X_INT)) {
    Serial.println("Failed to find BNO08x chip");
    while (1) { delay(10); }
  }
  Serial.println("BNO08x Found!");


  setReports(reportType, reportIntervalUs);

  Serial.println("Reading events");
  delay(100);
}

void quaternionToEuler(float qr, float qi, float qj, float qk, euler_t* ypr, bool degrees = false) {

    float sqr = sq(qr);
    float sqi = sq(qi);
    float sqj = sq(qj);
    float sqk = sq(qk);

    ypr->yaw = atan2(2.0 * (qi * qj + qk * qr), (sqi - sqj - sqk + sqr));
    ypr->pitch = asin(-2.0 * (qi * qk - qj * qr) / (sqi + sqj + sqk + sqr));
    ypr->roll = atan2(2.0 * (qj * qk + qi * qr), (-sqi - sqj + sqk + sqr));

    if (degrees) {
      ypr->yaw *= RAD_TO_DEG;
      ypr->pitch *= RAD_TO_DEG;
      ypr->roll *= RAD_TO_DEG;
    }
}

void quaternionToEulerRV(sh2_RotationVectorWAcc_t* rotational_vector, euler_t* ypr, bool degrees = false) {
    quaternionToEuler(rotational_vector->real, rotational_vector->i, rotational_vector->j, rotational_vector->k, ypr, degrees);
}

void quaternionToEulerGI(sh2_GyroIntegratedRV_t* rotational_vector, euler_t* ypr, bool degrees = false) {
    quaternionToEuler(rotational_vector->real, rotational_vector->i, rotational_vector->j, rotational_vector->k, ypr, degrees);
}

void loop() {

  if (bno08x.wasReset()) {
    Serial.print("sensor was reset ");
    setReports(reportType, reportIntervalUs);
  }
  
  if (bno08x.getSensorEvent(&sensorValue)) {
    // in this demo only one report type will be received depending on FAST_MODE define (above)
    switch (sensorValue.sensorId) {
      case SH2_ARVR_STABILIZED_RV:
        quaternionToEulerRV(&sensorValue.un.arvrStabilizedRV, &ypr, true);
      case SH2_GYRO_INTEGRATED_RV:
        // faster (more noise?)
        quaternionToEulerGI(&sensorValue.un.gyroIntegratedRV, &ypr, true);
        break;
    }
    static long last = 0;
    long now = micros();
    Serial.print(now - last);             Serial.print("\t");
    last = now;
    Serial.print(sensorValue.status);     Serial.print("\t");  // This is accuracy in the range of 0 to 3
    Serial.print(ypr.yaw);                Serial.print("\t");
    Serial.print(ypr.pitch);              Serial.print("\t");
    Serial.println(ypr.roll);
  }

}
I was able to get it to work using the wire library on its own, but I’d like to have that part of my code abstracted with the adafruit library for readability.

User avatar
mikeysklar
 
Posts: 13936
Joined: Mon Aug 01, 2016 8:10 pm

Re: Esp32 feather v2 can’t find bno08x over i2c

Post by mikeysklar »

When you run the Adafruit i2c scanner specific to the V2 does it work? There is a line of code in here pulling the NEOPIXEL_I2C_POWERPIN high.
The Feather ESP32 V2 has a NEOPIXEL_I2C_POWER pin that must be pulled HIGH to enable power to the STEMMA QT port. Without it, the QT port will not work

Code: Select all

 #if defined(ADAFRUIT_FEATHER_ESP32_V2)
  // Turn on the I2C power by pulling pin HIGH.
  pinMode(NEOPIXEL_I2C_POWER, OUTPUT);
  digitalWrite(NEOPIXEL_I2C_POWER, HIGH);
#endif
}
https://learn.adafruit.com/adafruit-esp ... an-3108213

Code: Select all

 #include <Adafruit_TestBed.h>
extern Adafruit_TestBed TB;

#define DEFAULT_I2C_PORT &Wire

// Some boards have TWO I2C ports, how nifty. We should scan both
#if defined(ARDUINO_ARCH_RP2040) \
    || defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2) \
    || defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM) \
    || defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3) \
    || defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO) \
    || defined(ARDUINO_SAM_DUE)
  #define SECONDARY_I2C_PORT &Wire1
#endif

void setup() {
  Serial.begin(115200);

  // Wait for Serial port to open
  while (!Serial) {
    delay(10);
  }
  delay(500);
  Serial.println("Adafruit I2C Scanner");

#if defined(ARDUINO_ADAFRUIT_QTPY_ESP32S2) || \
    defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM) || \
    defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3) || \
    defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO)
  // ESP32 is kinda odd in that secondary ports must be manually
  // assigned their pins with setPins()!
  Wire1.setPins(SDA1, SCL1);
#endif

#if defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2)
  // turn on the I2C power by setting pin to opposite of 'rest state'
  pinMode(PIN_I2C_POWER, INPUT);
  delay(1);
  bool polarity = digitalRead(PIN_I2C_POWER);
  pinMode(PIN_I2C_POWER, OUTPUT);
  digitalWrite(PIN_I2C_POWER, !polarity);
#endif

#if defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2_TFT)
  pinMode(TFT_I2C_POWER, OUTPUT);
  digitalWrite(TFT_I2C_POWER, HIGH);
#endif

#if defined(ADAFRUIT_FEATHER_ESP32_V2)
  // Turn on the I2C power by pulling pin HIGH.
  pinMode(NEOPIXEL_I2C_POWER, OUTPUT);
  digitalWrite(NEOPIXEL_I2C_POWER, HIGH);
#endif
}

void loop() {
  Serial.println("");
  Serial.println("");

  Serial.print("Default port (Wire) ");
  TB.theWire = DEFAULT_I2C_PORT;
  TB.printI2CBusScan();

#if defined(SECONDARY_I2C_PORT)
  Serial.print("Secondary port (Wire1) ");
  TB.theWire = SECONDARY_I2C_PORT;
  TB.printI2CBusScan();
#endif

  delay(3000); // wait 3 seconds
}

User avatar
christophersheffield90
 
Posts: 5
Joined: Sun Jan 29, 2023 5:18 pm

Re: Esp32 feather v2 can’t find bno08x over i2c

Post by christophersheffield90 »

Despite the data sheet specifying to turn that pin to high for the 3.3v supply to i2c, the qt stemma works with or without turning it on. I tried it both ways for multiple stemma sensors. Only the bno08x doesn’t work.

I did try the adafruit I2c scanner. It picks it up as 0x4a.

I have also pulled sda to high using a 2k2 resistor.

User avatar
mikeysklar
 
Posts: 13936
Joined: Mon Aug 01, 2016 8:10 pm

Re: Esp32 feather v2 can’t find bno08x over i2c

Post by mikeysklar »

Which version of the bno08x library are you running? v1.2.3 looks to have some ESP32 compatibility enhancements put in a few months ago.

https://github.com/adafruit/Adafruit_BNO08x

User avatar
christophersheffield90
 
Posts: 5
Joined: Sun Jan 29, 2023 5:18 pm

Re: Esp32 feather v2 can’t find bno08x over i2c

Post by christophersheffield90 »

Off top of my head I’m not sure the version number but I downloaded the most current branch off of github as of four days ago

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

Re: Esp32 feather v2 can’t find bno08x over i2c

Post by gammaburst »

Hi christophersheffield90,

I ran your sketch on my ESP32-V2 and BNO085 with updated Arduino libraries and board managers, and it fails exactly as you describe. Try inserting "delay(400)" between your "Serial.begin()" and your "bno08x.begin_I2C()".

The culprit is a long-standing bug in Adafruit's library. The library tries to access the BNO immediately after power-up or reset to "see" if the BNO is ready to communicate, but that's not how the BNO datasheet says to do it, and it's unreliable. Datasheet section 5.2 "Establishing Contact" says to wait until HOST_INTN indicates ready to communicate. Unfortunately that signal is unavailable on the STEMMA/Qwiic connector. My workaround is to insert sufficient delay to allow HOST_INTN to occur before communicating. All of my BNO085 devices seem to assert HOST_INTN about 220ms after power-up, so I'm using a 400ms delay.

I hope that works for you. Sometimes we have multiple problems.

User avatar
christophersheffield90
 
Posts: 5
Joined: Sun Jan 29, 2023 5:18 pm

Re: Esp32 feather v2 can’t find bno08x over i2c

Post by christophersheffield90 »

That was it gammaburst. First time I’ve heard this fix. I’ve seen you helping out lots of others on this very topic. I appreciate it.

Do you happen to have any ideas why the data sheet says to pull the neopixeli2c pin high for the qt stemma but it always works when you don’t? I saw in the schematic that the pin is used for 3.3v power. Did they change this in v2 and forgot to take out that detail in the data sheet?

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

Re: Esp32 feather v2 can’t find bno08x over i2c

Post by gammaburst »

Hi christophersheffield90,

The ESP32 board's schematic shows a small regulator powering the NEOPIXEL and STEMMA connector. The regulator has an enable input that's controlled by a GPIO signal from the ESP32. When I press the ESP32's RESET button, I see the enable signal turn OFF then ON, so something in the Arduino environment or library is automatically controlling the enable signal for us. The warning in Adafruit's data sheet (learning guide?) isn't specifically discussing the Arduino environment. Other environments may not automatically control the enable signal for us. That's just my guess.

That OFF-ON behavior will reset all the I2C peripherals on the STEMMA bus. That should be a great feature because the STEMMA connectors lacks a RESET signal.

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

Return to “Feather - Adafruit's lightweight platform”