เกี่ยวกับโปรเจคนี้
ในโปรเจคนี้ น้องจะได้เรียนรู้วิธีควบคุมความสว่างของ LED ด้วยรีโมตใดก็ได้ น้องจะได้เรียนรู้วิธีปรับความสว่างของ LED แบบละเอียดยิบ โดยใช้สัญญาณอินฟราเรด (IR) จากรีโมตทั่วไปในบ้าน เช่น รีโมตทีวีหรือรีโมตแอร์ เราจะใช้หลักการ Pulse Width Modulation (PWM) ในการปรับความสว่าง และการถอดรหัสโปรโตคอล IR เพื่อสั่งงาน Arduino
STEP 1: อุปกรณ์ที่ต้องใช้







สำหรับทูตนี้ น้องต้องมี:
- Arduino uno
- ตัวต้านทาน 221 โอห์ม (เพื่อจำกัดกระแสไม่ให้ไหลผ่าน LED มากเกินไปจนพัง)
- สายจัมเปอร์
- IR Receiver & Remote (ตัวรับสัญญาณอินฟราเรด มักทำงานที่ 38kHz และรีโมตที่ส่งสัญญาณ)
- เบรดบอร์ด
- LED
STEP 2: วงจร

ถ้าน้องยังไม่รู้ว่า IR Receiver และ Transmitter ทำงานยังไง ลองไปหาอ่านเพิ่มเติมได้ตามเว็บไซต์สอนอิเล็กทรอนิกส์ทั่วไปเลย เรื่องสำคัญเวลาเชื่อมต่อวงจร IR Receiver คือต้องดู "pinout" ของตัวรับให้ดี เพราะในตลาดมีทั้งแบบโมดูลสำเร็จรูป (Breakout Board) และแบบไดโอดเดี่ยวๆ
การจัดวางขาของโมดูลสำเร็จรูปส่วนใหญ่จะหน้าตาแบบนี้:

การจัดวางขาของไดโอดเดี่ยวๆ ส่วนใหญ่จะหน้าตาแบบนี้:

