Arduino Nano 적외선 리모컨: 수신부터 재송신까지

Arduino IR Lab · 01

코드 하나를 찾는 대신 수신기, RAW 타이밍, IR LED, 실제 기기 반응을 한 단계씩 분리해 검증한 실기 기록입니다.

● 실기 확인 읽기 약 9분 입문자용 기술 기준일 2026-09-26

리모컨 버튼 하나를 복제하려면 코드 숫자만 알아서는 부족합니다. 수신기가 신호를 받는지, Arduino가 타이밍을 저장하는지, IR LED가 올바른 반송파로 보내는지, 대상 기기가 실제로 반응하는지를 차례로 확인해야 합니다.

이 프로젝트에서는 Arduino Nano 호환 보드에 IR 수신기와 IR LED를 연결하고 수신 → RAW 저장 → 재송신 → 실제 반응 확인까지 진행했습니다. 사례 기기는 Sharp DVD 플레이어였지만 진단 순서는 TV, 오디오, 셋톱박스 프로젝트에도 적용할 수 있습니다.

한눈에 보는 결과

단계확인 방법실제 결과
송신 LED스마트폰 카메라IR LED 점멸 확인
D2 수신 입력초당 GPIO 에지대기 0, 입력 시 35·165·200
프레임 캡처디코드와 RAW 타이밍UNKNOWN 78개 타이밍과 별도 디코드 프레임 확보
RAW 재송신D3에서 38 kHz 송신대상 기기 실제 동작
공개 코드 교차검증3프레임 전송전원 토글과 트레이 열림 확인

보드의 TX done이나 REPLAY_DONE은 송신 루틴 완료를 뜻합니다. 대상 기기의 수신 성공은 화면·전원·트레이 반응으로 따로 확인했습니다.

준비물과 결선

  • Arduino Nano 호환 보드
  • 38 kHz 대역 IR 수신기
  • 투명 IR LED와 전류 제한 저항
  • 브레드보드, 점퍼선, Arduino-IRremote 라이브러리
IR 수신기 OUT ───────────── Nano D2
IR 수신기 VCC ───────────── Nano 5V
IR 수신기 GND ───────────── Nano GND

Nano D3 ── 전류 제한 저항 ── IR LED 애노드(+)
Nano GND ─────────────────── IR LED 캐소드(-)

[조립 사진 삽입 위치]

수신기 핀 순서는 제품마다 다를 수 있습니다. 데이터시트를 먼저 확인하고, 배선을 바꿀 때는 USB 전원부터 분리합니다.

신호 흐름

물리 리모컨 → IR 수신기 → D2 → Arduino Nano → RAW 저장
대상 기기 ← IR LED ← D3 / 38 kHz 송신

Arduino-IRremote는 적외선 신호의 수신·송신과 알려지지 않은 프로토콜의 RAW 타이밍 처리를 지원합니다.[1] 디코더가 프로토콜 이름을 붙이지 못해도 RAW 데이터를 보존해 재송신할 수 있게 구성했습니다.

1. 컴파일과 업로드

호환 Nano에는 구형 부트로더 설정이 필요했습니다. 실기 환경에서는 CH340 계열 직렬 포트와 IRremote 4.7.1을 사용했습니다.

arduino-cli compile \
  --fqbn arduino:avr:nano:cpu=atmega328old \
  IR_Capture_Replay_Test

arduino-cli upload \
  -p /dev/cu.usbserial-2240 \
  --fqbn arduino:avr:nano:cpu=atmega328old \
  IR_Capture_Replay_Test

업로드가 막혔을 때는 시리얼 모니터의 포트 점유를 먼저 확인했습니다. 점유 프로세스를 종료한 뒤 같은 설정으로 업로드했습니다.

2. IR LED 발광 확인

IR LED를 스마트폰 카메라로 보면서 송신 명령을 실행하자 희미한 점멸이 보였습니다. 여기서 확인한 것은 D3 쪽 LED가 빛을 낸다는 사실뿐입니다.

  • 정확한 반송파와 프레임 타이밍은 카메라로 확인할 수 없습니다.
  • 대상 기기까지 도달할 광량과 조준 상태도 별도 문제입니다.
  • 카메라의 적외선 차단 필터 때문에 정상 LED도 잘 안 보일 수 있습니다.

3. D2 에지 수로 수신 경로 확인

완전한 디코드 로그가 나오지 않았을 때 수신기 고장으로 단정하지 않고 D2의 전기적 변화를 직접 셌습니다.

volatile uint16_t edgeCount = 0;

void onEdge() {
  edgeCount++;
}

void setup() {
  pinMode(2, INPUT);
  attachInterrupt(digitalPinToInterrupt(2), onEdge, CHANGE);
}

대기 상태는 D2=HIGH, edges/s=0이었고, 버튼을 누르자 35, 165, 200 edges/s가 기록됐습니다. 수신기 출력에서 D2까지 전기적 변화가 들어온다는 뜻이며 프로토콜 해석이나 프레임 무결성까지 입증하지는 않습니다.

  1. 에지도 없다면 전원, 핀 배열, 배선과 수신기부터 점검합니다.
  2. 에지가 있다면 디코더, 버퍼, 타이밍으로 범위를 좁힙니다.
  3. 캡처가 되면 저장 데이터와 송신 루틴을 확인합니다.
  4. 재송신 뒤에는 LED 조준·거리와 대상 기기 반응을 봅니다.

4. RAW 캡처와 재송신

캡처 스케치는 반복 프레임, 패리티 실패, 버퍼 오버플로를 제외했습니다. 디코더가 UNKNOWN 또는 범용 펄스 형식으로 판단하면 보정된 RAW 타이밍을 저장합니다.

