로그인회원가입

[MicroPython] 라이브러리 없이 IR 수신기(적외선 센서) 제어하기 – 원리부터 실전까지

안녕하세요, Mana’s Lab입니다!

오늘은 ESP32-C3나 ESP32-S3 같은 보드에서 흔히 사용하는 IR 수신기(적외선 센서)를 다뤄보려고 합니다. 보통은 만들어져 있는 라이브러리를 가져다 쓰지만, 외부 라이브러리 의존성을 줄이고 싶거나 통신 프로토콜의 원리를 직접 파악하고 싶을 때가 있습니다.

오늘은 라이브러리 없이 마이크로파이썬(MicroPython)의 기본 기능만으로 리모컨 신호를 읽어오는 방법을 알아보겠습니다.

1. IR 수신기의 하드웨어 연결

가장 흔하게 사용되는 IR 수신 모듈(예: VS1838B)은 3개의 핀으로 구성되어 있습니다.

연결 방법은 매우 간단합니다:

  • VCC: 보드의 3.3V (또는 5V)
  • GND: 보드의 GND
  • OUT (또는 S): ESP32의 GPIO 핀 (이번 예제에서는 GPIO 4를 사용합니다)

주의: IR 수신기의 OUT 핀은 평소(대기 상태)에 **HIGH(1)**를 유지하다가, 적외선 신호가 들어오면 **LOW(0)**로 떨어지는 ‘Active Low’ 방식을 사용합니다.

2. NEC 프로토콜의 이해

우리가 집에서 흔히 쓰는 TV나 셋톱박스 리모컨의 90% 이상은 NEC 프로토콜을 사용합니다. 리모컨 버튼을 누르면 적외선이 특정 시간 간격으로 깜빡이며 데이터를 전송하는데, 그 규칙은 다음과 같습니다.

  1. Lead Code (시작 신호): 9ms 동안 LOW, 이후 4.5ms 동안 HIGH를 유지하며 “이제 데이터 보낸다!”라고 알립니다.
  2. Data (32비트): 총 32개의 0과 1을 보냅니다.
    • 숫자 ‘0’: 560µs LOW + 560µs HIGH
    • 숫자 ‘1’: 560µs LOW + 1.69ms HIGH (HIGH 구간이 훨씬 깁니다)
  3. End (종료 신호): 짧은 펄스로 통신을 마칩니다.

라이브러리 없이 이 신호를 해독하려면, OUT 핀의 상태가 변할 때마다 시간차(펄스의 길이)를 마이크로초(µs) 단위로 정밀하게 측정하기만 하면 됩니다.

3. 마이크로파이썬 코드 (라이브러리 없이 구현)

인터럽트(IRQ)를 사용하면 메인 루프를 방해하지 않고 핀의 상태 변화(RISING/FALLING)가 일어난 정확한 시간을 배열에 기록할 수 있습니다.

아래 코드를 ESP32-C3 등에 업로드하고 리모컨을 눌러보세요.

Python

무료 회원가입 하고 코드 보기

코드 리뷰 및 활용 포인트

이 방식의 핵심은 time.ticks_us()time.ticks_diff()를 이용해 상태가 변한 시점 간의 마이크로초 단위 시간차를 구하는 것입니다.

출력된 durations 배열을 확인해보면, 대략 9000, 4500, 560, 1690, 560, 560... 과 같은 숫자들의 나열을 볼 수 있습니다. 이 숫자들을 if/else 문으로 01로 치환한 뒤 비트 연산을 해주면, 라이브러리 없이도 완벽한 나만의 IR 디코더를 만들 수 있습니다.

단순한 제어가 필요할 때 무거운 라이브러리를 통째로 올리는 대신, 이처럼 펄스 폭을 직접 측정하는 방식을 사용해보시면 임베디드 하드웨어의 통신 원리를 이해하는 데 큰 도움이 될 것입니다.

  • 응용 예제 코드: 리모콘으로 LED 램프를 토글식으로 켜고 타이머로 30초만 켜짐. 자동 모드로 랜덤으로 깜빡이는 촛불 모드로 5초 켜기
무료 회원가입 하고 코드 보기
무료 회원가입 하고 코드 보기

코멘트

답글 남기기