BNO086 I2C Communication problem with Teensy 4.1

@rcarr, I think you are right.
I wondered about it as well, but skipped right over it. But I believe that is only called after you do a beginTransmission, followed by some writes...

And it makes sense why the Logic Analyzer was showing a setup write operation....
 
@rcarr. I will ditto what @KurtE said. Saw it but didn't register it.

I removed it in the sketch and it did resolve an issue with softreset. So now that I added parsing the rotation vector:
Code:
I2C timeout
END SETUP
AFTER STARTUP ADVERTISE MSG READ:
- Send '1' to request ProductID msg
- Send '2' to enable Rotation Vector Output
flagStartup = 1
enableRotationVector
Output in form i, j, k, real, accuracy
0.02,0.02,-0.74,0.67,0.79,
0.02,0.02,-0.74,0.67,0.79,
0.02,0.02,-0.74,0.67,0.79,
0.02,0.02,-0.74,0.67,0.79,
0.02,0.02,-0.74,0.67,0.79,
0.02,0.02,-0.74,0.67,0.79,
0.02,0.02,-0.74,0.67,0.79,
0.02,0.02,-0.74,0.67,0.79,
0.02,0.02,-0.74,0.67,0.79,
which pretty much matches the output from the sparkfun sketch
 

Attachments

  • BNO080_86_issue_kurte-221220a.zip
    3.9 KB · Views: 53
Hi, I am designing a PCB with BNO086 and Teensy 4.1. Is the problem solved? Can I use BNO086 sensor and Teensy 4.1 with Sparkfun Arduino library?
 
Last edited:
Hi, I am designing a PCB with BNO086 and Teensy 4.1. Is the problem solved? Can I use BNO086 sensor and Teensy 4.1 with Sparkfun Arduino library?
I don't have a bno086 to say 100% but probably 99.5% sure it would work. As we said above we tested with the BNO080.

It looks like Sparkfun now has a breakout board: https://www.sparkfun.com/products/22857. Haven't looked maybe will pick one up

EDIT: ok ordered one out of curiosity should have it on friday
 
Adafruit has a breakout for BNO085, and it includes the I2C-related warning shown below. The i.MX RT 1011 is listed as one of the CPUs that may not be able to communicate with the sensor via I2C. Not sure if that might imply trouble with iMXRT 1062 (Teensy), but you might want to search the Adafruit forums or ask a question.

The BNO08x I2C implementation violates the I2C protocol in some circumstances. This causes it not to work well with certain chip families. It does not work well with Espressif ESP32, ESP32-S3, and NXP i.MX RT1011, and it does not work well with I2C multiplexers. Operation with SAMD51, RP2040, STM32F4, and nRF52840 is more reliable.
 
Hello there. After months, in our opinion the I2C problem continues to be related with PJRC Wire library that is performing unwanted writes after the read action, like shown in previous post:
In addition, I post a screen of the detail where in our opinion lies the error, or that Teensy periodically sends unwanted write requests (containing the buffer of the last request actually executed in the sketch) during the periodic reading of the data. In our opinion, this is a misbehavior due to the Wire library or Teensy itself.

View attachment 29994

The I2C protocol is designed to receive a response to a request for a specific register. Unexpected writes come immediately after a read, so we suspect that there is an algorithm in the Wire library that repeats the write in case the response read is not what one expects.
This problem has been experienced with Teensy 4.1, Teensyduino 1.57.2, BNO086, with all the libraries (Adafruit, Sparkfun, custom). With Arduino and ESP32 the problem doesn't show, so the suspect is that is something related to Teensy Wire or iMRXT architecture. We preferred to develop the IMU communication with SPI, that is more reliable and efficient in this case if you don't have to cover long wires distances.
 
I will have a BNO086 breakout board next week, but I'm certainly no expert on I2C or the Wire library. I'll test it as soon as I get it, though, and let you know what I see.
 
Received my BNO086 today and just hooked it up to a Teensy Micromod. I installed both the adafruit BNO08x and the sparkfun BNO08x libraries and both failed:
Adafruit:

