The Direct Answer: Which IR Sensor and Arduino Pin to Use
If you are wiring an IR sensor to an Arduino to decode standard remote controls, use a 38kHz active receiver module like the KY-022 (specifically one with a Vishay TSOP38238 chip) connected to digital Pin 11, and utilize the IRremote v4.x library. Pin 11 is optimal on the Uno R3 because it is a hardware PWM-capable pin, which prevents timer conflicts if you later add an IR blaster (transmitter) to the same circuit.
The hobbyist market is flooded with IR modules. Here is the decision path to ensure you buy the right one for your specific application:
| Your Goal | Required Sensor Type | Concrete Part Pick |
|---|---|---|
| Decode TV/AC/Audio remotes (NEC, Sony, RC5 protocols) | 38kHz Carrier Demodulator | KY-022 (with TSOP38238) |
| Detect physical objects or obstacles (break-beam/proximity) | Active IR Emitter + Phototransistor | KY-032 (Obstacle Avoidance) |
| Analyze raw, unmodulated IR light (flame detection) | Raw Photodiode + Op-Amp | KY-015 or raw BPW34 diode |
Most cheap KY-022 modules ship with a generic VS1838B chip. While it works in dark rooms, its Automatic Gain Control (AGC) is notoriously fragile. If exposed to continuous IR noise (like CFL bulbs or direct sunlight), the VS1838B locks up and outputs a solid HIGH or LOW. If your project will be used in a living room with sunlight, spend the extra $1.50 to source a module with a genuine Vishay TSOP38238, which handles continuous noise gracefully without locking the AGC.
Parts List and Pin Mapping Spec Sheet
This build targets the Arduino Uno R3 (ATmega328P). While the code is compatible with the Uno R4 Minima and Nano, the Uno R3 remains the baseline for 5V logic and hardware timer mappings in the IRremote library.
| Component | Exact Variant / Spec | Est. Cost (2026) |
|---|---|---|
| Microcontroller | Arduino Uno R3 (ATmega328P, 5V logic) | $27.00 (Official) / $12.00 (Clone) |
| IR Receiver | KY-022 Module (TSOP38238 preferred, VS1838B acceptable) | $2.50 |
| Wiring | 3x Male-to-Female 20cm Dupont Jumper Wires | $0.50 |
| Library | IRremote by shirriff / crankyoldgit (v4.2.0 or newer) | Free (Arduino IDE Library Manager) |
Pin Mapping
| KY-022 Pin | Arduino Uno R3 Pin | Notes & Warnings |
|---|---|---|
| VCC (or +) | 5V | Do not use 3.3V. The internal preamp requires 4.5V-5.5V. Running at 3.3V causes brownouts and locked output states. |
| GND (or -) | GND | Ensure a solid ground connection; floating grounds introduce 60Hz/50Hz mains hum into the signal. |
| OUT (or S) | Digital Pin 11 | Outputs ACTIVE LOW (pulls to GND when IR is detected). Pin 11 avoids timer conflicts with Pin 9/10 PWM. |
Step-by-Step Wiring and Compilable Code
Follow these numbered steps to ensure a clean hardware connection before uploading code.
- De-energize the board: Unplug the USB cable from the Arduino Uno R3. Never wire sensors while the microcontroller is powered to avoid shorting the 5V rail to the data pin.
- Connect Power: Plug the red Dupont wire from the KY-022 VCC pin to the Arduino 5V pin. Plug the black wire from GND to GND.
- Connect Signal: Plug the yellow (or signal) wire from the KY-022 OUT pin to Arduino Digital Pin 11.
- Verify Voltage: Power the Arduino via USB. Use a multimeter set to DC Voltage. Probe the VCC and GND pins directly on the KY-022 module header. You must read between 4.8V and 5.1V. If you read 3.3V, you are on the wrong power rail.
- Install Library: Open Arduino IDE, go to Sketch > Include Library > Manage Libraries, search for
IRremote, and install the latest v4.x release by shirriff.
Complete Compilable Code (IRremote v4.x)
This code includes explicit pin definitions, overflow error handling, and repeat-code filtering. It targets the Uno R3 architecture.
#include
// Explicit pin definition - change if using a different board variant
#define IR_RECEIVE_PIN 11
void setup() {
// Initialize serial at a fast baud rate to prevent buffer overruns
Serial.begin(115200);
// Start the IR receiver. ENABLE_LED_FEEDBACK blinks the onboard LED on receive.
// If your module has its own LED, you can pass DISABLE_LED_FEEDBACK.
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);
Serial.println("IR Receiver initialized on Pin 11.");
Serial.println("Point your remote at the sensor and press a button.");
}
void loop() {
// Check if a complete IR frame has been received
if (IrReceiver.decode()) {
// ERROR HANDLING: Check for buffer overflow (happens if signal is too long/noisy)
if (IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_OVERFLOW) {
Serial.println("ERROR: IR Buffer Overflow. Signal too long or excessive noise.");
}
// Handle standard repeat codes (when user holds down a button)
else if (IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT) {
Serial.println("REPEAT command received.");
}
// Handle valid, new IR data
else {
Serial.print("Protocol: ");
Serial.print(IrReceiver.decodedIRData.protocol);
Serial.print(" | Hex Value: ");
// Print the raw 32-bit hex value of the command
Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX);
// Example: Trigger an action for a specific NEC Power button code
if (IrReceiver.decodedIRData.decodedRawData == 0xFFA25D) {
Serial.println(">>> POWER BUTTON PRESSED <<<");
}
}
// CRITICAL: Resume the receiver to clear the buffer and listen for the next signal
IrReceiver.resume();
}
}
Debugging: The First Three Things to Check When It Fails
IR circuits are notorious for silent failures and cryptic serial output. If your build isn't working, run through this ranked troubleshooting path.
1. Compiler Error: 'IRrecv' does not name a type
The Exact Error String: error: 'IRrecv' does not name a type; did you mean 'irrecv'? or error: 'IRremote' was not declared in this scope.
The Cause: You copied code from a tutorial written before 2021. The IRremote library underwent a massive API rewrite in v3.0. The old object-oriented syntax (IRrecv irrecv(RECV_PIN);) was completely deprecated in favor of the singleton IrReceiver object.
The Fix: Delete the old object declarations. Replace irrecv.enableIRIn() with IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK), and replace irrecv.resume() with IrReceiver.resume(). Use the exact code block provided above.
2. Serial Monitor Spamming 'FFFFFFFF' or Random Hex
The Symptom: Without pressing any buttons, the serial monitor rapidly prints FFFFFFFF or random 8-character hex strings.
The Cause: The TSOP38238/VS1838B is being blinded by ambient IR noise. Compact Fluorescent Lamps (CFLs), incandescent bulbs, and direct sunlight emit massive amounts of broad-spectrum IR light. The sensor's AGC maxes out, and it interprets the noise as a continuous stream of data.
The Fix:
- Hardware: Create a physical shroud. Roll a small piece of black electrical tape into a tube and place it over the IR dome to block off-axis light.
- Environmental: Move the prototype away from windows and CFL desk lamps. Test in a shaded area.
3. Hardware LED is Solid ON or Completely Dead
The Symptom: The tiny LED on the KY-022 module stays solidly lit, or it never blinks even when a remote is pressed directly against it.
The Cause: Voltage mismatch or a blown internal current-limiting resistor. If wired to the 3.3V pin, the VS1838B chip brownouts, causing the output transistor to latch LOW (which turns the module's indicator LED solid ON). If completely dead, the 5V trace may be severed.
The Fix: Disconnect power. Move the VCC wire to the 5V pin. Re-measure with a multimeter. If the LED remains solid ON at 5V, the module's internal photodiode is shorted; discard the $2 module and replace it.
Extending and Simplifying Your IR Build
Once you have stable serial output, you need to decide how to scale the project. Here is the definitive path forward based on your end goal.
How to Extend: Add High-Voltage Switching
If your goal is home automation (e.g., turning on a desk lamp or fan with a TV remote), do not wire the Arduino directly to the load. Extend the build by adding a 5V SRD-05VDC-SL-C Relay Module.
- Wire the Relay VCC to Arduino 5V, GND to GND, and IN to Digital Pin 8.
- In the
setup(), addpinMode(8, OUTPUT); digitalWrite(8, HIGH);(most relay modules are ACTIVE LOW). - In the
loop(), when your target hex code is matched, toggle the pin:digitalWrite(8, !digitalRead(8));.
How to Simplify: Ditch the Wiring
If you hate Dupont wires and breadboard noise, simplify the build by migrating to an ESP32-based integrated module like the M5Stack Core2 or an ESP8266 NodeMCU with a pre-soldered IR shield. These boards integrate the IR receiver, microcontroller, and display into a single PCB, eliminating loose connections. For the ESP32, use the IRremoteESP8266 fork, which is optimized for the ESP32's dual-core RTOS environment and prevents the watchdog timer resets that can occur on single-core AVRs during long IR frame decodes.
Final Recommendation: For 95% of hobbyist remote-control decoding projects, the KY-022 (TSOP38238) paired with an Arduino Uno R3 on Pin 11 is the undisputed standard. It offers the best balance of 5V logic compatibility, library support, and physical prototyping ease. Buy the TSOP38238 variant to avoid sunlight lockups, use the IRremote v4 singleton API, and your IR sensor to Arduino integration will work on the first compile.






