Arduino Tutorial: HX1838 IR Wireless Remote Control Kit (Receive + Decode + Transmit)

Beginner Tutorial Views: 1347

This is a comprehensive, Arduino-based tutorial for the <strong>HX1838 Infrared (IR) wireless remote control kit</strong> (Leobot Product #196). You will learn how IR remotes work, how to wire the receiver module, how to decode button presses reliably, how to map buttons to actions (relays, LEDs, menus), and how to transmit IR using the included IR LED for “remote cloning” or controlling IR devices from your Arduino.

Arduino Tutorial: HX1838 IR Wireless Remote Control Kit (Receive + Decode + Transmit)

This is a comprehensive, Arduino-based tutorial for the HX1838 Infrared (IR) wireless remote control kit (Leobot Product #196). You will learn how IR remotes work, how to wire the receiver module, how to decode button presses reliably, how to map buttons to actions (relays, LEDs, menus), and how to transmit IR using the included IR LED for “remote cloning” or controlling IR devices from your Arduino.

Tutorial Beginner ? Advanced Arduino IR Remote HX1838 Receiver Transmitter Home Automation
What’s in the kit:
  • 1x IR Remote Control (typical working distance up to ~8m depending on environment)
  • 1x IR Receiver Module (HX1838-style)
  • 1x IR LED (transmitter LED)

Typical remote uses a CR2025 coin cell battery.

1) What IR remote control is (and what it’s good for)

IR remote control is a short-range, line-of-sight wireless method where a remote transmits pulses of infrared light. A receiver module demodulates those pulses and outputs a digital signal that your Arduino can read.

It is excellent for:

  • Simple user interfaces for projects (menus, mode selection, tuning parameters)
  • Controlling relays, lights, fans (through proper drivers)
  • DIY home automation prototypes (TV-style control of devices)
  • Debugging devices without a PC connected (button-driven test modes)

It is not ideal for:

  • Long-range communication (typically a few meters indoors)
  • Non-line-of-sight environments (IR does not go through walls)
  • Very noisy light environments (direct sunlight can overwhelm receivers)

2) How IR remotes work (38kHz carrier + protocols)

Most consumer IR remotes use a modulated carrier around 38kHz. The remote turns the IR LED on/off at that carrier frequency in bursts. Those bursts encode bits (0/1) using timing patterns.

The key concepts:

  • Carrier frequency: The receiver module is tuned to detect bursts near 38kHz and reject ambient light.
  • Protocol: The timing of bursts defines the protocol (NEC, Sony, RC5, RC6, etc.).
  • Address + command: Many protocols encode both a device address and the button command.
  • Repeat codes: Holding a button often sends a special “repeat” frame, not the full code each time.
Why decoding is easy: The receiver module performs demodulation and outputs a clean-ish digital stream, which the Arduino library interprets into decoded command values.

3) Identifying the parts (receiver module + IR LED + remote)

3.1 IR Receiver Module (HX1838 style)

The receiver module typically has 3 pins:

  • VCC (usually 3.3V–5V)
  • GND
  • OUT / SIG (digital output to Arduino pin)

3.2 IR LED (transmitter)

The IR LED is used to transmit IR from your Arduino. It behaves like a normal LED but emits infrared light. To get good range, you usually drive it with short pulses at 38kHz and (often) higher peak currents than a normal indicator LED. That typically requires a transistor driver stage (covered later).

3.3 Remote control

The remote sends encoded IR signals. In most kits of this style, each button produces a stable code that you can map to a function.


4) Wiring the HX1838 receiver module to Arduino (UNO/Nano/Mega)

4.1 Recommended wiring (UNO/Nano)

Receiver Pin Arduino UNO/Nano Notes
VCC 5V Most modules accept 5V; 3.3V also often works.
GND GND Must share ground.
OUT / SIG D2 Any digital pin is typically OK; D2 is a common default.

4.2 Mega wiring

Same concept: VCC to 5V, GND to GND, OUT to any digital pin (e.g., 2).

Noise tip: If your project includes motors/relays, power those separately and share ground. Power noise can cause missed IR reads or false triggers.

5) Arduino library setup (IRremote)

The most common Arduino library for IR receive/transmit is IRremote. Install it via:

  1. Arduino IDE ? Sketch ? Include Library ? Manage Libraries…
  2. Search for IRremote
  3. Install (choose a commonly maintained release)
Version note: IRremote has had API changes across major versions. If you copy code from old tutorials and it fails to compile, it’s often because the library API changed. The examples in the library itself are the best reference for your installed version.

6) Project 1: Decode buttons and print codes

This first sketch prints decoded IR values to the Serial Monitor so you can identify each button’s code. Once you have the codes, you can map them to actions in your application.