Code:
Adafruit BNO08x test!
BNO08x Found!
Setting desired reports
Reading events
sensor was reset Setting desired reports
9065887    0    93.49    2.04    -177.83
7499    0    0.31    -4.30    -4.07
11574    0    0.31    -4.31    -4.07
4617    0    0.31    -4.31    -4.07
3264    0    0.31    -4.31    -4.07
3128    0    0.31    -4.31    -4.07
3250    0    0.31    -4.31    -4.07
sensor was reset Setting desired reports
sensor was reset Setting desired reports
sensor was reset Setting desired reports
sensor was reset Setting desired reports
sensor was reset Setting desired reports
....
It starts out ok but then keeps resetting as you can see from the output.

Sparkfun

Code:
BNO08x Read Example
I2C address found
BNO08x not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...
It finds the device but then dies.

Will have to dig into whats going on with them.


Based on their recommendation I hooked up RST and INT:
// For the most reliable interaction with the SHTP bus, we need
// to use hardware reset control, and to monitor the H_INT pin.
// The H_INT pin will go low when its okay to talk on the SHTP bus.
// Note, these can be other GPIO if you like.
// Define as -1 to disable these features.
and it worked:

Code:
BNO08x found!
Setting desired reports
Could not enable rotation vector
Reading events
sensor was reset Setting desired reports
Rotation vector enabled
Output in form i, j, k, real, accuracy
sensor was reset Setting desired reports
Rotation vector enabled
Output in form i, j, k, real, accuracy
-0.01,0.81,-0.02,0.59,3.14
-0.01,0.81,-0.02,0.59,3.14
-0.01,0.81,-0.02,0.59,3.14
-0.01,0.81,-0.02,0.59,3.14
-0.01,0.81,-0.02,0.59,3.14
-0.01,0.81,-0.02,0.59,3.14
-0.01,0.81,-0.02,0.59,3.14

Will look at the I2C traces in the morning
 
Last edited:
Now for the interesting part using one of test sketches @KurtE and I were playing with earlier in the thread it seems to be working no issue - at least for Rotation Vector:

Code:
I2C timeout
END SETUP
AFTER STARTUP ADVERTISE MSG READ:
- Send '1' to request ProductID msg
- Send '2' to enable Rotation Vector Output
flagStartup = 1
productIdReq
enableRotationVector
Output in form i, j, k, real, accuracy
-0.47,-0.08,0.04,0.89,0.79,
-0.47,-0.08,0.04,0.89,0.79,
-0.47,-0.08,0.04,0.89,0.79,
-0.47,-0.08,0.04,0.89,0.79,
-0.47,-0.08,0.04,0.89,0.79,
-0.47,-0.08,0.04,0.89,0.79,
-0.47,-0.08,0.04,0.89,0.79,
-0.47,-0.08,0.04,0.89,0.79,
-0.47,-0.08,0.04,0.89,0.79,

Here is the sketch:
Code:
#include <Wire.h>
#include <math.h>

#define SERIAL_CMD true
uint8_t MAX_BUFF_LENGTH = 32;
uint8_t requestBytes = 4;

#define HEADER_LENGTH 4

#define SHTP_REPORT_COMMAND_RESPONSE 0xF1
#define SHTP_REPORT_COMMAND_REQUEST 0xF2
#define SHTP_REPORT_FRS_READ_RESPONSE 0xF3
#define SHTP_REPORT_FRS_READ_REQUEST 0xF4
#define SHTP_REPORT_PRODUCT_ID_RESPONSE 0xF8
#define SHTP_REPORT_PRODUCT_ID_REQUEST 0xF9
#define SHTP_REPORT_BASE_TIMESTAMP 0xFB
#define SHTP_REPORT_SET_FEATURE_COMMAND 0xFD

//All the different sensors and features we can get reports from
//These are used when enabling a given sensor
#define SENSOR_REPORTID_ACCELEROMETER 0x01
#define SENSOR_REPORTID_GYROSCOPE 0x02
#define SENSOR_REPORTID_MAGNETIC_FIELD 0x03
#define SENSOR_REPORTID_LINEAR_ACCELERATION 0x04
#define SENSOR_REPORTID_ROTATION_VECTOR 0x05
#define SENSOR_REPORTID_GRAVITY 0x06
#define SENSOR_REPORTID_GAME_ROTATION_VECTOR 0x08
#define SENSOR_REPORTID_GEOMAGNETIC_ROTATION_VECTOR 0x09
#define SENSOR_REPORTID_GYRO_INTEGRATED_ROTATION_VECTOR 0x2A
#define SENSOR_REPORTID_TAP_DETECTOR 0x10
#define SENSOR_REPORTID_STEP_COUNTER 0x11
#define SENSOR_REPORTID_STABILITY_CLASSIFIER 0x13
#define SENSOR_REPORTID_RAW_ACCELEROMETER 0x14
#define SENSOR_REPORTID_RAW_GYROSCOPE 0x15
#define SENSOR_REPORTID_RAW_MAGNETOMETER 0x16
#define SENSOR_REPORTID_PERSONAL_ACTIVITY_CLASSIFIER 0x1E
#define SENSOR_REPORTID_AR_VR_STABILIZED_ROTATION_VECTOR 0x28
//#define SENSOR_REPORTID_AR_VR_STABILIZED_GAME_ROTATION_VECTOR*0x29

