PROJECTS (DIY)Embedded DIY

สร้างรีโมตอัจฉริยะด้วย Arduino Nano รับ–ส่งสัญญาณได้ในตัว

เปลี่ยน Arduino Nano ให้กลายเป็นระบบรีโมตอินฟราเรด (IR Remote) แบบมัลติฟังก์ชันที่สามารถทั้ง รับ ถอดรหัส และส่งสัญญาณอินฟราเรด ได้ในอุปกรณ์ชุดเดียว โดยใช้ Arduino Nano, โมดูลรับสัญญาณ TSOP38238 และ IR Transmitter LED เป็นองค์ประกอบหลัก โปรเจกต์นี้ผสานการทำงานของ IR Signal Decoding และ IR Signal Transmission ไว้บนแพลตฟอร์ม Embedded เพื่อสร้างระบบควบคุมอุปกรณ์ผ่านสัญญาณอินฟราเรดได้อย่างครบวงจร

การทำงานของระบบแบ่งออกเป็น 2 ส่วนหลัก ได้แก่ การเรียนรู้และถอดรหัสสัญญาณอินฟราเรด และ การส่งคำสั่งควบคุมผ่านอินฟราเรด

ในส่วนแรก Arduino จะทำหน้าที่เป็นตัวรับสัญญาณจากรีโมตอินฟราเรด โดยใช้โมดูล TSOP38238 ในการรับข้อมูล จากนั้นระบบจะถอดรหัสตามโปรโตคอล NEC และแสดงรายละเอียดของสัญญาณที่ได้รับผ่าน Serial Monitor ซึ่งประกอบด้วย Raw Code ในรูปแบบ Hexadecimal, Protocol Type, Address และ Command ทำให้สามารถตรวจสอบและนำรหัสเหล่านี้ไปใช้งานต่อได้อย่างสะดวก

เมื่อได้รหัสอินฟราเรดที่ต้องการแล้ว ระบบจะสามารถทำงานเป็นรีโมตอินฟราเรดแบบโปรแกรมได้ (Programmable IR Remote Transmitter) สำหรับส่งคำสั่งกลับผ่าน IR LED เพื่อควบคุมอุปกรณ์ต่าง ๆ เช่น แถบไฟ RGB LED และ ระบบควบคุมมอเตอร์แบบไร้สาย โดยใช้ปุ่มกดเพียง 3 ปุ่ม

ระบบสามารถบันทึกรหัสอินฟราเรดที่ถอดรหัสได้ลงในหน่วยความจำ EEPROM ทำให้ข้อมูลคำสั่งยังคงอยู่แม้หลังจากปิดการทำงานของระบบ และสามารถนำกลับมาใช้งานได้ทันทีโดยไม่ต้องรับสัญญาณใหม่อีกครั้ง นอกจากนี้ยังรองรับฟังก์ชันต่าง ๆ เช่น การเปลี่ยนสี RGB LED, การกำหนดคำสั่งควบคุมมอเตอร์แบบเฉพาะ, การสลับโหมดด้วยการกดปุ่มค้าง และการแสดงสถานะการทำงานผ่าน LED บนบอร์ด

ด้วยการผสานความสามารถของ Arduino, การสื่อสารผ่านอินฟราเรด และไลบรารี IRremote โปรเจกต์นี้จึงเป็นตัวอย่างของการสร้างระบบควบคุมไร้สายบนแพลตฟอร์ม Embedded ที่รวมการรับส่งสัญญาณ IR, การจัดการโปรโตคอล NEC, การบันทึกข้อมูลด้วย EEPROM และการควบคุมผ่านปุ่มกดหลายรูปแบบไว้ในระบบเดียว

อุปกรณ์ที่ใช้

  • Arduino Nano
  • IR LED เบอร์ TSAL6400
  • โมดูลรับสัญญาณอินฟราเรด TSOP38238
  • ตัวต้านทาน 82Ω 1/4W 5%
  • ปุ่มกด (Push Button)
  • เบรดบอร์ด (Breadboard)
  • สายเชื่อมต่อ (Connecting Wires)

รู้จักอุปกรณ์

