OLED conflict using SSD1306? with Adafruit BNO055 restore_offsets example

PARTIALLY SOLVED…
So I traced the issue being to these lines of code associated with the OLED.

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library. 
// On an arduino UNO:       A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO:   2(SDA),  3(SCL), ...
// Reset pin not used but needed for library
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
//Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_SSD1306 display(OLED_RESET);

When I just use Adafruit_SSD1306 display(OLED_RESET); , by the way the OLED is just a 4pin board with no reset pin, the display comes to life and shows the results I’m after. However I now obviously lose the capability of the SCREEN_WIDTH and SCREEN_HEIGHT.
Looking at the Adafruit_SSD1306.h and the class Adafruit_SDD1306 : public Adafruit_GFX…inside public: is this constructor…
// NEW CONSTRUCTORS – recommended for new projects
Adafruit_SSD1306(uint8_t w, uint8_t h, TwoWire *twi = &Wire,
int8_t rst_pin = -1, uint32_t clkDuring = 400000UL,
uint32_t clkAfter = 100000UL);
inside protected is…
TwoWire *wire; ///< Initialized during construction when using I2C. See
///< Wire.cpp, Wire.h

So my question is HOW do I make full use of the OLED display when using SCREEN_WIDTH, SCREEN_HEIGHT, &WIRE which appear to be the root cause of my original problem as previously posted below???

Hi All,
Been awhile since I last posted as I continue my self learning. I’ve looked through other posts to see if there’s anything similar to my problem but can’t see anything, apologies if anyone knows of one.
I have a working example of code I’m using based on Paul McWhorters Tutorials for the BNO055 displaying the dynamic state of variables like Acceleration etc.
I decided to try and implement the restore_offsets example into my code to relieve the issue of calibrating each time I power up apart from the magnetometer value.
by implementing the code from the restore_offsets example I seem to have generated a conflict somewhere as the OLED display has ceased to function. It looks like it isn’t updating from the I2C bus yet when I use Serial.print statements they are printed to the Terminal perfectly??
A little stumped at the moment hoping for some guidance please.
main.cpp file

#include <Arduino.h>
#include <Wire.h>
#include <math.h>                    //Header file from Tut 6
#include <Adafruit_Sensor.h>         /******************************/ 
#include <Adafruit_BNO055.h>         /* Header files from Tutorial */
#include <utility/imumaths.h>        /*                            */
                                     /******************************/
#include <EEPROM.h>                  //Header file from Calibration Example
#include <Adafruit_I2CDevice.h>      /*************************/
#include <Adafruit_BusIO_Register.h> /* Header files req'd by */
                                     /* Platformio            */
                                     /*************************/
//Header files for added OLED display
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define I2C_ADDRESS 0x28 //0x29 /* Definition taken from Example */
Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS); /* Class instantiation */

#define BNO055_SAMPLERATE_DELAY_MS (100)
#define PI 3.1415926535897932384626433832795

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library. 
// On an arduino UNO:       A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO:   2(SDA),  3(SCL), ...
// Reset pin not used but needed for library
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//Initialise Filter values
float thetaFold = 0;
float phiFold = 0;
float psiFold = 0;
float thetaG = 0;
float phiG = 0;
float theta; // Variable used in loop code, theta =  calculated Pitch
float phi;   // Variable used in loop code, psi = calculated Roll
 
unsigned long millisOld;

//Create a BNO055 Object called myIMU
Adafruit_BNO055 myIMU = Adafruit_BNO055(55,0x28); //Updated from Adafruit_BNO055 example

/**************************************************************************/
/*
    Display sensor calibration status
*/
/**************************************************************************/
int displayCalStatus(void)
{
    /* Get the four calibration values (0..3) */
    /* Any sensor data reporting 0 should be ignored, */
    /* 3 means 'fully calibrated" */
    uint8_t system, gyro, accel, mg;
    system = gyro = accel = mg = 0;
    int Acceleration;
    Acceleration = 0;
    
    myIMU.getCalibration(&system, &gyro, &accel, &mg);

    /* The data should be ignored until the system calibration is > 0 */
    if (accel < 3)
    { 
      Acceleration = accel;
      digitalWrite(4, HIGH);
      delay (50);
      digitalWrite(4,LOW);
      delay (50);
    }
    else if (accel == 3)
    { digitalWrite(4, HIGH);
      Acceleration = 3;
    } 
    if (system == 3)
    { digitalWrite(2, HIGH); }
    else if (system < 1)
    {
     digitalWrite(2, LOW);
     digitalWrite(3, HIGH);
     delay (50);
     digitalWrite(3,LOW);
     delay (50);
    }
  return Acceleration;
}