#define DEBUG_I2C false

const byte CHANNEL_COMMAND = 0;
const byte CHANNEL_EXECUTABLE = 1;
const byte CHANNEL_CONTROL = 2;
const byte CHANNEL_REPORTS = 3;
const byte CHANNEL_WAKE_REPORTS = 4;
const byte CHANNEL_GYRO = 5;

uint8_t deviceAddress = 0x4B;
uint8_t shtpDataRead[128];
uint8_t shtpDataWrite[128];
uint8_t shtpDataSend[128];
uint8_t sequenceNumber[6] = { 0, 0, 0, 0, 0, 0 };

uint8_t syncCom = 0;
uint16_t remainingBytes = 0;
uint8_t flagStartup = 0;

uint32_t timerToSend = 1000;
uint32_t timeToSend = 0;

uint32_t timerToSendConf = 2000;
uint32_t timeToSendConf = 0;

uint32_t timer_head_i2c = 70;
uint32_t time_head_i2c = 0;
int pinInterrupt = 8;

float quatI, quatJ, quatK, quatReal, quatRadianAccuracy;
uint8_t quatAccuracy;


void setup() {
  // put your setup code here, to run once:
  while(!Serial && millis() < 3000) ;
  //if (CrashReport) {
  //  Serial.print(CrashReport);
  //  while (Serial.read() == -1);
  //  while (Serial.read() != -1);
  //}
  pinMode(pinInterrupt, INPUT_PULLUP);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  Serial.begin(115200);
  Wire.begin();
  Wire.setClock(400000);
  softResetI2C();
  delay(250);
  Serial.println("END SETUP");
  Serial.println("AFTER STARTUP ADVERTISE MSG READ:");
  Serial.println("- Send '1' to request ProductID msg");
  Serial.println("- Send '2' to enable Rotation Vector Output");
}

void loop() {
  if (SERIAL_CMD) {
    if (Serial.available() > 0) {
      char cmd = Serial.read();
      if (cmd == '1') {
        timeToSend = millis();
        productIdReq();
        delay(100);
        flagStartup = 2;
        Serial.println("productIdReq");
      }
      if (cmd == '2') {
        timeToSendConf = millis();
        enableRotationVectorI2C(10);
        flagStartup = 3;
        Serial.println("enableRotationVector");
        Serial.println(F("Output in form i, j, k, real, accuracy"));
      }
      if (cmd == '3') {
        timeToSendConf = millis();
        softResetI2C();
        Serial.println("softReset");
      }
    }
  } else {
    if (((millis() - timeToSendConf) > timerToSendConf) && (flagStartup == 1)) {
      timeToSend = millis();
      productIdReq();
      flagStartup = 2;
      Serial.println("productIdReq");
    }
    if (((millis() - timeToSend) > timerToSend) && (flagStartup == 2)) {
      timeToSend = millis();
      enableRotationVectorI2C(10);
      flagStartup = 3;
      Serial.println("enableRotationVector");
      Serial.println(F("Output in form i, j, k, real, accuracy"));
    }
  }

  if (interruptOn()) {
    timeToSend = millis();
    if ((micros() - time_head_i2c) > timer_head_i2c) {
      receivePackets();
      time_head_i2c = micros();
    
    if (shtpDataRead[2] == CHANNEL_REPORTS && shtpDataRead[4] == SHTP_REPORT_BASE_TIMESTAMP) {
      getQuat(quatI, quatJ, quatK, quatReal, quatRadianAccuracy, quatAccuracy);
      Serial.print(quatI, 2);
      Serial.print(F(","));
      Serial.print(quatJ, 2);
      Serial.print(F(","));
      Serial.print(quatK, 2);
      Serial.print(F(","));
      Serial.print(quatReal, 2);
      Serial.print(F(","));
      Serial.print(quatRadianAccuracy, 2);
      Serial.print(F(","));
      Serial.println();
    }
    }
  }
}

