Run GY-955 (BNO055) through I2C connection in Arduino IDE

Hello Everyone.
Gy-955 and BNO055 have the same German IC but different modules. When we connect GND, S1 and SR pins together for Gy-955 module, we can communicate with BNO055 directly, through I2C connection. Here I will represent my Code to run Gy-955 (BNO055) by Arduino IDE, 3 times FASTER than BNO055.h library (because of better I2C Message structure):

// Connect GND, S1 and SR pins together.

#include <Wire.h>
float Yaw,Roll,Pitch,magx,magy,magz,accx, accy,accz, gyrox,gyroy,gyroz,q0,q1,q2,q3,Roll2,Pitch2,Yaw2,LIAx,LIAy,LIAz,GRVx,GRVy,GRVz;
const int GY_955=0x29;
void setup() 
{
Wire.begin();
Wire.setClock(400000); // I2C clock rate ,You can delete it but it helps the speed of I2C (default rate is 100000 Hz)
delay(100);
Wire.beginTransmission(GY_955);
Wire.write(0x3E); // Power Mode 
Wire.write(0x00); // Normal:0X00 (or B00), Low Power: 0X01 (or B01) , Suspend Mode: 0X02 (orB10)
Wire.endTransmission();
delay(100);
Wire.beginTransmission(GY_955);
Wire.write(0x3D); // Operation Mode
Wire.write(0x0C); //NDOF:0X0C (or B1100) , IMU:0x08 (or B1000) , NDOF_FMC_OFF: 0x0B (or B1011)
Wire.endTransmission();
delay(100);
Serial.begin(115200);  //Setting the baudrate
delay(100);
}
void loop()
{
Wire.beginTransmission(GY_955);
Wire.write(0x08);  
Wire.endTransmission(false);
Wire.requestFrom(GY_955,32,true);
// Accelerometer
accx=(int16_t)(Wire.read()|Wire.read()<<8 )/100.00; // m/s^2
accy=(int16_t)(Wire.read()|Wire.read()<<8 )/100.00; // m/s^2
accz=(int16_t)(Wire.read()|Wire.read()<<8 )/100.00; // m/s^2
// Magnetometer
magx=(int16_t)(Wire.read()|Wire.read()<<8 )/16.00; // mT
magy=(int16_t)(Wire.read()|Wire.read()<<8 )/16.00; // mT
magz=(int16_t)(Wire.read()|Wire.read()<<8 )/16.00; // mT
// Gyroscope
gyrox=(int16_t)(Wire.read()|Wire.read()<<8 )/16.00; // Dps
gyroy=(int16_t)(Wire.read()|Wire.read()<<8 )/16.00; // Dps
gyroz=(int16_t)(Wire.read()|Wire.read()<<8 )/16.00; // Dps
// Euler Angles
Yaw=(int16_t)(Wire.read()|Wire.read()<<8 )/16.00;  //in Degrees unit
Roll=(int16_t)(Wire.read()|Wire.read()<<8 )/16.00;  //in Degrees unit
Pitch=(int16_t)(Wire.read()|Wire.read()<<8 )/16.00;  //in Degrees unit
// Quaternions
q0=(int16_t)(Wire.read()|Wire.read()<<8 )/(pow(2,14)); //unit less
q1=(int16_t)(Wire.read()|Wire.read()<<8 )/(pow(2,14)); //unit less
q2=(int16_t)(Wire.read()|Wire.read()<<8 )/(pow(2,14)); //unit less
q3=(int16_t)(Wire.read()|Wire.read()<<8 )/(pow(2,14)); //unit less
//Convert Quaternions to Euler Angles
Yaw2=(atan2(2*(q0*q3+q1*q2),1-2*(pow(q2,2)+pow(q3,2))))*180/PI;
Roll2=(asin(2*(q0*q2-q3*q1)))*180/PI;
Pitch2=(atan2(2*(q0*q1+q2*q3),1-2*(pow(q1,2)+pow(q2,2))))*180/PI;
//Linear (Dynamic) & Gravitational (static) Acceleration
Wire.beginTransmission(0x29);
Wire.write(0x28);  
Wire.endTransmission(false);
Wire.requestFrom(0x29,12,true);
LIAx=(int16_t)(Wire.read()|Wire.read()<<8)/100.00; // m/s^2
LIAy=(int16_t)(Wire.read()|Wire.read()<<8)/100.00; // m/s^2
LIAz=(int16_t)(Wire.read()|Wire.read()<<8)/100.00; // m/s^2
GRVx=(int16_t)(Wire.read()|Wire.read()<<8)/100.00; // m/s^2
GRVy=(int16_t)(Wire.read()|Wire.read()<<8)/100.00; // m/s^2
GRVz=(int16_t)(Wire.read()|Wire.read()<<8)/100.00; // m/s^2
// Print data
Serial.print("Yaw=");
Serial.print(Yaw);
Serial.print(" Roll=");
Serial.print(Roll);
Serial.print(" Pitch=");
Serial.println(Pitch);
}