/**************************************************************************/
/*
  Display the raw calibration offset and radius data
*/
/**************************************************************************/
void displaySensorOffsets(const adafruit_bno055_offsets_t &calibData)
{
    Serial.print("Accelerometer: ");
    Serial.print(calibData.accel_offset_x); Serial.print(" ");
    Serial.print(calibData.accel_offset_y); Serial.print(" ");
    Serial.print(calibData.accel_offset_z); Serial.print(" ");

    Serial.print("\nGyro: ");
    Serial.print(calibData.gyro_offset_x); Serial.print(" ");
    Serial.print(calibData.gyro_offset_y); Serial.print(" ");
    Serial.print(calibData.gyro_offset_z); Serial.print(" ");

    Serial.print("\nMag: ");
    Serial.print(calibData.mag_offset_x); Serial.print(" ");
    Serial.print(calibData.mag_offset_y); Serial.print(" ");
    Serial.print(calibData.mag_offset_z); Serial.print(" ");

    Serial.print("\nAccel Radius: ");
    Serial.print(calibData.accel_radius);

    Serial.print("\nMag Radius: ");
    Serial.print(calibData.mag_radius);
}

void setup()
{
  Serial.begin(115200);
  myIMU.begin();
  delay(1000);
  //int8_t temp = myIMU.getTemp();
  //Serial.println(temp);
  //myIMU.setExtCrystalUse(true);
 
  int eeAddress = 0;
  long bnoID;
  bool foundCalib = false;

  EEPROM.get(eeAddress, bnoID);

  adafruit_bno055_offsets_t calibrationData;
  sensor_t sensor;

  /*
   *  Look for the sensor's unique ID at the beginning oF EEPROM.
   *  This isn't foolproof, but it's better than nothing.
  */
  myIMU.getSensor(&sensor);
   if (bnoID != sensor.sensor_id)
   {
      Serial.println("\nNo Calibration Data for this sensor exists in EEPROM");
      delay(500);
    }
    else
    {
      Serial.println("\nFound Calibration for this sensor in EEPROM.");
      eeAddress += sizeof(long);
      EEPROM.get(eeAddress, calibrationData);

      displaySensorOffsets(calibrationData);

      Serial.println("\n\nRestoring Calibration data to the BNO055...");
      myIMU.setSensorOffsets(calibrationData);

      Serial.println("\n\nCalibration data loaded into BNO055");
      foundCalib = true;
    }

  delay(1000);

  /* Display some basic information on this sensor */
  //displaySensorDetails();

  /* Optional: Display current status */
  //displaySensorStatus();

  sensors_event_t event;
  myIMU.getEvent(&event);
  /* always recal the mag as It goes out of calibration very often */
  if (foundCalib)
   {
     Serial.println("Move sensor slightly to calibrate magnetometers");
     while (!myIMU.isFullyCalibrated())
     {
       myIMU.getEvent(&event);
       delay(BNO055_SAMPLERATE_DELAY_MS);
      }
    }
    else
    {
      Serial.println("Please Calibrate Sensor: ");
      while (!myIMU.isFullyCalibrated())
      {
        myIMU.getEvent(&event);
        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);

        /* Optional: Display calibration status */
        //displayCalStatus();
        /* New line for the next sample */
        Serial.println("");

        /* Wait the specified delay before requesting new data */
        delay(BNO055_SAMPLERATE_DELAY_MS);
      }
    }

  Serial.println("\nFully calibrated!");
  Serial.println("--------------------------------");
  Serial.println("Calibration Results: ");
  adafruit_bno055_offsets_t newCalib;
  myIMU.getSensorOffsets(newCalib);
  displaySensorOffsets(newCalib);

  Serial.println("\n\nStoring calibration data to EEPROM...");

  eeAddress = 0;
  myIMU.getSensor(&sensor);
  bnoID = sensor.sensor_id;

  EEPROM.put(eeAddress, bnoID);

  eeAddress += sizeof(long);
  EEPROM.put(eeAddress, newCalib);
  Serial.println("Data stored to EEPROM.");

  Serial.println("\n--------------------------------\n");
  delay(500);

  /* Crystal must be configured AFTER loading calibration data into BNO055. */
  myIMU.setExtCrystalUse(true);

  // Initialize OLED with I2C addr 0x3C
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  millisOld = millis(); 
}

