This is an old revision of the document!
ESP32 Infrared Remote
Author: Petru Zincenco
Master: IA
Introduction
I am creating this project because I already have a Home Assistant server running on a Raspberry Pi 3, and I want to extend its capabilities to control my stereo system and air conditioner via IR. By turning an ESP32 into an IR transceiver, I can sniff existing NEC-protocol remote commands, replay them, and even send arbitrary data over IR directly from my phone through Home Assistant.
General Description
Block Diagram
Modules and Interactions
Hardware Design
Parts List
4-channel 3.3 V ↔ 5 V level-shifter – 11 RON
YS-IRTM IR emitter/receiver module (38 kHz) – 22 RON
ESP32 development board – 46 RON
Jumper wires and breadboard
Total cost: 79 RON
Schematics and Signal Diagrams
Connections and Wiring Diagram
Software Design
Development Environment and Libraries
ESPHome (YAML-based configuration, OTA updates, Home Assistant integration)
Micropython-YS-IRTM examples for UART-based NEC IR transceiving
`uart` component on TX/RX GPIOs for communicating with the YS-IRTM module
`remote_receiver` component for decoding NEC pulses into codes
`remote_transmitter` component for keying a 38 kHz carrier according to NEC timing
YS-IRTM Module Details
Integrated dual 38 kHz 940 nm IR LED emitter and TSOP-style demodulator receiver with onboard MCU handling modulation/demodulation and UART.
On receive, the module outputs TTL-level pulses over TXD representing NEC-encoded bursts (9 ms leader + 32 bits) which the ESP32 times to reconstruct address/command words.
On transmit, the module accepts a UART frame of five bytes and generates a keyed 38 kHz IR carrier: a 9 ms AGC burst, 4.5 ms space, 32 bits of 562.5 µs bursts with 562.5 µs (0) or 1.6875 ms (1) spaces, plus a final 562.5 µs burst.
Transmit Protocol
Payload Structure: Five-byte UART frame: (Address, Command, Data 1, Data 2, Data 3). The module automatically appends the inverse of the Command as the fourth byte in the IR frame.
NEC Framing:
*Leader: 9 ms carrier-ON, 4.5 ms carrier-OFF
Data: 32 bits LSB first, each bit = 562.5 µs carrier + 562.5 µs space (0) or 1.6875 ms space (1)
Trailer: 562.5 µs burst to mark end-of-frame
Repeat: on long key-press, a 9 ms burst + 2.25 ms space + 562.5 µs burst every ~108 ms.
* UART Confirmation:** Module echoes back the Command byte on successful IR send; no reply indicates invalid payload.
Results
Conclusions
Download
Journal
Bibliography/Resources