GY 89 Gyro Accelerometer Sensor Module for Multiwii Quadcopter

by Sramir27 in Circuits > Sensors

13822 Views, 12 Favorites, 0 Comments

GY 89 Gyro Accelerometer Sensor Module for Multiwii Quadcopter

d3f7c521436e9ad9ef181635817eb8b7.image.225x149.jpg

This is my first Instructable, so please bear with me. So like most people interested in quadcopters i wanted to make one cheaply. Well after a little bit of time and import from across the world i was able to do that. I used the Multiwii 2.4 program running on an Arduino Uno. The thing I had the hardest time with was the IMU. I bought the GY-521 (MPU6050) ACC/GYRO first and realized for my particular project i needed a better IMU. I went onto eBay and looked up a 10DOF IMU and found the cheapest one for the GY-89. This board has LSM303D,L3GD20 and BMP180. The problem is I wasn't aware the Multiwii platform didn't have code written for this. I looked everywhere, and couldn't figure it out. I attempted writing code for it(based on my extremely limited knowledge) and failed miserably. I finally came across this.

http://www.multiwii.com/forum/viewtopic.php?f=6&t=...

Thanks to Dryteo I was able to get a start. I eventually just changed a couple of more things and poof, like magic it worked well for me. I haven't tested this over and over, but it so far is working for me. I hope this is easy to follow.

Where I Got the GY-89 IMU

I got the IMU on eBay. It was the cheapest 10DOF IMU I could find at the moment.

http://www.ebay.com/itm/GY-89-10DOF-L3GD20-LSM303D-BMP180-Gyro-Accelerometer-Sensor-Module-For-Arduino-/272265791345?hash=item3f644e4771:g:UAYAAOSwbYZXVYvs

Setup GY_89 and Find Sensor Addresses

  1. Solder the pins onto the board if it doesn't come pre-soldered
  2. Connect 3.3v, GND, SDA, and SCL to respective pins.
  3. Copy and paste the code
  4. Upload to Arduino
  5. Open Serial Monitor and write down addresses.
    • Mine were LSM - 0x1D, L3G - 0x6B, BMP - 0x77
    • These should be confirmed in the code written under the address portion of each code.
    • If yours are different simply look at the snippets of code changed. Look for my address and change them to yours accordingly.

I2C scanner code found online somewhere

// --------------------------------------
// i2c_scanner // // Version 1 // This program (or code that looks like it) // can be found in many places. // For example on the Arduino.cc forum. // The original author is not know. // Version 2, Juni 2012, Using Arduino 1.0.1 // Adapted to be as simple as possible by Arduino.cc user Krodal // Version 3, Feb 26 2013 // V3 by louarnold // Version 4, March 3, 2013, Using Arduino 1.0.3 // by Arduino.cc user Krodal. // Changes by louarnold removed. // Scanning addresses changed from 0...127 to 1...119, // according to the i2c scanner by Nick Gammon // http://www.gammon.com.au/forum/?id=10896 // Version 5, March 28, 2013 // As version 4, but address scans now to 127. // A sensor seems to use address 120. // Version 6, November 27, 2015. // Added waiting for the Leonardo serial communication. // // // This sketch tests the standard 7-bit addresses // Devices with higher bit address might not be seen properly. // #include void setup() { Wire.begin(); Serial.begin(9600); while (!Serial); // Leonardo: wait for serial monitor Serial.println("\nI2C Scanner"); } void loop() { byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for(address = 1; address < 127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address<16) Serial.print("0"); Serial.print(address,HEX); Serial.println(" !"); nDevices++; } else if (error==4) { Serial.print("Unknow error at address 0x"); if (address<16) Serial.print("0"); Serial.println(address,HEX); } } if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("done\n"); delay(5000); // wait 5 seconds for next scan }

Download the Multiwii Code

Screen Shot 2016-11-22 at 12.47.18 AM.png

After downloading the Multiwii code from https://code.google.com/archive/p/multiwii/

Open it in the Arduino I.D.E.

The resource I found from Dryteo said to define the individual parts of the GY_89 board in the "independent sensors" section inside of the config.h tab. The sensors to define are L3G4200D, LSM303DLx_ACC, BMP085, and HMC5883.

The gyroscope: L3G4200D code covers the L3GD20

The accelerometer: LSM303DLx_ACC code covers the LSM303D

The barometer: BMP085 code covers the BMP180

The magnetometer: HMC5883 code covers the magnetometer part of the LSM sensor

I found this to run the code for the IMU a little slowly which could have been the issue with it. so i didn't do this part. I instead wrote in my own directory.

Change the Code: Tab Config.h

Screen Shot 2016-11-22 at 1.00.07 AM.png

Instead of defining the individual parts by uncommenting them, I wrote in a place for them to be seen as 1 board.

  1. Go to the config.h tab
  2. Under //#define GY_88 write in :
    • #define GY_89

Change the Code: Tab Def.h

