Introduction: GY 89 Gyro Accelerometer Sensor Module for Multiwii Quadcopter
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.
Step 1: 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
Step 2: Setup GY_89 and Find Sensor Addresses
- Solder the pins onto the board if it doesn't come pre-soldered
- Connect 3.3v, GND, SDA, and SCL to respective pins.
- Copy and paste the code
- Upload to Arduino
- 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 }
Step 3: Download the Multiwii Code
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.
Step 4: Change the Code: Tab Config.h
Instead of defining the individual parts by uncommenting them, I wrote in a place for them to be seen as 1 board.
- Go to the config.h tab
- Under //#define GY_88 write in :
#define GY_89
Step 5: Change the Code: Tab Def.h
- Go to the def.h tab
- Scroll down to #if defined(GY_88) around line 1300
- 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
Step 6: Change the Code: Tab Sensors.cpp
- Go to the Sensors.cpp tab
- Scroll down to "I2C Accelerometer LSM303DLx" around line 809
- 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>
Step 7: Change the Code: Tab Sensors.cpp
- Scroll down on Sensors.cpp tab
- Around line 997 find I2C compass HMC5883
- In that section of code you will see a lot of #defines
- 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
Step 8: 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!