본문 바로가기
아두이노

[Do it! 아두이노] 6. 디지털 입력으로 아두이노 작동하기

by Lizardee 2023. 8. 19.
1. 푸시 버튼으로 LED 제어하기

▶ 푸시 버튼(push button)

: 푸시 버튼은 대표적인 디지털 입력 장치로, 버튼을 누르면 상태가 변경되고 누르지 않으면 원래 상태로 되돌아온다.

--> 푸시 버튼은 주로 사용자로부터 입력을 받을 때 사용한다. 예를 들어, 버튼을 눌러 LED를 켜거나 끌 수 있는 것처럼 특정 장치를 작동하거나 멈출 때 사용된다.

푸시 버튼의 구성 요소, 작동 시 회로도

푸시 버튼을 구성하는 네 개의 단자 중 1번과 3번, 2번과 4번 단자는 처음부터 서로 연결되어 있다.

푸시 버튼을 누르지 않았을 때는 1, 3번 단자가 있는 왼쪽 부분과 2, 4번 단자가 있는 오른쪽 부분 사이의 연결이 서로 끊어져 있다. 푸시 버튼을 누르면 둘 사이가 연결된다.

 

Do it! 실습 6-1. 푸시 버튼으로 LED 켜고 끄기

푸시 버튼으로 LED 켜고 끄기

// C++ code
//
void setup()
{
  Serial.begin(9600); //직전 통신 초기화
  
  pinMode(8, OUTPUT); //8번 디지털 핀을 출력 모드로 설정
  pinMode(7, INPUT);  //7번 디지털 핀을 입력 모드로 설정
}

void loop()
{
  int readValue=digitalRead(7); //입력 핀의 값을 읽어 변수에 저장
  Serial.println(readValue);    //변숫값을 직렬 모니터에 출력
  
  if(readValue==HIGH)            //입력값에 따라 LED 출력값 제어
    digitalWrite(8, HIGH);      //readvalue=HIGH이면 실행
  else
    digitalWrite(8, LOW);       //readvalue=LOW이면 실행
}

▶ setup()

  • Serial.begin(9600): 직렬 모니터를 통해 출력값 확인
  • pinMode(핀 번호, 사용 목적)

loop()

  • int readValue = digitalRead(): digitalRead 값을 읽어 변수 readValue에 저장
  • Serial.println(readValue): 변수 readValue 값 직렬 모니터에 출력
    - 변수 readValue 값 = 푸시 버튼을 누르는 동안에는 HIGH, 푸시 버튼을 누르지 않을 때는 LOW
  • digitalWrite(핀 번호, 신호값): 핀 번호에 신호값을 보냄

 


2. 플로팅 현상과 풀업, 풀다운 저항 이해하기

플로팅(floating) 현상

: HIGH 또는 LOW의 값이 일정하지 않고, 무작위로 변하는 것

 

Do it! 실습 6-2. 플로팅 현상 이해하기

풀다운 저항 회로

// C++ code
//
void setup()
{
  Serial.begin(9600); //직전 통신 초기화
  
  pinMode(8, OUTPUT); //8번 디지털 핀을 출력 모드로 설정
  pinMode(7, INPUT);  //7번 디지털 핀을 입력 모드로 설정
}

void loop()
{
  int readValue=digitalRead(7); //입력 핀의 값을 읽어 변수에 저장
  Serial.println(readValue);    //변숫값을 직렬 모니터에 출력
  
  if(readValue==HIGH)            //입력값에 따라 LED 출력값 제어
    digitalWrite(8, HIGH);      //readvalue=HIGH이면 실행
  else
    digitalWrite(8, LOW);       //readvalue=LOW이면 실행
}
  • 아두이노는 디지털 입력 핀에 접지를 직접 연결하면 LOW값(0)만 읽으며, 전원에 직접 연결하면 HIGH값(1)만 읽는다.
  • 플로팅 현상: HIGH값 또는 LOW값 중 명확하게 한쪽에 정착하지 못해 값이 계속 바뀌는 현상
    --> 따라서 한쪽에 정착할 수 있도록 핀을 접지 또는 전원에 연결해야 한다.

하지만 디지털 핀에 직접 연결하면 핀에 보낼 신호를 원하는 대로 조절할 수 없다. 그래서 저항과 함께 연결하는 것이다.

 

