Unit D - Sensors & Buses

22. Infrared Remote Control

Decode modulated infrared commands and map them to actions.

Estimated time 3 hours

Learning outcomes

  • Explain how a remote modulates IR light and a 38 kHz receiver demodulates it
  • Wire an IR receiver safely after checking its pin labels
  • Use IRremote 4.x (IRremote.hpp and IrReceiver) to print protocol and command
  • Capture your own remote codes, then map commands to sketch actions

Parts and preparation

Uno, 38 kHz IR receiver module, compatible IR remote, jumper wires, and IRremote by shirriff / z3t0 / ArminJo (see Libraries box).

Before power: inspect wiring, confirm supply voltage and ensure all connected circuits share GND.

Libraries for this lesson

In Arduino IDE 2 open Tools → Manage Libraries…. Search by the Library Manager name and install the package by the exact author below. Similar names from other authors can use different APIs and will break the example.

IncludeLibrary Manager nameAuthorInstall note
IRremote.hppIRremoteshirriff, z3t0, ArminJoInstall IRremote 4.x via Library Manager (maintainer Armin Joachimsmeyer). Older forks or 2.x examples use a different API.
Infrared Remote Control instructional connection diagram

IR remote vs IR obstacle sensor

This lesson uses a demodulating IR receiver module made for TV-style remotes (often labelled VS1838B or similar), plus a handset that flashes an infrared LED.

It is not the same as a reflective IR proximity / obstacle pair (those measure reflected light for distance or detection). Here the remote encodes button presses as timed bursts of infrared light; the receiver turns that into digital pulses for the Uno.

Flow from remote IR LED through a 38 kHz receiver that demodulates into pulses decoded by the Uno
Remote flashes a modulated IR carrier. Receiver demodulates. Library reports protocol and command.

Carrier, demodulation and protocols

Most consumer remotes modulate a carrier near 38 kHz so ambient light is less likely to look like a button press. The module strips that carrier and leaves a pulse train the MCU can time.

Protocols such as NEC define how address and command bits are packed into those pulses. You do not need to bit-bang the timing for this course - IRremote does that - but you do need to capture the protocol and command your handset actually sends.

Three cards for protocol, address and command fields reported by the IR library
Map actions from the command value you capture. Address is optional for early labs.
TermMeaning
CarrierAbout 38 kHz IR on/off that the module expects
ProtocolTiming rules (often NEC on kit remotes)
CommandValue for which button was pressed
RepeatHeld button may send repeat frames - handle if needed

Receiver pinout

Typical modules have three pins: VCC, GND and OUT (signal). Left-to-right order is not universal - some boards print OUT GND VCC, others VCC GND OUT. Always follow the silkscreen or datasheet before powering.

Course practice: OUT to D2, VCC to the voltage the module is rated for (commonly 5 V on Uno kits), GND shared. Aim the dome toward the remote and keep strong sunlight or some fluorescent lamps off the face if reception is noisy.

Two example IR receiver modules with different left-to-right pin orders for OUT GND VCC versus VCC GND OUT
Same three signals; never assume pin order. Read the labels on your part.
ConnectionCourse practice
OUTD2
VCCModule-rated supply (often 5 V)
GNDUno GND
RemotePoint at the receiver dome

IRremote 4.x API

Install IRremote 4.x from Library Manager (shirriff / z3t0 / ArminJo). Include IRremote.hpp. Call IrReceiver.begin in setup with the receive pin and optional LED feedback. In loop, if IrReceiver.decode() is true, read IrReceiver.decodedIRData, then call IrReceiver.resume().

Older tutorials and IRremote 2.x use a different object and header. If an example will not compile, check the major version before rewriting everything.

Flow of begin, decode, use protocol and command data, then resume for the next IR frame
begin once, then decode / use / resume. Skipping resume can freeze reception.
#include <IRremote.hpp>
const byte receivePin = 2;

void setup() {
  Serial.begin(9600);
  IrReceiver.begin(receivePin, ENABLE_LED_FEEDBACK);
}

void loop() {
  if (IrReceiver.decode()) {
    Serial.print(getProtocolString(IrReceiver.decodedIRData.protocol));
    Serial.print(" 0x");
    Serial.println(IrReceiver.decodedIRData.command, HEX);
    IrReceiver.resume();
  }
}

Capture, then map

Remotes are not interchangeable by button label. Press each key you care about and write down the printed Command HEX. Only then compare IrReceiver.decodedIRData.command to those constants and drive LEDs, buzzers or other outputs.

Ignore random code tables from websites unless they match your handset. Held buttons may produce repeats - for simple labs, mapping the first printed command is enough.

Three-step workflow: capture Serial command HEX, compare with if statements, then act on outputs
Capture your codes first. Then map. Challenge: three RGB colours from three buttons.
// After capture, replace 0x45 / 0x46 with YOUR commands
if (IrReceiver.decodedIRData.command == 0x45) {
  // action A
} else if (IrReceiver.decodedIRData.command == 0x46) {
  // action B
}

Wiring and safe build sequence

Breadboard wiring for lesson 22: Infrared Remote Control
Breadboard layout for this lesson. Match colours and pins before powering the circuit. Click the image for a larger view.
  1. Receiver VCC -> module-rated supply (commonly 5 V)
  2. GND -> GND
  3. OUT -> D2
  4. Confirm pin labels before applying power
Power rule: switch off before moving wires. Arduino I/O pins are control signals; high-current loads require a driver and suitable external supply.
#include <IRremote.hpp>

const byte receivePin = 2;

void setup() {
  Serial.begin(9600);
  IrReceiver.begin(receivePin, ENABLE_LED_FEEDBACK);
}

void loop() {
  if (IrReceiver.decode()) {
    Serial.print("Protocol=");
    Serial.print(getProtocolString(IrReceiver.decodedIRData.protocol));
    Serial.print(" Command=0x");
    Serial.println(IrReceiver.decodedIRData.command, HEX);
    IrReceiver.resume();
  }
}

How the code works

  1. Print protocol and command from your own remote before mapping actions.
  2. Command values are easier to map than copying arbitrary example raw codes.
  3. resume prepares the receiver for the next frame - call it after you finish using the data.

Test and record evidence

Expected result: Each remote press prints its protocol and command value.

Practical evidence checklist

Common faults and checks
  • Verify receiver pin order against the module labels.
  • Avoid direct sunlight or strong fluorescent interference on the dome.
  • Confirm installed IRremote major version is 4.x with IRremote.hpp.
  • Aim the remote at the receiver and try closer range.
  • If only one press works, check that resume() is called after decode.
Extension challenge: Capture three commands and use them to set an RGB LED to three colours.

Check your understanding

Q1. Why capture your own codes?

Show answer

Commands vary between remote models.

Q2. What does IrReceiver.resume do?

Show answer

Re-arms reception for the next message.

Q3. Why is pin order important on the receiver?

Show answer

VCC, GND and OUT order varies between packages.

Q4. What does the 38 kHz carrier help with?

Show answer

It helps the module reject ordinary ambient light as a remote signal.