NOTE: Powerup this sensor, toward the north to prevent Yaw error or drift (As I showed in the attached picture).
NOTE: Yaw, Roll and Pitch are more reliable than Yaw2, Roll2 and Pitch2.
Enjoy it!!! It is very stable and exact (0.01 degree exactness) and it can differ Linear (Dynamic) Acceleration & Gravitational (static) Acceleration.

Also you can run Gy-955 by Bosch library (BNO055.h) as below but it is at least 3 times slower.

1. Connect GND, S1 and SR pins together.

2. Open IDE>> sketch >> including library >> manage library, in the Library Manager window, in the search blank type BNO055, after that click install for "BNO055 by ROBERT BOSCH GMBH" library.

3. Install Notepad++ on your pc.

4. File explorer>> Documents >> Arduino >> libraries>> BNO055 >> BNO055.h (open it with Notepad++), go to line 84, and change "#define BNO055_I2C_ADDR      BNO055_I2C_ADDR1" to "#define BNO055_I2C_ADDR    BNO055_I2C_ADDR2" and save it.

5. Open IDE>> File >> Examples >> INCOMPATIBLE >> BNO055>> Euler_Streaming (will report roll, pitch and yaw degrees)

Also you can Run GY-955 through Serial connection:

I used GY-955 through Serial connection for my system, but the final result of GY-955 with I2C connection was very better in comparison to GY-955 Serial connection.

Also I used GY-25 for my system, but the final result of GY-955 through I2C connection was very better in comparison to GY-25. Here is the code to get Euler angles from GY-25 through Serial connection: Run GY 25 in Arduino IDE (with Kalman filter) - Sensors - Arduino Forum

And here is my code to run CMPS12:

Also I get data from MPU 6050 or GY 521 or MPU 9250 with correct measurement units here:

If you have any question, you can ask me in comments or by a pm.

1 Like
  1. Enjoy it!!! it is very stable and exact (0.01 degree exactness).

Extremely unlikely. Many people have given up on the BNO055, because the firmware performs so poorly. The calibration routines are very primitive, and hardly work at all. At best yaw angles are repeatable to about +/- 5 degrees.

See this page and this long discussion. The BNO080 is reported to work a bit better, but still has a long way to go.

I recommend RTImulib with Pololu's Altimu10 or Altimu9 instead.

I used this sensor with this code. It reports roll, pitch and yaw exactly good and without noise. Also it works very good on my system.

Please prove the “exactness”, after reading the articles I linked.

Many other people would be interested if you can demonstrate accurate results. But I will bet that you can’t.

Yes, I can show it. Do I send a clip about its exactness?

No clips, just post the results, and all the important details about how you calibrated the sensor and determined the accuracy of the angles.

For your report, you could follow this outline, for example.

Yes, I will do that. But with respect I mention that BNO055 Adafruit libraries and GY_955 Libraries, and calibration are different. So maybe the library codes of GY-955 caused more accuracy. Also maybe module of GY_955 caused more stability by filtering current noises and instabilities.

Thank you my friend. You are the only one on the internet who shares this information clearly.

You're welcom. I have used this module and Arduino Mega for my system. It is a great module for degress in range -90 to 90.

