[아두이노] 먼지센서 (GP2Y1010AU0F) 활용하기

기본 설명

지름 2.5㎛의 미세먼지까지 인식 가능한 미세먼지 센서 입니다. 내부의 적외선 LED를 빠르게 깜빡여 먼지에 의해 반사된 빛을 감지하는 원리로 동작합니다. 기본형태의 경우 회로에 다이오드와 저항의 연결이 필요하지만, 모듈형의 경우 회로에 내장되어 있어 연결이 간편합니다.

[모듈형 미세먼지 센서] 아두이노 센서를 활용하기 위한 추가적인 작업이 적어집니다.
[아두이노] 먼지센서 (GP2Y1010AU0F) 활용하기 더보기

[아두이노] 충돌센서 (Limit switch) 활용하기

기본 설명

충돌센서 혹은 리미트 스위치 등으로 불리는 센서 모듈입니다. 모듈 가장자리에 위치한 스위치가 눌리면 LED에 불이 점등됨과 동시에 OUT 핀에서 LOW 값을 출력합니다.

[아두이노] 충돌센서 (Limit switch) 활용하기 더보기

[아두이노] 압력센서 (FSR) 활용하기

기본 설명

누르는 압력의 상대적 값을 측정할 수 있는 센서 입니다. 평소 높은 저항 값을 띄고 있다가 센싱 부위에 압력이 가해지면 저항 값이 낮아지게 되고, 그 값을 아날로그 핀에서 읽어 들여 압력의 세기를 측정합니다. 저항 값의 변화로 압력을 측정하므로 센서에 가해진 절대적인 압력 값은 알 수 없습니다. 크기와 모양이 다양하며, 최대 측정 범위 또한 달라 용도에 맞는 센서를 선택하여야 합니다. 일반적으로 최대 측정 범위가 큰 센서일수록 둔감하여 미세한 압력변화는 측정하기 힘듭니다.

원형 압력 센서 모습
[아두이노] 압력센서 (FSR) 활용하기 더보기

[아두이노] 토양 습도 센서 (Keyestudio, DHT11) 활용하기

기본 설명

두개의 전도성 플레이트가 있으며 1개는 전원 1개는 접지와 연결이 되어있습니다. 토양을 통해 전류를 흐르게 하여 2개의 플레이트 사이의 수분에 따른 저항을 측정하여 토양의 습도를 측정할 수 있습니다. 수분의 정도를 0 ~ 1024 사이의 값으로 알려줍니다.

아두이노 배선

아두이노토양습도센서 (DHT11)
5V VCC + (빨강색)
GND GND – (주황색)
A0 output signal S (갈색)
[아두이노] 토양 습도 센서 (Keyestudio, DHT11) 활용하기 더보기

[아두이노] 초음파 센서 (HC-SR04) 활용하기

기본 설명

HC-SR04 초음파 센서는 수신부와 송신부로 이루어져 있습니다.
송신부에서 초음파를 쏘아 올리고 벽 혹은 물체에 반사되어 오는 초음파를 수신부에서 인식합니다. 이 때 보낸 시간과 반사되어 돌아온 시간을 측정하여 거리를 계산할 수 있습니다.

– 측정 범위 : 2~400cm
– 측정 각도 : 30°

※주의 사항 : 스펙상 측정 범위는 2~400cm이지만 실제로는 5~400cm 정도이고 측정 각도 또한 오차를 고려해 15° 이하 범위에서 측정하는 것을 권장합니다.

아두이노 배선

아두이노초음파 센서 (HC-SR04) 
5VVCC (노랑색)
GNDGND (주황색)
D8Trig (갈색)
D9Echo (빨강색)
초음파 센서 배선도

아두이노 소스 코드

아두이노를 이용해 초음파 센서를 동작시켜 커멘드창을 통해 거리를 볼 수 있습니다.

#define trig 8
#define echo 9

void setup()
{
Serial.begin(9600);
Serial.println("초음파 센서 시작");
pinMode(trig, OUTPUT);
pinMode(echo, INPUT);
}

void loop()
{
long duration, distance;
digitalWrite(trig, LOW);
delayMicroseconds(2);
digitalWrite(trig, HIGH);
delayMicroseconds(10);
digitalWrite(trig, LOW);
duration = pulseIn(echo, HIGH);
distance = duration * 170 / 1000;
Serial.print("거리: ");
Serial.print(distance);
Serial.println("mm");
delay(100);
}
배선된 초음파 센서 모습

[아두이노] 적외선 거리 센서 활용하기

기본 설명

적외선 센서란 가시광선(사람이 볼 수 있는 파장의 영역)보다 한 층 긴 파장의 영역을 적외선이라고 합니다. 이미지에서 두 렌즈 중 한 곳은 적외선을 흡수하고, 다른 한 곳은 적외선을 반사시킨다는 성질을 이용하여 적외선이 반사해 돌아오는 시간을 계산해 거리를 탐지할 수 있게 되는 것입니다.

아두이노 배선

