Moostafia Goattea
Published

Universal decoding IR remote

Decode any IR remote and use it with your own universal remote customizing and programming the buttons one by one. A simple way to customize

IntermediateFull instructions provided2 hours113
Universal decoding IR remote

Things used in this project

Hardware components

Arduino Mega 2560
Arduino Mega 2560
×1
RGB LCD Shield Kit, 16x2 Character Display
RGB LCD Shield Kit, 16x2 Character Display
×1
Elegoo Membrane switch module. Keypad
×1
Elegoo IR receiver module (38kHz)
×1
IR LED (transmitter)
×1
Resistor 220 ohm
Resistor 220 ohm
×1
Single Turn Potentiometer- 10k ohms
Single Turn Potentiometer- 10k ohms
×1
Breadboard and jumper wires
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

layout

IR decoder and emitter

The layout for your breadboard and Arduino

Code

IR Decoder and emitter

C/C++
#include <LiquidCrystal.h>
#include <IRremote.h>
#include <Keypad.h>
#include <EEPROM.h>

// LCD pins - D4 moved to pin 13
LiquidCrystal lcd(7, 8, 13, 10, 11, 12);

// IR pins
#define IR_RECEIVE_PIN 5
// IR transmit is automatically pin 9 on Arduino Mega

// Keypad setup
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {31, 32, 33, 34};
byte colPins[COLS] = {35, 36, 37, 38};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

// IR objects
IRrecv irrecv(IR_RECEIVE_PIN);
IRsend irsend;
decode_results results;

// Stored IR codes (16 buttons)
unsigned long storedCodes[16];

// State machine
enum State { READY, WAITING_FOR_IR, WAITING_FOR_BUTTON };
State state = READY;

unsigned long capturedCode = 0;
int poundCount = 0;
unsigned long lastPoundTime = 0;

int keyIndex(char key) {
  String keyList = "123A456B789C*0#D";
  return keyList.indexOf(key);
}

void showReady() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("IR Remote Ready");
  Serial.println("--- State: READY ---");
}

void setup() {
  Serial.begin(9600);
  Serial.println("=== IR Remote Starting ===");

  lcd.begin(16, 2);
  showReady();
  irrecv.enableIRIn();
  Serial.println("IR Receiver enabled on pin 5");
  Serial.println("IR Transmitter on pin 9 (Mega default)");

  // Load stored codes from EEPROM
  for (int i = 0; i < 16; i++) {
    EEPROM.get(i * sizeof(unsigned long), storedCodes[i]);
    if (storedCodes[i] != 0xFFFFFFFF && storedCodes[i] != 0) {
      Serial.print("EEPROM loaded slot ");
      Serial.print(i);
      Serial.print(": 0x");
      Serial.println(storedCodes[i], HEX);
    }
  }
}

void loop() {
  char key = keypad.getKey();

  if (key != NO_KEY) {
    Serial.print("Key pressed: ");
    Serial.println(key);

    if (key == '#') {
      unsigned long now = millis();
      if (now - lastPoundTime < 1000) {
        poundCount++;
      } else {
        poundCount = 1;
      }
      lastPoundTime = now;
      Serial.print("Pound count: ");
      Serial.println(poundCount);

      if (poundCount >= 2) {
        poundCount = 0;

        if (state == READY) {
          state = WAITING_FOR_IR;
          capturedCode = 0;
          irrecv.enableIRIn();
          Serial.println("Entering LEARN MODE  waiting for IR signal...");
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Code Ready to");
          lcd.setCursor(0, 1);
          lcd.print("Receive...");

        } else if (state == WAITING_FOR_BUTTON) {
          Serial.println("Learn mode cancelled.");
          state = READY;
          capturedCode = 0;
          showReady();
          irrecv.enableIRIn();
        }
      }

    } else {
      poundCount = 0;

      if (state == WAITING_FOR_BUTTON && capturedCode != 0) {
        int idx = keyIndex(key);
        storedCodes[idx] = capturedCode;
        EEPROM.put(idx * sizeof(unsigned long), capturedCode);

        Serial.print("Code 0x");
        Serial.print(capturedCode, HEX);
        Serial.print(" programmed to button: ");
        Serial.println(key);

        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Programmed to:");
        lcd.setCursor(0, 1);
        lcd.print(key);
        delay(2000);

        state = READY;
        capturedCode = 0;
        showReady();
        irrecv.enableIRIn();

      } else if (state == READY) {
        int idx = keyIndex(key);
        Serial.print("Transmit request for button: ");
        Serial.print(key);
        Serial.print(" (slot ");
        Serial.print(idx);
        Serial.print(")  stored code: 0x");
        Serial.println(storedCodes[idx], HEX);

        if (storedCodes[idx] != 0 && storedCodes[idx] != 0xFFFFFFFF) {
          Serial.println("Transmitting now via IR LED on pin 9...");
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Sending:");
          lcd.setCursor(0, 1);
          lcd.print(storedCodes[idx], HEX);
          irsend.sendNEC(storedCodes[idx], 32);
          Serial.println("Transmission complete.");
          delay(500);
          irrecv.enableIRIn();
          delay(500);
          showReady();
        } else {
          Serial.println("No code stored for this button.");
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("No code for:");
          lcd.setCursor(0, 1);
          lcd.print(key);
          delay(2000);
          showReady();
        }
      }
    }
  }

  // Receive IR in learn mode
  if (state == WAITING_FOR_IR) {
    if (irrecv.decode(&results)) {
      Serial.print("IR signal received! Raw value: 0x");
      Serial.print(results.value, HEX);
      Serial.print(" Protocol: ");
      Serial.println(results.decode_type);

      if (results.value != 0xFFFFFFFF) {
        capturedCode = results.value;
        Serial.print("Captured code: 0x");
        Serial.println(capturedCode, HEX);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Code: ");
        lcd.print(capturedCode, HEX);
        lcd.setCursor(0, 1);
        lcd.print("Press a button");
        state = WAITING_FOR_BUTTON;
        Serial.println("State: WAITING_FOR_BUTTON  press keypad button to assign");
      } else {
        Serial.println("Repeat code received, ignoring...");
      }
      irrecv.resume();
    }
  }
}

Credits

Moostafia Goattea
1 project • 0 followers

Comments