Hi Payman,
I'm using the BNO080 in my artificial horizon project. Used the accelerator readout. The hard & software are working ok, as long the unit is on my hobby table. But in real flight the roll and pitch are not given any readout any at all.
How did you solve this ?
Regards, Marc

Vliegvogeltla:
Hi Payman,
I'm using the BNO080 in my artificial horizon project. Used the accelerator readout. The hard & software are working ok, as long the unit is on my hobby table. But in real flight the roll and pitch are not given any readout any at all.
How did you solve this ?
Regards, Marc

Hi my friend.
I attached gy-955 VCC to 3.3 Volt pin of Arduino Mega 2560. I also have used Electrolyte capacitors parallel to power source of Arduino to remove noises. if you still have problem you can pm me to get more help.

Hi Peyman, in your opinion, are the SR and SI pins on the GY-955 boards actually PS0 and PS1, as detailed in the Bosch Sensortec BNO055 Data Sheet? That says to set the protocol select pins PS0 and PS1 LOW to enable I2C (see page 90 for details).

Hi Justin. It is a good idea but I think the best way to find it is to track S1 & SR pins on Gy 955 PCB. If you find any information please let me know. Thanks

Hi Peyman,

I am a complete beginner with GY-955 (I only used GY-953 till now).

You tell you had very better results using I2C connexion than serial, could you explain better in what? (speed, accuracy, ...?)

Thanks,

Pierre

Hi Pierre, thanks for your question.
Gy 955 in Serial connection mode, filters raw data of Bno055 with only a simple Kalman filter so its outputs (Euler Angles) will show wrong values after few minutes (drift error). And also I tested it on my system and this mode will show wrong values after motors power up (because of vibration noises of motors). But in I2C mode, Bno055 will filters raw data of Bno055 itself with better and more complex filters so outputs (Euler Angles) will show correct values even after hours (no drift error) and also I tested it on my system and this mode will show correct values after motors power up ( it is also robust against vibration noises).

Thanks for your quick and clear answer, I'll have to use I2C mode then.
By the way, I did not find a GY955 user manual (only for BNO055). If I unterstood well, using I2C and connecting S1 and SR to ground lets me work directly with the BNO055 which is inside, so I don't need the GY955 doc.
My application is an home made large (80cm) autonomous mower, so I would like to try going straight in one direction for a while, then rotate exactly 180° and go back in the opposite direction during the same time, and again... I would like to keep less than 40cm lateral drift for a 10m path. With your knowledge, do you believe it can be achieved, or do I have to move to RTK (with a raspberry pi and 2 GPS, a big change for me)?
I also want to stop the cutting blades rotation quickly if it is not horizontal anymore, but this seems very easy.
Could you advice me some settings and calibrations to navigate as precisely as possible (of course I will also have to build a good tracking control loop)? I have 3 big electric motors onboard (1kg each) and they can not be far from my electronics (15cm max)...
Thanks

Pierre

Hello Peyman, I would like to ask if the "Gy-955 module" I2c lines are 5V logic. Since the arduino I2C lines are 5v logic but the bno055 chip I2C lines are 3.3V logic. Does the Gy955 module contain Logic Level Shifter to make it arduino conpatible. Thank in advance.

Thanks, Peyman you did a great job, my question is how can I connect my MEGA 2560 to the gy-955?

T_Go:
Hello Peyman, I would like to ask if the "Gy-955 module" I2c lines are 5V logic. Since the arduino I2C lines are 5v logic but the bno055 chip I2C lines are 3.3V logic. Does the Gy955 module contain Logic Level Shifter to make it arduino conpatible. Thank in advance.

Hi, lots of logic shift modules with little sizes are available in the markets that can shift 5v to 3.3 and vice versa. You can use them easily.

raminpapoo:
Thanks, Peyman you did a great job, my question is how can I connect my MEGA 2560 to the gy-955?

Hi, Thanks. Connect S1, SR and Gnd pins together. Also connect VCC pin to 3.3v or 5v and GND pin to GND of Mega 2560. Then SDA pin to SDA of Mega and SCL pin to SCL of Mega and run the code!