▶ 풀업 저항과 풀다운 저항

  • 풀다운(pull-down) 저항: 저항을 접지(GND) 선(-)에 연결한 것
  • 풀업(pull-ip) 저항: 저항을 전원(5V) 선(+)에 연결한 것

▷ 풀다운 저항

  • 풀다운 저항을 사용하면 아두이노의 디지털 7번 핀은 푸시 버튼을 누르지 않을 때 저항을 거쳐 접지(GND)로 연결된 선을 통해 LOW값을 읽는다.
  • 푸시 버튼을 누르면 전류가 <전원(5V) --> 푸시 버튼 --> 저항 --> 접지>로 흐르는데, 이때 디지털 7번 핀과 전원의 전압 차를 감지해 입력값이 HIGH로 바뀐다.
    --> 따라서 풀다운 저항은 일반적으로 생각하는 푸시 버튼의 기능을 수행한다. 즉, 푸시 버튼을 눌렀을 때는 디지털 7번 핀의 입력값이 HIGH, 누르지 않았을 때는 LOW이다.

▷ 풀업 저항

  • 풀업 저항을 사용하면 아두이노의 디지털 7번 핀은 푸시 버튼을 누르지 않아도 저항을 거쳐 전원에 연결된 선을 통해 HIGH값을 읽는다.
  • 푸시 버튼을 누르면 푸시 버튼 단자가 연결되고, 전류가 흐르는 길은 디지털 7번으로 가는 것과 푸시 버튼을 거쳐 접지로 가는 두 가지 경로로 나뉜다. 이때 디지털 7번 핀과 접지가 서로 연결되기 때문에 전압 차가 0이므로 LOW값을 읽는다.

풀다운 저항 vs. 풀업 저항

  • 풀다운(pull-down) 저항: 저항을 접지(GND) 선(-)에 연결한 것
  • 풀업(pull-ip) 저항: 저항을 전원(5V) 선(+)에 연결한 것

--> 버튼을 누를 때만 전원을 공급하고 싶다면 풀다운(pull-down) 저항이 필요하고, 평상시에는 전원을 공급하다가 버튼을 눌렀을 때 공급을 멈추고 싶다면 풀업(pull-up) 저항이 필요하다.

예를 들어, 버튼을 눌러 작동하는 선풍기, 전등과 같은 장치는 풀다운(pull-down) 저항을 사용한다. 반면, 공장에서 위험한 상황에 장비를 멈추기 위한 응급 버튼, 컴퓨터의 전원을 껐다 켜기 위한 리셋 버튼에는 풀업(pull-up) 저항을 사용한다.

또한 하드웨어적인 특성으로 인해 풀업(pull-up) 저항을 사용할 때가 풀다운(pull-down) 저항을 사용할 때보다 에너지를 절감할 수 있기 때문에 에너지 효율성의 축면에서 풀업 저항을 사용하기도 한다.

 

Do it! 실습 6-3. 내부 풀업(pull-up) 저항을 사용해서 LED 전원 스위치 만들기

// C++ code
//
void setup()
{
  Serial.begin(9600); //직전 통신 초기화
  
  pinMode(8, OUTPUT);        //8번 디지털 핀을 출력 모드로 설정
  pinMode(7, INPUT_PULLUP);  //내부 풀업 저항을 사용하도록 설정
}

void loop()
{
  int readValue=digitalRead(7); //입력 핀의 값을 읽어 변수에 저장
  Serial.println(readValue);    //변숫값을 직렬 모니터에 출력
  
  if(readValue==HIGH)            //입력값에 따라 LED 출력값 제어
    digitalWrite(8, LOW);       //readvalue=HIGH이면 LOW 실행
  else
    digitalWrite(8, HIGH);      //readvalue=LOW이면 HIGH 실행
}

▷ 풀업 저항을 사용했으므로,

  • 푸시 버튼을 누르기 전에는 HIGH값(1)이 출력되고,
    푸시 버튼을 누르면 LOW값(0)이 출력된다.
  • 푸시 버튼의 입력값이 HIGH일 때는 디지털 8번 핀에 LOW값을 쓰기 때문에 LED에 불이 들어오지 않고, 
    푸시 버튼을 누르면 디지털 8번 핀에 HIGH값을 쓰고, 전압 5V가 걸리기 때문에 전류가 흐르면서 LED에 불이 들어온다.

 


3. 슬라이드 스위치로 LED 제어하기

▶ 슬라이드 스위치(slide switch)

