Build a compact multi-function IR remote system using Arduino Nano, a TSOP38238 IR receiver module, and an IR transmitter LED. This project combines IR signal decoding and IR signal transmission into a single embedded platform. The first Arduino setup captures infrared remote control signals and displays complete NEC protocol information including hexadecimal raw code, protocol type, address, and command values on the Serial Monitor. The second setup works as a programmable IR remote transmitter capable of controlling RGB LED strips and wireless motor functions using only three push buttons. The system supports EEPROM-based IR code storage, RGB color cycling, custom motor control commands, long-press mode switching, and onboard LED visual feedback. This project demonstrates practical implementation of infrared communication, NEC protocol handling, EEPROM memory usage, multi-button input processing, and wireless embedded control systems using the IRremote library.
Components Required
About the Components
Arduino Nano with Type-C
The Arduino Nano with USB Type-C is a compact and breadboard-friendly development board based on the ATmega328P microcontroller. It features a modern USB Type-C connector for reliable connectivity and uses the CH340 USB-to-Serial converter for programming and serial communication. Its small DIP form factor makes it suitable for embedded electronics and compact DIY projects.

- ATmega328P microcontroller
- USB Type-C interface
- CH340 USB-to-Serial converter
- Compact breadboard-friendly design
- Supports UART, SPI, and I2C communication
- 14 Digital I/O pins with PWM support
- 8 Analog input pins
- 16 MHz clock speed
- 32 KB Flash memory
- Compatible with Arduino IDE
In this project, the Arduino Nano captures infrared signals, stores NEC codes, processes button inputs, and transmits wireless infrared commands.
TSOP38238 IR Receiver
The TSOP38238 is an infrared receiver module designed for decoding 38KHz infrared remote signals. It includes internal demodulation and noise filtering circuitry for reliable signal reception.

- 38KHz infrared signal detection
- Low power consumption
- Built-in noise filtering
- Active LOW output
- Supports NEC protocol
- Compatible with Arduino platforms
In this project, the TSOP38238 receives infrared remote signals and sends decoded pulse data to the Arduino Nano.
5mm IR Transmitter LED
The IR transmitter LED emits infrared light invisible to the human eye but detectable by infrared receivers. It is commonly used in remote controls and wireless infrared communication systems.

- 940nm infrared wavelength
- Suitable for 38KHz modulation
- Low forward voltage
- Compatible with IRremote library
- Used for NEC infrared transmission
In this project, the IR LED transmits learned NEC commands and custom motor control signals wirelessly.
Circuit Connection

Fig. Circuit Diagram