stored.useRaw = stored.decoded.protocol == UNKNOWN ||
                stored.decoded.protocol == PULSE_WIDTH ||
                stored.decoded.protocol == PULSE_DISTANCE;

if (stored.useRaw) {
  IrReceiver.compensateAndStoreIRResultInArray(stored.raw);
}

첫 캡처에서는 다음 특징을 확인했습니다.

Protocol: UNKNOWN
RAW timing count: 78
Header: 약 4550 / 4400 µs
Total: 약 59.25 ms
Hash: 0x78B0144B

저장한 신호는 수신을 잠시 멈춘 뒤 D3의 IR LED로 재송신했습니다.

IrReceiver.stop();
delay(5);
IrSender.sendRaw(stored.raw, stored.rawLength, 38);
delay(5);
IrReceiver.start();

보드에서 REPLAY_DONE을 확인했고 사용자는 대상 기기가 실제로 동작했다고 확인했습니다. 이때 D2 수신 → 메모리 저장 → D3 송신 → 대상 기기 수신의 전체 경로가 검증됐습니다.

5. 유한 자동 반복

시리얼 로그와 대상 기기 화면을 동시에 보기 어려워 5초 간격, 최대 12회로 제한한 자동 재송신을 추가했습니다.

if (stored.hasCode) {
  autoReplayRemaining = 12;
  nextAutoReplayMillis = millis();
}

무한 반복을 피한 이유는 전원이나 트레이 같은 토글 명령이 계속 실행되는 것을 막기 위해서입니다. 반응을 확인하면 즉시 중지하고 어떤 프레임에서 어떤 동작이 나타났는지 기록합니다.

6. 공개 코드로 교차검증

공개 IRDB 코드셋에는 SharpDVD device 8, subdevice 48의 전원 기능이 65(0x41), 트레이 열기 기능이 66(0x42)으로 기록돼 있습니다.[3] SharpDVD 프로토콜 자료는 38 kHz, 400 µs 단위와 OEM 바이트 0xAA, 0x5A를 설명합니다.[2]

AA 5A 8F 30 41 F1

38 kHz / 400 µs 조건에서 같은 프레임을 3회 보냈고 사용자는 DVD 전원이 꺼졌다고 확인했습니다. 트레이 명령도 같은 방식으로 시험해 실제 열림을 확인했습니다. 공개 코드셋은 후보를 고르는 근거이고 최종 판정은 해당 기기의 실제 반응입니다.

헷갈리기 쉬운 지점

UNKNOWN은 신호 없음이 아니다

디코더가 프로토콜 이름을 붙이지 못했을 뿐 RAW 타이밍은 유효할 수 있습니다. 에지 수와 RAW 길이를 함께 확인합니다.

카메라에 빛이 보여도 끝이 아니다

발광, 반송파, 프레임 정확성, 광량, 조준은 서로 다른 문제입니다. 실제 기기 반응까지 확인해야 합니다.

송신 로그는 기기 응답 로그가 아니다

TX done은 Arduino의 작업 완료입니다. 대상 기기의 전원·화면·트레이 변화는 별도 관찰 기록으로 남깁니다.

전원 버튼은 토글일 수 있다

현재 상태를 모른 채 전원 프레임을 보내면 기기를 켜려다 끌 수 있습니다. 시험 전에 현재 상태를 확인하고 반복 횟수를 제한합니다.

문제 해결 체크리스트

  1. USB를 분리하고 수신기 핀 배열과 IR LED 극성을 확인합니다.
  2. D3과 IR LED 사이의 전류 제한 저항을 확인합니다.
  3. 보드와 부트로더 FQBN을 기록하고 컴파일부터 통과시킵니다.
  4. 시리얼 모니터가 업로드 포트를 점유하는지 확인합니다.
  5. 카메라로는 발광 여부만 확인합니다.
  6. 알려진 정상 리모컨으로 D2 에지 수를 확인합니다.
  7. 반복·패리티 실패·오버플로 프레임을 저장하지 않습니다.
  8. 디코드가 안 되면 RAW 타이밍을 보존합니다.
  9. 캡처한 신호를 먼저 원래 대상에 재송신합니다.
  10. 후보는 하나씩, 유한 횟수로 시험합니다.
  11. 보드 로그와 사람의 관찰을 나눠 기록합니다.

네 줄 요약

  • IR 리모컨 복제는 수신, 저장, 송신, 실제 반응을 따로 검증해야 합니다.
  • D2 에지 진단으로 수신 하드웨어와 디코드 문제를 분리했습니다.
  • RAW 재송신으로 전체 신호 경로가 실제 기기에서 동작함을 확인했습니다.
  • 카메라 점멸이나 TX done만으로 성공을 선언하지 않습니다.

프로젝트 파일

  • IR_Capture_Replay_Test/IR_Capture_Replay_Test.ino — RAW 캡처·재송신과 유한 자동 반복
  • IR_RX_Edge_Diagnostic/IR_RX_Edge_Diagnostic.ino — D2 전기적 에지 진단
  • Sharp_DVSL20_Pattern_Test/Sharp_DVSL20_Pattern_Test.ino — 알려진 SharpDVD 송신 조건 비교
  • photos/assembly-original.jpg — 사용자 제공 조립 사진 원본

Sources

  1. Arduino-IRremote README
  2. JP1 Remotes Wiki — SharpDVD
  3. IRDB SharpDVD device 8 / subdevice 48 codes

Arduino는 Arduino SA의 상표입니다. Sharp는 각 권리자의 상표입니다. 이 글은 사용자 제공 조립 사진과 로컬 실기 로그를 바탕으로 작성한 독립 프로젝트 기록입니다.

댓글

이 블로그의 인기 게시물

Install NS2.35 to Mac OS(Lion)

New power saving mode in android M.

Test DHT11 and SEN0018 raspberry