STEP 3: โค้ด
หลักการทำงาน
ก่อนจะดูโค้ด เราต้องรู้ปุ่มต่างๆ บนรีโมตของเราก่อน เริ่มแรกน้องต้องดาวน์โหลดไลบรารี IRremote มาใช้ โดยสามารถหาโหลดได้จากแหล่งไลบรารี Arduino ทั่วไป วิธีการติดตั้งไลบรารีจากไฟล์ ZIP ให้เปิด Arduino IDE ขึ้นมา แล้วไปที่ Sketch > Include Library > Add.ZIP Library จากนั้นเลือกไฟล์ ZIP ของ IRremote ที่ดาวน์โหลดมา พอเสร็จแล้ว อัพโหลดโค้ดด้านล่างแล้วเปิด Serial Monitor (นี่เป็นโอกาสดีที่จะได้เช็คว่าต่อขาถูกต้องมั้ยด้วยนะ)
#include
const int RECV_PIN = 8;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup(){
Serial.begin(9600);
irrecv.enableIRIn();
irrecv.blink13(true);
}
void loop(){
if (irrecv.decode(&results)){
```cpp
Serial.println(results.value, HEX);
irrecv.resume();
}
```
ถ้าไม่มีอะไรเกิดขึ้นเลย (ไฟ LED บน Arduino ไม่กระพริบตอนกดปุ่มรีโมท) ให้เช็คการต่อสายอีกที เผื่อน้องสลับ Vcc กับ S อยู่
น้องสามารถจดค่าปุ่มแต่ละปุ่มของรีโมทเก็บไว้ในไฟล์ txt เพื่อเอาไปใช้อ้างอิงทีหลังได้เลย
NOTE: เวลาน้องกดปุ่มค้างไว้ หน้าจอ Serial Monitor จะแสดงค่า 0XFFFFFFFF นี่คือ "Repeat Code" นะจ๊ะ จดค่า HEX ของปุ่ม "เพิ่มความสว่าง" กับ "ลดความสว่าง" ไว้ให้ดี จะได้เอาไปใช้ในขั้นตอนต่อไป
ตอนนี้น้องรู้ค่าปุ่มของรีโมทแล้ว มาดูโค้ดกันทีละส่วนดีกว่า
#include
const int RECV_PIN = 7;
IRrecv irrecv(RECV_PIN);
decode_results results;
const int ledPin = 10;
int brightness=0;
unsigned long key_value = 0;
เวลาใช้ไลบรารี่ IRremote เราต้องสร้างออบเจ็กต์ชื่อ irrecv และระบุพินที่ต่อกับตัวรับสัญญาณ IR (บรรทัดที่ 3) ออบเจ็กต์นี้จะจัดการเรื่องโปรโตคอลและประมวลผลข้อมูลจากตัวรับให้เอง
ขั้นต่อไปเราสร้างออบเจ็กต์ชื่อ results จากคลาส decode_results ซึ่งออบเจ็กต์ irrecv จะใช้ส่งข้อมูลที่ถอดรหัสแล้วมาให้แอปของเรา (บรรทัดที่ 5)
ต่อมาเราสร้างตัวแปรเพื่อเซ็ตพิน 10 (ต้องเป็นพินที่รองรับ PWM เช่น 3, 5, 6, 9, 10, 11) สำหรับ LED และเก็บค่าความสว่าง ตัวแปรสุดท้าย key_value เอาไว้เก็บโค้ดปุ่มล่าสุดเพื่อจัดการตอนกดค้าง
void setup(){
irrecv.enableIRIn();
irrecv.blink13(true);
pinMode(ledPin, OUTPUT);
}
ในบล็อก void setup() เริ่มจากเซ็ตอัตราบอด (baud rate) ของ Serial Monitor จากนั้นเริ่มทำงานตัวรับ IR โดยเรียกฟังก์ชันเมมเบอร์ enableIRIn() (บรรทัดที่ 10)
ฟังก์ชัน irrecv.blink13(true) ในบรรทัดที่ 11 จะทำให้ไฟ LED บนบอร์ด Arduino กระพริบทุกครั้งที่ตัวรับได้สัญญาณจากรีโมท เอาไว้ใช้ดีบั๊กงานง่ายๆ
ฟังก์ชัน pinMode(ledPin, OUTPUT) กำหนดให้ ledPin (พิน 10) ทำงานเป็นเอาต์พุต พร้อมส่งสัญญาณ PWM
void loop() {
if (irrecv.decode(&results)){
// ถ้าเป็นค่า Repeat ให้ใช้ค่าที่รับล่าสุด
if (results.value == 0XFFFFFFFF) {
results.value = key_value;
}
// ตัวอย่างโค้ด HEX (ต้องเปลี่ยนตามรีโมทของน้องนะ)
if(results.value == 0xF076C13B){ // ปุ่มลดความสว่าง
brightness -= 5;
if (brightness < 0) brightness = 0;
}
else if(results.value == 0xA3C8EDDB){ // ปุ่มเพิ่มความสว่าง
brightness += 5;
if (brightness > 255) brightness = 255;
}
key_value = results.value; // เก็บโค้ดปัจจุบันไว้ใช้รอบต่อไป
irrecv.resume(); // รีเซ็ตตัวรับ IR
}
brightnessControl(brightness); // อัพเดตความสว่าง LED
}
ในบล็อก void loop() ฟังก์ชัน irrecv.decode จะคืนค่า true ถ้ารับโค้ดได้ และโปรแกรมจะทำงานในคำสั่ง if โค้ดที่ได้รับจะเก็บไว้ใน results.value ตรรกะสำคัญคือการจัดการค่า 0XFFFFFFFF ถ้าเราได้รับค่านี้ แปลว่าน้อง "กดปุ่มเดิมค้างไว้" เราต้องสั่งโปรแกรมให้ใช้โค้ดที่เก็บไว้ก่อนหน้าใน key_value มาทำงานต่อ
เงื่อนไข if ตรวจสอบว่าปุ่มที่กดคือ + หรือ - (โค้ด HEX ของน้องอาจต่างกันนะ ขึ้นอยู่กับรีโมทและตัวรับ) แล้วเพิ่มหรือลดค่าความสว่าง เงื่อนไขต่อไปจะจำกัดค่าความสว่างให้อยู่ระหว่าง 0 ถึง 255
irrecv.resume() เนี่ย เอาไว้รีเซ็ตตัวรับสัญญาณ (receiver) ให้พร้อมรับโค้ดถัดไปจ้า
ส่วนบรรทัด brightnessControl(brightness); นี้ มันคือการเรียกใช้ฟังก์ชัน brightnessControl() แล้วโยนค่าความสว่างปัจจุบัน (brightness) เข้าไปเป็นอาร์กิวเมนต์ เพื่ออัพเดตค่าให้ LED ของเรานั่นเอง
void brightnessControl(int value){
analogWrite(ledPin,value);
}
ฟังก์ชัน brightnessControl() นี้รับค่าจำนวนเต็ม (integer) เป็นอาร์กิวเมนต์ แล้วใช้มันตั้งค่าความสว่างของ LED ผ่าน PWM (Pulse Width Modulation) ครับพี่น้อง ฟังก์ชัน analogWrite() จะสร้างสัญญาณ Square Wave ความถี่คงที่ แต่ปรับความกว้างของช่วงสัญญาณ High (Duty Cycle) เพื่อควบคุมปริมาณพลังงานที่ส่งไปให้ LED ทำให้เรารู้สึกว่าแสงสว่างขึ้นหรือมืดลงนั่นเอง จัดไปวัยรุ่น!
อยากรู้ลึกเรื่อง PWM ไปหาอ่านเพิ่มเติมได้ตามแหล่งความรู้ทั่วไปนะครับ
ส่วนรายละเอียดของไลบรารี IRremote ก็ลองไปศึกษาจากแหล่งข้อมูลที่เกี่ยวข้องดูได้
STEP 4: ยินดีด้วย!!!
เสร็จซะที เยี่ยมมาก! น้องได้สร้างระบบควบคุมแสงด้วยรีโมทสำเร็จแล้ว โครงการนี้เป็นพื้นฐานชั้นดีสำหรับการเริ่มต้นทำ Home Automation เลยนะ สู้งานนะน้อง
หวังว่าน้องจะชอบบทเรียนนี้ ถ้ามีข้อเสนอแนะอะไรเกี่ยวกับโค้ด หรือมีเทคนิคดีๆ มาช่วยปรับปรุงประสิทธิภาพ (เช่น การใช้ Interrupts หรือการเก็บค่าความสว่างใน EEPROM) ก็คอมเมนต์มาแชร์กันได้เลย ไม่ต้องเกรงใจ ห้ามช็อตนะตัวนี้
ขอบคุณครับ