ÀÌ ¸Å´º¾óÀº ÁÖ½Äȸ»ç Á¦ÀÌÄÉÀÌÀÌ¿¥¾¾(JK EMC) ¿¡ ÀÇÇؼ­ ¹ø¿ª, ¼öÁ¤, ÀÛ¼º µÇ¾ú°í ¼ÒÀ¯±Ç ¶ÇÇÑ
ÁÖ ½Äȸ»ç Á¦ÀÌÄÉÀÌÀÌ¿¥¾¾(JK EMC)ÀÇ °ÍÀÔ´Ï´Ù. ¼ÒÀ¯±ÇÀÚÀÇ Çã°¡¸¦ ¹ÞÁö ¾Ê°í ¹«´ÜÀ¸·Î ¼öÁ¤, »èÁ¦Çϰųª ¹èÆ÷ ÇÒ ¼ö ¾ø½À´Ï´Ù.

 

 

ADXL335 3Ãà Accelerometer °¡¼Óµµ GY-61 3.3/5V ·¹±Ö·¹ÀÌÅÍ ³»ÀåÇü ¼¾¼­ ¸Þ´º¾ó


  * Update history

- 2016.8.3 : ÇÁ·Î¼¼½Ì ÄÚµå Ãß°¡
- 2016.7.15 : Ãʱâ Release


 
1. ADXL335 ¼¾¼­ ¼Ò°³
2. ¾Æ µÎÀ̳ë¿Í °°ÀÌ »ç¿ëÇϱâ
    2.1 ¼¾¼­ ȸ·Îµµ¹× ¿Ü°û Ä¡¼ö
    2.2 ¾ÆµÎÀ̳ë UNO R3 ¹è¼±µµ
    2.3 ¾ÆµÎÀÌ³ë ½ºÄÉÄ¡ ÄÚµå
3. ÇÁ·Î¼¼½ÌÀ» ÀÌ¿ëÇؼ­ 3Â÷¿ø ±×·¡ÇÈ Ç¥½Ã
    3.1 ÇÁ·Î¼¼½Ì ¼³Ä¡ Çϱâ
    3.2 ¾ÆµÎÀ̳ë UNO R3 ¹è¼±µµ
    3.3 ¾ÆµÎÀÌ³ë ½ºÄÉÄ¡ ÄÚµå
    3.4 ÇÁ·Î¼¼½Ì ÄÚµå



 

1. ADXL335 ¼¾¼­ ¼Ò°³

ADXL335´Â 3Ãà(X, Y, Z)À» ±âÁØÀ¸·Î ȸÀü°¢ÀÇ º¯È­¿¡ ´ëÇÑ °¡¼Óµµ¸¦ ±¸ÇÒ ¼ö Àִµ¥, 3ÃàÀÇ µ¥ÀÌÅ͸¦ ¾Æ³¯·Î±× °ªÀ¸·Î Ãâ·ÂÇØÁØ´Ù.



Characteristic Value Unit
Supply Voltage 3.0 ~ 5.0 V
Supply Current 350 uA
Measuring range ¡¾3.6 dps(deg/s)
Sensitivity(X/Y/Z) 270/300/330 mdps/digit
Measuring Axis X, Y, Z  
Operating Temperature -40 ~ 85 ¡ÆC



2. ¾ÆµÎÀ̳ë¿Í °°ÀÌ »ç¿ëÇϱâ

2.1 ¼¾¼­ ȸ·Îµµ¹× ¿Ü°û Ä¡¼ö

