BNO055 and SSD1306 wont work simultaneously

Hi.

In my current project I’m using an Arduino Nano with a BNO055 IMU angle sensor and an SSD1306 OLED display and they work fine, but the OLED won’t work if the BNO is active.

When the display is initialized with OLED.begin() it will respond and write anything I want, but as soon as the BNO is initialized the display won’t update itself if the code write something to it. It will just display what it already is displaying.

I’ve scanned for i2c addresses and it finds both devices at 0x28 (BNO) and 0x3C (OLED). I’ve also read in a post with a similar problem that grounding the ADR pin on the BNO will solve the problem, but it did not work for me.

With the code below, “Serial online” followed by “Program started” is being displayed properly on the display, but anything after that will not be written to the OLED.

#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <U8g2lib.h>
#include <U8x8lib.h>
#include <SPI.h>

double xPos = 0, yPos = 0, headingVel = 0;
uint16_t BNO055_SAMPLERATE_DELAY_MS = 10; //how often to read data from the board
uint16_t PRINT_DELAY_MS = 100; // how often to print the data
uint16_t printCount = 0; //counter to avoid printing every 10MS sample

//velocity = accel*dt (dt in seconds)
//position = 0.5*accel*dt^2
double ACCEL_VEL_TRANSITION =  (double)(BNO055_SAMPLERATE_DELAY_MS) / 1000.0;
double ACCEL_POS_TRANSITION = 0.5 * ACCEL_VEL_TRANSITION * ACCEL_VEL_TRANSITION;
double DEG_2_RAD = 0.01745329251; //trig functions require radians, BNO055 outputs degrees

// Check I2C device address and correct line below (by default address is 0x29 or 0x28)
//                                   id, address
Adafruit_BNO055 bno = Adafruit_BNO055(55, 0x28);

U8G2_SSD1306_128X64_NONAME_1_SW_I2C OLED(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);

void writeOLED(String topRow, String bottomRow) {
  OLED.firstPage();
  do {
    OLED.setCursor(0, 25);
    OLED.print(topRow);
    OLED.setCursor(0, 50);
    OLED.print(bottomRow);
  } while ( OLED.nextPage() );
}

void setup(void)
{
  Serial.begin(9600);
  Serial.println("Serial online"); // This is displayed

  OLED.begin();
  OLED.enableUTF8Print();
  OLED.setFont(u8g2_font_ncenB14_tr);
  OLED.setFontDirection(0);
  writeOLED("     Serial" , "      online"); // This is displayed

  delay(1000);

  writeOLED("     Program" , "      started"); // This is displayed
  if (!bno.begin())
  {
    Serial.print("No BNO055 detected");
    while (1);
  }
  bno.enterSuspendMode();
  writeOLED("     After" , "      BNO055"); // This is NOT displayed
}

void loop(void)
{
  
  unsigned long tStart = micros();
  sensors_event_t orientationData , linearAccelData;
  bno.getEvent(&orientationData, Adafruit_BNO055::VECTOR_EULER);
  //  bno.getEvent(&angVelData, Adafruit_BNO055::VECTOR_GYROSCOPE);
  bno.getEvent(&linearAccelData, Adafruit_BNO055::VECTOR_LINEARACCEL);

  xPos = xPos + ACCEL_POS_TRANSITION * linearAccelData.acceleration.x;
  yPos = yPos + ACCEL_POS_TRANSITION * linearAccelData.acceleration.y;

  // velocity of sensor in the direction it's facing
  headingVel = ACCEL_VEL_TRANSITION * linearAccelData.acceleration.x / cos(DEG_2_RAD * orientationData.orientation.x);

  if (printCount * BNO055_SAMPLERATE_DELAY_MS >= PRINT_DELAY_MS) {
    
    Serial.print("x = ");
    Serial.println(orientationData.orientation.x);
    Serial.print("y = ");
    Serial.println(orientationData.orientation.y);
    Serial.print("z = ");
    Serial.println(orientationData.orientation.z);
    Serial.println();

    writeOLED("x= ,y= z= ","It just works"); // This is NEVER displayed

    printCount = 0;
  }
  else {
    printCount = printCount + 1;
  }

  while ((micros() - tStart) < (BNO055_SAMPLERATE_DELAY_MS * 1000))
  {
    //poll until the next sample is ready
  }
}

void printEvent(sensors_event_t* event) {
  Serial.println();
  Serial.print(event->type);
  double x = -1000000, y = -1000000 , z = -1000000; //dumb values, easy to spot problem
  if (event->type == SENSOR_TYPE_ACCELEROMETER) {
    x = event->acceleration.x;
    y = event->acceleration.y;
    z = event->acceleration.z;
  }
  else if (event->type == SENSOR_TYPE_ORIENTATION) {
    x = event->orientation.x;
    y = event->orientation.y;
    z = event->orientation.z;
  }
  else if (event->type == SENSOR_TYPE_MAGNETIC_FIELD) {
    x = event->magnetic.x;
    y = event->magnetic.y;
    z = event->magnetic.z;
  }
  else if ((event->type == SENSOR_TYPE_GYROSCOPE) || (event->type == SENSOR_TYPE_ROTATION_VECTOR)) {
    x = event->gyro.x;
    y = event->gyro.y;
    z = event->gyro.z;
  }

  Serial.print(": x= ");
  Serial.print(x);
  Serial.print(" | y= ");
  Serial.print(y);
  Serial.print(" | z= ");
  Serial.println(z);
}

A picture of the wiring: Arduino, BNO055 and an SSD1306 - Album on Imgur (couldn’t get “Insert an image” to work…)

I hope I posted in the right part of the forum.

Very grateful for all the help I can get!

// Eophex

To post an image, just append it to your post. However, a photo of a breadboard wiring rat's nest is useless, so please take the time to draw out a clear wiring diagram (pencil and paper) and post a pic of that.

There should be no conflict between the two devices on the I2C bus, but if for some weird reason there is, the display can also use either a parallel or SPI connection. Try the latter.

I happened to stumble upon another problem that makes solving the first one useless. The project needs the screen to update with new information every 5 or 10 milliseconds. I tried to execute the OLED code as is during every loop without the display working, and it increased the "loop-time" by like ten times lol. So I tried using just a regular 4 digit hex display and it worked really well, real fast and real smooth. I'll just have to be happy with 4 numbers instead of two rows of text.

Thanks for the help nontheless!