아두이노적외선 센서(Gp2Y0A02) 모듈
5VVCC (빨강색)
GNDGND (검은색)
A0output signal (노랑색)
적외선 센서 거리 측정 센서 모듈 배선도

아두이노 소스 코드

소스를 보기 전에 적외선 센서를 쓰는데 필요한 라이브러리를 아두이노 IDE에 추가하여야 합니다.

추가하기 전에 아래의 라이브러리 zip 파일을 다운로드 하고..
라이브러리 추가하는 방법을 참고하시기 바랍니다.

#include <GP2Y0A02YK0F.h>

GP2Y0A02YK0F irSensor;
int distance;

void setup()
{
Serial.begin(9600);
irSensor.begin(A0);
}

void loop()
{
distance = irSensor.getDistanceCentimeter();
Serial.print("\nDistance in centimeters: ");
Serial.print(distance);
delay(500);
}

실행 장면

배선 장면
거리가 움직이는 모습을 확인해 보세요.

[아두이노] 자이로 센서(MPU-6050 or MPU-6500) 활용하기

기본 설명

가속도 센서란 지구의 중력가속도를 기준으로 사물이 얼마만큼의 힘을 받고 있는지를
측정하는 센서입니다.

자이로 센서의 구성

가만히 있을 때 센서에 작용하는 중력 가속도를 x, y, z 축으로 벡터 3개로 나누어 크기를 측정하고 가속도 센서의 값들은 정지된 상태에서도 특정한 값을 갖기 때문에 기얼어진 정도를 파악하거나 진동을 파악하는데 많이 사용됩니다.

※ 주의 사항 : 이번 코딩은 라이브러리를 I2Cdev_library, MPU6050_library를 전부 받아서 압축을 풀어줘야 합니다.

zip 파일로 된 라이브러리를 사용하려면 아래의 링크에서 다운로드 받으시고 [아두이노 zip 파일 라이브러리 추가하는 방법] 링크를 참고하세요.

아두이노 배선

아두이노I2C(IIC) 모듈
5VVCC (노랑색)
GNDGND (초록색)
A4SDA (보라색)
A5SCL (파랑색)
D2INT (주황색)
자이로 센서 배선도

아두이노 소스 코드

코드가 좀 깁니다만.
사실 #define, #if ~ #endif 만 잘 이해하는 기회로 생각해 보시기 바랍니다.

그리고…

Serial.println(mpu.testConnection() ? F(“MPU6050 connection successful”) : F(“MPU6050 connection failed”));

이게 무슨 뜻인지 한번 잘 찾아 보시기 바랍니다.

#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif

MPU6050 mpu;

#define OUTPUT_READABLE_YAWPITCHROLL
#define INTERRUPT_PIN 2
#define LED_PIN 13

bool blinkState = false;
bool dmpReady = false; 
uint8_t mpuIntStatus;  
uint8_t devStatus;     
uint16_t packetSize;   
uint16_t fifoCount;    
uint8_t fifoBuffer[64];

Quaternion q; 
VectorInt16 aa;
VectorInt16 aaReal; 
VectorInt16 aaWorld;
VectorFloat gravity;   

float euler[3]; 
float ypr[3];
uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };

volatile bool mpuInterrupt = false; 

void dmpDataReady() {
    mpuInterrupt = true;
}

void setup() {
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        Wire.setClock(400000); 
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    Serial.begin(115200);
    while (!Serial);

    Serial.println(F("Initializing I2C devices..."));

    mpu.initialize();
    pinMode(INTERRUPT_PIN, INPUT);
    Serial.println(F("Testing device connections..."));
    Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
    Serial.println(F("\nSend any character to begin DMP programming and demo: "));

    while (Serial.available() && Serial.read()); // empty buffer
    while (!Serial.available());                 // wait for data
    while (Serial.available() && Serial.read()); // empty buffer again
    Serial.println(F("Initializing DMP..."));

    devStatus = mpu.dmpInitialize();
    mpu.setXGyroOffset(220);
    mpu.setYGyroOffset(76);
    mpu.setZGyroOffset(-85);
    mpu.setZAccelOffset(1788); 

    if (devStatus == 0) {
        // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP..."));
        mpu.setDMPEnabled(true);
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();
        Serial.println(F("DMP ready! Waiting for first interrupt..."));
        dmpReady = true;
        packetSize = mpu.dmpGetFIFOPacketSize();
    } else {
        Serial.print(F("DMP Initialization failed (code "));
        Serial.print(devStatus);
        Serial.println(F(")"));
    }
    pinMode(LED_PIN, OUTPUT);
}

