Reading data from a BNO055 using the Wire.h library

I am currently trying to read the yaw value of a BNO055 sensor using i2c with the Wire library on the NodeMCU. My problem is that when I run my program on the NodeMCU which should only print out the yaw value via the serial print function, the sensor stops to respond to the requests of data from the NodeMCU after some time (usually 15-30seconds after the start of the program). When I then try to reset the board by pressing the reset button, the BNO055 proceeds to send only zeros even after the restet. Then if i cut the power by disconecting the NodeMCU from the mini-USB cable (which is also used to programm it) and connect it again the whole process of working for a few seconds then stoping.

This is the code I am using NodeMCU_I2C_BNO055 - Pastebin.com

This is the code I am using NodeMCU_I2C_BNO055 - Pastebin.com

Post code to this forum and not some temporary web storage! Don't forget to use code tags!

Post a link to the schematics of your breakout board!

Post a complete wiring diagram!

How long are the wires from the ESP board to the sensor board?

Code:

#include <Wire.h>
 
#define BNO055_ADDR      (0x28)
#define BNO055_CHIP_ID          0x00
#define BNO055_CHIP_ID_VALUE    0xa0
#define BNO055_AXIS_MAP_CONFIG  0x41
#define BNO055_OPR_MODE         0x3d
#define CONFIGMODE              0x00
#define MODE_NDOF               0x0c
#define ACCEL_OFFSET_X_LSB      0x55
#define ACCEL_OFFSET_X_MSB      0x56
#define ACCEL_OFFSET_Y_LSB      0x57
#define ACCEL_OFFSET_Y_MSB      0x58
#define ACCEL_OFFSET_Z_LSB      0x59
#define ACCEL_OFFSET_Z_MSB      0x5a
#define MAG_OFFSET_X_LSB        0x5b
#define MAG_OFFSET_X_MSB        0x5c
#define MAG_OFFSET_Y_LSB        0x5d
#define MAG_OFFSET_Y_MSB        0x5e
#define MAG_OFFSET_Z_LSB        0x5f
#define MAG_OFFSET_Z_MSB        0x60
#define GYRO_OFFSET_X_LSB       0x61
#define GYRO_OFFSET_X_MSB       0x62
#define GYRO_OFFSET_Y_LSB       0x63
#define GYRO_OFFSET_Y_MSB       0x64
#define GYRO_OFFSET_Z_LSB       0x65
#define GYRO_OFFSET_Z_MSB       0x66
#define ACCEL_RADIUS_LSB        0x67
#define ACCEL_RADIUS_MSB        0x68
#define MAG_RADIUS_LSB          0x69
#define MAG_RADIUS_MSB          0x6a
#define BNO055_EULER_H_LSB      0x1a
#define BNO055_EULER_H_MSB      0x1b
#define BNO055_EULER_R_LSB      0x1c
#define BNO055_EULER_R_MSB      0x1d
#define BNO055_EULER_P_LSB      0x1e
#define BNO055_EULER_P_MSB      0x1f
 