Screen Shot 2016-11-22 at 1.21.07 AM.png
  1. Go to the def.h tab
  2. Scroll down to #if defined(GY_88) around line 1300
  3. After the #endif portion of that piece of code write in this:
#if defined(GY_89)
  #define L3G4200D
  #define HMC5883
  #define LSM303DLx_ACC
  #define BMP085
  #define ACC_ORIENTATION(X, Y, Z) {imu.accADC[ROLL] = -X; imu.accADC[PITCH] = -Y; imu.accADC[YAW] = Z;}
  #define GYRO_ORIENTATION(X, Y, Z) {imu.gyroADC[ROLL] = Y; imu.gyroADC[PITCH] = -X; imu.gyroADC[YAW] = -Z;}
  #define MAG_ORIENTATION(X, Y, Z) {imu.magADC[ROLL] = X; imu.magADC[PITCH] = Y; imu.magADC[YAW] = -Z;}
  #undef INTERNAL_I2C_PULLUPS
#endif

Change the Code: Tab Sensors.cpp

Screen Shot 2016-11-22 at 1.32.15 AM.png
  1. Go to the Sensors.cpp tab
  2. Scroll down to "I2C Accelerometer LSM303DLx" around line 809
  3. Highlight that code that starts with the comment lines for I2C accelerometer LSM303DLx and ends with the #endif of the I2C Gyroscope L3G4200D code (around lines 809-874)and paste in this:
<p>// ************************************************************************************************************<br>// I2C Accelerometer LSM303DLx
// ************************************************************************************************************
#if defined(LSM303DLx_ACC)
#define LSM303DLx_ADDR  0x1D //LSM303DLHC Address From Adafruit 10 DOF IMU
void ACC_init () {
  delay(10);
 i2c_writeReg(LSM303DLx_ADDR,0x20,0x27);
  i2c_writeReg(LSM303DLx_ADDR,0x23,0x30);
  i2c_writeReg(LSM303DLx_ADDR,0x21,0x00);
}</p><p> void ACC_getADC () {
  i2c_getSixRawADC(LSM303DLx_ADDR,0xA8); //0x28+0x80 = 0xA8</p><p>  ACC_ORIENTATION( ((rawADC[1]<<8) | rawADC[0])>>4 ,
                   ((rawADC[3]<<8) | rawADC[2])>>4 ,
                   ((rawADC[5]<<8) | rawADC[4])>>4 );
  ACC_Common();
}
#endif</p><p>// ************************************************************************************************************
// ADC ACC
// ************************************************************************************************************
#if defined(ADCACC)
void ACC_init(){
  pinMode(A1,INPUT);
  pinMode(A2,INPUT);
  pinMode(A3,INPUT);
}</p><p>void ACC_getADC() {
  ACC_ORIENTATION(  analogRead(A1) ,
                    analogRead(A2) ,
                    analogRead(A3) );
  ACC_Common();
}
#endif</p><p>// ************************************************************************************************************
// I2C Gyroscope L3G4200D 
// ************************************************************************************************************
#if defined(L3G4200D)
//#define L3G4200D_ADDRESS 0x69
 #define L3G4200D_ADDRESS 0x6B //L3GD20H Address From Adafruit 10 DOF IMU
void Gyro_init() {
  delay(100);
  i2c_writeReg(L3G4200D_ADDRESS ,0x20 ,0x8F ); // CTRL_REG1   400Hz ODR, 20hz filter, run!
  delay(5);
  i2c_writeReg(L3G4200D_ADDRESS ,0x24 ,0x02 ); // CTRL_REG5   low pass filter enable
  delay(5);
  i2c_writeReg(L3G4200D_ADDRESS ,0x23 ,0x30); // CTRL_REG4 Select 2000dps
}</p><p>void Gyro_getADC () {
  i2c_getSixRawADC(L3G4200D_ADDRESS,0x80|0x28);</p><p>  GYRO_ORIENTATION( ((rawADC[1]<<8) | rawADC[0])>>2  ,
                    ((rawADC[3]<<8) | rawADC[2])>>2  ,
                    ((rawADC[5]<<8) | rawADC[4])>>2  );
  GYRO_Common();
}
#endif</p>

Change the Code: Tab Sensors.cpp

Screen Shot 2016-11-22 at 1.36.39 AM.png
  1. Scroll down on Sensors.cpp tab
  2. Around line 997 find I2C compass HMC5883
  3. In that section of code you will see a lot of #defines
  4. Find #define MAG_ADDRESS 0x1E (or whatever it is) and change this to the address of the LSM sensor you found via the I2C scanner (Step 2).
    • For me this address was 0x1D
#define MAG_ADDRESS 0x1D

DONE!

That's it! Upload the code to the board. Open up the Multiwii Conf program that came with the code download. Connect to board. Click Start. Run calibrations on flat surface. Wait a few seconds and test it out! Good Luck, Have fun!