void loop() {
    if (!dmpReady) return;
    while (!mpuInterrupt && fifoCount < packetSize) {
    }

    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();
    fifoCount = mpu.getFIFOCount();

    if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
        mpu.resetFIFO();
        Serial.println(F("FIFO overflow!"));
    } else if (mpuIntStatus & 0x02) {
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
        mpu.getFIFOBytes(fifoBuffer, packetSize);
        fifoCount -= packetSize;

        #ifdef OUTPUT_READABLE_QUATERNION
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            Serial.print("quat\t");
            Serial.print(q.w);
            Serial.print("\t");
            Serial.print(q.x);
            Serial.print("\t");
            Serial.print(q.y);
            Serial.print("\t");
            Serial.println(q.z);
        #endif

        #ifdef OUTPUT_READABLE_EULER
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetEuler(euler, &q);
            Serial.print("euler\t");
            Serial.print(euler[0] * 180/M_PI);
            Serial.print("\t");
            Serial.print(euler[1] * 180/M_PI);
            Serial.print("\t");
            Serial.println(euler[2] * 180/M_PI);
        #endif

        #ifdef OUTPUT_READABLE_YAWPITCHROLL
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
            Serial.print("ypr\t");
            Serial.print(ypr[0] * 180/M_PI);
            Serial.print("\t");
            Serial.print(ypr[1] * 180/M_PI);
            Serial.print("\t");
            Serial.println(ypr[2] * 180/M_PI);
        #endif

        #ifdef OUTPUT_READABLE_REALACCEL
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetAccel(&aa, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
            Serial.print("areal\t");
            Serial.print(aaReal.x);
            Serial.print("\t");
            Serial.print(aaReal.y);
            Serial.print("\t");
            Serial.println(aaReal.z);
        #endif

        #ifdef OUTPUT_READABLE_WORLDACCEL
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetAccel(&aa, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
            mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);
            Serial.print("aworld\t");
            Serial.print(aaWorld.x);
            Serial.print("\t");
            Serial.print(aaWorld.y);
            Serial.print("\t");
            Serial.println(aaWorld.z);
        #endif

        #ifdef OUTPUT_TEAPOT
            teapotPacket[2] = fifoBuffer[0];
            teapotPacket[3] = fifoBuffer[1];
            teapotPacket[4] = fifoBuffer[4];
            teapotPacket[5] = fifoBuffer[5];
            teapotPacket[6] = fifoBuffer[8];
            teapotPacket[7] = fifoBuffer[9];
            teapotPacket[8] = fifoBuffer[12];
            teapotPacket[9] = fifoBuffer[13];
            Serial.write(teapotPacket, 14);
            teapotPacket[11]++; 
        #endif
        blinkState = !blinkState;
        digitalWrite(LED_PIN, blinkState);
    }
}

실행 화면

배선 모습

[아두이노] 온습도 센서 활용하기

기본 설명

습도센서는 두 전극 사이의 저항 변화를 측정함으로써 공기 중의 습도 변화를 알아 낼 수 있습니다. 습도 센서의 표면에는 전극이 부착된 얇은 판이 있는데 이 판이 공기 중의 수분을 흡수하게 되고 표면에 부착된 수분의 양에 의해 전극의 전도도에 변화가 일어나게 되면 이를 감지하게 됩니다. 온도센서는 고온에서 소결된 반도체 세라믹으로 온도에 따라서 물질의 저항값이 변하는 소재를 이용하여 저항값의 변화를 감지해서 온도를 측정하게 됩니다.

– 습도 측정 범위 : 20~90% (오차 : 5%)
– 온도 측정 범위 : 0~50℃ (오차 : 2℃)

아두이노 배선

아두이노DHT11(온습도 센서)
5VVCC (주황색)
GNDGND (갈색)
D4output (빨강색)
온습도 센서 배선도

아두이노 소스 코드

#include <DHT11.h>

int pin=4;
DHT11 dht11(pin);

void setup()
{
Serial.begin(9600);
while (!Serial) {
}
}

void loop()
{
int err;
float temp, humi;

if((err=dht11.read(humi, temp))==0)
{
Serial.print("temperature:");
Serial.print(temp);
Serial.print(" humidity:");
Serial.print(humi);
Serial.println();
} else {
Serial.println();
Serial.print("Error No :");
Serial.print(err);
Serial.println();
}
delay(DHT11_RETRY_DELAY);
}

여기서 유의할 점.

소스코드에 ” #include <DHT11.h>”가 생소하지 않나요?

아두이노 코딩 전부를 모든 개발자가 처음부터 끝까지 한다면 세상에 코딩이 제일 어려운 일 중에 하나가 될 겁니다. 그래서 선지적인 선배 개발자들이 자신들이 만든 부품에 맞게 라이브러리(Library)를 제공합니다.
즉, 처음부터 기계적인 특성(Data sheet)을 모두 공부해서 개발하지 않아도 쉽게 사용할 수 있도록 개발에 활용할 수 있도록 방법을 제공하는 거죠.

이 온습도 센서에는 다른 개발자들이 이 센서를 잘, 쉽게 사용할 수 있도록 개발하여 제공하는 “DHT11″이라는 라이브러리가 존재합니다.

이 라이브러리를 활용하기 전에 먼저 다음의 링크에서 라이브러리 zip 파일을 다운로드 받으세요.

그리고 다음의 링크를 참고하셔서 라이브러리를 추가하시면 됩니다.

동작 화면