(1) ADXL335 ¼¾¼­ ȸ·Îµµ
     - ADXL335 PDF ȸ·Îµµ ´Ù¿î·Îµå
     - ADXL335 µ¥ÀÌÅͽÃÆ® ´Ù¿î·Îµå(http://www.jkelec.co.kr)
     - ADXL335 DXF ijµå ÆÄÀÏ ´Ù¿î·Îµå

mpu9250

(2) ADXL335 ¼¾¼­ ¿Ü°û(mm´ÜÀ§) Ä¡¼ö

      atmega128

2.2 ¾ÆµÎÀ̳ë UNO R3 ¹è¼±µµ

(1) ¾ÆµÎÀ̳ë UNO R3¿Í ¿¬°áÇؼ­ °¡¼Óµµ, ÀÚÀÌ·Î ¼¾ÅÍ µ¥ÀÌÅÍ Ãâ·Â Çϱâ
      XÃà<->A0, YÃà<->A1, ZÃà<->A2 ¿Í ¿¬°áÇÑ´Ù. º» Á¦Ç°Àº ³»ºÎ¿¡ ȸ·ÎÀûÀ¸·Î 3.3VÀü¿ø ·¹µâ·¹ÀÌÅÍ¿Í I2C ·¹º§½¬ÇÁÅ͸¦ ³»ÀåÇÏ°í À־ 5.0V¿Í 3.3V ¿¡¼­ ¸ðµÎ »ç¿ëÀÌ °¡´É ÇÏ´Ù. STM32, ¶óÁ¸®ÆÄÀÌ µî°ú °°ÀÌ 3.3V Àü¿øÀ» »ç¿ëÇÏ´Â ÇÁ·Î¼¼¼­¿¡¼­ »ç¿ëÇÒ °æ¿ì¿¡´Â VCC ´ë½Å¿¡ 3.3V ÇÉÀ» ÅëÇؼ­ Àü¿øÀ» ¹Ù·Î ¿¬°áÇØ ÁÖ¸é µÈ´Ù.


     - Fritzing ÆÄÀÏ ´Ù¿î·Îµå

mpu9250

 



2.3 ¾ÆµÎÀÌ³ë ½ºÄÉÄ¡ ÄÚµå

´Ü¼øÈ÷ ¼¾¼­ÀÇ µ¥ÀÌÅ͸¦ ½Ã¸®¾ó µ¥ÀÌÅÍ·Î Ãâ·ÂÇÏ´Â ¿¹Á¦ ÀÌ´Ù.

(1) ¾ÆµÎÀÌ³ë ½ºÄÉÄ¡ ÄÚµå
     - ADXL335 raw µ¥ÀÌÅÍ Ç¥½Ã ½ºÄ³Ä¡ ÆÄÀÏ ´Ù¿î·Îµå

//////////////////////////////////////////////////////////////////
//©2011 bildr
//Released under the MIT License - Please reuse change and share
//Simple code for the ADXL335, prints calculated orientation via serial
//////////////////////////////////////////////////////////////////
//Analog read pins
const int xPin = 0;
const int yPin = 1;
const int zPin = 2;
//The minimum and maximum values that came from
//the accelerometer while standing still
//You very well may need to change these
int minVal = 265;
int maxVal = 402;
//to hold the caculated values
double x;
double y;
double z;
void setup(){
Serial.begin(9600); }
void loop(){
//read the analog values from the accelerometer
int xRead = analogRead(xPin);
int yRead = analogRead(yPin);
int zRead = analogRead(zPin);
//convert read values to degrees -90 to 90 - Needed for atan2
int xAng = map(xRead, minVal, maxVal, -90, 90);
int yAng = map(yRead, minVal, maxVal, -90, 90);
int zAng = map(zRead, minVal, maxVal, -90, 90);
//Caculate 360deg values like so: atan2(-yAng, -zAng)
//atan2 outputs the value of -¥ð to ¥ð (radians)
//We are then converting the radians to degrees
x = RAD_TO_DEG * (atan2(-yAng, -zAng) + PI);
y = RAD_TO_DEG * (atan2(-xAng, -zAng) + PI);
z = RAD_TO_DEG * (atan2(-yAng, -xAng) + PI);
//Output the caculations
Serial.print("x: ");
Serial.print(x);
Serial.print(" | y: ");
Serial.print(y);
Serial.print(" | z: ");
Serial.println(z);
delay(100);//just here to slow down the serial output - Easier to read
}

(2) ½ÇÇà °á°ú 

mpu9250

º» ¸Þ´º¾óÀÇ ¾ÆµÎÀ̳ë ÄÚµå´Â ¾Æ·¡ http://bildr.org/2011/04/sensing-orientation-with-the-adxl335-arduino/ ÀÇ ³»¿ëÀ» ÂüÁ¶ÇÏ¿© ÀÛ¼º ÇÏ¿´´Ù.

3. ÇÁ·Î¼¼½ÌÀ» ÀÌ¿ëÇؼ­ 3Â÷¿ø ±×·¡ÇÈ Ç¥½Ã

3.1 ÇÁ·Î¼¼½Ì ¼³Ä¡ Çϱâ

¾ÆµÎÀ̳븦 ÀÌ¿ëÇؼ­ ¼¾¼­¿¡¼­ µ¥ÀÌÅ͸¦ ÃßÃâÇؼ­ ½Ã¸®¾ó µ¥ÀÌÅÍ·Î Ãâ·ÂÀ» Çؼ­ µ¥ÀÌÅÍ °ªÀ» È®ÀÎÀ» ½±°Ô ÇÒ ¼ö ÀÖ¾ú´Ù. ±×·¸´Ù¸é ÅؽºÆ® µ¥ÀÌÅÍ°¡ ¾Æ´Ï¶ó Á¶±Ý´õ ½Ã°¢ÀûÀΠǥÇö ¹æ¹ýÀÌ ¾øÀ»±î? ±×°Íµµ ¾ÆÁÖ ½±°Ô.. 
ÇÁ·Î¼¼½ÌÀ» ÀÌ¿ëÇÏ¸é ¾ÆµÎÀÌ³ë ½ºÄÉÄ¡ Äڵ带 ÀÔ·ÂÇϵíÀÌ ¾ÆÁÖ ½±°Ô ½Ã°¢ÀûÀΠǥÇöÀÌ °¡´ÉÇÏ´Ù. ¿ì¼± ÇÁ·Î¼¼½Ì °³¹ß ȯ°æÀ» ¼³Ä¡Çϴ°ͺÎÅÍ Çغ¸ÀÚ.

(1) ÇÁ·Î¼¼½Ì ¼³Ä¡
      - ÇÁ·Î¼¼½Ì °³¹ßȯ°æ ¼³Ä¡ Çϱâ(»õâ)

3.2 ¾ÆµÎÀ̳ë UNO R3 ¹è¼±µµ

¹è¼±µµ´Â ÀÌÀü ¿¹Á¦¿Í µ¿ÀÏÇÏ´Ù.

mpu6050

3.3 ¾ÆµÎÀÌ³ë ½ºÄÉÄ¡ ÄÚµå

(1) ¾ÆµÎÀ̳ë ÇÁ·Î¼¼½Ì ÄÚµå
ÇÁ·Î¼¼½Ì Äڵ忡¼­ ÇÑ°¡Áö ÁÖÀÇ ÇؾßÇÒ »çÇ×Àº ½Ã¸®Åë Åë½ÅÀÇ ¼Óµµ¸¦ 9600bps ·Î ¼³Á¤À» ÇÏ¿´´Ù. ±×·¸±â ¶§¹®¿¡ ¾ÆµÎÀ̳ëÀÇ ½Ã¸®¾ó ¸ð´ÏÅÍâ¿¡¼­µµ µ¿ÀÏÇÑ Åë½Å¼Óµµ¸¦ ¸ÂÃß¾î ÁÖ¾î¾ß ÇÑ´Ù.

     - ADXL335 ¾ÆµÎÀ̳ë, ÇÁ·Î¼¼½Ì ½ºÄ³Ä¡ ÆÄÀÏ ´Ù¿î·Îµå


// Maurice Ribble 
// 6-28-2009
// http://www.glacialwanderer.com/hobbyrobotics
// This app just probes two external sensors (ADXL330 and IDG300) and
// then sends that data over a serial connection. I used a sparkfun
// breakout board to make using these chips easier.
// http://www.sparkfun.com/commerce/product_info.php?products_id=741
// I wrote a processing.org app that reads in this data and graphs it
// on a pc.
#define X_ACCEL_APIN 0
#define Y_ACCEL_APIN 1
#define Z_ACCEL_APIN 2
//#define V_REF_APIN 3
//#define Y_RATE_APIN 4
//#define X_RATE_APIN 5
void setup()
{
Serial.begin(115200);
}
// If this is defined it prints out the FPS that we can send a
// complete set of data over the serial port.
//#define CHECK_FPS
void loop()
{
int xAccel=0, yAccel=0, zAccel=0; // , vRef=0, xRate=0, yRate=0;
unsigned int startTag = 0xDEAD; // Analog port maxes at 1023 so this is a safe termination value
int loopCount;
#ifdef CHECK_FPS
unsigned long startTime, endTime;
startTime = millis();
#endif
// Can't do more than 64 loops or could overflow the 16 bit ints
// This just averages together as many sensor reads as we can in
// order to reduce sensor noise. Might want to introduce add
// a smarter filter her in the future.
loopCount = 12; // 12 gives a little over 100 FPS
for(int i = 0; i< loopCount; ++i)
{
// It takes 100 us (0.0001 s) to read an analog input
xAccel += analogRead(X_ACCEL_APIN);
yAccel += analogRead(Y_ACCEL_APIN);
zAccel += analogRead(Z_ACCEL_APIN);
//vRef += analogRead(V_REF_APIN);
//xRate += analogRead(X_RATE_APIN);
//yRate += analogRead(Y_RATE_APIN);
}
xAccel /= loopCount;
yAccel /= loopCount;
zAccel /= loopCount;
//vRef /= loopCount;
//xRate /= loopCount;
//yRate /= loopCount;
Serial.write( (unsigned byte*)&startTag, 2);
Serial.write((unsigned byte*)&xAccel, 2);
Serial.write((unsigned byte*)&yAccel, 2);
Serial.write((unsigned byte*)&zAccel, 2);
//Serial.write((unsigned byte*)&vRef, 2);
//Serial.write((unsigned byte*)&xRate, 2);
//Serial.write((unsigned byte*)&yRate, 2);
#ifdef CHECK_FPS
endTime = millis();
Serial.print(" - FPS: ");
Serial.println(1.f / (endTime-startTime) * 1000);
#endif
}

3.4 ÇÁ·Î¼¼½Ì ÄÚµå

ÇÁ·Î¼¼½Ì Äڵ忡¼­ ÇÑ°¡Áö ÁÖÀÇ ÇؾßÇÒ »çÇ×Àº ½Ã¸®¾ó Æ÷Æ®¸¦ °¢ÀÚÀÇ È¯°æ¿¡ ¸ÂÃ߾ ¼öÁ¤À» ÇØÁÖ¾î¾ß ÇÑ´Ù´Â °ÍÀÌ´Ù.
¾Æ·¡ ÇÁ·Î¼¼½Ì Äڵ忡¼­ "[0]" ÀÇ 0À̶ó´Â ¼ýÀÚ´Â ÀåÄ¡°ü¸®ÀÚ¿¡¼­ COMÆ÷Æ®ÀÇ ¹øÈ£°¡ ¾Æ´Ï¶ó Æ÷Æ®ÀÇ ¼ø¼­¶ó´Â°Í¿¡ ÁÖÀÇ ÇØ¾ß ÇÑ´Ù.

mpu6050

À§ÀÇ ÀåÄ¡°ü¸®ÀÚ È­¸é¿¡¼­ ¿¹¸¦ µç´Ù¸é ´ÙÀ½°ú °°´Ù.

Serial.list()[0]; // --> COM31
Serial.list()[1]; // --> COM5

ÇÁ·Î¼¼½Ì Äڵ带 ½ÇÇàÇÒ¶§ Å×½ºÆ®ÇÏ´Â PCÀÇ COM Æ÷Æ® »óÅ¿¡ µû¶ó¼­ "Serial.list()[0]" ÀÇ ¼ýÀÚ¸¦ ¹Ù²Ù¾î ÁÖ¾î¾ß ÇÑ´Ù.

(1) ÇÁ·Î¼¼½Ì ÄÚµå

// Maurice Ribble 
// 6-28-2009
// http://www.glacialwanderer.com/hobbyrobotics
// This takes data off the serial port and graphs it.
// There is an option to log this data to a file.
// I wrote an arduino app that sends data in the format expected by this app.
// The arduino app sends accelerometer and gyroscope data.
import processing.serial.*;
// Globals
int g_winW = 820; // Window Width
int g_winH = 600; // Window Height
// boolean g_dumpToFile = true; // Dumps data to c:\\output.txt in a comma seperated format (easy to import into Excel)
boolean g_enableFilter = true; // Enables simple filter to help smooth out data.
cDataArray g_xAccel = new cDataArray(200);
cDataArray g_yAccel = new cDataArray(200);
cDataArray g_zAccel = new cDataArray(200);
//cDataArray g_vRef = new cDataArray(200);
//cDataArray g_xRate = new cDataArray(200);
//cDataArray g_yRate = new cDataArray(200);
cGraph g_graph = new cGraph(10, 190, 800, 400);
Serial g_serial;
PFont g_font;
void setup()
{
size(820, 600, P2D);
println(Serial.list());
g_serial = new Serial(this, Serial.list()[0], 115200, 'N', 8, 1.0);
g_font = createFont("Arial",14,true);
fill(0, 0, 0);
}
void draw()
{
// We need to read in all the avilable data so graphing doesn't lag behind
while (g_serial.available() >= 2*6+2)
{
processSerialData();
}
strokeWeight(1);
fill(255, 255, 255);
g_graph.drawGraphBox();
strokeWeight(1.5);
stroke(255, 0, 0);
g_graph.drawLine(g_xAccel, 0, 1024);
stroke(0, 255, 0);
g_graph.drawLine(g_yAccel, 0, 1024);
stroke(0, 0, 255);
g_graph.drawLine(g_zAccel, 0, 1024);
// add axis info
// This draws the graph key info
strokeWeight(1.5);
stroke(255, 0, 0); line(20, 460, 40, 460);
stroke(0, 255, 0); line(20, 480, 40, 480);
stroke(0, 0, 255); line(20, 500, 40, 500); textFont(g_font,16); // STEP 3 Specify font to be used
fill(0); // STEP 4 Specify font color
text("xAccel", 60, 460);
text("yAccel", 60, 480);
text("zAccel", 60, 500);
/*
if (g_dumpToFile)
{
// This clears deletes the old file each time the app restarts
byte[] tmpChars = {'\r', '\n'};
saveBytes("c:\\output.txt", tmpChars);
}
*/ }
// This reads in one set of the data from the serial port
void processSerialData()
{
int inByte = 0;
int curMatchPos = 0;
int[] intBuf = new int[2];
intBuf[0] = 0xAD;
intBuf[1] = 0xDE;
while (g_serial.available() < 2); // Loop until we have enough bytes
inByte = g_serial.read();
// This while look looks for two bytes sent by the client 0xDEAD
// This allows us to resync the server and client if they ever
// loose sync. In my testing I haven't seen them loose sync so
// this could be removed if you need to, but it is a good way to
// prevent catastrophic failure.
while(curMatchPos < 2)
{
if (inByte == intBuf[curMatchPos])
{
++curMatchPos;
if (curMatchPos == 2)
break;
while (g_serial.available() < 2); // Loop until we have enough bytes
inByte = g_serial.read();
}
else
{
if (curMatchPos == 0)
{
while (g_serial.available() < 2); // Loop until we have enough bytes
inByte = g_serial.read();
}
else
{
curMatchPos = 0;
}
}
}
while (g_serial.available() < 2*3); // Loop until we have a full set of data
// This reads in one set of data
{
byte[] inBuf = new byte[2];
int xAccel, yAccel, zAccel, vRef, xRate, yRate;
g_serial.readBytes(inBuf);
// Had to do some type conversion since Java doesn't support unsigned bytes
xAccel = ((int)(inBuf[1]&0xFF) << 8) + ((int)(inBuf[0]&0xFF) << 0);
g_serial.readBytes(inBuf);
yAccel = ((int)(inBuf[1]&0xFF) << 8) + ((int)(inBuf[0]&0xFF) << 0);
g_serial.readBytes(inBuf);
zAccel = ((int)(inBuf[1]&0xFF) << 8) + ((int)(inBuf[0]&0xFF) << 0);
g_serial.readBytes(inBuf);
g_xAccel.addVal(xAccel);
g_yAccel.addVal(yAccel);
g_zAccel.addVal(zAccel);
/*
if (g_dumpToFile) // Dump data to a file if needed
{
String tempStr;
tempStr = xAccel + "," + yAccel + "," + zAccel + "," + vRef + "," + xRate + "," + yRate + "\r\n";
FileWriter file;
try
{
file = new FileWriter("c:\\output.txt", true); //bool tells to append
file.write(tempStr, 0, tempStr.length()); //(string, start char, end char)
file.close();
}
catch(Exception e)
{
println("Error: Can't open file!");
}
}
*/ /*
print(xAccel); print(" "); print(yAccel); print(" "); print(zAccel); print(" ");
print(vRef); print(" "); print(xRate); print(" "); println(yRate);
*/
}
}
// This class helps mangage the arrays of data I need to keep around for graphing.
class cDataArray
{
float[] m_data;
int m_maxSize;
int m_startIndex = 0;
int m_endIndex = 0;
int m_curSize;
cDataArray(int maxSize)
{
m_maxSize = maxSize;
m_data = new float[maxSize];
}
void addVal(float val)
{
if (g_enableFilter && (m_curSize != 0))
{
int indx;
if (m_endIndex == 0)
indx = m_maxSize-1;
else
indx = m_endIndex - 1;
m_data[m_endIndex] = getVal(indx)*.5 + val*.5;
}
else
{
m_data[m_endIndex] = val;
}
m_endIndex = (m_endIndex+1)%m_maxSize;
if (m_curSize == m_maxSize)
{
m_startIndex = (m_startIndex+1)%m_maxSize;
}
else
{
m_curSize++;
}
}
float getVal(int index)
{
return m_data[(m_startIndex+index)%m_maxSize];
}
int getCurSize()
{
return m_curSize;
}
int getMaxSize()
{
return m_maxSize;
}
}
// This class takes the data and helps graph it
class cGraph
{
float m_gWidth, m_gHeight;
float m_gLeft, m_gBottom, m_gRight, m_gTop;
cGraph(float x, float y, float w, float h)
{
m_gWidth = w;
m_gHeight = h;
m_gLeft = x;
m_gBottom = g_winH - y;
m_gRight = x + w;
m_gTop = g_winH - y - h;
}
void drawGraphBox()
{
stroke(0, 0, 0);
rectMode(CORNERS);
rect(m_gLeft, m_gBottom, m_gRight, m_gTop);
}
void drawLine(cDataArray data, float minRange, float maxRange)
{
float graphMultX = m_gWidth/data.getMaxSize();
float graphMultY = m_gHeight/(maxRange-minRange);
for(int i=0; i<data.getCurSize()-1; ++i)
{
float x0 = i*graphMultX+m_gLeft;
float y0 = m_gBottom-((data.getVal(i)-minRange)*graphMultY);
float x1 = (i+1)*graphMultX+m_gLeft;
float y1 = m_gBottom-((data.getVal(i+1)-minRange)*graphMultY);
line(x0, y0, x1, y1);
}
}
}

(2) ½ÇÇà °á°ú



º» ¸Þ´º¾óÀÇ ÇÁ·Î¼¼½Ì ÄÚµå´Â ¾Æ·¡ URLÀÇ ³»¿ëÀ» ÂüÁ¶ÇÏ¿© ÀÛ¼º ÇÏ¿´´Ù.
http://www.glacialwanderer.com/hobbyrobotics/?p=261

* ´Ù¸¥ ¼¾¼­µéÀÇ ¾ÆµÎÀ̳ë¿Í ÇÁ·Î¼¼½Ì ¸Þ´º¾ó º¸±â

(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 ¼¾¼­ ¾ÆµÎÀ̳ë, ÇÁ·Î¼¼½Ì ¸Þ´º¾ó(»õâ)