Fig. Schematic Diagram
IR Receiver Connection
- OUT → Arduino Pin 3
- VCC → 5V
- GND → GND
IR LED Connection
- Anode → Arduino Pin 2 through 220Ω resistor
- Cathode → GND
Push Button Connection
- Button 1 → Pin 5 → GND
- Button 2 → Pin 8 → GND
- Button 3 → Pin 11 → GND
(INPUT_PULLUP configuration)
Code Explanation
Libraries Used
Arduino · C++
#include <IRremote.hpp>
#include <EEPROM.h>
Purpose of Libraries
#include <IRremote.hpp> → Handles infrared signal decoding and NEC protocol transmission.
#include <EEPROM.h> → Stores learned infrared codes permanently inside EEPROM memory.
IR Code Capture
Arduino · C++
IrReceiver.begin(IR_RECEIVE_PIN, DISABLE_LED_FEEDBACK);
Initializes the infrared receiver module and starts listening for remote control signals.
Decoded Data Printing
Arduino · C++
Serial.print("Captured Code: 0x");
Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX);
Serial.print("Protocol: ");
Serial.println(getProtocolString(IrReceiver.decodedIRData.protocol));
Serial.print("Address: 0x");
Serial.println(IrReceiver.decodedIRData.address, HEX);
Serial.print("Command: 0x");
Serial.println(IrReceiver.decodedIRData.command, HEX);
Prints complete infrared decoding information including hexadecimal raw code, protocol type, address, and command value.
Pin Definitions
Arduino · C++
const int IR_SEND_PIN = 2;
const int IR_RECEIVE_PIN = 3;
const int BUTTON_POWER = 5;
const int BUTTON_UP = 8;
const int BUTTON_DOWN = 11;
const int STATUS_LED = 13;
- IR_SEND_PIN → IR LED output pin
- IR_RECEIVE_PIN → TSOP38238 receiver input pin
- BUTTON_POWER → Power and mode switching
- BUTTON_UP → RGB color cycle or motor speed increase
- BUTTON_DOWN → LED effects or motor speed decrease
- STATUS_LED → Visual feedback indicator
EEPROM Code Storage
Arduino · C++
EEPROM.get(0, savedCodeOn);
EEPROM.get(4, savedCodeOff);
Loads previously stored ON and OFF infrared commands from EEPROM memory.
Mode Switching
Arduino · C++
if (millis() - pressStartTime > 2000) {
isMotorMode = !isMotorMode;
}
A long press on the power button toggles between LED control mode and motor control mode.
IR Signal Transmission
Arduino · C++
IrSender.sendNECRaw(savedCodeOn, 0);
Transmits stored NEC infrared commands wirelessly through the IR LED.
RGB Color Cycling
Arduino · C++
IrSender.sendNECRaw(COLORS[colorTracker], 0);
Cycles through multiple predefined RGB LED colors sequentially.
Motor Control Commands
Arduino · C++
const uint32_t MOTOR_POWER = 0xE111EF00;
const uint32_t MOTOR_SPEED_UP = 0xE222EF00;
const uint32_t MOTOR_SPEED_DOWN = 0xE333EF00;
Custom NEC hexadecimal values are used as wireless motor control commands.
Status LED Feedback
Arduino · C++
digitalWrite(STATUS_LED, HIGH);
delay(800);
digitalWrite(STATUS_LED, LOW);
The onboard LED provides visual indication during mode switching.
Working of Loop
- Continuously monitors push buttons and IR receiver input
- Captures and decodes NEC infrared signals
- Prints protocol, command, and hexadecimal data
- Detects short press and long press actions
- Switches between LED mode and motor mode
- Loads saved IR codes from EEPROM
- Transmits NEC infrared commands
- Cycles RGB LED colors
- Sends wireless motor control signals
- Provides LED feedback for active mode
System Summary
The Arduino Nano continuously receives and decodes infrared remote signals using the TSOP38238 receiver module. Captured NEC hexadecimal codes can then be retransmitted wirelessly using the IR LED for RGB LED strip control and motor-based applications. EEPROM memory preserves learned codes after power loss, while the dual-mode architecture enables multiple wireless control functions using only three push buttons.
Why this Architecture Works
- Infrared communication enables low-cost wireless control
- EEPROM storage preserves learned NEC codes
- Dual-mode operation increases functionality without extra hardware
- NEC protocol support ensures compatibility with common remotes
- Single-controller architecture simplifies implementation
- Push-button multiplexing reduces hardware complexity
Real-Life Applications
-
RGB LED Controller: Wireless lighting control system
-
Motor Control: Infrared-based robotic or fan control
-
Home Automation: Appliance switching using custom remotes
-
DIY Smart Devices: Multi-function programmable IR transmitter
-
Embedded Systems Learning: Practical NEC protocol implementation
Result
The system successfully captures infrared remote signals and decodes NEC protocol information including hexadecimal raw code, protocol type, address, and command values. The Arduino Nano transmitter reliably retransmits stored infrared commands for RGB LED control and wireless motor operation. EEPROM-based code storage, RGB color cycling, custom motor commands, and long-press mode switching operate correctly, creating a compact and flexible multi-function infrared remote system.

