제목 : 아두이노 INPUT, OUTPUT 핀의 내부
부제 : floating 현상에 대한 이해
아두이노는 AVR 이라는 MCU 를 사용한다.
MCU 는 내부적으로 레지스터라는 일종의 스위치를 가지고 있다. 이 레지스터를 어떻게 조작하느냐에 따라 여러가지 기능을 끄거나 켜서 사용자가 원하는 행동을 하게 한다. 쉽게 예를 들면 전기밥통과 같다. 전기밥통에 쌀을 썻어서 잘 넣어두었다고 밥이 되지는 않는다. 전기를 연결해야 하고 뚜껑을 닫은 다음 밥을 짓는 스위치를 눌러야한다. 그러면 일정시간 열이 들어와 밥이 된다. 일정시간이 지나면 다시 전열장치는 꺼진다. MCU 도 마찬가지다. 조금 더 많을 뿐이다.
위 그림은 아두이노 우노에 사용된 ATMEGA328P 의 데이터시트[
LINK] 80페이지에 있는 그림이다.
이 그림에서 보여지듯 핀을 통해 어떤 데이터가 들어올때와 나갈때 상당히 많은 장치를 통과하게 된다. 이것들을 보통 논리회로라고 부르는데, 이런 논리회로들의 조합으로 일종의 스위치가 만들어진다. 이것을 MCU 에서는 '레지스터' 라고 부른다.
레지스터를 조작함으로 MCU 는 내부적으로 어떤 핀을 통해 데이터가 들어올 것인지 나갈 것인지를 결정한다. 데이터가 나갈때는 (편의상 디지털핀에 국한해서 설명한다) 전원만큼의 전기를 보내거나(VCC, 우노에서는 5V), 혹은 전기가 들어오게(GND, 0V) 한다. 이것을 1과 0으로 표현한다. 즉, OUTPUT 상태의 핀에서는 1 또는 0의 상태가 확실하게 결정되어 있다. 1이 출력되거나 혹은 0이 출력된다. 그래서 OUTPUT 상태에서는 플로팅현상이 없다.
아두이노의 핀이 INPUT 상태인 경우를 생각해보자. INPUT 상태이므로 외부에서 오는 신호를 읽기 위해 준비를 하고 있다. 즉, 핀에 연결된 신호가 0V가 되거나 혹은 5V 가 되어야 한다. 그런데 이때 만약 INPUT 에 연결된 신호선이 단선되었다면 어떻게 될까? 항상 연결되어 읽어들여야 할 값이 순간적이라도 끊어졌을때도 INPUT 핀은 여전히 끊어졌다는 것을 알지못한채 계속 신호를 읽게 된다. 끊어진 선은 0V 일까 5V 일까? 아무것도 아니다. 5V 라 함은 전위차가 기본이 되는 GND 보다 5V 만큼 높다는 것을 의미하고, 0V 라 함은 전원의 기준을 의미한다. GND(0V)는 전기가 흘러들어갈 수 있는 곳이다. 하지만 끊어진 선은 전기를 내보내지도, 받아들이지도 않는다. 그래서 floating 이라는 말을 사용한다. 전기를 받아들이지도 내보내지도 못하는 곳은 언뜻 보면 0V 와 비슷하게 보이지만 실제로 0V가 아니다.
현실적으로 floating 된 곳에 아주 작은 전하가 모일 수 있다. 그래서 floating 된 곳은 0 과 1 을 의미없이 반복하게 된다. 주기적인것도 아니고, 특별한 이유가 있는 것도 아니다. 주변에 생기는 자기장의 변화때문에, 정전기 때문에 이러한 현상이 반복된다. 그래서 INPUT 모드에서는 기본적으로 PULLUP 또는 PULLDOWN 을 해준다. AVR 의 경우 외부에 PULLUP저항을 추가하는 대신 내부에서 레지스터를 건드리는 것 만으로 PULLUP 이 가능하게 해 두었다.
13번 핀을 LED 를 켜고 끄기 위한 OUTPUT 으로 사용할때 AVR 에서 여러가지 레지스터를 다루어야 했던 것과 달리 아두이노는 아래와 같이 간단한 한줄로 설정이 끝난다.
pinMode(13, OUTPUT);
하지만 이 한줄을 컴파일하면 보이지 않는 내부에서는 위에 그려진 여러 레지스터를 조작하게 된다.
INPUT 모드에서 두가지가 있다.
pinMode(12, INPUT);
pinMode(12, INPUT_PULLUP);
두가지는 내부 풀업저항을 사용하느냐 아니냐에 따라 달라진다. 외부에 풀업저항, 혹은 풀다운저항을 사용한다면 pinMode(12, INPUT); 을 사용하면 되고, 내부 풀업을 사용한다면 pinMode(12, INPUT_PULLUP); 을 사용하면 된다.
실제 아두이노 IDE 에서 레지스터의 조작에 관해서는 데이터시트의 75페이지 이하 부분과 아래 링크를 참고하라.