void printSyncCom() {
  Serial.print("syncCom:");
  Serial.println(syncCom);
}

bool receivePackets() {
  Wire.requestFrom((uint8_t)deviceAddress, requestBytes);
  if (waitForI2C() == false)
    return (false);  //Error
  return readI2C();
}
uint8_t byteToread = 0;
uint8_t readI2C() {
  //Serial.printf("readI2C: %u ", syncCom); Serial.flush();
  switch (syncCom) {
    case 0:
      byteToread = Wire.available();
      //Serial.printf(" avail: %u\n", byteToread); Serial.flush();
      if (byteToread >= requestBytes) {
        //Serial.println(requestBytes);
        for (uint8_t k = 0; k < byteToread; k++) {
          shtpDataRead[k] = Wire.read();
        }
        printPacketI2C(requestBytes);
        remainingBytes = getRemainingBytes(shtpDataRead[1], shtpDataRead[0]);
        //Serial.println(remainingBytes);
        if (remainingBytes < (MAX_BUFF_LENGTH - HEADER_LENGTH)) {
          requestBytes = remainingBytes;
          syncCom = 2;
        } else {
          requestBytes = MAX_BUFF_LENGTH;
          syncCom = 1;
        }
      }
      if( syncCom == 0) return true;
      break;

    case 1:
      byteToread = Wire.available();
      //Serial.printf(" avail: %u\n", byteToread); Serial.flush();
      if (byteToread >= requestBytes) {
        for (uint8_t k = 0; k < byteToread; k++) {
          shtpDataRead[k] = Wire.read();
        }
        printPacketI2C(requestBytes);
        remainingBytes -= (MAX_BUFF_LENGTH - HEADER_LENGTH);
        if (remainingBytes < (MAX_BUFF_LENGTH - HEADER_LENGTH)) {
          requestBytes = remainingBytes;
          syncCom = 2;
        }
      }
      if( syncCom == 1) return true;
      break;

    case 2:
      byteToread = Wire.available();
      //Serial.printf(" avail: %u\n", byteToread); Serial.flush();
      if (Wire.available() >= byteToread) {
        for (uint8_t k = 0; k < byteToread; k++) {
          shtpDataRead[k] = Wire.read();
        }
        syncCom = 0;
        printPacketI2C(requestBytes);
        requestBytes = HEADER_LENGTH;
        if (flagStartup == 0) {
          flagStartup = 1;
          Serial.println("flagStartup = 1");
        }
      }
      return true;
      break;
  }
  return false;
}

uint8_t packetContinue(uint8_t MSB) {
  uint8_t temp_bit = (MSB >> 7);
  return temp_bit;
}

uint16_t getRemainingBytes(uint8_t MSB, uint8_t LSB) {
  uint16_t dataLengtha = (((uint16_t)MSB) << 8) | ((uint16_t)LSB);
  dataLengtha &= ~((uint16_t)1 << 15);  //Clear the MSbit.
  return dataLengtha;
}


uint8_t interruptOn() {
  if (digitalRead(pinInterrupt) == LOW) {
    return true;
  } else {
    return false;
  }
}

void setFeatureCommandI2C(uint8_t reportID, uint16_t timeBetweenReports, uint32_t specificConfig) {
  long microsBetweenReports = (long)timeBetweenReports * 1000L;

  shtpDataWrite[0] = SHTP_REPORT_SET_FEATURE_COMMAND;      //Set feature command. Reference page 55
  shtpDataWrite[1] = reportID;                             //Feature Report ID. 0x01 = Accelerometer, 0x05 = Rotation vector
  shtpDataWrite[2] = 0;                                    //Feature flags
  shtpDataWrite[3] = 0;                                    //Change sensitivity (LSB)
  shtpDataWrite[4] = 0;                                    //Change sensitivity (MSB)
  shtpDataWrite[5] = (microsBetweenReports >> 0) & 0xFF;   //Report interval (LSB) in microseconds. 0x7A120 = 500ms
  shtpDataWrite[6] = (microsBetweenReports >> 8) & 0xFF;   //Report interval
  shtpDataWrite[7] = (microsBetweenReports >> 16) & 0xFF;  //Report interval
  shtpDataWrite[8] = (microsBetweenReports >> 24) & 0xFF;  //Report interval (MSB)
  shtpDataWrite[9] = 0;                                    //Batch Interval (LSB)
  shtpDataWrite[10] = 0;                                   //Batch Interval
  shtpDataWrite[11] = 0;                                   //Batch Interval
  shtpDataWrite[12] = 0;                                   //Batch Interval (MSB)
  shtpDataWrite[13] = (specificConfig >> 0) & 0xFF;        //Sensor-specific config (LSB)
  shtpDataWrite[14] = (specificConfig >> 8) & 0xFF;        //Sensor-specific config
  shtpDataWrite[15] = (specificConfig >> 16) & 0xFF;       //Sensor-specific config
  shtpDataWrite[16] = (specificConfig >> 24) & 0xFF;       //Sensor-specific config (MSB)

  //Transmit packet on channel 2, 17 bytes
  sendPacketI2C(CHANNEL_CONTROL, 17);
}

