I2C Communication Hanging with 4Duino (Arduino Uno)

For my project I am using a 4Duino screen (basically an Arduino Uno), a Teensy 3.2, and a BNO055. What I want is to press (touch the lcd screen) a button on the screen, it sends a character to the Teensy through I2C communication. This character (in this case ‘c’) tells the Teensy to start collecting a series of values over a specified time from the BNO055, also through I2C communication. Once the data is collected, the Teensy will change ‘reply’ to ‘r’ for ready. Otherwise, ‘reply’ stays ‘n’ for not ready. Once ‘reply’ is ‘r’ the 4Duino will request the data to be sent over.

I am able to get the Teensy to read the character and start collecting. I am struggling with the part of having the 4Duino request the data and have it sent over. So in the code where it says “Requesting Data” on the master code it just stays there. This makes me think that the bus is busy. I am not sure where it would be busy. My thought was the BNO. I initialize the BNO once the character is received because if I initialize it in the slave setup area the 4Duino will never send the character over.

I have set the BNO on address 0x29 (default is 0x28 – LOW) because I thought it would free the bus for the 4Duino but it does seem to change anything. I have also tried setting up the BNO to communicate with UART but was advised against it because it is slow and can cause a lot of errors. I was wondering if maybe resetting the BNO mid-run would free the bus to allow the screen to request but I am not sure if it is even the BNO that is stopping the screen from requesting.

I have attached a simplified master (4duino) and slave (teensy) code below as well as the spec sheets for the 4Duino, Teensy 3.2 and BNO055. I need the Teensy because there is not enough memory on the 4Duino for me to collect data from the BNO and do calculations with it. This is my first project using I2C communication so I am very new to it. Any comments or suggestions are greatly appreciated. Thanks in advance!

Master Code (4Duino)

//#1 4Duino (Master)

#include <Wire.h>                                  //Wire library

//==========================================================================

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Wire.begin(8);                    // Start I2C Bus as Master on device #8

  /*Screen setup code follows
     .
     .
     .

  */
}
//======= END SETUP =========================================================
void loop() 
{
  Form1();
}
//======= END LOOP =========================================================
int Form1()
{
  /* Code for screen
     .
     . 
     .
*/
//once button is pressed go to:
  recEvent();
}
//======= END FORM 1 ========================================================
void recEvent() 
{
  Wire.beginTransmission(9);
  Wire.write('c');
  byte error = Wire.endTransmission(true); //false = keeps on the I2C bus. true = releases the bus

  if (error == 0)
  {
    Serial.println("No Errors");
    delay(3000);  //wait 3 seconds
    Serial.println("Requesting data...");
    Wire.requestFrom(9, 2); //request 2 bytes of data from device #9 (Teensy)
    Serial.println("Requested data");

    while (Wire.available())
    {
      int c = Wire.read();
      Serial.print(c);
    }
  }
  if (error == 1)
  {
    Serial.print("data too long to fit in transmit buffer");
  }
  if (error == 2)
  {
    Serial.print("Received NACK on transmit of address");
  }
  if (error == 3)
  {
    Serial.print("Recieved NACK on transmit of data");
  }
  if (error == 4)
  {
    Serial.print("Error. Restart and try again");
  }
}
//======= END recEvent ======================================================

Slave Code (Teensy 3.2)

//#2 Teensy (Slave)
#include <Adafruit_BNO055.h>                     //Adafruit sensor
#include <Adafruit_Sensor_Calibration.h>         //Sensor calibration values
#include <utility/imumaths.h>                    //Lets you do math
Adafruit_BNO055 bno = Adafruit_BNO055(55, 0x29);       //Declaring the sensor as bno. High (0x29) low (0x28) <--Default

//==========================================================================
//Declaration of Variables
char rec = 'a';   //what Teensy RECEIVES from Screen
char reply = 'n'; //what Teensy SENDS    to Screen