Arduino Nano พร้อมพอร์ต USB Type-C

Arduino Nano with Type-C
Fig1. Arduino Nano

Arduino Nano พร้อมพอร์ต USB Type-C เป็นบอร์ดพัฒนาขนาดกะทัดรัดที่สามารถใช้งานร่วมกับเบรดบอร์ดได้สะดวก โดยใช้ไมโครคอนโทรลเลอร์ ATmega328P เป็นแกนหลัก

บอร์ดรุ่นนี้มาพร้อมพอร์ต USB Type-C ซึ่งให้การเชื่อมต่อที่มีความเสถียรและเชื่อถือได้ และใช้ชิป CH340 USB-to-Serial Converter สำหรับการโปรแกรมบอร์ดและการสื่อสารผ่านพอร์ตอนุกรม (Serial Communication)

ด้วยรูปแบบบอร์ดแบบ DIP ขนาดเล็ก จึงเหมาะสำหรับงานด้าน Embedded Electronics และโปรเจกต์ DIY ที่มีข้อจำกัดด้านพื้นที่ติดตั้ง


TSOP38238 IR Receiver

TSOP38238 IR Receiver
Fig2. TSOP38238

TSOP38238 เป็นโมดูลรับสัญญาณอินฟราเรด (IR Receiver) ที่ออกแบบมาสำหรับการรับและถอดรหัสสัญญาณรีโมตอินฟราเรดที่มีความถี่พาหะ 38 kHz ภายในโมดูลมีวงจรถอดสัญญาณ (Demodulation) และวงจรกรองสัญญาณรบกวน (Noise Filtering) ในตัว ช่วยให้สามารถรับสัญญาณอินฟราเรดได้อย่างแม่นยำและมีความน่าเชื่อถือสูง।

IR Transmitter LED ขนาด 5 มม.

IR Transmitter LED
Fig3. IR Transmitter

IR Transmitter LED ขนาด 5 มม. เป็นไดโอดเปล่งแสงอินฟราเรดที่ปล่อยแสงในช่วงคลื่นอินฟราเรด ซึ่งไม่สามารถมองเห็นได้ด้วยสายตามนุษย์ แต่สามารถตรวจจับได้ด้วยตัวรับสัญญาณอินฟราเรด (IR Receiver) โดยทั่วไปนิยมนำไปใช้ในรีโมตคอนโทรลและระบบสื่อสารไร้สายผ่านสัญญาณอินฟราเรดต่าง ๆ

Remote ตัวส่ง NEC Protocol ( Options )

IR Remote NEC
Fig4. IR Transmitter (nec protocol)


การต่อวงจร

Fig . Circuit Diagram
Fig5. Circuit Diagram
Schematic Full
Fig6. Schematic

สรุปการทำงานของระบบเบื้องต้น

Arduino Nano รับและถอดรหัสสัญญาณจากรีโมตอินฟราเรดผ่านโมดูล TSOP38238 จากการถอดสัญญาณรีโมทแบบ NEC Protocal จะได้ Hexadecimal แล้วนำ Hexadecimal ที่ได้รับสามารถนำมาส่งซ้ำผ่าน IR LED เพื่อใช้ควบคุมแถบไฟ RGB LED และอุปกรณ์ที่ใช้มอเตอร์แบบไร้สาย หรือ นำ Hexadecimal ที่ได้รับทำงาน

ระบบใช้หน่วยความจำ EEPROM สำหรับจัดเก็บรหัสอินฟราเรดที่บันทึกไว้ ทำให้ข้อมูลยังคงอยู่แม้ไฟเลี้ยงถูกตัดหรือปิดการทำงานของระบบ ขณะที่โครงสร้างการทำงานแบบ Dual-Mode ช่วยให้สามารถสลับระหว่างการควบคุมไฟ LED และมอเตอร์ได้อย่างสะดวก โดยใช้ปุ่มกดเพียง 3 ปุ่ม เท่านั้น


Code

  • #include <IRremote.hpp>
    ใช้สำหรับรับและถอดรหัสสัญญาณอินฟราเรด รวมถึงส่งสัญญาณตามโปรโตคอล NEC
  • #include <EEPROM.h>
    ใช้สำหรับจัดเก็บรหัสสัญญาณอินฟราเรดที่เรียนรู้ไว้ลงในหน่วยความจำ EEPROM