void I2C_BNO055_INIT()
{
  char data[7];
  char chip_id;
   
  char accel_offset_x_lsb_value = 8;
  char accel_offset_x_msb_value = 0;
  char accel_offset_y_lsb_value = 34;
  char accel_offset_y_msb_value = 0;
  char accel_offset_z_lsb_value = 7;
  char accel_offset_z_msb_value = 0;
 
  char mag_offset_x_lsb_value = 45;
  char mag_offset_x_msb_value = 255;
  char mag_offset_y_lsb_value = 116;
  char mag_offset_y_msb_value = 0;
  char mag_offset_z_lsb_value = 90;
  char mag_offset_z_msb_value = 1;
 
  char gyro_offset_x_lsb_value = 1;
  char gyro_offset_x_msb_value = 0;
  char gyro_offset_y_lsb_value = 1;
  char gyro_offset_y_msb_value = 0;
  char gyro_offset_z_lsb_value = 0;
  char gyro_offset_z_msb_value = 0;
 
  char accel_radius_lsb_value = 0;
  char accel_radius_msb_value = 3;
  char mag_radius_lsb_value = 66;
  char mag_radius_msb_value = 2;
   
  data[0] = BNO055_CHIP_ID;
 
  Wire.beginTransmission(BNO055_ADDR);
  Wire.write(data, 1);
  Wire.endTransmission(false);
 
  Wire.requestFrom(BNO055_ADDR, 7, true);
  Serial.println(Wire.available());
  data[0] = Wire.read();
  data[1] = Wire.read();
  data[2] = Wire.read();
  data[3] = Wire.read();
  data[4] = Wire.read();
  data[5] = Wire.read();
  data[6] = Wire.read();
 
  chip_id = data[0];
 
  while (chip_id != BNO055_CHIP_ID_VALUE)
  {
    data[0] = BNO055_CHIP_ID;
 
    Wire.beginTransmission(BNO055_ADDR);
    Wire.write(data, 1);
    Wire.endTransmission(false);
 
   
    Wire.requestFrom(BNO055_ADDR, 7, true);
       
    Serial.println(Wire.available());
    data[0] = Wire.read();
    data[1] = Wire.read();
    data[2] = Wire.read();
    data[3] = Wire.read();
    data[4] = Wire.read();
    data[5] = Wire.read();
    data[6] = Wire.read();
 
    chip_id = data[0];
    yield();
  }
 
  data[0] = BNO055_OPR_MODE;
  data[1] = CONFIGMODE;
 
  Wire.beginTransmission(BNO055_ADDR);
  Wire.write(data,2);
  Wire.endTransmission(true);
 
  delay(50);
 
  data[0] = BNO055_AXIS_MAP_CONFIG;
  data[1] = 0x24;
  data[2] = 0x00;
 
  Wire.beginTransmission(BNO055_ADDR);
  Wire.write(data,2);
  Wire.endTransmission(true);
   
  data[0] = ACCEL_OFFSET_X_LSB; data[1] = accel_offset_x_lsb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = ACCEL_OFFSET_X_MSB; data[1] = accel_offset_x_msb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = ACCEL_OFFSET_Y_LSB; data[1] = accel_offset_y_lsb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = ACCEL_OFFSET_Y_LSB; data[1] = accel_offset_y_msb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = ACCEL_OFFSET_Z_LSB; data[1] = accel_offset_z_lsb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = ACCEL_OFFSET_Z_LSB; data[1] = accel_offset_z_msb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
   
  data[0] = MAG_OFFSET_X_LSB; data[1] = mag_offset_x_lsb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = MAG_OFFSET_X_MSB; data[1] = mag_offset_x_msb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = MAG_OFFSET_Y_LSB; data[1] = mag_offset_y_lsb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = MAG_OFFSET_Y_LSB; data[1] = mag_offset_y_msb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = MAG_OFFSET_Z_LSB; data[1] = mag_offset_z_lsb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = MAG_OFFSET_Z_LSB; data[1] = mag_offset_z_msb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
   
  data[0] = GYRO_OFFSET_X_LSB; data[1] = gyro_offset_x_lsb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = GYRO_OFFSET_X_MSB; data[1] = gyro_offset_x_msb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = GYRO_OFFSET_Y_LSB; data[1] = gyro_offset_y_lsb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = GYRO_OFFSET_Y_LSB; data[1] = gyro_offset_y_msb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = GYRO_OFFSET_Z_LSB; data[1] = gyro_offset_z_lsb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = GYRO_OFFSET_Z_LSB; data[1] = gyro_offset_z_msb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
   
  data[0] = ACCEL_RADIUS_LSB; data[1] = accel_radius_lsb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = ACCEL_RADIUS_MSB; data[1] = accel_radius_msb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = MAG_RADIUS_LSB; data[1] = mag_radius_lsb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
  data[0] = MAG_RADIUS_MSB; data[1] = mag_radius_msb_value; Wire.beginTransmission(BNO055_ADDR); Wire.write(data,2); Wire.endTransmission(true); delay(20);
   
  data[0] = BNO055_OPR_MODE;
  data[1] = MODE_NDOF;
 
  Wire.beginTransmission(BNO055_ADDR);
  Wire.write(data,2);
  Wire.endTransmission(true);
 
  delay(10);
}
 
