[아두이노] [강좌] 10. 아날로그 기능 - analogRead() 함수
지난 시간까지 디지털 함수에 대해 알아봤으니, 이번 시간엔 아날로그 함수에 대해 알아보도록 하자.
디지털 함수에서 사용할 수 있는 핀은 아두이노의 모든 핀이었던 반면, 아날로그 기능으로 사용할 수 있는 핀은 정해져 있다. 아날로그 입력으로 사용할 수 있는 핀은, 아두이노 보드의 핀들 중 'A'가 붙어있는 핀들. "ANALOG IN"이라는 문구로 표시되어 있다.

그리고 아날로그 출력으로 사용할 수 있는 핀은, 아두이노 보드에 "PWM"이라고 표시된 핀들이다.

메가의 경우 2번 핀부터 13번 핀까지가 아날로그 출력(PWM)으로 사용할 수 있는 핀이며, 우노의 경우에는 “Digital”이라고 표시된 핀들 중 앞에 ‘~’가 붙은 핀(3, 5, 6, 9, 10, 11번 핀)이 PWM 출력 핀이다.
난 '메가' 보드를 사용하기 때문에 16개의 아날로그 입력 핀과 12개의 아날로그 출력 핀을 가지고 있다.
핀의 개수는 보드의 종류마다 다르고, 번호도 다를 수 있으므로 잘 확인하자.
그럼 우선 '아날로그'가 뭔지에 대해서 간단히 설명을 하자면.
디지털 함수를 설명할 때, 아두이노의 모든 기능은 0(LOW) 또는 1(HIGH)로 이루어 진다고 설명했었다. 아두이노 뿐 아니라 모든 전자 기기들이 그렇다고. 하지만 전자 기기 외의 다른 모든 것들은 사실 0과 1로만 이루어지는 것이 아니다.
예를 들면 빛. 소리. 냄새. 뭐 이런 것들. 0과 1 만으로는 이루어지지 않는 모든 신호들을 ‘아날로그 신호’라고 봐도 좋다.
아두이노에서 말하는 ‘아날로그’는 '0'과 '1'이 아닌, 연속된 값들? 이라고 설명해야 하나? 이어진 값들, 이라고 설명해야 하나? -_-??? 연속된 값의 변화?? 음, 이게 제일 있어 보이네. 0과 1 사이에서 연속적으로 변화하는 신호를 말한다.
다음은 네이버 지식인에 "아날로그 디지털"이라고 검색하면 나오는 그림이다. 내 블로그는 네이버 블로그고, 이 이미지는 네이버 백과사전에 나오는 이미지니까 저작권 따위 걸리지 않겠지..?

출처: 네이버 백과사전
(이라고 소심하게 달아본다)
그림으로 보니 "연속된 값의 변화"라는 게 왠지 딱 맞는 말 같다. +_+!!
아날로그 신호로 가장 쉽게 들 수 있는 예는 바로 '소리'이다. 소리에 대한 아날로그 파형은 이퀄라이져 프로그램이나 녹음기 어플 등에서 심심찮게 찾아볼 수 있다. "쿵쿵짝" 할 때마다 커지고 작아지던 그래프들 말이다.
아무튼, 이런 게 아날로그 신호라는 말. 음??
앞으로 우리가 사용하게 될 많은 센서 중에 상당한 수의 센서들이 이러한 아날로그 신호로 값을 전달한다. 소리 센서, 가스 센서, 빛 센서 등등. 소리나 빛을 0과 1만으로 나타낼 수는 없으니까.
그런데 이런 센서들의 값을 확인하려니까 어떻게 읽어야 될지를 모르겠더라고. 도대체 저 아날로그 그래프가 나타내는 값이 뭐냐는 말이지. 커졌다 작아졌다 하고 있다는 거밖에 모르겠잖아.
그래서, 저 아날로그 신호를 우리가, 아니 사실은 아두이노 보드가 알아볼 수 있도록 디지털 값으로 변환해주는 과정을 ADC(Analog-Digital Converter)라고 하며, "ANALOG IN"이라고 표시된 'A'가 붙은 핀들이 ADC 기능을 가지고 있다.
디지털로 변환한다고 해서 읽어온 값이 '0' 또는 '1'의 값으로 변환한다는 뜻은 아니고, 디지털로 표현할 수 있는 값으로 변환한다는 것이 맞는 말일 듯.
간단하게 설명하면, 아두이노 보드에서 받아들일 수 있는 최저 전압(아마도 0V겠지)과 최고 전압(메가(Mega 2560/ADK)의 경우 기본 출력 전압인 5V로 설정되어 있고, analogReferance() 함수로 변경할 수도 있음) 사이를 1024개의 구간으로 나누고, 현재 읽어 들인 아날로그 신호의 전압이 어느 구간에 속하느냐를 알아오는 것이랄까. (아두이노 듀에(Due)의 경우 4096개 구간까지 나눌 수 있다.)
다시 말하면, 소리나 빛을 측정할 수 있는 최저 값을 0, 최고 값을 1023으로 놓고, 현재 측정된 소리나 빛의 세기가 얼마냐,를 계산하는 과정이라고 보면 된다.
다음은 아날로그 신호가 디지털 값으로 변환되는 과정을 간단하게 그림으로 나타낸 것인데, 그냥 이렇구나~ 정도로 보고 넘어가면 된다. ADC의 원리가 뭔지 자세히 몰라도 사용하는 데는 전혀 지장이 없다.