uint8_t sendPacketI2C(uint8_t channelNumber, uint8_t dataLength) {
  digitalWrite(4, HIGH);
  uint8_t packetLength = dataLength + 4;  //Add four bytes for the header

  Wire.beginTransmission(deviceAddress);

  shtpDataSend[0] = (packetLength & 0xFF);
  shtpDataSend[1] = (packetLength >> 8);
  shtpDataSend[2] = (channelNumber);
  shtpDataSend[3] = (sequenceNumber[channelNumber]);  //Send the sequence number, increments with each packet sent, different counter for each channel

  for (uint8_t i = 0; i < (dataLength); i++) {
    shtpDataSend[i + 4] = shtpDataWrite[i];
  }

  for (uint8_t i = 0; i < (dataLength + 4); i++) {
    Wire.write(shtpDataSend[i]);
  }

  sequenceNumber[channelNumber]++;
  Wire.endTransmission();
  digitalWrite(4, LOW);
  return true;
}
void productIdReq() {
  shtpDataWrite[0] = SHTP_REPORT_PRODUCT_ID_REQUEST;  //Set feature command. Reference page 55
  shtpDataWrite[1] = 0;
  sendPacketI2C(CHANNEL_CONTROL, 2);
}

void softResetI2C() {
  shtpDataWrite[0] = 1;
  sendPacketI2C(CHANNEL_EXECUTABLE, 1);

  //Read all incoming data and flush it
  delay(50);
  while (receivePackets() == true)
    ;  //delay(1);
  delay(50);
  while (receivePackets() == true)
    ;  //delay(1);
}

void enableRotationVectorI2C(uint16_t timeBetweenReports) {
  setFeatureCommandI2C(SENSOR_REPORTID_ROTATION_VECTOR, timeBetweenReports, 0);
}

void enableAccelerometerI2C(uint16_t timeBetweenReports) {
  setFeatureCommandI2C(SENSOR_REPORTID_LINEAR_ACCELERATION, timeBetweenReports, 0);
}

void printPacketI2C(uint8_t printBytes) {
  if (DEBUG_I2C) {
    //Serial.printf("printPacketI2C(%u)\n", printBytes); Serial.flush();
    for (uint8_t j = 0; j < printBytes; j++) {
      Serial.print(shtpDataRead[j], HEX);
      Serial.print(",");
    }
    Serial.println();
  }
}

boolean waitForI2C() {
  for (uint8_t counter = 0; counter < 255; counter++)  //Don't got more than 255
  {
    if (Wire.available() > 0)
      return (true);
    delay(1);
  }

  //if (_printDebug == true)
  Serial.println(F("I2C timeout"));
  return (false);
}