Code
IR Code Capture Sketch
#include <IRremote.hpp>
const int IR_RECEIVE_PIN = 3;
void setup() {
Serial.begin(115200);
// Start IR Receiver
IrReceiver.begin(IR_RECEIVE_PIN, DISABLE_LED_FEEDBACK);
Serial.println("IR Code Capture Ready");
Serial.println("Press any button on your remote...");
}
void loop() {
// Check if IR signal received
if (IrReceiver.decode()) {
// Print Raw HEX Code
Serial.print("Captured Code: 0x");
Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX);
// Print Protocol Type
Serial.print("Protocol: ");
Serial.println(getProtocolString(IrReceiver.decodedIRData.protocol));
// Print Address
Serial.print("Address: 0x");
Serial.println(IrReceiver.decodedIRData.address, HEX);
// Print Command
Serial.print("Command: 0x");
Serial.println(IrReceiver.decodedIRData.command, HEX);
Serial.println("-------------------------");
// Resume receiver
IrReceiver.resume();
}
}
IR Remote Transmitter Sketch
#include <IRremote.hpp>
#include <EEPROM.h>
// --- PIN DEFINITIONS ---
const int IR_SEND_PIN = 2;
const int BUTTON_POWER = 5;
const int BUTTON_UP = 8;
const int BUTTON_DOWN = 11;
const int STATUS_LED = 13;
// --- STATE TRACKING ---
bool isMotorMode = false;
bool isPowerOn = false;
// --- SAVED POWER CODES ---
uint32_t savedCodeOn = 0;
uint32_t savedCodeOff = 0;
// --- MOTOR COMMAND CODES ---
const uint32_t MOTOR_POWER = 0xE111EF00;
const uint32_t MOTOR_SPEED_UP = 0xE222EF00;
const uint32_t MOTOR_SPEED_DOWN = 0xE333EF00;
// --- LED COLOR CODES ---
const uint32_t COLORS[] = {
0xFB04EF00, 0xFA05EF00, 0xF906EF00,
0xF708EF00, 0xF609EF00, 0xF50AEF00,
0xF30CEF00, 0xF20DEF00, 0xF10EEF00,
0xEF10EF00, 0xEE11EF00, 0xED12EF00,
0xEB14EF00, 0xEA15EF00, 0xE916EF00
};
const int NUM_COLORS = 15;
int colorTracker = 0;
void setup() {
Serial.begin(115200);
IrSender.begin(IR_SEND_PIN, DISABLE_LED_FEEDBACK);
pinMode(BUTTON_POWER, INPUT_PULLUP);
pinMode(BUTTON_UP, INPUT_PULLUP);
pinMode(BUTTON_DOWN, INPUT_PULLUP);
pinMode(STATUS_LED, OUTPUT);
EEPROM.get(0, savedCodeOn);
EEPROM.get(4, savedCodeOff);
Serial.println("Nano Remote Ready!");
}
void loop() {
// --- BUTTON 1 : POWER & MODE TOGGLE ---
if (digitalRead(BUTTON_POWER) == LOW) {
unsigned long pressStartTime = millis();
bool isLongPress = false;
while (digitalRead(BUTTON_POWER) == LOW) {
if (millis() - pressStartTime > 2000) {
isLongPress = true;
break;
}
}
if (isLongPress) {
// TOGGLE MODE
isMotorMode = !isMotorMode;
visualFeedback(isMotorMode);
Serial.println(isMotorMode ? "Switched to MOTOR MODE" : "Switched to LED MODE");
} else {
// SHORT PRESS
if (isMotorMode) {
IrSender.sendNECRaw(MOTOR_POWER, 0);
} else {
isPowerOn ? IrSender.sendNECRaw(savedCodeOff, 0)
: IrSender.sendNECRaw(savedCodeOn, 0);
isPowerOn = !isPowerOn;
}
}
delay(300);
while (digitalRead(BUTTON_POWER) == LOW);
}
// --- BUTTON 2 : COLOR / SPEED UP ---
if (digitalRead(BUTTON_UP) == LOW) {
if (isMotorMode) {
IrSender.sendNECRaw(MOTOR_SPEED_UP, 0);
} else {
IrSender.sendNECRaw(COLORS[colorTracker], 0);
colorTracker = (colorTracker + 1) % NUM_COLORS;
}
delay(300);
while (digitalRead(BUTTON_UP) == LOW);
}
// --- BUTTON 3 : EFFECT / SPEED DOWN ---
if (digitalRead(BUTTON_DOWN) == LOW) {
if (isMotorMode) {
IrSender.sendNECRaw(MOTOR_SPEED_DOWN, 0);
} else {
IrSender.sendNECRaw(0xEC13EF00, 0);
}
delay(300);
while (digitalRead(BUTTON_DOWN) == LOW);
}
}
void visualFeedback(bool motorMode) {
if (motorMode) {
digitalWrite(STATUS_LED, HIGH);
delay(800);
digitalWrite(STATUS_LED, LOW);
} else {
for (int i = 0; i < 3; i++) {
digitalWrite(STATUS_LED, HIGH);
delay(100);
digitalWrite(STATUS_LED, LOW);
delay(100);
}
}
}