아두이노 기초 강좌 5 – digitalRead, digitalWrite
아두이노 기초 강좌는 아두이노를 처음 접하시는 전자분야 비 전공자를 위한 강좌입니다. 이해를 위해서는 간단한 프로그래밍 지식이 필요할 수 있습니다. 프로그래밍이 처음이라면 [아두이노 프로그래밍 기초] 강좌를 먼저 읽으시길 권해 드립니다.
=============================================================
.
아두이노의 기본 구조를 익혔다면 이제 아두이노에 수십개 달린 핀(pin)들을 어떻게 사용하는지에 대해서 알아볼 차례입니다. 이번 회에서 실험해 볼 대상 핀은 아두이노에 D2 ~ D13으로 프린트 되어 있는 디지털 핀들입니다. 아두이노에서는 이 디지털 핀들에 들어오는 전압(0V~5V)을 읽을 수도 있고, 이 핀으로 전압을 출력할 수도 있습니다. 이런 동작을 하기위해 사용되는 함수가 digitalRead, digitalWrite 함수입니다. 이름처럼 on(=5V, HIGH), off(=0V, LOW) 두 가지 상태를 읽고 쓸수 있는 함수입니다. 예제를 통해 어떻게 동작하는지 보시죠.
1. 버튼 예제
이번 장에서는 버튼을 눌렀을 때 이를 감지하고 그 결과를 Serial Monitor로 출력하는 예제를 보도록 하겠습니다. 아두이노 공식 홈페이지에도 소스와 매뉴얼이 있으니 참고하시면 됩니다.
http://arduino.cc/en/Tutorial/DigitalReadSerial
아두이노 회로를 위와 같이 구성해서 테스트 할 수 있습니다.
버튼 아래쪽에 달려 있는건 10k Ohm 저항입니다. 5V – GND 즉 +, – 가 아무런 중간 장치 없이 직접 연결되지 않도록 달아둔거라 생각하심 됩니다. 버튼 아래쪽 면에 있는 다리 2개를 5V, GND(그라운드) 로 연결해 두고, 위쪽 면에 있는 다리를 2번 핀에 연결해 뒀습니다. 버튼은 한쪽면에 있는 다리끼리는 연결되어 있고, 서로 다른면의 다리는 버튼을 눌러야만 연결됩니다. 그래서… 버튼이 눌려지지 않은 상태에서는 2번 핀에 아무것도 연결이 안되므로 2번 핀의 입력을 읽었을 때 off 상태(0, 0V, LOW) 로 읽히고, 버튼을 누르면 5v 전류가 2번 핀으로 연결되므로 on 상태로(1, 5V, HIGH) 읽힙니다.
2. digitalRead 예제 소스
어떻게 동작되는지 대강의 흐름을 파악했으니 이걸 구동하는 예제 소스를 보시겠습니다. 아두이노 기본 예제 중 하나인 DigitalReadSerial 예제입니다.
/* DigitalReadSerial Reads a digital input on pin 2, prints the result to the serial monitor This example code is in the public domain. */ // digital pin 2 has a pushbutton attached to it. Give it a name: int pushButton = 2; // the setup routine runs once when you press reset: void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); // make the pushbutton's pin an input: pinMode(pushButton, INPUT); } // the loop routine runs over and over again forever: void loop() { // read the input pin: int buttonState = digitalRead(pushButton); // print out the state of the button: Serial.println(buttonState); delay(1); // delay in between reads for stability }
말씀드렸다시피 2번 핀(D2)을 통해서 버튼이 눌러졌는지 확인할 겁니다. 그래서 pushButton 변수에 2를 넣어뒀습니다.
이제 초기화를 담당하는 setup() 함수를 보시죠. 초기화 할 때 해야할 작업은 2가지입니다. Serial 통신을 통해 PC로 현재 상태를 보내줘야 하기 때문에 이 기능을 담당하는 Serial 클래스를 초기화 해야 합니다. 보통 기본 9600 속도로 초기화 하며 아래와 같이 사용합니다. PC에서 실행하는 아두이노 Serial Monitor도 같은 속도로 설정되어야 합니다.
Serial.begin(9600);
begin 함수가 Serial 통신을 초기화 하기 위해 Serial 클래스 안에 정의되어 있는 함수입니다. 이걸 호출하면 Serial 통신을 통해 PC와 통신할 준비는 끝납니다.
앞서서 디지털 핀은 on, off 상태를 읽을수도 쓸수도 있다고 했습니다. 그래서 어떤 모드로 사용할 것인지를 미리 지정해 줘야 합니다. 아래와 같이 pinMode 함수를 이용해서 설정할 수 있습니다.
pinMode(pushButton, INPUT);
pushButton으로 지정된 2번 핀을 INPUT(읽기) 모드로 사용하겠다는 뜻입니다. 출력 모드로 사용하고 싶다면 OUTPUT을 대신 넣으면 되겠죠.
이제 계속 반복해서 실행되는 loop 함수를 보시죠. 여기서는 버튼 상태를 읽고 그 값을 PC로 전송해 주는 작업을 해야겠습니다.
int buttonState = digitalRead(pushButton);
위 라인이 버튼의 상태를 읽는 라인입니다.
digitalRead 함수는 이름처럼 on/off 상태를 확인할 수 있게 해주는 함수죠. 이 함수는 핀 번호값을 전달하면 해당 핀이 on인지 off 인지 결과를 출력해줍니다. 위 코드에서는 digitalRead 가 출력하는 on/off 결과를 다시 buttonState라는 변수에 저장을 합니다.
digitalRead가 출력하는 결과는 정수로 전달하도록 정해져있어서, 이 값을 받아서 저장하는 buttonState라는 변수를 정수형(int)으로 만들었습니다. 실제로 digitalRead 함수는 지정한 핀의 상태가 off 상태일 때(입력되는 전압이 0V 일 때) 0을 전달하고, on 상태일 때(입력되는 전압이 5V) 일 때 1을 전달해줍니다. 0과 1로 표현하면 헷갈릴 우려가 있어서 아두이노에서는 이걸 LOW(0), HIGH(1) 라고 상수로 정의해 뒀습니다.
자 이제 buttonState 라는 변수에 저장된 0과 1값을 (LOW, HIGH) PC에 전달해줄 차례입니다.
Serial.println(buttonState);
Serial 클래스에는 println 이라는 함수가 미리 정의되어 있습니다. Serial.println(출력할 값) 형태로 호출하면 PC로 전송해줍니다. 0 또는 1이 전송되겠네요.
delay(1); // delay in between reads for stability
위와 같이 마지막에 delay 함수가 사용되었습니다. 주석에 적혀있다시피 굉장히 빠른 속도로 loop 안에 정의된 작업이 반복되기 때문에 안정성을 위해 잠시 아두이노가 멈추도록 하는겁니다. 1 이라고 적은 것은 1/1000 초 동안 쉬도록 하기 위해서입니다. 아두이노는 오로지 하나의 thread(쓰레드, 작업하는 사람) 만을 사용하기 때문에 delay 함수로 멈추게되면 정해진 시간동안 다른 어떤 작업도 할 수가 없습니다. 그럼에도 delay 는 매우 흔하게 사용되는 유용한 함수입니다.
이제 소스코드 컴파일 – 업로드를 마치고 아두이노 개발환경에서 Serial Monitor 창을 켜보시죠. 그러면 [0000000000000000000] 이 빠르게 출력될 겁니다. 스위치를 누르면 [000000011000000] 이렇게 1(HIGH)이 누른 시간만큼 출력될 겁니다.
3. digitalWrite 예제 소스
아두이노 디지털 핀을 읽는 방법을 알아봤으니 이제 쓰는 방법을 알아보겠습니다. 기억하시겠지만 아두이노 13번 핀은 아두이노가 자체적으로 가진 LED가 연결되어 있습니다. 이제 버튼을 누르면 PC에서 확인하는 대신 아두이노의 LED를 통해 불빛으로 보여주도록 수정해 보겠습니다. 아두이노가 가진 LED를 이용할 예정이니 위에서 설정한 회로를 그대로 이용하시면 됩니다.
/* DigitalReadSerial Reads a digital input on pin 2, prints the result to the LED This example code is in the public domain. */ // digital pin 2 has a pushbutton attached to it. Give it a name: int pushButton = 2; // LED on Arduino int led = 13; // the setup routine runs once when you press reset: void setup() { // make the pushbutton's pin an input: pinMode(pushButton, INPUT); // set led pin as output: pinMode(led, OUTPUT); } // the loop routine runs over and over again forever: void loop() { // read the input pin: int buttonState = digitalRead(pushButton); // print out the state of the button: digitalWrite(led, buttonState); delay(1); // delay in between reads for stability }
바뀐 부분만 이해를 하시면 되겠습니다. 먼저 이전 예제에서 사용했던 Serial 클래스의 함수들이 모두 빠졌습니다. PC가 아니라 LED로 알려줄려고 하니까요. 대신 led 핀 번호를저장하는 변수가 사용되었습니다.
int led = 13;
setup 함수를 보시죠. 디지털 13번 핀을 통해 LED를 on, off 제어할 예정입니다. 13번 핀의 출력을 상황에 따라 0V, 5v로 바꿔야겠죠. 따라서 pin mode 를 OUTPUT으로 초기화를 해줘야 합니다.
// set led pin as output: pinMode(led, OUTPUT);
이제 기존에 PC로 출력하던 코드를 LED로 출력하도록 바꾸면 됩니다. Serial.println 으로 출력하던 부분을 digitalWrite 함수로 교체하면 됩니다.
// print out the state of the button: digitalWrite(led, buttonState);
digitalWrite 함수는 핀 번호에 해당하는 핀을 on, off 상태(0V, 5V) 로 바꿔주는 함수입니다. 앞서 digitalRead 함수를 통해 버튼 상태를 읽어서 buttonState 변수에 저장했습니다. 그럼 buttonState 변수에는 on(=HIGH, 5V), off(=LOW, 0V) 값이 저장되어 있습니다. 이걸 그대로 digitalWrite 함수에 사용하면… 버튼 상태가 누름(=HIGH, 5V) 일 때 그대로 입력값으로 사용되므로 LED가 켜지게 됩니다. 뗀 상태일 때는 반대로 될거구요. 위 라인을 굳이 복잡하게 바꾸면…
if(buttonState == HIGH) { digitalWrite(led, HIGH); } else { digitalWrite(led, LOW); }
이렇게 됩니다.
이제 직접 테스트를 해보시면. 버튼의 입력 상태를 LED로 확인하실 수 있으실겁니다!!
# 강좌의 내용이 명확하지 않거나 이해가 힘든 부분이 있으시면 댓글로 말씀해 주세요. 해당 부분을 지속적으로 업데이트 하겠습니다.
=============================================================
이 문서는 작성자의 동의없이 개인적인 목적 외의 상업적인 목적으로 활용되어서는 안됩니다.
이 문서의 일부 혹은 전체를 수정, 삭제, 재배포 하여서는 안됩니다.
작성자 : GodsTale (godstale@hotmail.com)