[참고 자료]
https://makeabilitylab.github.io/physcomp
https://mazdah.tistory.com/685
https://www.arduino.cc/en/Tutorial/Foundations/DigitalPins
Tact Switch : '버튼' 또는 'Key' 라고 불리며, 스위치를 누르면 회로가 연결되고, 손을 떼면 회로가 끊어진다.
1, 2번 핀과 3, 4번 핀은 스위치 누름 여부와 상관없이 서로 연결되어 있다.
스위치를 누르면 1, 2, 3, 4번 핀이 모두 연결된다.
아두이노와 연결
1) 배경 지식
텍트 스위치는 아두이노의 디지털 핀에 연결하여 사용할 수 있다.
Setup() 함수 안에 pinMode() 함수를 이용하여 사용하고자 하는 핀을 입력(INPUT)으로 지정한다.
사실, 아두이노의 각 핀은 기본값으로 'INPUT' 이 설정되어 있기 때문에, pinMode() 함수를 사용하지 않아도 큰 문제는 없지만 가독성과 명확성을 위해 넣어주는 것이 좋다.
아두이노의 핀을 입력으로 설정하면 '하이 임피던스(High Impedance )' 상태가 되어, 전류가 아주 미약하게 흐른다.
디지털 회로에서 해당 Logic 이 출력을 내보내지 않을 때는 하이 임피던스 상태로 두게 된다. 다시 말해, 출력 임피던스를 매우 높은 값이 되게 한다는 것이고, 그 말은 로직의 출력에 매우 높은 임피던스의 저항이 직렬로 연결된 것처럼 동작하게 한다는 뜻이다.
결과적으로는 전기 회로 상에서 거의 단절된 것과 같은 상황이 만들어진다.
어떤 입력 단자에 연결되어 있는 모든 출력 단자가 동시에 하이 임피던스 상태가 되면 전기적으로 입력 단자에 아무것도 연결되어 있지 않는 것과 동일한 상태가 되어서 안정적인 논리 상태를 구현할 수 없다. 다시 말해 플로팅 상태에 빠진다. 그렇기 때문에 하이 임피던스 상태를 수반하는 신호선은 풀업 또는 풀다운을 하는 것이 일반적이다.
출력 상태로 설정된 핀은 '로우 임피던스(Low Impedance)' 상태를 갖는다.
# Low Impedance : 많은 양의 전류를 외부로 공급할 수 있는 상태
* 최대 40mA까지의 양의 전류를 공급하면 소스(source)
* 최대 40mA까지의 음의 전류를 공급하면 싱크(sink)
플로팅 현상 : 신호가 0(LOW) 과 1(HIGH) 사이의 애매한 위치에 떠 있어 정확한 값을 읽어들이지 못함
일반적으로 디지털 회로의 입력 단자는 내부 임피던스가 높기 때문에 입력 단자가 어디에도 연결되어 있지 않으면 근처의 정전기나 전자기 유도에 의하여 예상할 수 없는 전압이 인가될 수 있다. 그렇기 때문에 케이블에 의해 외부로 연결되는 입력 단자는 커넥터가 잘못 연결되어 비정상적인 전압이 인가되지 않도록 해야 한다.
위 그림에서 스위치가 열려 있을 때 INPUT에 들어가는 신호는 LOW일 것 같지만 사실은 HIGH인지 LOW인지 정확히 알 수 없다.
이 현상을 없애기 위해서는 풀업(Pull-up) 저항 또는 풀다운(Pull-down) 저항을 사용해야 한다.
풀업 저항이 노이즈에 더 좋기 때문에, 풀다운 저항보다는 풀업 저항을 많이 사용한다.
풀업 저항은 일반적으로 10kΩ ~ 100kΩ 까지의 값을 가장 많이 쓴다.
풀업 저항을 계산하는 방법은 마이크로컨트롤러의 I/O핀이 받아 들일수 있는 전류의 양을 확인해야 한다.
예를 들어, 5V의 전압을 준 상태에서 1mA의 전류가 필요하다면, 옴(Ω)의 법칙(V = I X R)에 의해 5kΩ이 필요하다.
R = 5V / 0.001A
0
0
풀업 저항(Pull-up) : 저항을 전원(VCC) 쪽에 붙여서 플로팅 현상을 해결하는 방법
전류는 스위치가 열려 있을 때, 전원에서 입력(INPUT) 핀 쪽으로 진행한다. 따라서 INPUT 핀의 값은 HIGH(1) 이다.
길이 하나 밖에 없기 때문에 INPUT 핀은 VCC를 기준으로 전위차를 측정한다.
INPUT 핀은 현재 '하이 임피던스' 상태이다. INPUT 핀에 매우 높은 저항(100MΩ 정도)이 연결되어 있다고 생각하면 된다. 스위치가 열려 있을 때는 풀업 저항과 하이 임피던스가 직렬로 연결되어 있는 구조이기 때문에 풀업 저항이 너무 크게 되면 INPUT 핀에 상대적으로 낮은 전압이 걸리게 된다.
# 두 개 이상의 저항이 직렬 연결된 전기 회로에서는 저항의 값에 비례하여 전압이 걸린다.
그렇게 되면 HIGH가 되는 기준 전압(약 3V 이상)을 충족할 지 못할 수도 있기 떄문에 풀업 저항에는 너무 큰 값의 저항을 사용하면 안된다.
풀업 저항을 적정 값의 저항(10kΩ)으로 달아주었다면, INPUT 핀에 걸린 전압은 기준 전압 이상이되므로 INPUT 핀은 HIGH 값을 감지한다.
스위치가 닫혀 있을 때, 전류는 전원(VCC)에서 그라운드(GND) 쪽으로 진행한다. 따라서 INPUT 핀의 값은 LOW(0) 이다.
스위치를 닫으면, 전류가 흐를 수 있는 두 가지 길이 생기는데 이 중 전류는 가장 쉬운 길로 가려고 한다.
스위치가 닫히면 하나의 저항(INPUT 핀의 하이 임피던스)을 가진 두 개의 길이 생기는데 전류는 저항이 없는 길(GND 쪽)로만 이동하려하므로 저항이 있는 INPUT 핀 쪽으로는 전류가 흐르지 않는다.
스위치가 닫혀 있을 때는 전원(VCC), 풀업 저항, GND가 직렬로 연결되어 있는 구조이기 때문에 풀업 저항이 너무 작으면 VCC와 GND 사이에 과도한 전류가 흐를 수 있다. 이 과전류는 아두이노 회로를 태워버릴 수 있기 때문에 풀업 저항으로 너무 작은 값의 저항을 사용하지 않는다.
INPUT 핀은 전위가 높은 VCC 쪽보다는 전위가 낮은 GND를 기준으로 전위차를 측정한다.
이 때, INPUT 핀에 걸린 전압은 1.5V 이하가 되므로 INPUT 핀은 LOW 값을 감지한다.
아두이노에는 풀업 저항이 내장되어 있어 스케치 코드를 이용하면 소프트웨어적으로 풀업 저항을 사용할 수 있다.
pinMode(pin number, INPUT_PULLUP);
풀업 저항은 스위치가 ON 일 때, 입력 값은 LOW(0) 이다.
풀업 저항은 스위치가 OFF 일 때, 입력 값은 HIGH(1) 이다.
풀다운 저항(Pull-down) : 저항을 그라운드(GND) 쪽에 붙여서 플로팅 현상을 해결하는 방법
스위치가 열려 있을 때, 전류의 방향은 INPUT 핀에서 그라운드(GND)로 진행한다. 따라서 INPUT 핀의 값은 LOW(0) 이다.
길이 하나 밖에 없기 때문에 INPUT 핀은 GND를 기준으로 전위차를 측정한다.
INPUT 핀보다 GND는 전위가 낮기 때문에 LOW 값을 감지한다.
스위치가 닫혀 있을 때, 전류는 전원(VCC)에서 INPUT 핀 방향으로 진행한다. 따라서 INPUT 핀의 값은 HIGH(1) 이다.
스위치를 닫는 순간 전류가 흐를 수 있는 두 가지 길이 생긴다.
두 가지 이상의 길이 있으면 전류는 가장 쉬운 길로 가려고 한다.
스위치가 닫히면 저항(풀다운 저항, INPUT 핀의 하이 임피던스)을 가진 두 개의 길이 생기므로 일종의 병렬 회로가 만들어진다.
병렬 회로에서는 전압이 동일하게 걸리기 때문에 INPUT 회로에는 기준 전압 이상의 전압이 걸리게 된다.
이 때, INPUT 핀에 걸린 전압은 기준 전압(3V) 이상이 되므로 INPUT 핀은 HIGH 값을 지한다.
풀다운 저항은 스위치가 ON 일 때, 입력 값은 HIGH(1) 이다.
풀다운 저항은 스위치가 OFF 일 때, 입력 값은 LOW(0) 이다.
위에서 알아본 바와 같이 아두이노의 디지털 핀 또는 아날로그 핀에서는 플로팅 현상으로 인해 정확한 입력 값을 측정할 수 없다.
이를 해결하기 위해서는 풀업 또는 풀다운 저항을 사용해야 한다.
그림과 같이 브레드보드에 텍트 스위치와 10kΩ 저항을 풀다운 저항 방식으로 끼워넣어준다.
LED의 긴 다리는 아두이노의 13번 핀에, 짧은 다리는 아두이노의 GND에 연결한다.
저항은 220Ω을 사용한다.
2) Sketch Code
const int INPUT_BUTTON_PIN = 2;
const int OUTPUT_LED_PIN = 13;
void setup()
{
pinMode(INPUT_BUTTON_PIN, INPUT);
pinMode(OUTPUT_LED_PIN, OUTPUT);
Serial.begin(9600);
}
void loop()
{
int buttonVal = digitalRead(INPUT_BUTTON_PIN); // returns 0 (LOW) or 1 (HIGH)
if(buttonVal == HIGH){
Serial.println("Button pressed!");
}else{
Serial.println("Button *NOT* pressed");
}
digitalWrite(OUTPUT_LED_PIN, buttonVal);
delay(5); // small delay
}