void loop()
{
  // Put your main code here, to run repeatedly:
  // Variables used in Calculations
  float thetaM, thetaFnew, thetaRad;
  float phiM, phiFnew, phiRad;
  float psiFnew; //NEW CODE
  
  // Filter Gain values where sum=1
  float thetaFoldGain = 0.9;
  float phiFoldGain   = 0.9;
  float psiFoldGain   = 0.85; //NEW CODE
  float thetaMGain    = 0.1;
  float phiMGain      = 0.1;
  float psiMGain      = 0.15; //NEW CODE

  float dt; //Time variable between loop calculations

  // Magnetometer variables
  float Xm;
  float Ym;
  float psi;

  int Acceleration;

  display.display();

  /* Display Calibration Values/Status */
  Acceleration = displayCalStatus();

  //Open AdaFruit Library imu and get data put into Vector<>
  imu::Vector<3> acc = myIMU.getVector(Adafruit_BNO055::VECTOR_ACCELEROMETER);
  imu::Vector<3> gyr = myIMU.getVector(Adafruit_BNO055::VECTOR_GYROSCOPE);
  imu::Vector<3> mag = myIMU.getVector(Adafruit_BNO055::VECTOR_MAGNETOMETER);

  //Calculate Pitch and Roll angles from Accelerometers & Gyros Lesson 7 & 8
  //Apply Low Pass Filter calculation
  thetaM = -atan2(acc.x()/9.8,acc.z()/9.8)/2/PI*360; //Pitch from Accelerometer
  thetaFnew = thetaFoldGain*thetaFold + thetaMGain*thetaM;
  phiM = -atan2(acc.y()/9.8,acc.z()/9.8)/2/PI*360; //Roll from Accelerometer
  phiFnew = phiFoldGain*phiFold + phiMGain*phiM;

  //Calculate the time between measurements 
  dt = (millis() - millisOld)/1000.0;
  millisOld = millis();

  //Lesson 9 Apply a Complimentary Filter for short term changes and long term stability 
  //Pitch value theta = short term value of GYRO (HIGH PASS FILTER) + long term value of ACCELEROMETER (LOW PASS FILTER)
  theta = (theta + gyr.y()*dt)*thetaFoldGain + thetaM*thetaMGain;
  //Roll value phi = short term value of GYRO (HIGH PASS FILTER) + long term value of ACCELEROMETER (LOW PASS FILTER)
  phi = (phi - gyr.x()*dt)*phiFoldGain + phiM*phiMGain;

  //Arduino works in RADIANS for sin, cos, tan calculations
  thetaRad = theta/360*(2*PI);
  phiRad = phi/360*(2*PI);
  
  //Calculate compensated psi (mag) value for the Pitch and Roll vectors
  Xm = mag.x()*cos(thetaRad) - mag.y()*sin(phiRad)*sin(thetaRad) + mag.z()*cos(phiRad)*sin(thetaRad);
  Ym = mag.y()*cos(phiRad) + mag.z()*sin(phiRad);
  //Calculate Magnetic North in degrees
  psi=atan2(Ym,Xm)/(2*PI)*360;

  psiFnew = psiFoldGain*psi + psiMGain*psiFold; //NEW CODE
  /*
  Serial.print(theta);
  Serial.print(", ");
  Serial.print(phi);
  Serial.print(", ");
  Serial.print(psi);
  Serial.print(", ")
  Serial.print(Acceleration)
  Serial.println(", ");
  */

  // Clear the display
  display.clearDisplay();
  //Set the color - always use white despite actual display color
  display.setTextColor(WHITE);
  //Set the font size
  display.setTextSize(1.5);
  //Set the cursor coordinates
  display.setCursor(0,0);
  display.print("Pitch:  ");
  display.print(theta);
  display.setCursor(0,10);
  display.print("Roll:   "); 
  display.print(phi);
  display.setCursor(0,20);
  display.print("Yaw:   ");
  display.print(psiFnew);
  display.setCursor(0,30);
  display.print("Acceleration: ");
  display.print(Acceleration);
  display.setCursor(0,40);
     
  thetaFold = thetaFnew; //Update theta filter old value
  phiFold   = phiFnew;   //Update phi filter old value
  psiFold   = psiFnew;
    
  delay (BNO055_SAMPLERATE_DELAY_MS);
}

platform.ini file

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:nanoatmega328]
platform = atmelavr
board = nanoatmega328
framework = arduino
monitor_speed = 115200
lib_deps = 
	adafruit/Adafruit BNO055@^1.6.3
	adafruit/Adafruit Unified Sensor@^1.1.14
	adafruit/Adafruit BusIO@^1.14.5
	adafruit/Adafruit SSD1306@^2.5.9

Made a few changes to the program and determined at the point where the loop hangs, but it’s a little beyond my understanding as to why at the moment?
when I un-comment the line display.setTextColor(WHITE); the code just hangs for some reason?

 /* Display Calibration Values/Status */
  Acceleration = displayCalStatus();

  Serial.print(theta);
  Serial.print(", ");
  Serial.print(phi);
  Serial.print(", ");
  Serial.print(psi);
  Serial.print(", ");
  Serial.print(Acceleration);
  Serial.println(", "); 
  
  // Clear the display
  display.clearDisplay();
  //Set the font size
  display.setTextSize(1.5); 
  //Set the color - always use white despite actual display color
  display.setTextColor(WHITE); //Loop hangs at this point after printing 1 line of results from above???  
  //Set the cursor coordinates
  display.setCursor(0,0);
  display.print("Pitch:  ");

FINALLY traced it to when the first OLED display.print("Pitch: "); instruction is executed the program produces an unexpected event??? OR an OLED display.print instruction is executed,

It prints 2 lines of 0.0, 0.0, 0.0, 3
Then prints 2 lines of values before hanging up and executing the setup() function again???

Bit beyond my knowledge/understanding this at the moment as to why.
My other program using the OLED display without the modification to use restore_offsets works perfectly ???