6.1 Decode sketch (works with many IRremote versions)


/*
  HX1838 IR Receiver - Decode Example
  Wiring: Receiver OUT -> D2 (or chosen pin)
*/

#include <IRremote.h>

const int IR_PIN = 2;

void setup() {
  Serial.begin(115200);
  delay(200);
  IrReceiver.begin(IR_PIN, ENABLE_LED_FEEDBACK); // LED feedback optional
  Serial.println("IR Receiver ready. Press remote buttons...");
}

void loop() {
  if (IrReceiver.decode()) {
    // Print a human-readable summary and raw data
    IrReceiver.printIRResultShort(&Serial);
    Serial.println();

    // For many protocols, the decoded command is here:
    // IrReceiver.decodedIRData.command
    // The full decoded raw value may be in:
    // IrReceiver.decodedIRData.decodedRawData
    Serial.print("Protocol: ");
    Serial.print(IrReceiver.decodedIRData.protocol);
    Serial.print(" | Address: 0x");
    Serial.print(IrReceiver.decodedIRData.address, HEX);
    Serial.print(" | Command: 0x");
    Serial.print(IrReceiver.decodedIRData.command, HEX);
    Serial.print(" | Raw: 0x");
    Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX);

    IrReceiver.resume(); // ready for next
  }
}
    

6.2 What to record

  • Which button you pressed
  • Protocol (e.g., NEC)
  • Command value (often the key value you use)
  • Address (if present)
  • Whether holding the button produces repeats (important for UI behavior)

7) Project 2: Map buttons to actions (LED/relay/menu)

After decoding, you typically implement a mapping like:

  • “VOL+” increases a setpoint
  • “VOL-” decreases a setpoint
  • “OK” toggles an output
  • Number keys select modes

7.1 Example: map commands to actions (toggle LED + set mode)


#include <IRremote.h>

const int IR_PIN = 2;
const int LED_PIN = 13;

int mode = 0;
bool ledOn = false;

// Replace these with the Command values you observed for your remote
const uint8_t CMD_OK   = 0x1C;
const uint8_t CMD_1    = 0x45;
const uint8_t CMD_2    = 0x46;
const uint8_t CMD_3    = 0x47;
const uint8_t CMD_VOLP = 0x40;
const uint8_t CMD_VOLM = 0x19;

int setpoint = 50;

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);

  IrReceiver.begin(IR_PIN, DISABLE_LED_FEEDBACK);
  Serial.println("IR mapping demo ready.");
}

void applyLed() {
  digitalWrite(LED_PIN, ledOn ? HIGH : LOW);
}

void loop() {
  if (!IrReceiver.decode()) return;

  // Basic filters
  auto &d = IrReceiver.decodedIRData;
  uint8_t cmd = d.command;

  // Handle mapping
  if (cmd == CMD_OK) {
    ledOn = !ledOn;
    applyLed();
    Serial.println("OK: Toggle LED");
  } else if (cmd == CMD_1) {
    mode = 1; Serial.println("Mode = 1");
  } else if (cmd == CMD_2) {
    mode = 2; Serial.println("Mode = 2");
  } else if (cmd == CMD_3) {
    mode = 3; Serial.println("Mode = 3");
  } else if (cmd == CMD_VOLP) {
    setpoint = min(setpoint + 1, 100);
    Serial.print("Setpoint = "); Serial.println(setpoint);
  } else if (cmd == CMD_VOLM) {
    setpoint = max(setpoint - 1, 0);
    Serial.print("Setpoint = "); Serial.println(setpoint);
  } else {
    Serial.print("Unhandled cmd: 0x");
    Serial.println(cmd, HEX);
  }

  IrReceiver.resume();
}
    
Production pattern: Keep all “button meanings” in one mapping function. This makes UI changes fast and reduces bugs.

8) Handling long-press repeat and debouncing

Many IR protocols send a special “repeat” frame when you hold a button. You generally want:

  • Short press: one action
  • Long press: repeated action (e.g., setpoint continues changing)
  • Debounce: avoid double-trigger from one physical press

8.1 Simple time-based debounce


unsigned long lastActionMs = 0;
const unsigned long debounceMs = 180;

bool allowActionNow() {
  unsigned long now = millis();
  if (now - lastActionMs < debounceMs) return false;
  lastActionMs = now;
  return true;
}
    

Use allowActionNow() before applying state changes for keys that should not repeat too quickly (e.g., “OK”).


9) Project 3: Transmit IR using the IR LED (send / clone)

Transmitting IR allows you to:

  • Clone a remote: capture a command code, then retransmit it from Arduino
  • Build automation: Arduino sends IR commands to TV/aircon/fan (as long as you know the protocol/codes)
  • Bridge systems: IR-in ? WiFi/MQTT ? IR-out

