TV Remote Control Protocols Explained: IR, RC5, RC6, NEC, CEC, and Practical API Examples
Remote controls are one of the simplest and most practical embedded communication examples. A TV remote may look trivial, but behind it are real protocol choices, timing constraints, carrier frequencies, and command encodings. If you want to build a DIY infrared controller, an IR blaster, or a home automation bridge, you need to understand the difference between raw IR, standard IR protocols, and HDMI-based control systems like CEC.
This guide is intentionally practical. It focuses on the protocols used in real TVs, the command patterns you will actually encounter, and the API style used to send commands from a Linux host or embedded controller.
What a TV Remote Control Protocol Really Is
A TV remote control protocol defines how a command is encoded and decoded.
At the physical layer, most remotes use infrared light. An LED sends bursts of light at a fixed carrier frequency, often around 38 kHz. The receiver is a photodiode and a demodulator that strips the carrier and then interprets the burst timing.
Typical remote control flow:
- The button press creates a command value
- The remote encodes bits using carrier bursts and silence gaps
- The IR receiver demodulates the signal
- The TV decodes the frame and executes the action
The important idea is that a remote does not send a human-friendly command like “volume up.” It sends a binary frame, often with address and command bytes, and the receiver translates that into the correct action.
Protocols at a Glance
Not all TV brands use completely unique protocols. In practice, many TV remotes use the same carrier frequency with different command layouts, address fields, and vendor-specific codes.
| Brand / Standard | Typical Carrier | Typical Format | Notes |
|---|---|---|---|
| NEC | 38 kHz | 32-bit frame (address + command + inverse) | Very common in TVs, AV receivers, AC units |
| RC5 | 36 kHz | 14-bit frame | Philips family, often used in set-top boxes and some AV gear |
| RC6 | 36 kHz | 20/24/32-bit frame | Philips, newer devices, extended commands |
| Sony SIRC | 40 kHz | 12/15/20-bit frame | Common in Sony TVs and audio gear |
| Samsung | ~38 kHz | Often NEC-like or custom | Many TVs use proprietary 32-bit codes |
| LG | ~38 kHz | Often NEC-like or custom | Commonly uses a vendor-specific frame mapping |
| Panasonic | ~38 kHz | Custom, often 32-bit | Manufacturer-specific command set |
| JVC / Sharp / Toshiba | ~38 kHz | Vendor-specific | Often custom commands; often not fully standardized |
| CEC | HDMI bus | Logical command packets | Not IR; uses HDMI wiring, no IR transmitter required |
Important: Many brands use a common modulation style but different command codes. A protocol detector must look at both the carrier frequency and the bit timing pattern, not just the brand name.
How IR Remote Signals Work
1. Carrier modulation
The IR LED is switched on and off very quickly at a carrier frequency such as:
- 38 kHz for NEC / Samsung / LG / many generic remotes
- 36 kHz for RC5 / RC6
- 40 kHz for Sony SIRC
The receiver demodulates the signal, so it sees a stream of logical pulses rather than the raw optical carrier.
2. Burst timing encodes bits
The command is usually a sequence of:
- leader pulse
- address bits
- command bits
- inverse bits
- stop/space gap
A common pattern is:
9 ms burst + 4.5 ms gap -> leader
560 us burst + 560 us gap -> logic 0
560 us burst + 1.69 ms gap -> logic 1
This is roughly the NEC style, and it is easy to recognize by looking at pulse widths.
3. Address and command pairing
Most IR protocols include:
- address: identifies the target device
- command: identifies the action
- inverse bits: basic checksum/error detection
For example, a NEC frame usually looks like:
leader
address (8 bits)
address_inverted (8 bits)
command (8 bits)
command_inverted (8 bits)
This is why an IR capture can often be decoded reliably even with a little noise.
Common TV Remote Protocols
NEC
NEC is one of the most common IR protocols.
Typical properties:
- Carrier: 38 kHz
- Frame length: 32 bits
- Byte structure: address, address inverse, command, command inverse
- Reliable and easy to decode
Example command payload:
0x00 0xFF 0x02 0xFD 0x00 0xFF 0x12 0xED
This is a common pattern for button codes, but actual values depend on the target device and remote.
RC5
RC5 uses a different bit structure and is widely used in Philips-based equipment.
Typical properties:
- Carrier: 36 kHz
- 14-bit frame
- Includes a toggle bit
- Manchester-coded data
A basic RC5 frame might look like this:
S T A5 A4 A3 A2 A1 A0 C5 C4 C3 C2 C1 C0
Where:
S= start bitT= toggle bitA= addressC= command
RC6
RC6 is the successor to RC5 and adds more capability.
Typical properties:
- Carrier: 36 kHz
- More flexible frame sizes
- Better support for advanced controls
- Common for newer set-top boxes and smart devices
Sony SIRC
Sony uses a different encoding that is easy to identify by timing and short frames.
Typical properties:
- Carrier: 40 kHz
- 12-bit, 15-bit, or 20-bit frames
- Uses pulse distances, not Manchester-like structures
CEC
CEC is not IR. It rides on the HDMI bus.
Advantages:
- No IR required
- Device-to-device communication over HDMI
- Can power on/off devices and send volume commands
Example CEC commands include:
POWER_ONPOWER_OFFVOLUME_UPVOLUME_DOWNSOURCE_SWITCH
This is increasingly useful for smart TVs and AVR control.
Example TV IR Command Table
The exact codes vary by brand and model. The table below is a practical summary of common TV families and their typical pattern.
| Brand / System | Protocol family | Typical carrier | Typical usage |
|---|---|---|---|
| Samsung | NEC-like or custom | 38 kHz | Power, volume, source, menu |
| LG | NEC-like or custom | 38 kHz | Power, source, volume, navigation |
| Sony | SIRC | 40 kHz | Power, volume, channel, input |
| Philips | RC5 / RC6 | 36 kHz | TV, set-top box, AV control |
| Panasonic | Custom / NEC-like | 38 kHz | TV and AV remote control |
| Toshiba | Custom / NEC-like | 38 kHz | TV and AVR control |
| Sharp | Custom | 38 kHz | TV and audio devices |
| JVC | Vendor-specific | 38 kHz | Media devices |
| Generic IR blaster | NEC / Samsung / LG | 38 kHz | Broad compatibility |
| HDMI CEC | HDMI bus | N/A | Smart TV control without IR |
Practical note: For real product work, always capture a waveform with a logic analyzer, IR receiver module, or oscilloscope. The brand name alone is not enough to guarantee the command code mapping.
Example curl Commands to Send Commands
In real projects, a controller or gateway usually exposes an HTTP API for sending IR commands. A common pattern looks like this:
curl -X POST http://tv-gateway.local:8080/api/ir/send \
-H "Content-Type: application/json" \
-d '{
"protocol": "nec",
"address": 0,
"command": 12,
"repeat": 1
}'
This sends a command using the NEC protocol. The specific command id depends on the target device.
Power on
curl -X POST http://tv-gateway.local:8080/api/ir/send \
-H "Content-Type: application/json" \
-d '{
"protocol": "nec",
"address": 0,
"command": 69,
"repeat": 1
}'
Volume up
curl -X POST http://tv-gateway.local:8080/api/ir/send \
-H "Content-Type: application/json" \
-d '{
"protocol": "nec",
"address": 0,
"command": 70,
"repeat": 1
}'
Input/source switch
curl -X POST http://tv-gateway.local:8080/api/ir/send \
-H "Content-Type: application/json" \
-d '{
"protocol": "rc5",
"address": 0,
"command": 32,
"repeat": 1
}'
Example using raw IR payloads
curl -X POST http://tv-gateway.local:8080/api/ir/send_raw \
-H "Content-Type: application/json" \
-d '{
"carrier_hz": 38000,
"ticks": [9000, 4500, 560, 560, 560, 1690, 560, 560, 560, 1690],
"repeat": 1
}'
Example using CEC over HDMI
curl -X POST http://media-center.local:8080/api/cec \
-H "Content-Type: application/json" \
-d '{
"command": "power_on"
}'
Practical point: Many API layers hide the protocol details; they accept a higher-level action such as
power_on,volume_up, orhdmi_1instead of raw IR bytes.
Detection Algorithm: How to Tell Which Protocol You Received
A detector works by looking at measured pulse widths and the carrier frequency. The idea is simple: recognize the timing signature of the protocol.
Basic algorithm
# Pseudocode for protocol detection
def detect_protocol(carrier_hz, pulse_times, gap_times):
# Step 1: estimate carrier frequency
if 37000 <= carrier_hz <= 39000:
carrier_family = "38khz"
elif 35000 <= carrier_hz <= 37000:
carrier_family = "36khz"
elif 39000 <= carrier_hz <= 41000:
carrier_family = "40khz"
else:
carrier_family = "custom"
# Step 2: detect long leader pulse
if len(pulse_times) > 0 and pulse_times[0] > 8000:
leader = True
else:
leader = False
# Step 3: classify by timing patterns
if carrier_family == "38khz" and leader:
# many NEC-like remotes share this timing
return "NEC-like / Samsung / LG / generic TV"
if carrier_family == "36khz" and pulse_times and max(pulse_times) < 2000:
return "RC5 / RC6"
if carrier_family == "40khz" and len(pulse_times) in (12, 15, 20):
return "Sony SIRC"
return "custom protocol or unknown vendor format"
What the decoder is really detecting
The algorithm usually checks:
- carrier frequency
- leader pulse length
- bit width (short vs long pulse gap)
- command length (12/15/20/32 bits)
- optional inverted bytes or toggle bits
A robust implementation also normalizes noisy signals and discards failed captures before decoding.
A Practical Example: NEC Decoding Flow
Suppose an IR capture looks like this:
leader: 9000 us
gap: 4500 us
bit 1: 560 us burst + 1690 us gap
bit 0: 560 us burst + 560 us gap
This is a classic NEC signature.
The decoder will:
- detect the 9 ms leader pulse
- identify the 4.5 ms gap
- measure each following burst-gap pair
- convert logic
1and0to bits - group the result into bytes
- verify the inverse bytes for consistency
If the result is valid, it can map directly to whatever TV command the remote sends.
Short Practical Summary
- IR remotes use modulated light, not just raw digital lines.
- The carrier frequency and timing pattern define the protocol.
- Many TVs use the same carrier families but different command codes.
- NEC, RC5, RC6, and Sony SIRC are the most common families.
- CEC is a better option when you have HDMI and want a cleaner smart-TV control path.
- A real decoder should classify by both carrier frequency and timing pattern.
When to Use Which Control Method
Use IR when:
- the TV has no network API
- you want a simple blaster interface
- you need compatibility with older hardware
Use CEC when:
- the TV supports HDMI-CEC
- you want cleaner device-to-device control
- you prefer no IR hardware dependence
Use a REST API when:
- you are building a home-automation gateway
- you want a simple control surface from Linux, Python, or Node.js
- you need to integrate with HA, scripts, or cron jobs
Final Thoughts
TV remote control systems are a good example of how simple industrial interfaces can still be very protocol-heavy. The hardware is small, but the design choices matter: modulation, data encoding, timing, and vendor-specific commands all affect reliability.
If you are building a home automation stack, the key is to understand the real protocol and not just the brand label. In many cases, the fastest path is:
- detect the signal waveform
- decide if it is IR or HDMI-CEC
- map the pulse pattern to the protocol family
- translate it into a command that your system can reuse
That gives you a solid foundation for both debugging existing remotes and building your own controlled IR or HDMI bridge.