버튼과 디바운싱

한 줄 요약 — 기계 접점은 붙었다 떨어졌다를 수 ms 동안 반복합니다. 하드웨어나 소프트웨어로 걸러야 합니다.


채터링 (chattering)

기계식 스위치는 접점이 닿는 순간 튀면서 수 µs~수십 ms 동안 여러 번 ON/OFF를 반복합니다.

스위치 종류채터링 시간
택트 스위치1~10 ms
토글 스위치5~20 ms
릴레이 접점1~5 ms
마이크로 스위치1~5 ms

결과: 한 번 눌렀는데 여러 번 눌린 것으로 인식됩니다.


하드웨어 디바운싱

1. RC 필터 + 슈미트 트리거

RC 디바운싱 필터 회로도RP10kΩ풀업RF10kΩ필터 저항VDD3.3VCF100nF필터 커패시터VCSWSW_IDEALVPBTNOUTCTLGND
RC 디바운싱 필터워크벤치에서 열기 →
부품어디에 붙나하는 일
RpullR_{pull} (10 kΩ)VCC ↔ 버튼 노드버튼을 안 눌렀을 때 노드를 High로 올린다
버튼그 노드 ↔ GND누르면 노드를 GND로 끌어내린다. 접점이 튀면서 여러 번 붙었다 떨어진다
R (10 kΩ)버튼 노드 ↔ 출력C와 함께 시정수시정수 time constantRC 회로가 목표값까지 63%를 가는 데 걸리는 시간으로, 회로의 빠르기를 한 숫자로 나타냅니다.τ=RC\tau = RC자세히 보기 →를 만든다
C (100 nF)출력 ↔ GND빠른 채터링을 못 따라오게 한다. 출력은 완만하게만 움직인다
슈미트 입력출력 ↔ MCU완만해진 파형을 다시 깔끔한 디지털 에지로 바꾼다
τ=RC=10k×100n=1 ms\tau = RC = 10\text{k}\times100\text{n} = 1\ \text{ms}
기호
tau시정수time constants
C정전용량capacitanceF
R저항resistanceΩ

설계 기준: τ≥\tau \geq 채터링 시간 / 3 정도. 10 ms 채터링이면 τ\tau = 3~10 ms.

⚠️ 슈미트 트리거(Schmitt trigger) 입력이 필수입니다. 일반 CMOS 입력에 느린 에지를 넣으면 문턱 근처에서 발진합니다. 대부분의 MCU GPIO는 슈미트 입력이지만 데이터시트로 확인하세요.

2. RS 래치 (SPDT 스위치)

3단자 스위치와 NAND 래치로 완벽하게 디바운스합니다. 접점이 어느 한쪽에 처음 닿는 순간 래치가 걸려 이후 튐을 무시합니다.

장점: 지연 없음, 완벽 단점: SPDT 스위치 필요, 부품 증가


소프트웨어 디바운싱

1. 지연 후 재확인

if (읽기() == 눌림) {
    delay(20ms);
    if (읽기() == 눌림) {
        // 확정
    }
}

간단하지만 blocking이라 실시간 시스템에 부적합합니다.

2. 주기적 샘플링 + 카운터 (권장)

// 1 ms 타이머 인터럽트에서
if (읽기() == 눌림) {
    if (count < THRESHOLD) count++;
} else {
    if (count > 0) count--;
}
state = (count >= THRESHOLD);

비블로킹이고 노이즈에도 강합니다. THRESHOLD를 20으로 잡으면 20 ms 디바운싱입니다.

3. 시프트 레지스터 방식

history = (history << 1) | 읽기();
if ((history & 0xFF) == 0xFF) 눌림_확정();
if ((history & 0xFF) == 0x00) 뗌_확정();

연속 8회 같은 값일 때만 인정합니다.


⚖️ 부품 트레이드오프

방식✅ 좋아지는 것⚠️ 나빠지는 것
RC + 슈미트하드웨어에서 해결, CPU 부담 0, 노이즈도 함께 제거부품 2개, 지연, 커패시터 방전 전류
RS 래치지연 없음, 완벽SPDT 스위치 + 게이트 필요
소프트웨어 (카운터)부품 0, 유연(임계값 조정)CPU 자원, 노이즈 펄스가 GPIO에 그대로 들어옴
소프트웨어 (지연)가장 간단블로킹, 실시간성 저하

💡 측정 시스템에서는 하드웨어 RC를 권장합니다. 이유는 디바운싱보다 노이즈 필터링 때문입니다. 긴 배선(trace)의 버튼은 안테나가 되어 노이즈를 주워오는데, RC 필터가 그것도 함께 막아줍니다.


🔌 실제 쓰임새