9.1 Basic transmit example (NEC-style command)

Many remotes use NEC-like protocols. The code below shows a typical pattern; adjust for the protocol detected in your decode step.


#include <IRremote.h>

const int IR_SEND_PIN = 3; // connect this to your IR LED driver input

void setup() {
  Serial.begin(115200);
  IrSender.begin(IR_SEND_PIN, DISABLE_LED_FEEDBACK);
  Serial.println("IR sender ready.");
}

void loop() {
  // Example: send NEC with address and command
  uint16_t address = 0x00FF;
  uint8_t  command = 0x45;

  Serial.println("Sending IR command...");
  IrSender.sendNEC(address, command, 0); // repeats=0

  delay(2000);
}
    
Important: If your decoded protocol is not NEC, use the corresponding send function (e.g., sendSony, sendRC5, etc.). Always base transmit code on what you actually decoded.

10) Driving the IR LED properly (range and reliability)

If you connect an IR LED directly to an Arduino pin, you will often get poor range. For decent range, drive the IR LED with a transistor so the LED can be pulsed at higher current safely (while limiting current with a resistor).

10.1 Recommended driver circuit (simple and effective)

  • Arduino IR_SEND_PIN ? 1kO ? NPN base (e.g., 2N2222/BC547)
  • NPN emitter ? GND
  • IR LED anode ? +5V through a resistor (start with 100O to 220O)
  • IR LED cathode ? NPN collector
  • Arduino GND must share ground with the circuit
Why this works: The transistor handles current. The Arduino pin only provides base drive, improving range and stability.

10.2 Current-limiting resistor selection

Start conservative (220O). If range is too short and your transistor/LED remain cool, you can lower the resistor (e.g., 150O or 100O). Do not “guess aggressively” without understanding peak currents and duty cycle.


11) Practical project patterns

Pattern A: IR-controlled relay box

  • Use IR remote to toggle relay channels (lights/fans/low-voltage loads)
  • Add long-press to switch all relays off
  • Add a status display (TM1637 or OLED) for mode feedback

Pattern B: IR remote UI for tuning parameters

  • VOL+/VOL- changes setpoint
  • OK saves to EEPROM
  • Numbers select preset profiles

Pattern C: IR learning + replay “macro controller”

  • Capture multiple IR commands (TV on, input select, volume)
  • Store in EEPROM or flash
  • Replay as a macro when a single button is pressed

Pattern D: IR-to-WiFi bridge (NodeMCU/ESP8266/ESP32)

  • IR receiver reads remote
  • Publishes command to MQTT
  • Home automation server triggers actions

12) Troubleshooting and common pitfalls

Nothing prints in Serial Monitor

  • Check wiring: VCC, GND, OUT
  • Try a different digital pin and update IR_PIN
  • Confirm Serial baud rate matches the sketch (115200 in examples)
  • Shield from sunlight and strong lighting; test indoors first

Sometimes works, sometimes not

  • Power noise from motors/relays: separate supply rails and share ground
  • Receiver module too close to high-current wiring: move it away
  • Remote battery weak: replace CR2025
  • Angle/distance: IR works best when the remote faces the receiver

Transmit range is terrible

  • Use a transistor driver (do not rely on direct GPIO drive)
  • Check IR LED polarity (anode/cathode)
  • Ensure the library is sending the correct protocol (match what you decoded)
  • Try different resistor values conservatively (start at 220O)

Codes change or look inconsistent

  • You might be reading “repeat” frames; handle repeats explicitly
  • Some remotes use different protocols; print protocol/address/command for clarity
  • Ensure you call IrReceiver.resume() after each decode

13) Quick checklist


HX1838 IR Remote Kit (#196) Checklist
-------------------------------------
? Receiver wiring: VCC->5V, GND->GND, OUT->Digital pin (e.g., D2)
? Install IRremote library (Arduino Library Manager)
? First test: decode and print protocol/address/command to Serial
? Record button codes for mapping
? Implement debounce and handle repeat frames for long-press behavior
? For transmitting IR: use a transistor driver for the IR LED (better range)
? Match transmit protocol to what you actually decoded
? Test indoors first; sunlight and strong lighting can reduce reliability
    

Suggested next tutorials

  • Arduino: Relay Switching Best Practices (drivers, flyback, isolation)
  • Arduino UI Patterns: Remote + Display + EEPROM Presets
  • IoT Bridge: IR Receiver ? MQTT ? Automation Rules

Leobot Electronics · Waverley, Pretoria, South Africa — Nationwide Delivery

Products that this may apply to