그럼 이제 아두이노 보드를 통해 아날로그 값을 읽어오는 방법을 알아볼까?
int analogRead(pin)
아날로그 값을 읽어오는 함수이다. pin 값에는 아두이노 보드의 'ANALOG IN'이라고 표시된 핀들, 즉 번호 앞에 'A'가 붙어있는 것들이 들어간다.
매개 변수
pin : 아날로그 데이터가 입력되는 핀. 즉, 아날로그 데이터를 읽어올 핀 번호.
핀 번호를 쓸 때,N'A0'라고 앞에 'A'를 붙여서 써도 되고 그냥 ‘0’이라고만 써도 된다. 아두이노에서 디지털 기능을 하는 ‘0’번 핀은 analogRead() 함수에 매개 변수로 올 수 없으므로 자동으로 ‘A0’ 핀이라고 인식한다. (그래도 헷갈리지 않게 'A'를 붙여 쓰는 걸 추천함)
실제 아두이노 내부 코드에서는 'A0'가 숫자로 바뀌도록 구현되어 있지만 자세히 알 필요는 없고, 그냥 아날로그 입력으로 사용하는 핀 번호는 알아보기 쉽게 'A'를 붙여줘야 한다고 기억하자. 혹시 'A0'가 어느 번호로 바뀌는지 궁금한 사람은 맨 마지막에 요약으로 접어놨으니 “*참고”을 참조. |
반환 값
value : 아날로그 값을 디지털로 변환하여 그 수치를 반환한다. 값은 0~1023 사이의 값을 가진다. '듀에(Due)' 등 12비트 ADC를 지원하는 아두이노 보드에서는 0~4095 사이의 값을 반환할 수도 있다. |
analogRead() 함수를 실습해보기 위해서 아날로그 출력을 내는 센서 종류가 있어야 하는데, 소리 센서, 가스 센서, 빛 센서 등 종류가 여러 가지이므로 해당 센서의 스펙을 잘 확인한 후 선택하도록 하자.
센서들 구매 사이트는 참조로 링크 걸어놨는데, 참고만 하도록 하고 실제 본인이 필요한 센서로 신중히 구매하시길.
ADC 방식을 사용하는 어떤 센서라도 상관없다. 난 조도 센서(빛 센서)를 가지고 설명하도록 하겠다.
조도 센서의 핀은 3개로, 전원(VCC), 접지(GND), ADC 데이터 출력(센서 입장에선 출력, 아두이노 입장에선 입력) 핀으로 이루어져 있다. 전원은 3.3V에 연결해야 하는지 5V에 연결해야 하는지를 잘 확인한 후 연결하자. 센서마다 다르고, 전원을 잘못 연결하면 ADC 값이 다르게 나오니까.
내가 가진 조도 센서는TEMT6000모듈로, 5V의 전원을 사용한다. ADC 데이터 핀은 ‘A0’번 핀에 연결해 주었다. 연결 그림은 다음을 참고하자.

센서마다 핀의 순서가 다를 수 있으므로 유의. SIG 핀이 ‘A0’ 핀에 연결되었다.
그리고 스케치 툴의 예제 중 “AnalogReadSerial” 예제를 열자. 스케치 툴의 ‘파일→예제→01.Basics→AnalogReadSerial’ 선택.
주석문을 제외하고 소스만 적으면 다음과 같다.
AnalogReadSerial.ino |
void setup() { Serial.begin(9600); }
void loop() { int sensorValue = analogRead(A0);
Serial.println(sensorValue); delay(100); } |
새로 나온 analogRead() 함수를 제외하고는 모두 이해할 수 있는 쉬운 소스 코드이다.
그래도 간단하게 설명하자면, setup() 함수에서는 시리얼 모니터 출력을 위한 Serial.begin() 함수를 호출하여 초기화 해주고, loop() 함수에서는 int 타입의 변수 ‘sensorValue’를 선언하여 analogRead() 함수를 이용해 ‘A0’ 핀의 아날로그 입력 값을 읽어와 저장한다. 그리고는 시리얼 모니터에 그 값을 출력. delay() 함수로 100밀리초만큼 딜레이. (쉬엄쉬엄 하라고 1밀리초에서 늘려줬음)
업로드 한 후 실행해보자.
아래와 같이 값이 출력되는가?

손으로 센서를 가렸다가 빛을 비췄다가 하면서 값의 변화를 확인해보니, 빛의 세기에 따라 값이 커졌다가 작아졌다가 하는 것을 확인할 수 있다.
이 외에 소리 센서를 사용했다면, 센서에 큰 소리를 냈다가, 작은 소리를 냈다가 하면서 값의 변화를 확인할 수 있고, 가스 센서라면 센서 주위에 라이터 등으로 가스를 (조심해서)발생시킨 후 값을 확인해볼 수도 있고, 습도 센서라면 물 묻은 티슈 등으로 확인할 수 있을 것이다.
analogRead()로 읽은 값은 사실 값 자체만으로는 별로 쓸 데가 없고, 이 값을 이용해서 다른 센서나 모듈 등을 동작시키는 데 주로 사용된다. 예를 들면, 위에서 실습했던 조도 센서를 이용해서 어두운 정도에 따라 LED의 밝기를 바꾼다던지. 또는 가스 센서의 값을 읽어 일정 값 이상의 값이 감지되면 알람을 울려 경고음을 낸다던지.
지금은 우리가 LED의 밝기를 조절한다거나 부저를 울리는 실습을 아직 안 해서 이번 강좌에서는 해보지 못하지만, analogWrite() 함수 실습이 끝나면 두 개를 섞어 쓰는 간단한 실습을 진행하도록 하자.
그럼 이번 강좌는 여기서 끝! 안녕~