상황권장
일반 UI 버튼소프트웨어 (카운터)
긴 배선의 버튼RC 필터 필수 (노이즈)
인터럽트로 받는 버튼RC 필수 (인터럽트가 여러 번 걸림)
안전 정지 스위치하드웨어 + 소프트웨어 이중
로터리 엔코더RC + 상태 머신
릴레이 접점 입력RC + 광절연 고려

⚠️ 인터럽트로 버튼을 받을 때는 반드시 하드웨어 디바운싱을 하세요. 채터링이 인터럽트를 수십 번 발생시켜 시스템이 마비될 수 있습니다.


시뮬레이션으로 확인

RC 디바운싱 필터 회로도RP10kΩ풀업RF10kΩ필터 저항VDD3.3VCF100nF필터 커패시터VCSWSW_IDEALVPBTNOUTCTLGND
RC 디바운싱 필터워크벤치에서 열기 →
# examples/10-mcu-interfacing/debounce-rc.yaml
meta:
  name: RC 디바운싱 필터
  lesson: docs/10-mcu-interfacing/02-debouncing.md
  note: 채터링을 펄스열로 모사하고 RC가 걸러내는지 본다
components:
  - {ref: VDD, type: vdc, value: 3.3}
  - {ref: RP,  type: r, value: 10k,  label: 풀업}
  - {ref: RF,  type: r, value: 10k,  label: 필터 저항}
  - {ref: CF,  type: c, value: 100n, label: 필터 커패시터}
  - {ref: SW,  type: sw, model: SW_IDEAL}
  - {ref: VC,  type: vpulse, params: {v1: 0, v2: 5, td: 1m, tr: 1u, tf: 1u, pw: 0.2m, per: 0.5m}}
nets:
  VP:  [VDD.p, RP.1]
  BTN: [RP.2, SW.1, RF.1]
  OUT: [RF.2, CF.1]
  CTL: [VC.p, SW.cp]
  GND: [VDD.n, SW.2, SW.cn, CF.2, VC.n]
analyses:
  - {type: tran, tstep: 10u, tstop: 10m}

BTN은 빠르게 튀지만 OUT은 완만하게 변하는 것을 확인하세요.


⚠️ 이상과 실제의 차이

이상실제
접점이 즉시 붙음수 ms 채터링
채터링 시간이 일정스위치 개체·마모·온도에 따라 변동
RC만으로 충분슈미트 입력이 없으면 발진
버튼은 노이즈원이 아님긴 배선은 안테나, ESD 유입 경로

연습문제

문제 1. 채터링 15 ms인 스위치에 RC 디바운싱을 설계하세요. RR = 10 kΩ이면 CC는?

연습 10-02-1 — 채터링 15 ms 를 RC 로 없애기 회로도R110kΩ풀업VDD3.3VC12.2µF디바운스VSW누름 동작SW1SW_IDEAL스위치VPPINCTLGND
연습 10-02-1 — 채터링 15 ms 를 RC 로 없애기워크벤치에서 열기 →
풀이

τ≥5\tau \geq 5 ms 정도로 잡으면:

C=τR=5×10−3104=0.5 μFC = \frac{\tau}{R} = \frac{5\times10^{-3}}{10^4} = 0.5\ \mu\text{F}
기호
mu이동도mobilitym²/V·s
tau시정수time constants
C정전용량capacitanceF
R저항resistanceΩ

470 nF 또는 1 µF 선택.

⚠️ 너무 크게 하면 버튼 반응이 느껴질 정도로 느려집니다. 50 ms를 넘지 않게 하세요.

문제 2. 1 ms 타이머로 소프트웨어 디바운싱을 합니다. 20 ms 디바운싱을 원하면 카운터 임계값은? 그리고 이 방식의 장점은?

exercises/10-02-debounce-20ms.yaml
풀이

임계값 = 20 (1 ms × 20 = 20 ms)

장점:

  • 비블로킹 — CPU가 다른 일을 할 수 있음
  • 노이즈 내성 — 단발 노이즈 펄스는 카운터를 조금 올릴 뿐 임계값에 도달하지 못함
  • 히스테리시스(hysteresis)히스테리시스 hysteresis켜지는 문턱과 꺼지는 문턱을 일부러 벌려 두어, 경계에서 덜덜 떠는 것을 막는 장치입니다.자세히 보기 → 효과 — 올릴 때와 내릴 때 임계값을 다르게 하면 더 안정
  • 임계값을 런타임에 조정 가능

개선: 상승/하강 임계값을 다르게 (예: 눌림 20, 뗌 5) 하면 반응이 빠르면서도 안정적입니다.


이전 ← 01 GPIO 입출력 | 다음 → 03 ADC 입력 설계