//Gets the full quaternion
//i,j,k,real output floats
void getQuat(float &i, float &j, float &k, float &real, float &radAccuracy, uint8_t &accuracy)
{
  uint16_t rawQuatI, rawQuatJ, rawQuatK, rawQuatReal, rawQuatRadianAccuracy, quatAccuracy;
  int16_t rotationVector_Q1 = 14;
  int16_t rotationVectorAccuracy_Q1 = 12; //Heading accuracy estimate in radians. The Q point is 12.
 
  //Calculate the number of data bytes in this packet
  int16_t dataLength = ((uint16_t)shtpDataRead[1] << 8 | shtpDataRead[0]);
  dataLength &= ~(1 << 15); //Clear the MSbit. This bit indicates if this package is a continuation of the last.
  //Ignore it for now. TODO catch this as an error and exit

  dataLength -= 4; //Remove the header bytes from the data count

  uint32_t timeStamp = ((uint32_t)shtpDataRead[HEADER_LENGTH + 4] << (8 * 3)) | ((uint32_t)shtpDataRead[HEADER_LENGTH + 3] << (8 * 2)) | ((uint32_t)shtpDataRead[HEADER_LENGTH + 2] << (8 * 1)) | ((uint32_t)shtpDataRead[HEADER_LENGTH + 1] << (8 * 0));
 
  uint8_t status = shtpDataRead[HEADER_LENGTH + 5 + 2] & 0x03; //Get status bits
  uint16_t data1 = (uint16_t)shtpDataRead[HEADER_LENGTH + 5 + 5] << 8 | shtpDataRead[5 + 4];
  uint16_t data2 = (uint16_t)shtpDataRead[HEADER_LENGTH + 5 + 7] << 8 | shtpDataRead[5 + 6];
  uint16_t data3 = (uint16_t)shtpDataRead[HEADER_LENGTH + 5 + 9] << 8 | shtpDataRead[5 + 8];
  uint16_t data4 = 0;
  uint16_t data5 = 0; //We would need to change this to uin32_t to capture time stamp value on Raw Accel/Gyro/Mag reports

  if (dataLength - 5 > 9)
  {
    data4 = (uint16_t)shtpDataRead[HEADER_LENGTH + 5 + 11] << 8 | shtpDataRead[HEADER_LENGTH + 5 + 10];
  }
  if (dataLength - 5 > 11)
  {
    data5 = (uint16_t)shtpDataRead[HEADER_LENGTH + 5 + 13] << 8 | shtpDataRead[HEADER_LENGTH + 5 + 12];
  }
    
  quatAccuracy = status;
  rawQuatI = data1;
  rawQuatJ = data2;
  rawQuatK = data3;
  rawQuatReal = data4;

  //Only available on rotation vector and ar/vr stabilized rotation vector,
  // not game rot vector and not ar/vr stabilized rotation vector
  rawQuatRadianAccuracy = data5;
 
 
  i = qToFloat(rawQuatI, rotationVector_Q1);
  j = qToFloat(rawQuatJ, rotationVector_Q1);
  k = qToFloat(rawQuatK, rotationVector_Q1);
  real = qToFloat(rawQuatReal, rotationVector_Q1);
  radAccuracy = qToFloat(rawQuatRadianAccuracy, rotationVector_Q1);
  accuracy = quatAccuracy;
}

//Given a register value and a Q point, convert to float
//See https://en.wikipedia.org/wiki/Q_(number_format)
float qToFloat(int16_t fixedPointValue, uint8_t qPoint)
{
  float qFloat = fixedPointValue;
  qFloat *= pow(2, qPoint * -1);
  return (qFloat);
}

@Paul - this is where that copy button would come in handy :)
 
Ok Couldn't wait until morning. Currently I am running on a micromd with Teenduino 1.59beta3 with arduino IDE 2.2.1 (one of the nightly builds after release). Setup is crude:
1700872622235.jpeg


Running the sketch in the previous post I am not seeing any extra writes after the reads - this is just one sample. Ran the trace on and off and sampled the data and did not see it.
Screenshot 2023-11-24 192604.png


Running the example sketch from the Sparkfun BNO08x library did not show any extra writes either.
Screenshot 2023-11-24 193009.png


Not sure how to duplicate what was shown earlier.
 
Ok figured out how to make it happen - after powering off and then powering back on I am seeing the issue with the spakrun library
Screenshot 2023-11-24 194236.png


and

Screenshot 2023-11-24 194401.png
 
I am not however seeing it with the test sketch in post 37 ever after powering on and off a couple of times. So not 100% sure its an issue with wire or an issue with library. We'll see but now for rest. Its getting late here.
Screenshot 2023-11-24 195015.png
 
Ok Weird but started looking at this again this morning and reran the rotation vector sketch from sparkfun library and not seeing the read- write issue.

EDIT: had it running for a bit and then tried to force the error again but not seeing it again
 
Last edited:
Ok Weird but started looking at this again this morning and reran the rotation vector sketch from sparkfun library and not seeing the read- write issue.

