1. L3G4200D ¼¾¼ ¼Ò°³
L3G4200D˼
MEMS(Micro Electro Mechanical Systems) ±â¹ÝÀÇ 3Ãà ÀÚÀÌ·Î ¼¾¼ÀÌ´Ù. L3G4200D´Â I2C
(Inter Integrated Circuit)¿Í SPI Åë½Å ÇÁ·ÎÅäÄÝÀ» ÅëÇؼ
µ¥ÀÌÅ͸¦ ÃßÃâ
ÇÒ ¼ö ÀÖ´Ù. º» Á¦Ç°Àº I2C Åë½Å ÀÎÅÍÆäÀ̽º¸¦ »ç¿ëÇϵµ·Ï Á¦ÀÛÀÌ µÇ¾ú´Ù. ´ë¿ªÆø°ú ¼Óµµ Á¶ÀýÀ» »ç¿ëÀÚ°¡ ÇÁ·Î±×·¥ ÇÒ ¼ö
ÀÖ°í, °ÔÀÓ¹× °¡»ó Çö½Ç ÀÔ·ÂÀåÄ¡, GPS, ³×ºñÄÉÀ̼Ç, ·Îº¿
½Ã½ºÅ۵ À¯¿ëÇÏ´Ù.
stic
Value
Unit
Supply
Voltage
2.4 ~ 3.6
V
Supply
Current
6.1
mA
Measuring
range
250,
500, 2000
dps(deg/s)
Sensitivity
FS=250 dps
8.75
mdps/digit
FS=500 dps
17.50
FS=2000 dps
70
Measuring
Axis
Roll,
Pitch, Yaw
Linearity
0.2
%FS
Noise
BW = 50Hz
dps/sqrt(HZ)
Digital
Output data rate
100,
200, 400, 800
Hz
Temperature
change
-1
C/digit
Operating
Temperature
-40 ~ 85
¡ÆC
2.1
¼¾¼ ȸ·Îµµ¹× ¿Ü°û Ä¡¼ö
(1) L3G4200D ¼¾¼ ȸ·Îµµ
- L3G4200D
PDF ȸ·Îµµ ´Ù¿î·Îµå
- L3G4200D
µ¥ÀÌÅͽÃÆ® ´Ù¿î·Îµå(http://www.jkelec.co.kr)
- L3G4200D
DXF ijµå ÆÄÀÏ ´Ù¿î·Îµå
(2) L3G4200D ¼¾¼ ¿Ü°û(mm´ÜÀ§) Ä¡¼ö
2.2
¾ÆµÎÀ̳ë UNO R3 ¹è¼±µµ
(1) ¾ÆµÎÀ̳ë UNO R3¿Í ¿¬°áÇؼ °¡¼Óµµ, ÀÚÀÌ·Î ¼¾ÅÍ µ¥ÀÌÅÍ Ãâ·Â Çϱâ
À̹ø ¿¹Á¦¿¡¼´Â ÀÎÅÍ·´Æ®¸¦ »ç¿ëÇÏÁö ¾Ê±â ¶§¹®¿¡ INTÇÉÀ» ¿¬°áÇÒ
ÇÊ¿ä´Â ¾ø´Ù.
-
Fritzing ÆÄÀÏ ´Ù¿î·Îµå
2.3
¾ÆµÎÀÌ³ë ½ºÄÉÄ¡ ÄÚµå
´Ü¼øÈ÷ ¼¾¼ÀÇ µ¥ÀÌÅ͸¦ ½Ã¸®¾ó µ¥ÀÌÅÍ·Î Ãâ·ÂÇÏ´Â ¿¹Á¦ ÀÌ´Ù.
(1) ¾ÆµÎÀÌ³ë ½ºÄÉÄ¡ ÄÚµå
-
L3G4200D raw µ¥ÀÌÅÍ Ç¥½Ã ½ºÄ³Ä¡ ÆÄÀÏ ´Ù¿î·Îµå
// I2C device class (I2Cdev) demonstration Arduino sketch for L3G4200D class // 7/31/2013 by Jonathan Arnett <j3rn@j3rn.com> // Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib // // Changelog: // 2011-07-31 - initial release /* ============================================ I2Cdev device library code is placed under the MIT license Copyright (c) 2011 Jonathan Arnett, Jeff Rowberg Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =============================================== */ // Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation // is used in I2Cdev.h #include <Wire.h> // I2Cdev and L3G4200D must be installed as libraries, or else the .cpp/.h files // for both classes must be in the include path of your project #include "I2Cdev.h" #include "L3G4200D.h" // default address is 105 // specific I2C address may be passed here L3G4200D gyro;int16_t avx, avy, avz;#define LED_PIN 13 // (Arduino is 13, Teensy is 6) bool blinkState = false ;void setup () {// join I2C bus (I2Cdev library doesn't do this automatically) Wire.begin();// initialize serial communication // (38400 chosen because it works as well at 8MHz as it does at 16MHz, but // it's really up to you depending on your project) Serial.begin(9600 );// initialize device Serial.println("Initializing I2C devices..." ); gyro.initialize();// verify connection Serial.println("Testing device connections..." ); Serial.println(gyro.testConnection() ? "L3G4200D connection successful" : "L3G4200D connection failed" );// configure LED for output pinMode(LED_PIN, OUTPUT);// data seems to be best when full scale is 2000 gyro.setFullScale(2000 ); }void loop () {// read raw angular velocity measurements from device gyro.getAngularVelocity(& avx, & avy, & avz); Serial.print("angular velocity: \t " ); Serial.print(avx); Serial.print(" \t " ); Serial.print(avy); Serial.print(" \t " ); Serial.println(avz);// blink LED to indicate activity blinkState = ! blinkState; digitalWrite(LED_PIN, blinkState); delay(1000 ); }
L3G4200DÀÇ I2C Slave Address´Â ±âº»ÀûÀ¸·Î 0x69ÀÌ´Ù.
#define L3G4200D_ADDRESS 0x69
(2) ½ÇÇà °á°ú
L3G4200DÀÇ I2C Åë½Å »óŸ¦ °Ë»çÇÏ°í ÀÚÀÌ·Î ¼¾¼ÀÇ X, Y, Z ÃàÀÇ °ªÀ» ¹Ýº¹Çؼ º¸¿©ÁØ´Ù.
º» ¸Þ´º¾óÀÇ ¾ÆµÎÀ̳ë ÄÚµå´Â ¾Æ·¡ https://github.com/jrowberg/i2cdevlib
ÀÇ ³»¿ëÀ» ÂüÁ¶ÇÏ¿© ÀÛ¼º ÇÏ¿´´Ù.
3.
ÇÁ·Î¼¼½ÌÀ» ÀÌ¿ëÇؼ 3Â÷¿ø ±×·¡ÇÈ Ç¥½Ã
3.1 ÇÁ·Î¼¼½Ì ¼³Ä¡ Çϱâ
¾ÆµÎÀ̳븦 ÀÌ¿ëÇؼ ¼¾¼¿¡¼ µ¥ÀÌÅ͸¦ ÃßÃâÇؼ ½Ã¸®¾ó µ¥ÀÌÅÍ·Î Ãâ·ÂÀ» Çؼ µ¥ÀÌÅÍ °ªÀ» È®ÀÎÀ» ½±°Ô ÇÒ ¼ö ÀÖ¾ú´Ù. ±×·¸´Ù¸é
ÅؽºÆ® µ¥ÀÌÅÍ°¡ ¾Æ´Ï¶ó Á¶±Ý´õ ½Ã°¢ÀûÀΠǥÇö ¹æ¹ýÀÌ ¾øÀ»±î? ±×°Íµµ ¾ÆÁÖ ½±°Ô..
ÇÁ·Î¼¼½ÌÀ» ÀÌ¿ëÇÏ¸é ¾ÆµÎÀÌ³ë ½ºÄÉÄ¡ Äڵ带 ÀÔ·ÂÇϵíÀÌ ¾ÆÁÖ ½±°Ô ½Ã°¢ÀûÀΠǥÇöÀÌ °¡´ÉÇÏ´Ù. ¿ì¼± ÇÁ·Î¼¼½Ì °³¹ß ȯ°æÀ»
¼³Ä¡Çϴ°ͺÎÅÍ Çغ¸ÀÚ.
(1) ÇÁ·Î¼¼½Ì ¼³Ä¡
-
ÇÁ·Î¼¼½Ì °³¹ßȯ°æ ¼³Ä¡ Çϱâ(»õâ)
ÇÁ·Î¼¼½ÌÄÚµå´Â L3G4200D ¸ðµâ¿¡¼ Ãâ·ÂÇÏ´Â µ¥ÀÌÅ͸¦ ½Ã¸®¾ó(RS232) Åë½ÅÀ»
ÅëÇؼ ÀÔ·ÂÀ» ¹Þ¾Æ µ¥ÀÌÅ͸¦ ó¸® Çϵµ·Ï µÇ¾î ÀÖ´Ù. ÀÌÁ¦ ¾ÆµÎÀ̳ë¿Í L3G4200D ¸ðµâÀ» ÀÌ¿ëÇؼ ÇÁ·Î¼¼½Ì¿¡¼ ó¸® Çϱâ
À§ÇÑ
µ¥ÀÌÅÍ Ãâ·ÂÀ» Çغ¸ÀÚ.
3.2
¾ÆµÎÀ̳ë UNO R3 ¹è¼±µµ
ÀÌÀü ¿¹Á¦ ¿¡¼´Â MPU6050ÀÇ INT ÇÉÀ» »ç¿ëÇÏÁö ¾Ê¾Ò´Âµ¥ À̹ø ¿¹Á¦¿¡¼´Â ¾ÆµÎÀ̳뿡¼
ÀÎÅÍ·´Æ®¸¦ »ç¿ëÇÏ°í Àֱ⠶§¹®¿¡ INTÇÉÀ» ¾ÆµÎÀ̳ëÀÇ D2ÇÉ¿¡ ¿¬°áÀ» ÇØÁÖ¾ú´Ù. ³ª¸ÓÁö ¹è¼±µµ´Â ÀÌÀü ¿¹Á¦¿Í µ¿ÀÏÇÏ´Ù.
3.3
¾ÆµÎÀÌ³ë ½ºÄÉÄ¡ ÄÚµå
(1) ¾ÆµÎÀ̳ë ÇÁ·Î¼¼½Ì ÄÚµå
ÇÁ·Î¼¼½Ì Äڵ忡¼ ÇÑ°¡Áö ÁÖÀÇ ÇؾßÇÒ »çÇ×Àº ½Ã¸®Åë Åë½ÅÀÇ ¼Óµµ¸¦ 9600bps ·Î ¼³Á¤À»
ÇÏ¿´´Ù. ±×·¸±â ¶§¹®¿¡ ¾ÆµÎÀ̳ëÀÇ ½Ã¸®¾ó ¸ð´ÏÅÍâ¿¡¼µµ µ¿ÀÏÇÑ Åë½Å¼Óµµ¸¦ ¸ÂÃß¾î ÁÖ¾î¾ß ÇÑ´Ù.
- L3G4200D
¾ÆµÎÀ̳ë, ÇÁ·Î¼¼½Ì ½ºÄ³Ä¡ ÆÄÀÏ ´Ù¿î·Îµå
#include <Wire.h> #define CTRL_REG1 0x20 #define CTRL_REG2 0x21 #define CTRL_REG3 0x22 #define CTRL_REG4 0x23 #define CTRL_REG5 0x24 // I2C address of the L3G4200D. // Use I2C scanner to find this value! int L3G4200D_Address = 0x69 ;// Can fine-tune this if you need to float DPS_MULT = 0.0000085 ;// Delta angles (raw input from gyro) int x = 0 ;int y = 0 ;int z = 0 ;// Actual angles float angX = 0 ;float angY = 0 ;float angZ = 0 ;// Previous angles for calculation float p_angX = 0 ;float p_angY = 0 ;float p_angZ = 0 ;// Calibration values int gyroLowX = 0 ;int gyroLowY = 0 ;int gyroLowZ = 0 ;int gyroHighX = 0 ;int gyroHighY = 0 ;int gyroHighZ = 0 ;// Used for calculating delta time unsigned long pastMicros = 0 ;void setup () { Wire.begin(); Serial.begin(9600 ); Serial.println("Starting up L3G4200D" ); setupL3G4200D(250 ); // Configure L3G4200 - 250, 500 or 2000 deg/sec delay(1000 ); // wait for the sensor to be ready calibrate(); attachInterrupt(0 , updateAngle, RISING); pastMicros = micros(); }void loop () { getGyroValues();// Calculate delta time float dt;if (micros() > pastMicros) //micros() overflows every ~70 minutes dt = (float ) (micros()- pastMicros)/ 1000000.0 ;else dt = (float ) ((4294967295 - pastMicros)+ micros())/ 1000000.0 ;// Calculate angles if (x >= gyroHighX || x <= gyroLowX) { angX += ((p_angX + (x * DPS_MULT))/ 2 ) * dt; p_angX = x * DPS_MULT; } else { p_angX = 0 ; }if (y >= gyroHighY || y <= gyroLowY) { angY += ((p_angY + (y * DPS_MULT))/ 2 ) * dt; p_angY = y * DPS_MULT; } else { p_angY = 0 ; }if (z >= gyroHighZ || z <= gyroLowZ) { angZ += ((p_angZ + (z * DPS_MULT))/ 2 ) * dt; p_angZ = z * DPS_MULT; } else { p_angZ = 0 ; } pastMicros = micros(); sendJson(); delay(10 ); }void updateAngle () { getGyroValues(); }void calibrate () { Serial.println("Calibrating gyro, don't move!" );for (int i = 0 ; i < 200 ; i++ ) { getGyroValues();if (x > gyroHighX) gyroHighX = x;else if (x < gyroLowX) gyroLowX = x;if (y > gyroHighY) gyroHighY = y;else if (y < gyroLowY) gyroLowY = y;if (z > gyroHighZ) gyroHighZ = z;else if (z < gyroLowZ) gyroLowZ = z; delay(10 ); } Serial.println("Calibration complete." ); }// Print angles to Serial (for use in Processing, for example) void sendJson () {char json[40 ]; sprintf(json, "{ \" x \" :%d, \" y \" :%d, \" z \" :%d}" , (int )(angX* 1000 ), (int )(angY* 1000 ), (int )(angZ* 1000 )); Serial.println(json); }void getGyroValues () { byte xMSB = readRegister(L3G4200D_Address, 0x29 ); byte xLSB = readRegister(L3G4200D_Address, 0x28 ); x = ((xMSB << 8 ) | xLSB); byte yMSB = readRegister(L3G4200D_Address, 0x2B ); byte yLSB = readRegister(L3G4200D_Address, 0x2A ); y = ((yMSB << 8 ) | yLSB); byte zMSB = readRegister(L3G4200D_Address, 0x2D ); byte zLSB = readRegister(L3G4200D_Address, 0x2C ); z = ((zMSB << 8 ) | zLSB); }int setupL3G4200D (int scale) {//From Jim Lindblom of Sparkfun's code // Enable x, y, z and turn off power down: writeRegister(L3G4200D_Address, CTRL_REG1, 0 b00001111);// If you'd like to adjust/use the HPF, you can edit the line below to configure CTRL_REG2: writeRegister(L3G4200D_Address, CTRL_REG2, 0 b00000000);// Configure CTRL_REG3 to generate data ready interrupt on INT2 // No interrupts used on INT1, if you'd like to configure INT1 // or INT2 otherwise, consult the datasheet: writeRegister(L3G4200D_Address, CTRL_REG3, 0 b00001000);// CTRL_REG4 controls the full-scale range, among other things: if (scale == 250 ) { writeRegister(L3G4200D_Address, CTRL_REG4, 0 b00000000); } else if (scale == 500 ) { writeRegister(L3G4200D_Address, CTRL_REG4, 0 b00010000); } else { writeRegister(L3G4200D_Address, CTRL_REG4, 0 b00110000); }// CTRL_REG5 controls high-pass filtering of outputs, use it // if you'd like: writeRegister(L3G4200D_Address, CTRL_REG5, 0 b00000000); }void writeRegister (int deviceAddress, byte address, byte val) { Wire.beginTransmission(deviceAddress); // start transmission to device Wire.write(address); // send register address Wire.write(val); // send value to write Wire.endTransmission(); // end transmission }int readRegister (int deviceAddress, byte address) {int v; Wire.beginTransmission(deviceAddress); Wire.write(address); // register to read Wire.endTransmission(); Wire.requestFrom(deviceAddress, 1 ); // read a byte while (! Wire.available()) {// waiting } v = Wire.read();return v; }
(2) ½ÇÇà °á°ú
¾ÆµÎÀÌ³ë ½Ã¸®¾ó ¸ð´ÏÅÍâ¿¡¼ ¹Ýµå½Ã º¸µå·¹ÀÌÆ®(Baudate)¸¦ 9600 À¸·Î ¼öÁ¤ ÇØ¾ß ÇÑ´Ù. ±×·¸Áö
¾ÊÀ¸¸é ½Ã¸®¾ó ¸ð´ÏÅÍ Ã¢¿¡ ¾Æ¹«·± µ¥ÀÌÅÍ°¡ Ç¥½ÃµÇÁö ¾Ê°Å³ª À߸øµÈ µ¥ÀÌÅÍ°¡ Ç¥½ÃµÉ °ÍÀÌ´Ù. ÇÁ·Î¼¼½Ì µ¥ÀÌÅ͸¦ ó¸®Çϱâ À§ÇÑ
µ¥ÀÌÅÍ À̹ǷΠµ¥ÀÌÅ͸¦ ¹Ù·Î Æǵ¶Çϱâ´Â ¾î·Æ´Ù. µ¥ÀÌÅÍ°¡ ¿Ã¹Ù¸£°Ô Ç¥½ÃµÇ´Â°ÍÀ» È®ÀÎ ÇÏ¿´´Ù¸é ÇÁ·Î¼¼½Ì¿¡¼ µ¿ÀÏÇÑ ½Ã¸®¾óÆ÷Æ®¸¦
»ç¿ëÇØ¾ß Çϱ⠶§¹®¿¡ ¾ÆµÎÀÌ³ë ½Ã¸®¾ó ¸ð´ÏÅÖ Ã¢À» ´Ýµµ·Ï ÇÏÀÚ.
3.4
ÇÁ·Î¼¼½Ì ÄÚµå
ÇÁ·Î¼¼½Ì Äڵ忡¼ ÇÑ°¡Áö ÁÖÀÇ ÇؾßÇÒ »çÇ×Àº ½Ã¸®¾ó Æ÷Æ®¸¦ °¢ÀÚÀÇ È¯°æ¿¡ ¸ÂÃß¾î¼ ¼öÁ¤À» ÇØÁÖ¾î¾ß ÇÑ´Ù´Â °ÍÀÌ´Ù.
¾Æ·¡ ÇÁ·Î¼¼½Ì Äڵ忡¼ "[0]" ÀÇ 0À̶ó´Â ¼ýÀÚ´Â ÀåÄ¡°ü¸®ÀÚ¿¡¼ COMÆ÷Æ®ÀÇ ¹øÈ£°¡ ¾Æ´Ï¶ó Æ÷Æ®ÀÇ ¼ø¼¶ó´Â°Í¿¡ ÁÖÀÇ ÇØ¾ß ÇÑ´Ù.
À§ÀÇ ÀåÄ¡°ü¸®ÀÚ È¸é¿¡¼ ¿¹¸¦ µç´Ù¸é ´ÙÀ½°ú °°´Ù.
Serial.list()[0 ]; // --> COM31
Serial.list()[1 ]; // --> COM5 ÇÁ·Î¼¼½Ì Äڵ带 ½ÇÇàÇÒ¶§ Å×½ºÆ®ÇÏ´Â PCÀÇ COM Æ÷Æ® »óÅ¿¡ µû¶ó¼ "Serial.list()[0 ]" ÀÇ ¼ýÀÚ¸¦ ¹Ù²Ù¾î ÁÖ¾î¾ß ÇÑ´Ù.
(1) ÇÁ·Î¼¼½Ì ÄÚµå
// import org.json.JSONObject; import processing.serial.* ; JSONObject json; Serial myPort; boolean ready = false ;int x = 0 ;int y = 0 ;int z = 0 ;void setup () { size(600 , 600 , P3D); println(Serial.list()); myPort = new Serial(this , Serial.list()[0 ], 9600 ); myPort.bufferUntil(10 ); }void draw () { lights(); background(0 );if (ready) { fill(255 ); textSize(16 ); text("X: " + x, 10 , 20 ); text("Y: " + y, 10 , 40 ); text("Z: " + z, 10 , 60 ); pushMatrix(); fill(255 , 0 , 0 ); translate(width/ 2 , height/ 2 , 0 ); rotateX(radians(- x)); rotateY(radians(z)); rotateZ(radians(y)); box(200 ); popMatrix(); } else { fill(255 ); textSize(20 ); text("Calibrating, don't move..." , 10 , 80 ); } }void serialEvent (Serial port) { String str = port.readString(); str = str.substring(0 , str.length() - 1 ); println(str);if (str.charAt(0 ) == '{' ) { ready = true ; str = str.substring(1 , str.length() - 2 );// println("str=" + str); String[] ar = splitTokens(str, ":," ); x = Integer.parseInt(ar[1 ]); y = Integer.parseInt(ar[3 ]); z = Integer.parseInt(ar[5 ]); } else { ready = false ; println(str); } }
(2) ½ÇÇà °á°ú
VIDEO
º» ¸Þ´º¾óÀÇ ÇÁ·Î¼¼½Ì ÄÚµå´Â ¾Æ·¡ URLÀÇ ³»¿ëÀ» ÂüÁ¶ÇÏ¿© ÀÛ¼º ÇÏ¿´´Ù.
https://gist.github.com/shoffing/9084561
* ´Ù¸¥ ¼¾¼µéÀÇ ¾ÆµÎÀ̳ë¿Í ÇÁ·Î¼¼½Ì ¸Þ´º¾ó º¸±â
(1) MPU6050 GY-521 ¼¾¼ ¾ÆµÎÀ̳ë, ÇÁ·Î¼¼½Ì ¸Þ´º¾ó(»õâ)
(2) MPU9250 GY-9250 ¼¾¼ ¾ÆµÎÀ̳ë, ÇÁ·Î¼¼½Ì ¸Þ´º¾ó(»õâ)
(3) L3G4200D GY-50 ¼¾¼ ¾ÆµÎÀ̳ë, ÇÁ·Î¼¼½Ì ¸Þ´º¾ó(»õâ)
(4) HMC5883L GY-271 ¼¾¼ ¾ÆµÎÀ̳ë, ÇÁ·Î¼¼½Ì ¸Þ´º¾ó(»õâ)
(5) BMP180 GY-68 ¼¾¼ ¾ÆµÎÀ̳ë, ÇÁ·Î¼¼½Ì ¸Þ´º¾ó(»õâ)
(6) ADXL345 GY-80 ¼¾¼ ¾ÆµÎÀ̳ë, ÇÁ·Î¼¼½Ì ¸Þ´º¾ó(»õâ)
(7) ADXL335 GY-61 ¼¾¼ ¾ÆµÎÀ̳ë, ÇÁ·Î¼¼½Ì ¸Þ´º¾ó(»õâ)