Skip to content

support@quartzcomponents.com

Free Shipping Over INR 500

Electronics Projects

DIY Arduino IR Remote Controller System with Signal Decoding

by RISHABH JANGID 12 May 2026 0 Comments

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);
    }
  }
}
Prev Post
Next Post

Leave a comment

Please note, comments need to be approved before they are published.

Thanks for subscribing!

This email has been registered!

Shop the look

Choose Options

Edit Option
Back In Stock Notification
is added to your shopping cart.
this is just a warning
Login