int I2C_BNO055_READ_YAW()
{
  int16_t wert;
  char data[6];
 
  data[0] = BNO055_EULER_H_LSB;
 
  Wire.beginTransmission(BNO055_ADDR);
  Wire.write(data, 1);
  Wire.endTransmission(false);
 
  Wire.requestFrom(BNO055_ADDR, 2, true);
  data[0] = ((Wire.available() > 0) ? Wire.read() : 0);
  data[1] = ((Wire.available() > 0) ? Wire.read() : 0);
  data[2] = ((Wire.available() > 0) ? Wire.read() : 0);
  data[3] = ((Wire.available() > 0) ? Wire.read() : 0);
  data[4] = ((Wire.available() > 0) ? Wire.read() : 0);
  data[5] = ((Wire.available() > 0) ? Wire.read() : 0);
 
  wert = data[1] << 8 | data[0];
  wert = (double)wert/16;
  return wert;
}
 
void setup() {
  Serial.begin(9600); /* begin serial for debug */
  Wire.begin(D1, D2); /* join i2c bus with SDA=D1 and SCL=D2 of NodeMCU */
  I2C_BNO055_INIT();
}
 
void loop() {
  Serial.print("YAW:");
  Serial.println(I2C_BNO055_READ_YAW());
 
  delay(200);
}

Breakout Board:

I was switching between 2 different breakoutbords of the same acceleration sensor.

First one: CJMCV-055


Wiring for CJMCV:
NodeMCU Sensor
3V3 ---------> VCC
GND ---------> GND
D1 ---------> ATX (I2C SDA)
D2 ---------> LRX (I2C SCL)
GND ---------> I2C

Second one: Adafruits BNO055

Wiring for Adafruits BNO055:
NodeMCU Sensor
3V3 ---------> Vin
GND ---------> GND
D1 ---------> SDA
D2 ---------> SCL

Wires used for all connections between the sensor and the NodeMCU are ca. 20cm jumper cables. I am using a Breadboard for the whole thing.

Wiring for Adafruits BNO055:
NodeMCU Sensor
3V3 ---------> Vin
GND ---------> GND
D1 ---------> SDA
D2 ---------> SCL

On the NodeMCU SCL is on D1 and SDA is on D2.

I tried wiring them differently:
that alone didn't work

When I then changed the Wire.begin(D1,D2); in the code to Wire.begin(); I got data back from the chip but the same problem occured.

I have gained a new insight:
I let the same code that I ran on the NodeMCU run on an Arduino Uno and it worked(!).
So the problem must lie by the NodeMCU (potentially its I2C communication?)

I also noticed when looking at the Serial printed values of orientation on the NodeMCU that there sometimes where values that didn't fit at all (something around 4000 something - could this value indicate something? Those values were not there in the communication of the arduino Uno (and with the arduino uno it worked)

