Capturing and Replaying IR Signals: A Practical Guide
IR remote control signals are surprisingly straightforward to capture and replay. The physics is simple: an IR LED pulses a light signal, a receiver demodulates it, a microcontroller records the timing. The BLEShark Nano does all of this in a compact device you can hold in one hand.
This guide walks through exactly how to capture signals from any remote, what you'll encounter with different device types, and how to troubleshoot when a capture doesn't replay reliably. No oscilloscope needed, no firmware hacking, no setup beyond navigating the BLEShark's menu.
graph TD A[ IR Capture ] --> B[ Capture Setup ] B --> C[ Step-by-Step Capture ] B --> D[ Storing and Naming Codes ]
Table of Contents
- How IR Capture Works on the BLEShark
- Capture Setup: Distance and Positioning
- Step-by-Step: Capturing a Signal
- Storing and Naming Captured Codes
- Replaying a Stored Code
- What Signal Formats You'll Encounter
- Troubleshooting: When Capture or Replay Fails
- Lighting and Environmental Interference
- Advanced: Using the File Portal for Code Libraries
How IR Capture Works on the BLEShark
The BLEShark Nano has an IR receiver component - a demodulating photodiode module (TSOP-type) that responds to IR light modulated at 38kHz. When an IR remote fires at it, the module strips the carrier and outputs a digital signal: high when no IR is present, low (active) when 38kHz IR is detected.
The ESP32-C3 monitors this signal using a timer interrupt. Every time the signal transitions (high to low, or low to high), the firmware records the current timer value. The result is a sequence of mark/space durations in microseconds: how long each pulse lasted, and how long each silence between pulses lasted.
This raw timing sequence is stored as the captured code. It's protocol-agnostic - the BLEShark doesn't need to know if you're capturing NEC, Sony SIRC, Philips RC-5, or some custom protocol from an obscure brand. It just records the timings. This means it works for virtually anything that uses IR remote control, including air conditioners with complex proprietary protocols, projectors, AV receivers, and older devices with non-standard encodings.
Capture Setup: Distance and Positioning
The IR receiver on the BLEShark has an optimal capture range of 10-50cm from the transmitting remote. The exact receiver location is marked on the device - it's a small dark component visible on the board.
At 10-15cm, signal level is strong and there's very little risk of errors. At 50cm, signal is adequate for most remotes with fresh batteries. Beyond 50cm, weak remotes with aging batteries may produce corrupted captures with missing pulses or incorrect timing.
Keep the remote pointed roughly at the receiver within about 30 degrees of perpendicular. IR LEDs have a beam angle - most consumer remotes use a narrow beam (15-30 degree half-angle) for range, not coverage. If you're off-axis by more than 30-40 degrees, signal strength drops significantly.
Don't shake the remote or move it during capture. The capture window for a single button press is 100-200ms. Any movement that causes the beam to break momentarily will produce a capture with an unusually long space that doesn't correspond to data.
Step-by-Step: Capturing a Signal
- Navigate to IR > Receive on the BLEShark. The OLED will show "Waiting for IR..."
- Hold the remote 15-30cm from the BLEShark's IR receiver
- Press and hold the button you want to capture. Hold it for about one second
- The BLEShark OLED will show the capture count or a confirmation that a signal was received
- Release the button
- The BLEShark will prompt you to save the capture with a name
- Use the navigation buttons to enter a name for the code
A one-second button hold is usually sufficient. For protocols that repeat the frame (like Sony SIRC which always sends 3 frames), one second ensures at least three complete transmissions. For NEC, one second gives the initial frame plus several repeat codes. The BLEShark captures the first complete frame and discards subsequent identical captures to avoid storing duplicates.
The naming step matters if you're building a code library. Use descriptive names: "TV_Power", "AC_Cool_20C", "Projector_HDMI_1". The file portal later will show you these names when browsing your stored codes.
Storing and Naming Captured Codes
Captured codes are stored in flash memory as raw timing files. The BLEShark can hold multiple codes - the practical limit depends on the size of each capture, but hundreds of typical remote codes fit comfortably.
Through the file portal (accessible when the BLEShark is in WiFi AP mode), you can browse your stored codes, download them to your computer as .txt or .json files, and upload new code files you've prepared elsewhere. This is the mechanism for loading a pre-built IR library rather than manually capturing every code.
Code files can be organized into groups - a "Living Room" group for the TV, soundbar, and Apple TV, and a "Bedroom" group for different equipment. Navigation through groups in the Transmit app keeps your library organized as it grows.
If you need to share codes between multiple BLEShark devices, download the code file from one device through the file portal and upload it to others. This is useful when setting up a Shiver mesh pack - you might want all nodes in a space to have the same IR library, or you might want each node to have the codes for the specific equipment closest to it.
Replaying a Stored Code
- Navigate to IR > Transmit on the BLEShark
- Browse to the code you want to replay
- Point the BLEShark's IR LED at the target device's IR receiver window
- Press the button to transmit
Position matters for replay just as it does for capture. Point the BLEShark's IR LED at the device's receiver window - on a TV this is usually a small window on the lower bezel, often labeled or visible as a slightly different color of plastic. On an air conditioner, it's typically on the front face of the indoor unit. Projectors vary widely.
The BLEShark transmits the stored timing sequence at 38kHz carrier. The target device's receiver demodulates the 38kHz, extracts the timing, and decodes the command. If the timing matches what the device expects for that command, it executes the function.
Hold the BLEShark steady during transmission. A typical IR command transmission takes 50-100ms. If you move the device during transmission, signal breaks can prevent the code from landing cleanly. You'll know it worked when the target device responds - TV volume changes, AC temperature updates, projector input switches.
What Signal Formats You'll Encounter
In practice, you'll encounter these protocols most frequently:
NEC and NEC variants - the most common. TVs from LG, Sharp, Toshiba, and many others. All use the 9ms+4.5ms lead and pulse-distance encoding. Frame length is consistent at ~67ms for all-ones data.
Samsung - visually similar to NEC but with subtle timing differences. Samsung uses a modified NEC format with slightly different lead timing. The BLEShark captures it without issues; replay is generally reliable.
Sony SIRC - pulse-width encoding, 40kHz carrier. Comes in 12, 15, or 20-bit variants. The BLEShark replays at 38kHz; most Sony receivers are tolerant enough that this works, though for critical applications where range is at the limit, the carrier difference can cause issues.
Air conditioner protocols - often completely proprietary. Most modern split-system ACs (Daikin, Mitsubishi, Fujitsu, Gree) use long proprietary frames that encode the full desired state - temperature, mode, fan speed, timer settings - in a single large packet of 100-200+ bits. These are NOT simple NEC or SIRC codes. Each different AC setting is a completely different code. Capturing "cool to 20C" doesn't give you "cool to 21C" - you'd need to capture each setting separately. The BLEShark handles these fine because it stores raw timing - the packet is longer but the capture mechanism is the same.
Philips RC-5 and RC-6 - common in European devices, older Philips TVs, Sky and cable boxes in the UK. RC-5 uses Manchester encoding at 36kHz. RC-6 is more complex with a tri-bit preamble. Raw timing capture handles both correctly for replay, though if you're trying to decode the codes analytically you need to understand the different encoding.
Projectors - highly varied. Epson, BenQ, NEC, Optoma each have their own protocols. Most projectors respond well to raw capture/replay. The tricky ones are older Barco and Christie professional projectors, which sometimes have unusual carrier frequencies.
Troubleshooting: When Capture or Replay Fails
Capture gets a garbled signal: Move closer to the remote (10-15cm). Check battery level in the remote - weak batteries produce inconsistent pulse timing that confuses the capture. Try a fresh battery and recapture.
Capture seems to work but replay has no effect: Distance issue. Try getting closer to the device's IR receiver window. Check that you're pointing at the correct receiver window - some devices have a specific receiver location that's not obvious. Try tilting the BLEShark slightly - sometimes a slight angle helps with reflective surfaces.
Replay works sometimes but not reliably: Ambient IR interference (see next section). Or the captured timing was slightly off - recapture with the remote at a closer and more stable distance. Also check if the target device's firmware requires a minimum received signal strength; commercial display screens in bright environments sometimes have high noise thresholds.
Sony device doesn't respond: The 40kHz vs 38kHz carrier difference. Try getting closer to compensate for the slight frequency mismatch. Very close range (5-10cm) usually overcomes the frequency tolerance issue on Sony receivers.
AC unit doesn't respond: Verify you're pointing at the indoor unit's IR receiver, not the outdoor unit (which has no IR sensor). The indoor unit receiver is usually behind the front panel - the AC needs to detect the signal through the panel material. This can require more IR power than a TV; try from 1-2 meters directly in front of the unit rather than from an angle.
Lighting and Environmental Interference
Fluorescent lights emit IR. Halogen bulbs emit significant IR. Bright sunlight contains huge amounts of IR. The TSOP-type demodulating receiver is designed to filter out these sources - it only responds to 38kHz modulated IR. But in extreme conditions, ambient IR can still cause problems.
Direct sunlight on the BLEShark's IR receiver will saturate it. Capturing in direct sun is unreliable - the receiver's AGC (automatic gain control) is overwhelmed by the DC component of sunlight even though the demodulation filter should reject it. Move to shade for best capture results.
Old fluorescent lights with failing ballasts can produce broadband IR noise including 38kHz components. If you're in a location with old fluorescent lighting and captures are noisy, move to a different location or switch to LED lighting.
For replay, the target device's IR receiver has the same ambient IR issues. If a TV in a sunlit room is not responding to IR, that's often the sun problem rather than your device or codes. Shade the TV's receiver window and try again.
Advanced: Using the File Portal for Code Libraries
The BLEShark's file portal gives you filesystem access to everything stored on the device over WiFi. When the BLEShark is in AP mode, connect to its WiFi network and navigate to the file portal in a browser.
From there you can:
- Download all captured IR codes as individual files
- Upload a pre-built IR code library (in BLEShark format)
- Delete codes you no longer need
- Rename codes
- Organize codes into folders/groups for navigation
For a household with many IR-controlled devices, it's practical to do a one-time capture session: systematically go through every remote in your home, capture all the functions you use regularly, name them clearly, and then upload the complete library to any BLEShark units you have. You never need to handle those remotes again for everyday control.
For a Shiver mesh deployment, you can prepare a code library on one node, download it through the file portal, and upload the same library to additional nodes in the pack. Each node then has the same capabilities. Use the mesh to send IR commands to specific nodes based on which room or zone you want to control - the mesh coordinator sends CMD_IR_CUSTOM_TX with the target node ID and code name, and that node fires the IR LED in its location.
The combination of IR capture, code storage, file portal access, and Shiver mesh coordination makes the BLEShark a surprisingly capable distributed IR control platform for both home automation and security testing scenarios.
IR capture and replay is for controlling your own devices or devices you have permission to control. All techniques described are standard methods used in universal remote control systems.