//==========================================================================
void setup()
{
  Wire.begin(9);                // Start the I2C Bus as Device #9
  Serial.begin(9600);
  Wire.onRequest(requestEvent);
  Wire.onReceive(receiveEvent);
}
//========== END SETUP ======================================================
void loop() 
{
  delay(100);
}
//========== END LOOP =======================================================
void receiveEvent(int howMany)
{
  while (Wire.available())
  {
    rec = Wire.read();
    Serial.println(rec);

    if (rec == 'c')       //if the button on the screen was pressed the character would be (c)ollect
    {
      //Initalize BNO

      if (!bno.begin())
      {
        Serial.println("ERRROR WITH BNO");
        while (1);
      }
      else
      {
        Serial.println("BNO Started");
      }
      delay(1000);
      bno.setExtCrystalUse(true);

      //Calibration
      adafruit_bno055_offsets_t calibrationData; //Calibration offsets for mag are the average of 6 calibrations
      bno.setSensorOffsets(calibrationData);     //Load calibration offsets
      //end BNO code

      Serial.println("BNO initalized. Collect ");
      //code for collecting BNO values here
      delay(100);
      reply = 'r'; //(r)eady to send data to screen
      Serial.println("Collected Data. Waiting for request");
     }   //end if rec == 'c'
   }     //end while
}
//========== END receiveEvent ==================================================
void requestEvent()
{
  Wire.write(reply);
}
//========= END requestEvent ==================================================

BNO055 Spec Sheet: https://cdn-shop.adafruit.com/datasheets/BST_BNO055_DS000_12.pdf
4Duino Spec Sheet: https://4dsystems.com.au/mwdownloads/download/link/id/166/
Teensy 3.2 Manual: https://www.pjrc.com/teensy/K20P64M72SF1RM.pdf
Teensy 3.2 Datasheet: https://www.pjrc.com/teensy/K20P64M72SF1.pdf

UPDATE:
So I definitely think it has something to do with the BNO. When I do a simple back and forth between the 4Duino and Teensy, I am able to get the data requested to the serial monitor of the 4Duino. But once I initialize the BNO I am not able to request that data. Is there a way to somehow un-initalize the BNO?

In an I2C system you have (normally) only one master and one or more slaves. Only the master can request data, the slaves can not. What normally happens is that the master poles the salves in effect asking them if they have any data to send. The slave responds and if it is a yes then the master asks the slaves for the data.

There is a system known as a multi master system where two or more masters can request data. But this has the problem of what happens if two masters request bus access at the same time. There are many strategies you can use for this and sometimes they are successful. But it is a can of worms and in my professional life I have spent a great deal of time trying to track problems down with such a system.
This does require special software. None of the normal libraries can handle this system.

Please give us a broader view of your project. What is it for ?

The 4Duino is a ATmega32U4, 16MHz, 5V board. That is just like the Arduino Leonardo.

Can de 4Duino get the data from the Adafruit BNO055 module ?
It will be a lot harder if you use two Arduino boards.
If you have a very good reason for a second board, then you take the risk that you may not get a working project.
If you really need two boards, can you rethink your project ?
Do you really only want data if you ask for it ? That slows things down.

Perhaps the Teensy can use Serial RX, TX pins (with GND), via a level shifter, to a TX, RX pin (with GND) of the 4Duino. Then you can send a command to get data. I prefer that the data is always transmitted, and the 4Duino can use it or not.

Using the I2C bus in this situation is not a good choice. I can write down the first things that come to my mind, but there is many more.

  1. The Teensy is a ARM Cortex M4 at 3.3V with a 3.3V I2C bus. The 4Duino has a 5V I2C bus. You may not just connect those I2C buses.
  2. Do you use pullup resistors for the I2C bus ? Does the 4Duino have pullup resistors ? And the Adafruit BNO055 module ? There should be some pullup, but not too much.
  3. Did you connect the GND between the Teensy and the 4Duino ?
  4. You want to use the 4Duino as a Master, and the Teensy as a Master for the BNO055. Then you have a multi-master bus. That will not work. Since you also set the Master in Slave mode, perhaps you want to send data to the Master, that is even worse.
  5. You don't have to write error messages for the return value of Wire.endTransmission(). Those values have different meanings on different board. Just check if it is zero for no error.
  6. Do you know if the Teensy 3.2 can operate in Slave mode ? Can you confirm that ?
  7. You may not use I2C functions or delay in the receiveEvent() function. That means you can not communicate with the BNO055 from there. Using the Serial functions can be done during testing, but they have to be taken out of there as well. That means that you can do a Wire.read() and that's all.