: 푸시 버튼(push button)이 누르는 동안만 상태를 변경하고 손을 떼면 원래 상태로 되돌아오는 장치라면, 슬라이드 스위치(slide switch)는 한번 상태를 변경하면 그 상태를 계속 유지하는 장치다.

슬라이드 스위치의 구성 요소와 작동 시 회로도

 

Do it! 실습 6-4. 슬라이드 스위치로 LED 켜고 끄기

슬라이드 스위치로 LED 켜고 끄기

// C++ code
//
void setup()
{
  Serial.begin(9600);   //직렬 통신 초기화
  
  pinMode(8, OUTPUT);   //8번 디지털 핀을 출력 모드로 설정
  pinMode(7, INPUT);    //7번 디지털 핀을 입력 모드로 설정
}

void loop()
{
  int readValue = digitalRead(7);   //입력 핀의 값을 읽어 변수에 저장
  Serial.println(readValue);        //변수의 값을 직렬 모니터에 출력
  
  if(readValue == HIGH)             //입력값에 따라 LED 출력값 제어
    digitalWrite(8, HIGH);          //조건문이 참이라면 HIGH 실행
  else
    digitalWrite(8, LOW);           //조건문이 거짓이라면 LOW 실행
}
  • 슬라이드 스위치가 위에 있을 때는 1번째 단자와 2번째 단자가 연결된 상태이므로, 디지털 7번 핀으로 읽는 값은 접지와 동일한 LOW(0)이다. 
  • 슬라이드 스위치를 아래로 내리면 2번째와 3번째 단자가 연결된 상태이므로, 디지털 7번 핀으로 읽는 값은 저항을 거쳐 전원(5V)에 연결되어 있으므로 HIGH(1)이다.

 


4. PIR 센서(passive infrared sensor)로 현관등 만들기

PIR 센서

: 적외선을 통해 열을 발산하는 물체의 움직임을 감지하는 센서로, 적외선 작동 감지 센서라고도 한다.

PIR 센서의 구조

단자는 세 개로 구성되며, 왼쪽부터 신호, 접지, 전원을 담당한다.

신호는 디지털 입력 핀으로, 값을 읽을 수 있으며, 움직이는 물체가 감지될 경우 HIGH를 반환하고, 그렇지 않을 경우 LOW를 반환한다.

 

Do it! 실습 6-5. PIR 센서로 현관 등 회로 만들기

// C++ code
//
void setup()
{
  Serial.begin(9600);
  
  pinMode(8, OUTPUT);
  pinMode(7, INPUT);
}

void loop()
{
  int readValue=digitalRead(7);
  Serial.println(readValue);     //변수의 값을 직렬 모니터에 출력
  
  if(readValue == HIGH)
    digitalWrite(8, HIGH);
  else
    digitalWrite(8, LOW);
}
  • 감지 범위 밖에 있으면 readValue 값이 LOW이고, 불이 꺼진다.
  • 감지 범위 안에 있으면 readValue 값이 HIGH이고, 불이 켜진다.

 


도전: 푸시 버튼을 슬라이드 스위치처럼 사용해 봐요!

: 푸시 버튼을 슬라이드 스위치처럼 사용한다. 즉, 푸시 버튼을 눌렀다 떼면 LED에 불이 켜지고, 다시 눌렀다 떼면 불이 꺼진다.

풀다운 저항

int flag = 0;                         // 상태를 구분하기 위한 변수, 0으로 초기화

void setup()
{
  pinMode(8, OUTPUT);
  pinMode(7, INPUT);
}

void loop()
{
  int inputValue = digitalRead(7);
  
  if (inputValue == HIGH) {           // 푸시버튼이 눌렸을 때
    if (flag == 0)                    // 꺼짐 상태이면 켜짐 상태로 변경
      flag = 1;
    
  } else {                            // 푸시버튼이 떼어졌을 때
    if (flag == 1) {
      int ledStatus = digitalRead(8); // 현재 LED의 상태를 읽음
      if (ledStatus == HIGH)          // LED의 상태가 켜짐이면 꺼짐으로 변경
        digitalWrite(8, LOW);
      else                            // LED의 상태가 꺼짐이면 켜짐으로 변경
        digitalWrite(8, HIGH);			
      flag = 0;                       // 상태 구분 변수를 초기화
    }
  }
  delay(100);                         // 100ms 지연시간
}
  • int ledStatus = digitalRead(8): 현재 LED의 상태를 읽음