EDIT: had it running for a bit and then tried to force the error again but not seeing it again
mike, not sure if I understand. Do you have the sensor working correctly? If so, could you tell us again your configuration and libraries?
 
mike, not sure if I understand. Do you have the sensor working correctly? If so, could you tell us again your configuration and libraries?

Yes the sensor is working with the Sparkfun BNO08x library but not the adafruit library for some reason. I have the INT on pin 8 and the RST on pin 7. Works out of the box.

The think that was getting me confused was that I saw a similar trace as in post 31 once but I have not been able to repeat it today. This is what I was looking at to see if there was an issue with the BNO08x library, Teensy wire library or the sensor itself. I am not seeing any issue with testing so far but havent had time to stress it. Right now kind of round robining projects around house and this.
 
Ok been running the sensor on a Teensy 4.1 with absolutely no issues using the Sparkfun BNO08x library.

So my 2 cents:
Can I use BNO086 sensor and Teensy 4.1 with Sparkfun Arduino library?
Yes you can run the Sparkfun library with with the Teensy 4.1 - remember to hook up the INT and RST pins per the comment in there sketches. If you run without them seems not to want to connect. If you run with just the rst pin hooked up I am seeing spikes in the data:
Code:
-2.6,-2.3,4.7
-2.6,-2.3,4.7
-154.4,24.2,93.4
-2.6,-2.3,4.7
-2.6,-2.3,4.7

Hello there. After months, in our opinion the I2C problem continues to be related with PJRC Wire library that is performing unwanted writes after the read action, like shown in previous post:

This problem has been experienced with Teensy 4.1, Teensyduino 1.57.2, BNO086, with all the libraries (Adafruit, Sparkfun, custom). With Arduino and ESP32 the problem doesn't show, so the suspect is that is something related to Teensy Wire or iMRXT architecture. We preferred to develop the IMU communication with SPI, that is more reliable and efficient in this case if you don't have to cover long wires distances.

As for the Teensy sending periodic write requests - I am not seeing that using TD 1.59beta3.
 
Ok been running the sensor on a Teensy 4.1 with absolutely no issues using the Sparkfun BNO08x library.

So my 2 cents:

Yes you can run the Sparkfun library with with the Teensy 4.1 - remember to hook up the INT and RST pins per the comment in there sketches. If you run without them seems not to want to connect. If you run with just the rst pin hooked up I am seeing spikes in the data:
Code:
-2.6,-2.3,4.7
-2.6,-2.3,4.7
-154.4,24.2,93.4
-2.6,-2.3,4.7
-2.6,-2.3,4.7



As for the Teensy sending periodic write requests - I am not seeing that using TD 1.59beta3.
Thanks for your fast response you have been very helpful. I will test like you when I manufacture the PCB but it can take 2 months.
 
Thanks for your fast response you have been very helpful. I will test like you when I manufacture the PCB but it can take 2 months.
Good luck and remember to hook up the RST and INT pins. Seems to work that way, any other way you may run into issues.
 
Quick followup, is there still reason to believe the Wire library may have a bug which I should investigate?

I see we have a solution to use Sparkfun's library and connect RST and INT pins. Is there any reason to believe the problems without those 2 signals, or the problems with Adafruit's library, are ultimately due to a problem with Wire on Teensy?
 
I see we have a solution to use Sparkfun's library and connect RST and INT pins. Is there any reason to believe the problems without those 2 signals, or the problems with Adafruit's library, are ultimately due to a problem with Wire on Teensy?
Personally I don't think its a Wire library issue. I just retested the both libraries by just attaching to the QWIIC connector on a Micromod board and a R4.

TMM: Sparkfun lib doesn't see the sensor for the couple examples I tested.
R4: Ditto to the sparkfun library

TMM, R4, GIGA: Has issues with the Adafruit library and Sparkfun does not work.

Now to be fair I haven't dug into the libraries or the Datasheet. And not 100% sure the adafruit lib is updated for the 086.
I can try on a few other boards I have lying around.
 
Thanks for confirming. I'll keep this thread on my list to watch, but sounds like no need to deep dive right now. If it is looking like Wire might have a problem, hopefully a clear test case can be made before I dive into the Wire library.
 
@PaulStoffregen

Was doing some more poking around with this chip and how its using RST and INT. Definitely don't think its as I2C issue - more of device/libary issue. As a note Sparkfun uses the CEVA library for interfacing with the device.
 
Back
Top