# HDMI Switcher IR Controller

This project allows you to control an HDMI switch (or any IR controlled device) using an **ESP32** running ESPHome.  
It also provides a way to **capture IR codes with an Arduino Uno R3**, so you can easily copy them into the ESPHome configuration.

The goal is to make this setup open-source, easy to reproduce, and fully documented.

---

## Table of Contents

<div class="markdown-heading" dir="auto" id="bkmrk--3">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/Smev1/ESPHOME_IR#table-of-contents)</div>1. [Hardware Requirements](https://github.com/Smev1/ESPHOME_IR#hardware-requirements)
2. [ESPHome Setup](https://github.com/Smev1/ESPHOME_IR#esphome-setup)
3. [Arduino IR Capture](https://github.com/Smev1/ESPHOME_IR#arduino-ir-capture)
4. [Capturing and Adding New IR Codes](https://github.com/Smev1/ESPHOME_IR#capturing-and-adding-new-ir-codes)
5. [Web Interface &amp; Buttons](https://github.com/Smev1/ESPHOME_IR#web-interface--buttons)
6. [Tips &amp; Troubleshooting](https://github.com/Smev1/ESPHOME_IR#tips--troubleshooting)
7. [Case](https://github.com/Smev1/ESPHOME_IR#case)
8. [File Structure](https://github.com/Smev1/ESPHOME_IR#file-structure)
9. [License](https://github.com/Smev1/ESPHOME_IR#license)

---

## Hardware Requirements

<div class="markdown-heading" dir="auto" id="bkmrk--6">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/Smev1/ESPHOME_IR#hardware-requirements)</div>**ESP32 Side (IR Transmitter):**

- ESP32 Dev Board (ESP32-DevKitC or similar)
- IR LED connected to **GPIO13**
- ESPHhome already installed

[![image](https://private-user-images.githubusercontent.com/93997706/553022697-84baa4fb-bcda-4b1c-ac1d-9ebdaa449f2c.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzI1ODIxMzcsIm5iZiI6MTc3MjU4MTgzNywicGF0aCI6Ii85Mzk5NzcwNi81NTMwMjI2OTctODRiYWE0ZmItYmNkYS00YjFjLWFjMWQtOWViZGFhNDQ5ZjJjLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAzMDMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzAzVDIzNTAzN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTdjMTRmNjdmNmFhOWE3ODBlOTczYTU1ZDI3OWU2ZmZkMWY0ZDUzOWIyNTNkNzk2MTA0MjczMjY1NjEwMjMxYTgmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.HxMqpINreguY7jCHlLB20No0dJuraRNAr9AiSSc37SA)](https://private-user-images.githubusercontent.com/93997706/553022697-84baa4fb-bcda-4b1c-ac1d-9ebdaa449f2c.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzI1ODIxMzcsIm5iZiI6MTc3MjU4MTgzNywicGF0aCI6Ii85Mzk5NzcwNi81NTMwMjI2OTctODRiYWE0ZmItYmNkYS00YjFjLWFjMWQtOWViZGFhNDQ5ZjJjLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAzMDMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzAzVDIzNTAzN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTdjMTRmNjdmNmFhOWE3ODBlOTczYTU1ZDI3OWU2ZmZkMWY0ZDUzOWIyNTNkNzk2MTA0MjczMjY1NjEwMjMxYTgmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.HxMqpINreguY7jCHlLB20No0dJuraRNAr9AiSSc37SA)

Note: Check the datasheet of your IR LED to see what pins will be connected to GND and GPIO13

**Arduino Side (IR Receiver for Capturing Codes):**

- Arduino Uno R3
- IR Receiver module connected to **Pin 4**

[![Screenshot 2026-02-21 102123](https://private-user-images.githubusercontent.com/93997706/553022709-5e805012-77be-43ac-8f84-536901dd16a8.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzI1ODIxMzcsIm5iZiI6MTc3MjU4MTgzNywicGF0aCI6Ii85Mzk5NzcwNi81NTMwMjI3MDktNWU4MDUwMTItNzdiZS00M2FjLThmODQtNTM2OTAxZGQxNmE4LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAzMDMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzAzVDIzNTAzN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTZiNzMxY2FjNjgyMTNiMTk4OTExMWVlNGRkYzE1Yjg0NGI3YjZhM2E1YzJmM2E2ODBkZGY3NGE3ZmIxMTA2MDImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.7dYxlyj8HzdcJbxgNvtH6TiKi2F_TdRQtgu2YFf1-fc)](https://private-user-images.githubusercontent.com/93997706/553022709-5e805012-77be-43ac-8f84-536901dd16a8.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzI1ODIxMzcsIm5iZiI6MTc3MjU4MTgzNywicGF0aCI6Ii85Mzk5NzcwNi81NTMwMjI3MDktNWU4MDUwMTItNzdiZS00M2FjLThmODQtNTM2OTAxZGQxNmE4LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAzMDMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzAzVDIzNTAzN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTZiNzMxY2FjNjgyMTNiMTk4OTExMWVlNGRkYzE1Yjg0NGI3YjZhM2E1YzJmM2E2ODBkZGY3NGE3ZmIxMTA2MDImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.7dYxlyj8HzdcJbxgNvtH6TiKi2F_TdRQtgu2YFf1-fc)

Note: Check the datasheet of your IR Reciver to see what pins will be connected to GND and GPIO4

## ESPHome Setup

<div class="markdown-heading" dir="auto" id="bkmrk--10">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/Smev1/ESPHOME_IR#esphome-setup)</div>The ESP32 runs ESPHome to transmit IR codes to the HDMI switch.

### How to Use

<div class="markdown-heading" dir="auto" id="bkmrk--12">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/Smev1/ESPHOME_IR#how-to-use)</div>1. Copy `hdmi-switcher-ir.yaml` ([Download](https://github.com/Smev1/ESPHOME_IR/releases/download/Main/hdmi-switcher-ir.yaml)) to your ESPHome folder.
2. Fill in the placeholders for: 
    - Wi-Fi credentials (Change in ESPHOME settings)
    - OTA password (Line 20)
    - API encryption key (Line 16)
    - Raw IR codes for your HDMI inputs

> **Note:** To find the OTA and API key just make a blank yaml config in ESPHOME

3. Upload the YAML to the ESP32 via OTA or USB.

> **Note:** The raw IR codes can be captured using the Arduino setup below. **Note:** The current IR signals are configured for a UGREEN HDMI Switcher

---

## Arduino IR Capture

<div class="markdown-heading" dir="auto" id="bkmrk--15">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/Smev1/ESPHOME_IR#arduino-ir-capture)</div>The Arduino is used to read raw IR signals from your HDMI remote and format them for ESPHome.

### How to Use

<div class="markdown-heading" dir="auto" id="bkmrk--17">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/Smev1/ESPHOME_IR#how-to-use-1)</div>1. Connect your IR receiver to Arduino Pin 4.
2. Upload `ir_capture.ino` ([Download](https://github.com/Smev1/ESPHOME_IR/releases/download/Main/ir_capture.ino)) to the Arduino.
3. Open the Serial Monitor at **115200 baud**.
4. Press a button on your HDMI remote.
5. Copy the array output from the Serial Monitor. This is the exact format needed for `transmit_raw` in ESPHome.

---

## Capturing and Adding New IR Codes

<div class="markdown-heading" dir="auto" id="bkmrk--20">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/Smev1/ESPHOME_IR#capturing-and-adding-new-ir-codes)</div>1. Run the Arduino IR capture sketch.
2. Press the desired button on your HDMI remote.
3. Copy the outputted array (e.g., `[8850, -4500, 550, -550, ...]`).
4. Paste it into the corresponding button in `hdmi-switcher-ir.yaml`.
5. Save and upload your updated YAML to the ESP32.
6. Make sure to refer to [IRremote Arduino Library](https://esphome.io/components/remote_transmitter.html) to add new features

---

## Web Interface &amp; Buttons

<div class="markdown-heading" dir="auto" id="bkmrk--23">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/Smev1/ESPHOME_IR#web-interface--buttons)</div>The ESPHome web server allows you to:

- Press buttons from a browser
- Test IR codes without integrating into Home Assistant

All buttons defined in `hdmi-switcher-ir.yaml` will appear in the web interface. And you should be able to access the device web ui from hdmi-switcher-ir.local (or whatever you rename the yaml)

---

## Tips &amp; Troubleshooting

<div class="markdown-heading" dir="auto" id="bkmrk--26">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/Smev1/ESPHOME_IR#tips--troubleshooting)</div>- **IR not working:** Try sending the signal multiple times using `repeat:` in ESPHome.
- **Carrier mismatch:** Some devices prefer 36–40 kHz. Adjust `carrier_frequency` if needed.
- **Series resistor:** Protect your IR LED with a 100–220Ω resistor.
- **Static IP:** Optional but helpful for accessing the ESP32 consistently via web UI.
- **Debugging:** Use the ESPHome logger to confirm button presses are being triggered.

---

## Case

<div class="markdown-heading" dir="auto" id="bkmrk--29">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/Smev1/ESPHOME_IR#case)</div>Additonally there is a case available on nexprint (coming soon)

---

## File Structure

<div class="markdown-heading" dir="auto" id="bkmrk--32">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/Smev1/ESPHOME_IR#file-structure)</div>├── README.md # This file  
├── hdmi-switcher-ir.yaml # ESPHome YAML config  
└── ir\_capture.ino # Arduino sketch to capture IR codes

---

## License

<div class="markdown-heading" dir="auto" id="bkmrk--35">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/Smev1/ESPHOME_IR#license)</div>This project is open-source. You can copy, modify, and use it freely.

---

## References

<div class="markdown-heading" dir="auto" id="bkmrk--38">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/Smev1/ESPHOME_IR#references)</div>- [ESPHome Remote Transmitter Docs](https://esphome.io/components/remote_transmitter/)
- [IRremote Arduino Library](https://github.com/Arduino-IRremote/Arduino-IRremote)