[I think, as i composed the final return value of two bytes, that one or both could've been 255, and thus the 4000 would be created - this is just a guess)]

Update:
I put out the delay and now the problem somehow changed: It runs longer, but then the whole thing of not receiving anything (even after a restart) happens. Whats notable though is that those strange, to high numbers only appear at the end, before the communication stops, but then there are several shortly after one another!

Duplicate deleted.

Could you take a few moments to Learn How To Use The Forum.
Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

I let the same code that I ran on the NodeMCU run on an Arduino Uno and it worked(!).

Which of the two boards did you connect to the UNO? Post that wiring diagram!

Did you use the same code? What board was selected during compilation for the NodeMCU?

I am using this programm now (same error however)

#include "bno055.h"
int counter;
void setup() {
  Serial.begin(9600);
  Wire.begin();
  WRITE_I2C_BNO055_INIT();

  counter = 0;
}

void loop() {
  int data;
  data = READ_I2C_BNO055_YAW();
  if(data > 6000){
    counter++;
  }
  Serial.println(data);
  Serial.println(counter);
  Serial.println("-----------");
  yield();
}

With this library

#include <Wire.h>

void WRITE_I2C_BNO055_INIT()
{
  do
  {
    delay(10);
    Wire.beginTransmission(0x28);
    Wire.write(0x00);
    Wire.endTransmission(false);
    Wire.requestFrom(0x28, 1, true);
  } while(Wire.read() != 0xA0);

  Wire.beginTransmission(0x28);
  Wire.write(0x3D);
  Wire.write(0x0C);
  Wire.endTransmission();

}

uint16_t READ_I2C_BNO055_YAW()
{
  uint16_t value = 0;
  Wire.beginTransmission(0x28);
  Wire.write(0x1A);  
  Wire.endTransmission(false);
  Wire.requestFrom(0x28, 2, true);
  value = (int16_t)(Wire.read()|Wire.read()<<8 )/16;  
  return value;  
}

uint16_t READ_I2C_BNO055_ROLL()
{
  uint16_t value = 0;
  Wire.beginTransmission(0x28);
  Wire.write(0x1C);  
  Wire.endTransmission(false);
  Wire.requestFrom(0x28, 2, true);
  value = (int16_t)(Wire.read()|Wire.read()<<8 )/16;  
  return value;  
}

uint16_t READ_I2C_BNO055_PITCH()
{
  uint16_t value = 0;
  Wire.beginTransmission(0x28);
  Wire.write(0x1E);  
  Wire.endTransmission(false);
  Wire.requestFrom(0x28, 2, true);
  value = (int16_t)(Wire.read()|Wire.read()<<8 )/16;  
  return value;  
}

pylon:
Which of the two boards did you connect to the UNO? Post that wiring diagram! Did you use the same code?

I Connected the Sensor to the UNO and let exactly the same (new) program (see above) run.

The connections were:
Arduino UNO Sensor
3V3 ----------> Vin
GND ----------> GND
A4 -----------> SDA
A5 -----------> SCL

With this setup (Arduino UNO to BNO055) I got right returns and it didn't stop.

I also connected the NodeMCU to the Arduino. There the communication also worked. (with this tutorial NodeMCU I2C with Arduino IDE | NodeMCU
The connections were:

NodeMCU(Master) Arduin UNO (Slave)
GND -----------------> GND
A4 ------------------> D1
A5 ------------------> D2

pylon:
What board was selected during compilation for the NodeMCU?

The board selected during compilation was "NodeMCU (ESP-12 Module)"

I think the thing described in

dinkelberg:
I have gained a new insight: ...

yields a strong hint for solving my problem.

Another Update:
When I give the NodeMCU power and open the serial monitor and just let it lie (don't move it around and thus do not chane the value it returns), I first receive 360,which should not be a return value and then if I don't move it around, there is again this known error where I receive nothing.

yet another update:
now the strange values do not appear only at the end (there was no change in the code however)

NodeMCU(Master) Arduin UNO (Slave)
GND -----------------> GND
A4 ------------------> D1
A5 ------------------> D2

Hopefully the other way around. BTW using this wiring you might damage the NodeMCU as the UNO runs on 5V and the ESP8266 is not 5V tolerant!

I Connected the Sensor to the UNO and let exactly the same (new) program (see above) run.

Which sensor? You posted pictures of two boards, which of the two did you connect to the UNO?

The Problem was solved!
The solution was to update the Arduino IDE and the "reinstall the board". Looks like I compiled for an old version of the board...
(It worked when I compiled for "NodeMCU 1.0 (ESP-12 Module)" instead of "NodeMCU (ESP-12 Module)"...

But thank you very much for your help @pylon!