아두이노의 digital I/O핀을 사용하려면 먼저 pinMode() 함수로 각각의 핀을 입력 또는 출력 모드로 사용하겠다고 먼저 선언해 줘야 한다.
그런데 입력으로 사용하는 경우 'INPUT'과 'INPUT_PULLUP' 두가지를 선택할 수 있다.
INPUT_PULLUP의 경우 프로세서 내부에 있는 pull-up 저항을 사용하겠다는걸 알려주는 것이다.
일반적으로 아두이노에 스위치를 연결하는 경우를 생각해 보자. 보통 아래 그림과 같이 외부에 pull-up 저항을 연결해 주는것이 보통이다. 하지만 ATmega168/328의 각 I/O 핀에는 노란색 부분의 회로가 들어있다. 하지만 디폴트는 노란색 부분을 사용하지 않게 되어 있다.
pinMode(7, INPUT);
그래서 INPUT 대신 INPUT_PULLUP을 사용하면 녹색 부분을 사용하게 되어 외부에 별도의 pull-up 저항을 붙이지 않아도 된다. (그림을 보면 알겠지만 아두이노 바깥쪽에 있던 저항이 아두이노 안쪽으로 들어간 것 뿐이다.)
pinMode(7, INPUT_PULLUP);
이렇게 하면 외부에 연결해야 하는 부품이 줄어들고 배선도 간단해진다.
아래는 INPUT_PULLUP으로 두개의 스위치를 연결해 LED 깜빡이는 속도를 조절하는 예제이다.
사진에서 볼 수 있는것 처럼 외부 저항이 없어 케이블이 훨씬 간편해졌다.
#define SW1 8
#define SW2 9
#define LED 13
boolean gLedStat = HIGH;
int gSpd = 500;
void setup() {
pinMode(SW1, INPUT_PULLUP);
pinMode(SW2, INPUT_PULLUP);
pinMode(LED, OUTPUT);
Serial.begin(115200);
}
void loop() {
static unsigned long last = 0;
static unsigned long lastSw = 0;
unsigned long now = millis();
static boolean prev1 = HIGH;
static boolean prev2 = HIGH;
boolean cur;
if ((now - lastSw) >= 10) { // Check switch for every 10ms
cur = digitalRead(SW1);
if ((HIGH == prev1) && (LOW == cur)) {
gSpd -= 100;
gSpd = constrain(gSpd, 100, 2000);
Serial.print("Delay up to ");
Serial.println(gSpd);
prev1 = LOW;
} else if ((LOW == prev1) && (HIGH == cur)) {
prev1 = HIGH;
}
cur = digitalRead(SW2);
if ((HIGH == prev2) && (LOW == cur)) {
gSpd += 100;
gSpd = constrain(gSpd, 100, 2000);
Serial.print("Delay down to ");
Serial.println(gSpd);
prev2 = LOW;
} else if ((LOW == prev2) && (HIGH == cur)) {
prev2 = HIGH;
}
lastSw = now;
}
if ((now - last) >= gSpd) {
gLedStat = !gLedStat;
digitalWrite(LED, gLedStat);
last = now;
}
}