TheSolderBenchnotes from my electronics bench

Log #67 · Oct 15, 2026

How to Use an IR Remote and Receiver with Arduino

Read any TV-style infrared remote with a VS1838B or TSOP receiver, find the code of each button, and use them to switch LEDs or relays. Wiring, IRremote library code and troubleshooting.

Sensors · 4 min read · Beginner

The small black-domed IR receiver in most Arduino kits can read almost any remote control: the credit-card remote from the kit, an old TV remote or an air-conditioner remote. With a few lines of code you can turn lights on and off, steer a robot or control a fan from across the room.

How IR remotes work

The remote has an infrared LED that flashes invisible light in a pattern. To avoid confusion with sunlight and lamps, the flashes are modulated at about 38 kHz: the LED blinks 38,000 times per second during each "on" pulse. The receiver module contains a photodiode, an amplifier and a filter tuned to 38 kHz, so it ignores steady light and outputs a clean digital signal: LOW while it sees 38 kHz bursts, HIGH otherwise.

The pattern of pulses encodes a protocol (NEC is the most common on cheap remotes), an address and a command, one per button. The Arduino library decodes all of that for you.

Wiring diagram: an IR receiver module with OUT, GND and VCC pins connected to Arduino pin 2, GND and 5V; a remote sends infrared pulses to the receiver; three LEDs on pins 8, 9 and 10 through 220 ohm resistors
Three wires for the receiver. The LEDs are just something to control.

Wiring

Receiver pin Arduino
OUT (S, signal) pin 2
GND (−) GND
VCC (+) 5 V

Check the pin order on your part. On a bare VS1838B, facing the dome, it is usually OUT, GND, VCC from left to right. On three-pin modules (KY-022) it's often S, + (middle), −, but some boards use −, +, S, so follow the labels printed on your board. Wiring VCC and GND backwards can destroy the receiver in seconds, and it gets hot.

For the example below, add three LEDs on pins 8, 9 and 10, each with a 220 Ω resistor (see choosing a resistor for an LED).

Install the library

In the Library Manager, search IRremote and install the one by shirriff, z3t0, ArminJo. This guide uses version 4.x, which changed the code style compared with old tutorials. If you copy an old sketch with IRrecv irrecv(...) and results.value, it is deprecated on the new version and gives different code values, so rewrite it in the new style shown here.

Step 1: read your remote's codes

#include <IRremote.hpp>

const int IR_PIN = 2;

void setup() {
  Serial.begin(9600);
  IrReceiver.begin(IR_PIN, ENABLE_LED_FEEDBACK);  // built-in LED blinks on signals
  Serial.println("Press buttons on the remote...");
}

void loop() {
  if (IrReceiver.decode()) {
    IrReceiver.printIRResultShort(&Serial);       // protocol, address, command
    IrReceiver.resume();                          // ready for the next one
  }
}

Open the Serial Monitor at 9600 baud and press each button. You'll see lines like:

Protocol=NEC Address=0x0 Command=0x45 Raw-Data=0xBA45FF00 32 bits LSB first

Write down the Command value for each button you want to use. Holding a button down usually sends repeat frames, shown with a "Repeat" flag.

Step 2: control things with the buttons

Replace the three command values with the ones from your remote:

#include <IRremote.hpp>

const int IR_PIN = 2;
const int LED_PINS[] = {8, 9, 10};

// Commands from step 1 (these are typical for the kit remote: 1, 2, 3)
const uint8_t BTN_1 = 0x0C;
const uint8_t BTN_2 = 0x18;
const uint8_t BTN_3 = 0x5E;

bool ledState[3] = {false, false, false};

void toggle(int i) {
  ledState[i] = !ledState[i];
  digitalWrite(LED_PINS[i], ledState[i] ? HIGH : LOW);
}

void setup() {
  Serial.begin(9600);
  for (int i = 0; i < 3; i++) pinMode(LED_PINS[i], OUTPUT);
  IrReceiver.begin(IR_PIN, ENABLE_LED_FEEDBACK);
}

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

  bool isRepeat = IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT;
  uint8_t cmd = IrReceiver.decodedIRData.command;
  IrReceiver.resume();

  if (isRepeat) return;            // ignore held-down repeats for toggles

  if (cmd == BTN_1) toggle(0);
  else if (cmd == BTN_2) toggle(1);
  else if (cmd == BTN_3) toggle(2);
  else {
    Serial.print("Unknown command 0x");
    Serial.println(cmd, HEX);
  }
}

Ignoring repeats keeps a toggle from flickering on and off while you hold the button. For something like volume or motor speed, you might want to use the repeats instead, so holding the button keeps changing the value.

To switch a lamp or anything on mains power, drive a relay module from one of the pins instead of an LED, and follow its safety rules.

Range and reliability

  • Typical range is 5–10 m in a room, less in bright sunlight.
  • Some LED and fluorescent lamps flicker in a way that confuses the receiver. If you get random codes, shade the receiver or move it.
  • A 100 Ω resistor in series with VCC and a 4.7–10 µF capacitor from VCC to GND near the receiver filter supply noise, the same circuit used inside TVs. Many modules already have it.
  • The remote and receiver must match the carrier frequency. 38 kHz is by far the most common; a 36 or 40 kHz remote usually still works at shorter range.

Conflicts to know about

On the Uno and Nano, the IRremote library uses Timer2, which is also used by tone() and by PWM on pins 3 and 11. If you need a buzzer with IR, use a buzzer that beeps on its own (active buzzer) with digitalWrite(), or check the library docs for selecting another timer. The Servo library uses Timer1, so servos and IR work together.

Troubleshooting

  • Nothing prints: check the pin order and that OUT goes to pin 2. The built-in LED should flicker when you press a button.
  • Receiver gets hot: VCC and GND are reversed. Unplug immediately.
  • Old sketch gives warnings or strange codes: it was written for IRremote 2.x. Use the new IrReceiver style shown here.
  • Codes are different every press: you're seeing "UNKNOWN" protocol or noise. Move closer, shade the receiver, and try another remote.

— TheSolderBench · found a mistake? tell me

More pages from this notebook

How to Use a PIR Motion Sensor

How passive infrared sensors detect people, how to set the HC-SR501 sensitivity and delay knobs, and code for a motion-activated light.

→ wait 60 s before trusting it

Reading a Potentiometer and a Joystick with Arduino

How potentiometers and analog thumb joysticks work, how to wire and read them, and how to add a dead zone and smoothing for steady control.

→ joystick center isn't exactly 512, add a dead zone