C
#include <IRremote.hpp>
#include <EEPROM.h>

IR Code Capture
– เริ่มต้นการทำงานของโมดูลรับสัญญาณอินฟราเรด และเริ่มรอรับสัญญาณจากรีโมตคอนโทรล.

C
IrReceiver.begin(IR_RECEIVE_PIN, DISABLE_LED_FEEDBACK);

Decoded Data Printing
– Code แสดงข้อมูลการถอดรหัสสัญญาณอินฟราเรดอย่างครบถ้วน ประกอบด้วย รหัสดิบในรูปแบบเลขฐานสิบหก (Hexadecimal Raw Code), ชนิดของโปรโตคอล (Protocol Type), Address และ ค่า Command.

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);


กำหนดขา Arduino

  1. IR_SEND_PIN → ขาเอาต์พุตสำหรับต่อ
  2. IR LEDIR_RECEIVE_PIN → ขาอินพุตสำหรับต่อโมดูลรับสัญญาณอินฟราเรด
  3. TSOP38238BUTTON_POWER → ปุ่มเปิด/ปิดการทำงาน และสลับโหมด
  4. BUTTON_UP → ปุ่มเปลี่ยนสี RGB หรือเพิ่มความเร็วมอเตอร์
  5. BUTTON_DOWN → ปุ่มเปลี่ยนเอฟเฟกต์ LED หรือลดความเร็วมอเตอร์
  6. STATUS_LED → LED แสดงสถานะการทำงานของระบบ
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;

EEPROM Code Storage
– Codeในส่วนโหลดคำสั่งอินฟราเรดสำหรับ เปิด (ON) และ ปิด (OFF) ที่บันทึกไว้ก่อนหน้านี้จากหน่วยความจำ EEPROM.

C
EEPROM.get(0, savedCodeOn);
EEPROM.get(4, savedCodeOff);

Mode Switching
– Code การกดปุ่ม Power ค้างไว้ จะเป็นการสลับโหมดการทำงานระหว่าง โหมดควบคุมไฟ LED และ โหมดควบคุมมอเตอร์.

C
if (millis() - pressStartTime > 2000) {
    isMotorMode = !isMotorMode;
}

IR Signal Transmission
– Code สำหรับส่งคำสั่งอินฟราเรดตามโปรโตคอล NEC ที่จัดเก็บไว้ ผ่าน IR LED แบบไร้สาย.

C
IrSender.sendNECRaw(savedCodeOn, 0);


RGB Color Cycling
สลับเปลี่ยนสีของ RGB LED ตามชุดสีที่กำหนดไว้ล่วงหน้าแบบลำดับต่อเนื่อง.

C
IrSender.sendNECRaw(COLORS[colorTracker], 0);

Motor Control Commands
ใช้รหัส Hexadecimal ตามโปรโตคอล NEC ที่กำหนดเองเป็นคำสั่งสำหรับควบคุมมอเตอร์แบบไร้สาย.

C
const uint32_t MOTOR_POWER = 0xE111EF00;
const uint32_t MOTOR_SPEED_UP = 0xE222EF00;
const uint32_t MOTOR_SPEED_DOWN = 0xE333EF00;


Status LED Feedback
LED บนบอร์ดทำหน้าที่แสดงสถานะการทำงานของระบบในระหว่างการสลับโหม

C
digitalWrite(STATUS_LED, HIGH);
delay(800);
digitalWrite(STATUS_LED, LOW);


Code การรับสัญญาณ Remote

C
#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();
  }
}


Code การส่ง Remote

C
#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);
    }
  }
}


Arduino Nano Schematic : Download (PDF)
Arduino Nano Pin : Download (PDF)

Source : DIY Arduino IR Remote Controller System| Full Step-By-Step Guide – QuartzComponents


my avatar

Pawinphat

Founder of Bunpajarn.com • Electronics & Embedded Systems

Leave a Reply

Your email address will not be published. Required fields are marked *