EMDEDDEDKNOWLEDGEGETTING-STARTED

IR Remote ตอนที่ 1: เปิดโลก Remote Control จากรีโมตทีวีสู่การควบคุมอุปกรณ์ด้วยไมโครคอนโทรลเลอร์

รีโมตคอนโทรลแบบอินฟราเรด

IR Remotes Revisited

IR Remote ตอนที่ 1: เปิดโลก Remote Control จากรีโมตทีวีสู่การควบคุมอุปกรณ์ด้วยไมโครคอนโทรลเลอร์

NEC IR

IR Remote ตอนที่ 2: NEC Protocol เจาะลึกภาษาลับของรีโมต IR ที่ไมโครคอนโทรลเลอร์เข้าใจ

บทนำ

เชื่อได้เลยว่าคุณน่าจะมีรีโมตคอนโทรลแบบอินฟราเรด (Infrared: IR) อย่างน้อยหนึ่งตัว และในความเป็นจริง หลายคนอาจมีรีโมตอยู่หลายตัว มากเสียจนแทบจำไม่ได้ว่ามีทั้งหมดกี่ตัว จากเดิมที่รีโมตคอนโทรลถูกใช้งานเฉพาะกับเครื่องรับโทรทัศน์ ปัจจุบันรีโมตได้กลายเป็นอุปกรณ์มาตรฐานที่มาพร้อมกับเครื่องใช้ไฟฟ้าและอุปกรณ์อิเล็กทรอนิกส์แทบทุกประเภท

รีโมตคอนโทรลแบบอินฟราเรด (IR Remote Control) เปิดโอกาสให้ผู้ทดลองและผู้ที่สนใจงานด้านไมโครคอนโทรลเลอร์สามารถนำไปประยุกต์ใช้งานได้อย่างหลากหลาย เราสามารถใช้ไมโครคอนโทรลเลอร์จำลองการทำงานของรีโมตคอนโทรล เพื่อควบคุมอุปกรณ์อิเล็กทรอนิกส์หลายชนิดผ่านโปรแกรมที่พัฒนาขึ้นเอง นอกจากนี้ ยังสามารถทำให้ไมโครคอนโทรลเลอร์ตอบสนองต่อสัญญาณจากรีโมตอินฟราเรดได้ ซึ่งเป็นวิธีที่สะดวกสำหรับการควบคุมโครงงานหรือระบบที่พัฒนาขึ้น

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

วันนี้เราจะมาทำความเข้าใจว่าอุปกรณ์ขนาดเล็กเหล่านี้ทำงานอย่างไร และสามารถนำไปประยุกต์ใช้ในโครงงานอิเล็กทรอนิกส์ของเราได้อย่างไร

พื้นฐานของรีโมตคอนโทรลแบบอินฟราเรด

โดยหลักการทำงาน รีโมตคอนโทรลแบบอินฟราเรด (IR Remote Control) จะส่งแสงอินฟราเรดที่ถูกมอดูเลต(Modulated)เป็นพัลส์ (Pulsed Infrared Signal) เพื่อใช้แทนรหัสคำสั่ง (Key Code) ของปุ่มที่กด เมื่อเครื่องรับตรวจจับสัญญาณได้ จะทำการถอดรหัสและประมวลผลคำสั่ง จากนั้นจึงดำเนินการตามฟังก์ชันที่กำหนดไว้

แสงอินฟราเรด

สัญญาณที่รีโมตคอนโทรลใช้สำหรับการสื่อสารคือ แสงอินฟราเรด (Infrared Light) ซึ่งเป็นคลื่นแม่เหล็กไฟฟ้าที่มีความยาวคลื่นอยู่ในช่วง ต่ำกว่าแสงสีแดง ของสเปกตรัมแสงที่ตามนุษย์สามารถมองเห็นได้ (Visible Spectrum)

Infrared Light

แสงแต่ละชนิดมีความยาวคลื่น (Wavelength) แตกต่างกัน โดยรีโมตคอนโทรลแบบอินฟราเรดส่วนใหญ่ทำงานในช่วงความยาวคลื่น 850–960 นาโนเมตร (nm) และค่าที่พบได้บ่อยที่สุดคือ 940 นาโนเมตร

ความถี่พาหะ (Carrier Frequency)

พัลส์ของแสงอินฟราเรดยังถูกมอดูเลต (Modulated) ด้วยคลื่นพาหะ (Carrier Wave) ในลักษณะเดียวกับการส่งสัญญาณวิทยุ เทคนิคนี้ช่วยให้ตัวรับสัญญาณสามารถแยกสัญญาณจากรีโมตออกจากสัญญาณรบกวนในย่านอินฟราเรด (Infrared Background Noise) ซึ่งอาจเกิดจากแสงในสภาพแวดล้อมและมีความเข้มสูงในบางกรณี เช่น แสงจากดวงอาทิตย์, แสงจากหลอดไฟ เป็นต้น

ความถี่พาหะของรีโมตคอนโทรลมีค่าแตกต่างกันไปในช่วง 30 ถึง 60 กิโลเฮิรตซ์ (kHz) แต่ค่าที่นิยมใช้งานมากที่สุดคือ 38 kHz

เทคนิคการมอดูเลตสัญญาณ (Modulation Techniques)

ข้อมูลทั้งหมดจากรีโมตคอนโทรลจะถูกส่งในลักษณะข้อมูลแบบอนุกรม (Serial Data) โดยข้อมูลจะถูกเข้ารหัสด้วยเทคนิคการมอดูเลตหลายรูปแบบ ซึ่งแต่ละเทคนิคจะกำหนดวิธีการเข้ารหัสบิต 0 และ 1 สำหรับการส่งผ่านสัญญาณอินฟราเรด

เทคนิคการมอดูเลตหลักที่ใช้ในรีโมตคอนโทรลมีอยู่ 3 รูปแบบ พร้อมทั้งมีรูปแบบย่อยที่แตกต่างออกไป ได้แก่

  • Pulse Density Modulation (PDM) หรือเรียกอีกชื่อว่า Space Encoding หรือ Pulse Distance Modulation
  • Pulse Width Modulation (PWM) หรือเรียกอีกชื่อว่า Pulse Encoding
  • Bi-Phase Modulation หรือเรียกอีกชื่อว่า Manchester Encoding

ภาพประกอบต่อไปนี้แสดงรูปแบบการจัดเรียงข้อมูลของทั้งสามเทคนิคการมอดูเลตดังกล่าว

Modulation Techniques

PWM IR

Bi-Phase IR

โปรโตคอลของรีโมตคอนโทรลแบบอินฟราเรด (IR Remote Protocols)

ลองนึกถึงรีโมตคอนโทรลหลายตัวที่วางอยู่บนโต๊ะรับแขกของคุณ แต่ละตัวมีฟังก์ชันการทำงานจำนวนมาก ทว่าโดยทั่วไปกลับแทบไม่รบกวนการทำงานซึ่งกันและกัน แม้ว่าบางส่วนอาจเกิดจากการใช้ความยาวคลื่นอินฟราเรดหรือความถี่พาหะที่แตกต่างกัน แต่ในความเป็นจริง 940 นาโนเมตร (940 nm) และ 38 กิโลเฮิรตซ์ (38 kHz) ถือเป็นมาตรฐานที่ได้รับความนิยมอย่างแพร่หลาย จึงมีความเป็นไปได้สูงว่ารีโมตคอนโทรลส่วนใหญ่ที่คุณใช้งานจะใช้ค่ามาตรฐานดังกล่าว

แล้วรีโมตแต่ละตัวหลีกเลี่ยงการรบกวนกันได้อย่างไร? คำตอบประการหนึ่งคือ การใช้โปรโตคอล (Protocol) ที่แตกต่างกัน

โปรโตคอลของรีโมตคอนโทรลแบบอินฟราเรดเป็นข้อกำหนดที่ใช้กำหนดรูปแบบการรับส่งข้อมูลผ่านสัญญาณอินฟราเรด โดยครอบคลุมพารามิเตอร์ต่าง ๆ เช่น

  • เทคนิคการมอดูเลต (Modulation Technique) ที่ใช้
  • รูปแบบและช่วงเวลาของบิตเริ่มต้น (Start Bit)
  • จำนวนบิตของข้อมูล Address และข้อมูลคำสั่ง (Command)
  • รูปแบบของการตรวจสอบความถูกต้องของข้อมูล (Error Checking)
  • รูปแบบของบิตสิ้นสุดข้อมูล (End of Message: EOM) หรือบิตหยุด (Stop Bit)
  • ลำดับการส่งข้อมูลว่าเริ่มจาก LSB (Least Significant Bit) หรือ MSB (Most Significant Bit)

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

โปรโตคอล NEC สำหรับรีโมตคอนโทรลแบบอินฟราเรด

NEC Protocol เป็นโปรโตคอลอินฟราเรดที่ได้รับความนิยมมากที่สุด โดยมีผู้ผลิตอุปกรณ์อิเล็กทรอนิกส์หลายร้อยรายนำไปใช้งาน อีกทั้งยังเป็นโปรโตคอลที่ศึกษาและพัฒนาได้ง่าย เนื่องจากมีเอกสารอ้างอิงเผยแพร่อย่างกว้างขวาง

มีความเป็นไปได้สูงว่ารีโมตคอนโทรลส่วนใหญ่ที่คุณใช้งานจะใช้ NEC Protocol ยกเว้นรีโมตของผู้ผลิตรายใหญ่บางราย เช่น Sony, LG, Panasonic, Apple และ Samsung ซึ่งมักเลือกใช้โปรโตคอลเฉพาะ (Proprietary Protocol) ที่พัฒนาขึ้นสำหรับผลิตภัณฑ์ของตนเอง

IR Remote Protocol

จะเห็นว่าแพ็กเก็ตข้อมูล (Packet) เริ่มต้นด้วยสัญญาณพัลส์ (Pulse Burst) ความยาว 9 มิลลิวินาที (9 ms) ซึ่งทำหน้าที่เป็นสัญญาณเริ่มต้นของแพ็กเก็ต จากนั้นจึงตามด้วยช่วงเว้นว่างของสัญญาณ (Space) เป็นเวลา 4.5 มิลลิวินาที (4.5 ms)

NEC IR

จากนั้นจึงส่งข้อมูล Address และ Command รวมทั้งหมด 32 บิต โดย Address และ Command มีขนาดอย่างละ 8 บิต และแต่ละค่าจะถูกส่งซ้ำในรูปของข้อมูลที่กลับค่าบิต (Inverted Data) เพื่อใช้ตรวจสอบความถูกต้องของข้อมูล (Error Checking)

สำหรับการประยุกต์ใช้งานทั่วไป สิ่งที่เราจำเป็นต้องนำมาใช้งานมีเพียงค่า Address และ Command เท่านั้น ซึ่งหลักการนี้ไม่ได้ใช้เฉพาะกับ NEC Protocol แต่ยังใช้ได้กับโปรโตคอลของรีโมตคอนโทรลแบบอินฟราเรดอื่น ๆ อีกด้วย

IR Remote Address Command

จากภาพประกอบจะเห็นได้ว่า การกำหนดค่า Address ที่แตกต่างกันช่วยให้รีโมตคอนโทรลสองตัวที่ใช้ NEC Protocol สามารถใช้งานอยู่ภายในห้องเดียวกันได้โดยไม่รบกวนการทำงานซึ่งกันและกัน แม้ว่าอุปกรณ์ทั้งสองจะใช้รหัสคำสั่ง 0x0A สำหรับการเปิด–ปิดเครื่อง (Power) เหมือนกัน แต่เนื่องจากใช้ Address คนละค่า จึงสามารถแยกแยะคำสั่งได้อย่างถูกต้อง

องค์ประกอบของระบบรีโมตคอนโทรลแบบอินฟราเรด

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

โมดูลรับสัญญาณอินฟราเรด (IR Receiver Module)

โมดูลรับสัญญาณอินฟราเรดประกอบด้วยวงจรสำหรับรับและประมวลผลสัญญาณไว้ภายในแพ็กเกจขนาดเล็ก ดังแสดงในภาพต่อไปนี้

IR Receiver Modules

โมดูลรับสัญญาณอินฟราเรดมีให้เลือกใช้งานหลายรุ่น โดยรองรับการทำงานที่ ความยาวคลื่นอินฟราเรด (IR Wavelength) แตกต่างกัน ซึ่ง 940 นาโนเมตร (940 nm) เป็นค่าที่ได้รับความนิยมมากที่สุด โดยทั่วไปค่าความยาวคลื่นจะถูกระบุไว้ใน หมายเลขรุ่น (Part Number) ของอุปกรณ์ ดังตัวอย่างของโมดูล Vishay TSOP34xx Series ที่แสดงไว้ในภาพ

IR remote sensor

ตัวส่งสัญญาณอินฟราเรด (IR Emitters)

IR Emitter โดยพื้นฐานแล้วคือ ไดโอดเปล่งแสง (LED) ที่ปล่อยแสงในช่วงอินฟราเรด เช่นเดียวกับตัวรับสัญญาณอินฟราเรด ตัวส่งสัญญาณก็มีให้เลือกหลายรุ่นตามช่วงความยาวคลื่นที่แตกต่างกัน

ภาพประกอบต่อไปนี้แสดงหมายเลขรุ่นของตัวส่งสัญญาณอินฟราเรดใน OSRAM SFH 45xx Series โดยเน้นรุ่นที่ใช้ความยาวคลื่น 940 นาโนเมตร (940 nm) ซึ่งเป็นรุ่นที่ได้รับความนิยมมากที่สุด

IR Emitters

การใช้งานตัวส่งสัญญาณอินฟราเรด

ตัวส่งสัญญาณอินฟราเรด (IR Emitter) ต้องการกระแสไฟฟ้าสูงกว่า LED ทั่วไปที่ให้แสงในย่านที่มองเห็นได้ จึงไม่เหมาะที่จะต่อขับโดยตรงจากขา GPIO ของไมโครคอนโทรลเลอร์ อุปกรณ์หลายรุ่นต้องการกระแสตั้งแต่ 100 mA ขึ้นไป และบางรุ่นสามารถรองรับกระแสได้สูงถึง 1 A เมื่อทำงานในโหมดพัลส์ (Pulsed Operation)

Driving IR Emitters

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

Driving IR Emitters 2 TR

นอกจากนี้ ยังสามารถใช้ทรานซิสเตอร์ขับ LED อินฟราเรดหลายดวงพร้อมกัน เพื่อเพิ่มระยะการส่งสัญญาณได้

การเชื่อมต่อกับ Arduino

ตัวอย่างต่อไปนี้แสดงการเชื่อมต่อ Arduino Uno, IR Emitter Diode และ IR Sensor เข้าด้วยกัน โดยจะเพิ่ม สวิตช์กด (Push button Switch) จำนวน 3 ตัว และ LED สำหรับแสดงสถานะ (Visible LED) อีก 1 ดวง เข้าไปในวงจรด้วย

Arduino IR

สิ่งที่ควรสังเกตเกี่ยวกับการเชื่อมต่อวงจรนี้มีดังต่อไปนี้

  • ทรานซิสเตอร์ที่ใช้ขับ IR Emitter ในตัวอย่างนี้คือ 2N2222 ชนิด NPN หากไม่มี 2N2222 ก็สามารถใช้ทรานซิสเตอร์ NPN รุ่นอื่นแทนได้ แต่ควรตรวจสอบการจัดเรียงขา (Pinout) ของทรานซิสเตอร์ที่ใช้แทน เนื่องจากตำแหน่งของขาอาจแตกต่างจาก 2N2222
  • ตัวเก็บประจุ 2.2 µF ทำหน้าที่เป็น ตัวกรองแหล่งจ่ายไฟ (Power Supply Filter Capacitor) สำหรับ IR Receiver Module ควรวางไว้ใกล้กับขาไฟเลี้ยงของโมดูลบนเบรดบอร์ด โดยค่าความจุไม่ได้มีความสำคัญมากนัก และสามารถใช้ตัวเก็บประจุอิเล็กโทรไลต์ที่มีค่าตั้งแต่ 1 µF ถึง 10 µF แทนได้
  • ตัวต้านทาน 33 Ω ที่ใช้จำกัดกระแสให้กับ IR Emitter อาจต้องปรับค่าให้เหมาะสมตามคุณสมบัติของ IR Emitter แต่ละรุ่น และในบางกรณีอาจไม่จำเป็นต้องใช้ตัวต้านทานตัวนี้เลย
  • นอกจากวงจร Arduino, คอมพิวเตอร์ และอุปกรณ์ต่าง ๆ แล้ว สิ่งที่ควรเตรียมเพิ่มเติมคือ รีโมตคอนโทรลหลาย ๆ ตัว สำหรับใช้ในการทดลอง ยิ่งมีหลายรุ่นก็ยิ่งสามารถทดลองได้หลากหลายมากขึ้น

IRremote Library

ในบทความนี้ เราจะติดตั้ง IRremote Library ลงใน Arduino IDE จากนั้นจะทดลองใช้งานไลบรารีผ่านตัวอย่างต่าง ๆ

วิธีที่ง่ายที่สุดในการติดตั้ง IRremote Library คือการติดตั้งโดยตรงผ่าน Library Manager ของ Arduino IDE

เมื่อติดตั้งไลบรารีเรียบร้อยแล้ว คุณจะสามารถเปิดใช้งาน Example Sketches ที่มาพร้อมกับไลบรารี ซึ่งเป็นตัวอย่างที่มีประโยชน์และน่าสนใจสำหรับการศึกษาและทดลองใช้งาน

Install arduino library

ตัวอย่างโปรแกรมใน Arduino-IRremote Library

ภายใน Arduino-IRremote Library มี Example Sketch ให้เลือกใช้งานไม่น้อยกว่า 25 ตัวอย่าง แต่ละตัวอย่างมีคำอธิบายประกอบไว้อย่างละเอียด และวงจร Arduino ที่เราได้ประกอบไว้ก่อนหน้านี้ก็ใช้การเชื่อมต่อขาตามค่าเริ่มต้น (Default Pins) ที่กำหนดไว้สำหรับตัวอย่างส่วนใหญ่

ข้อยกเว้นคือ ขา D5 ซึ่งในตัวอย่างต่าง ๆ จะถูกอ้างอิงด้วยชื่อ APPLICATION_PIN โดยในหลายตัวอย่างขานี้จะไม่ได้ถูกใช้งาน แต่ในบางตัวอย่างจะถูกกำหนดให้เป็น เอาต์พุต (Output) ขณะที่บางตัวอย่างจะใช้เป็น อินพุตสำหรับสวิตช์ (Switch Input) สำหรับการทดลองในบทความนี้ ขา D5 ถูกเชื่อมต่อเข้ากับ LED เนื่องจากขาดังกล่าวรองรับการสร้างสัญญาณ PWM ซึ่งเป็นคุณสมบัติที่เราจะใช้งานในหัวข้อถัดไป นอกจากนี้ยังสามารถใช้ร่วมกับตัวอย่าง ControlRelay แทนการเชื่อมต่อกับโมดูลรีเลย์เอาต์พุตได้อีกด้วย

ไฟล์ PinDefinitionsAndMore

Example Sketch เกือบทั้งหมดใน Arduino-IRremote Library จะใช้งานไฟล์ชื่อ PinDefinitionsAndMore.h ซึ่งตามชื่อของไฟล์ ไฟล์นี้ทำหน้าที่รวบรวม การกำหนดขา (Pin Definitions) สำหรับไมโครคอนโทรลเลอร์หลายรุ่น รวมถึงการกำหนด ค่าคงที่ (Constants) ที่ใช้งานร่วมกันในตัวอย่างต่าง ๆ

ภายในไฟล์จะมีชื่อไมโครคอนโทรลเลอร์ (ที่รองรับ พร้อมระบุขาเริ่มต้น (Default Pins) สำหรับแต่ละบอร์ด หากเชื่อมต่อวงจรตามที่กำหนดไว้ จะช่วยให้การเขียนโปรแกรมง่ายขึ้น แม้ว่าจะสามารถกำหนดขาใหม่และแก้ไขโค้ดให้สอดคล้องกับการต่อวงจรได้ แต่การใช้ขาตามค่าเริ่มต้นจะสะดวกและช่วยลดความยุ่งยากมากกว่า

ค่าคงที่ (Constants) ที่ใช้ในตัวอย่างโปรแกรมต่อจากนี้ ส่วนใหญ่ถูกกำหนดไว้ในไฟล์ PinDefinitionsAndMore.h

ตัวอย่างโปรแกรม SimpleReceiver

SimpleReceiver เป็น Example Sketch ตัวแรกที่เราจะนำมาทดลองใช้งาน และจากชื่อก็คงพอจะเดาได้ว่าโปรแกรมนี้มีหน้าที่อะไร ตัวอย่างนี้รวมถึง Example Sketch อื่น ๆ สามารถเปิดใช้งานได้จากเมนู

📂 File/ Examples/ Examples from Custom Libraries/ IRremote folder.

C
/*
 * SimpleReceiver.cpp
 *
 * Demonstrates receiving NEC IR codes with IRremote
 *
 *  This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
 *
 ************************************************************************************
 * MIT License
 *
 * Copyright (c) 2020-2023 Armin Joachimsmeyer
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is furnished
 * to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 ************************************************************************************
 */

/*
 * Specify which protocol(s) should be used for decoding.
 * If no protocol is defined, all protocols (except Bang&Olufsen) are active.
 * This must be done before the #include <IRremote.hpp>
 */
//#define DECODE_DENON        // Includes Sharp
//#define DECODE_JVC
//#define DECODE_KASEIKYO
//#define DECODE_PANASONIC    // alias for DECODE_KASEIKYO
//#define DECODE_LG
#define DECODE_NEC          // Includes Apple and Onkyo
//#define DECODE_SAMSUNG
//#define DECODE_SONY
//#define DECODE_RC5
//#define DECODE_RC6

//#define DECODE_BOSEWAVE
//#define DECODE_LEGO_PF
//#define DECODE_MAGIQUEST
//#define DECODE_WHYNTER
//#define DECODE_FAST

//#define DECODE_DISTANCE_WIDTH // Universal decoder for pulse distance width protocols
//#define DECODE_HASH         // special decoder for all protocols

//#define DECODE_BEO          // This protocol must always be enabled manually, i.e. it is NOT enabled if no protocol is defined. It prevents decoding of SONY!

//#define DEBUG               // Activate this for lots of lovely debug output from the decoders.

//#define RAW_BUFFER_LENGTH  180  // Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100.

#include <Arduino.h>

/*
 * This include defines the actual pin number for pins like IR_RECEIVE_PIN, IR_SEND_PIN for many different boards and architectures
 */
#include "PinDefinitionsAndMore.h"
#include <IRremote.hpp> // include the library

void setup() {
    Serial.begin(115200);
    // Just to know which program is running on my Arduino
    Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE));

    // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED
    IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);

    Serial.print(F("Ready to receive IR signals of protocols: "));
    printActiveIRProtocols(&Serial);
    Serial.println(F("at pin " STR(IR_RECEIVE_PIN)));
}

void loop() {
    /*
     * Check if received data is available and if yes, try to decode it.
     * Decoded result is in the IrReceiver.decodedIRData structure.
     *
     * E.g. command is in IrReceiver.decodedIRData.command
     * address is in command is in IrReceiver.decodedIRData.address
     * and up to 32 bit raw data in IrReceiver.decodedIRData.decodedRawData
     */
    if (IrReceiver.decode()) {

        /*
         * Print a short summary of received data
         */
        IrReceiver.printIRResultShort(&Serial);
        IrReceiver.printIRSendUsage(&Serial);
        if (IrReceiver.decodedIRData.protocol == UNKNOWN) {
            Serial.println(F("Received noise or an unknown (or not yet enabled) protocol"));
            // We have an unknown protocol here, print more info
            IrReceiver.printIRResultRawFormatted(&Serial, true);
        }
        Serial.println();

        /*
         * !!!Important!!! Enable receiving of the next value,
         * since receiving has stopped after the end of the current received data packet.
         */
        IrReceiver.resume(); // Enable receiving of the next value

        /*
         * Finally, check the received data and perform actions according to the received command
         */
        if (IrReceiver.decodedIRData.command == 0x10) {
            // do something
        } else if (IrReceiver.decodedIRData.command == 0x11) {
            // do something else
        }
    }
}

โปรแกรมตัวอย่างรองรับโปรโตคอลการสื่อสารของรีโมตอินฟราเรดหลายรูปแบบ แต่ในโค้ดจะคอมเมนต์ (Comment Out) โปรโตคอลส่วนใหญ่ไว้ และเปิดใช้งานเฉพาะ NEC Protocol เป็นค่าเริ่มต้น

จากนั้นโปรแกรมจะรวมไลบรารีและไฟล์ PinDefinitionsAndMore.h เข้ามาใช้งาน ก่อนเข้าสู่ฟังก์ชัน setup() เนื่องจากไฟล์ดังกล่าวได้กำหนดค่าคงที่ที่จำเป็นไว้เรียบร้อยแล้ว ภายใน setup() โปรแกรมจะเริ่มต้นการสื่อสารผ่าน Serial Monitor และแสดงหมายเลขเวอร์ชันของไลบรารี IR Remote ที่กำลังใช้งาน

ภายในฟังก์ชัน setup() โปรแกรมจะเริ่มต้นการสื่อสารผ่าน Serial Monitor จากนั้นจะแสดงข้อมูลต่าง ๆ เช่น ชื่อโปรแกรม วันที่คอมไพล์ และเวอร์ชันของไลบรารี Arduino-IRremote ที่กำลังใช้งาน ก่อนเริ่มต้นการรับสัญญาณอินฟราเรด

ขั้นตอนถัดไปคือการเปิดใช้งาน IR Receiver ด้วยคำสั่งต่อไปนี้

C
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);

ค่าคงที่ IR_RECEIVE_PIN ถูกกำหนดให้ใช้ ขา 2 ไว้ในไฟล์ PinDefinitionsAndMore.h ซึ่งตรงกับการต่อวงจรของ Arduino ในตัวอย่างนี้

ส่วน ENABLE_LED_FEEDBACK เป็นตัวแปรชนิดบูลีน (Boolean) ที่ใช้เปิดหรือปิดการแสดงผลผ่าน LED บนบอร์ด เมื่อกำหนดค่าเป็น true LED จะกะพริบทุกครั้งที่มีการรับสัญญาณอินฟราเรด

จากนั้นโปรแกรมจะเข้าสู่ฟังก์ชัน loop() เพื่อรอรับข้อมูลจากรีโมต เมื่อมีการรับแพ็กเก็ตข้อมูลอินฟราเรด (IR Packet) ที่ถูกต้อง ไลบรารีจะทำการถอดรหัสข้อมูลโดยอัตโนมัติ

หลังจากถอดรหัสสำเร็จ โปรแกรมจะแสดงรายละเอียดของข้อมูลผ่าน Serial Monitor ได้แก่ Address, Command และชนิดของ Protocol ที่ตรวจพบ อย่างไรก็ตาม ในการตั้งค่าเริ่มต้น ไลบรารีจะถอดรหัสเฉพาะ NEC Protocol เท่านั้น หากต้องการรองรับโปรโตคอลอื่น จะต้องเปิดใช้งานเพิ่มเติมในโค้ด

สิ่งที่ควรทราบคือ เมื่อไลบรารีรับและถอดรหัสแพ็กเก็ตข้อมูลได้สำเร็จ จะหยุดรอรับข้อมูลชั่วคราว ดังนั้น ก่อนที่จะรับข้อมูลชุดถัดไป จะต้องเรียกใช้คำสั่งต่อไปนี้เพื่อให้ตัวรับสัญญาณกลับมาทำงานอีกครั้ง

C
IrReceiver.resume();
  if (IrReceiver.decodedIRData.command == {command}) {
      /* 
         Do action based on the received value
      */  
  }

ภายในโปรแกรมตัวอย่างมีส่วนของโค้ดสำหรับตรวจสอบค่า Command ที่ได้รับจากรีโมตไว้แล้ว คุณสามารถเพิ่มโค้ดเพื่อให้โปรแกรมทำงานตามคำสั่งที่ต้องการได้ในตำแหน่งนี้

การใช้งาน SimpleReceiver

โหลดโปรแกรม SimpleReceiver ลงในบอร์ด Arduino จากนั้นเปิด Serial Monitor แล้วหันรีโมตคอนโทรลไปที่โมดูลรับสัญญาณอินฟราเรด (IR Receiver Module) และกดปุ่มใด ๆ บนรีโมต

หากรีโมตที่ใช้งานเป็นแบบ NEC Protocol (ซึ่งเป็นโปรโตคอลที่พบได้บ่อยที่สุด) โปรแกรมจะแสดงข้อมูลเกี่ยวกับ โปรโตคอล (Protocol), Address และ Command ผ่านทาง Serial Monitor

Running SimpleReceiver

อย่างไรก็ตาม หากรีโมตที่ใช้งานใช้ โปรโตคอลรูปแบบอื่น โปรแกรมจะแสดงเพียงข้อมูลดิบ (Raw Data) พร้อมข้อความแจ้งเตือนว่า

ซึ่งหมายความว่าได้รับสัญญาณรบกวน หรือได้รับโปรโตคอลที่ไม่รู้จัก (หรือยังไม่ได้เปิดใช้งาน)

ตัวอย่างโปรแกรม SimpleSender

ต่อไปเราจะมาดูตัวอย่างโปรแกรม SimpleSender ซึ่งจากชื่อก็น่าจะพอเดาได้ว่ามีหน้าที่ส่งสัญญาณอินฟราเรด โปรแกรมนี้ทำงานในลักษณะเดียวกับตัวอย่างก่อนหน้า แต่เปลี่ยนจากการรับสัญญาณมาเป็นการส่งสัญญาณแทน

โปรแกรมนี้ใช้ NEC Protocol ในการส่งข้อมูล โดยจะวนส่งค่า Command, Address และ Repeat Code ตามลำดับ ดังนั้น หากนำโปรแกรมไปรันในห้องที่มีอุปกรณ์ควบคุมด้วยรีโมตอินฟราเรด ก็มีโอกาสที่อุปกรณ์บางชิ้นจะตอบสนองต่อสัญญาณที่ส่งออกมาโดยไม่ตั้งใจ

C
/*
 * SimpleSender.cpp
 *
 *  Demonstrates sending IR codes in standard format with address and command
 *  An extended example for sending can be found as SendDemo.
 *
 *  Copyright (C) 2020-2022  Armin Joachimsmeyer
 *  armin.joachimsmeyer@gmail.com
 *
 *  This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
 *
 *  MIT License
 */
#include <Arduino.h>

#define DISABLE_CODE_FOR_RECEIVER // Disables restarting receiver after each send. Saves 450 bytes program memory and 269 bytes RAM if receiving functions are not used.
//#define SEND_PWM_BY_TIMER         // Disable carrier PWM generation in software and use (restricted) hardware PWM.
//#define USE_NO_SEND_PWM           // Use no carrier PWM, just simulate an active low receiver signal. Overrides SEND_PWM_BY_TIMER definition

/*
 * This include defines the actual pin number for pins like IR_RECEIVE_PIN, IR_SEND_PIN for many different boards and architectures
 */
#include "PinDefinitionsAndMore.h"
#include <IRremote.hpp> // include the library

void setup() {
    pinMode(LED_BUILTIN, OUTPUT);

    Serial.begin(115200);

    // Just to know which program is running on my Arduino
    Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE));
    Serial.print(F("Send IR signals at pin "));
    Serial.println(IR_SEND_PIN);

    /*
     * The IR library setup. That's all!
     */
//    IrSender.begin(); // Start with IR_SEND_PIN as send pin and if NO_LED_FEEDBACK_CODE is NOT defined, enable feedback LED at default feedback LED pin
    IrSender.begin(DISABLE_LED_FEEDBACK); // Start with IR_SEND_PIN as send pin and disable feedback LED at default feedback LED pin
}

/*
 * Set up the data to be sent.
 * For most protocols, the data is build up with a constant 8 (or 16 byte) address
 * and a variable 8 bit command.
 * There are exceptions like Sony and Denon, which have 5 bit address.
 */
uint8_t sCommand = 0x34;
uint8_t sRepeats = 0;

void loop() {
    /*
     * Print current send values
     */
    Serial.println();
    Serial.print(F("Send now: address=0x00, command=0x"));
    Serial.print(sCommand, HEX);
    Serial.print(F(", repeats="));
    Serial.print(sRepeats);
    Serial.println();

    Serial.println(F("Send standard NEC with 8 bit address"));
    Serial.flush();

    // Receiver output for the first loop must be: Protocol=NEC Address=0x102 Command=0x34 Raw-Data=0xCB340102 (32 bits)
    IrSender.sendNEC(0x00, sCommand, sRepeats);

    /*
     * Increment send values
     */
    sCommand += 0x11;
    sRepeats++;
    // clip repeats at 4
    if (sRepeats > 4) {
        sRepeats = 4;
    }

    delay(1000);  // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal
}

โปรแกรมตัวอย่างนี้มีค่าคงที่ (Constants) บางรายการที่จำเป็นต้องกำหนดค่าก่อนเรียกใช้งานไลบรารี โดยหนึ่งในนั้นคือ DISABLE_CODE_FOR_RECEIVER ซึ่งถูกเปิดใช้งาน

การเปิดใช้งานตัวเลือกนี้จะเป็นการปิดฟังก์ชันของตัวรับสัญญาณ (Receiver Function) ซึ่งจะเริ่มทำงานใหม่หลังจากการส่งสัญญาณแต่ละครั้ง ช่วยลดการใช้หน่วยความจำลงได้ประมาณ 450 ไบต์

ภายในฟังก์ชัน Setup() โปรแกรมจะกำหนดให้ LED ที่ติดตั้งมากับบอร์ด (Built-in LED) ทำหน้าที่จำลองเป็นเอาต์พุต (Output) เพื่อทดสอบการทำงานในเบื้องต้นเท่านั้น แต่ LED ตัวตั้งใจไว้ว่าจะกำหนดให้เป็น LED เป็นตัวแสดงสถานะการทำงาน โดย LED กะพริบทุกครั้งที่มีการส่งสัญญาณอินฟราเรด

จากนั้นเราจะเริ่มต้นตัวส่งสัญญาณอินฟราเรด (IR Sender) ด้วยคำสั่งต่อไปนี้

C
IrSender.begin(DISABLE_LED_FEEDBACK);

ในตัวอย่างนี้ได้ปิดการทำงานของ LED Feedback ไว้ หากต้องการให้ LED ที่ติดตั้งมากับบอร์ด (Built-in LED) กะพริบเพื่อแสดงสถานะขณะส่งสัญญาณอินฟราเรด สามารถเปิดใช้งานฟังก์ชันนี้ได้

นอกจากนี้ หลังจากฟังก์ชัน setup() โปรแกรมยังประกาศตัวแปรอีกหลายรายการ ซึ่งใช้เป็นค่าตั้งต้นของรหัสอินฟราเรด (IR Codes) และค่าการส่งซ้ำ (Repeat Values) โดยโปรแกรมจะเพิ่มค่าของตัวแปรเหล่านี้ตามลำดับในระหว่างการทดสอบการทำงาน

ภายในฟังก์ชัน loop() โปรแกรมจะแสดงค่าปัจจุบันของตัวแปรผ่าน Serial Monitor จากนั้นจึงใช้คำสั่งต่อไปนี้เพื่อส่งข้อมูลอินฟราเรด

C
IrSender.sendNEC(0x00, sCommand, sRepeats);


พารามิเตอร์ตัวแรกคือ Address ซึ่งในตัวอย่างนี้จะกำหนดค่าเป็น 00 เสมอ แต่ผู้ใช้งานสามารถเปลี่ยนค่าได้ตามต้องการหลังจากส่งข้อมูลแล้ว โปรแกรมจะทำการเปลี่ยนค่าตัวแปรเหล่านี้ จากนั้นหน่วงเวลาเป็นเวลา 1 วินาที แล้วจึงเริ่มกระบวนการส่งข้อมูลซ้ำอีกครั้ง

IR Hex

โหลดโปรแกรมลงในบอร์ด Arduino จากนั้นสังเกตผลลัพธ์ที่แสดงบน Serial Monitorนอกจากนี้ คุณยังสามารถใช้งาน Arduino อีกหนึ่งบอร์ด ที่รันโปรแกรม SimpleReceiver ได้เช่นเดียวกับที่ผู้เขียนทดลองใช้งาน ซึ่งจะช่วยให้สามารถตรวจสอบและติดตามผลลัพธ์ของสัญญาณที่ถูกส่งออกมาได้

สรุป

จากตัวอย่างที่ผ่านมา เราได้เรียนรู้หลักการทำงานเบื้องต้นของระบบรีโมตคอนโทรลอินฟราเรด (IR Remote Control) ตั้งแต่โครงสร้างของสัญญาณ การรับและส่งข้อมูลด้วย Arduino-IRremote Library รวมถึงการประยุกต์ใช้งานผ่านโปรแกรมตัวอย่างต่าง ๆ ซึ่งเพียงพอสำหรับการพัฒนาโปรเจกต์ที่รองรับโปรโตคอลอินฟราเรดที่ใช้งานกันทั่วไป

อย่างไรก็ตาม Arduino-IRremote ไม่ใช่ไลบรารีเพียงตัวเดียวที่รองรับการทำงานด้านอินฟราเรด อีกหนึ่งไลบรารีที่ได้รับความนิยมคือ IRMP (Infrared Multi Protocol Decoder + Encoder Library) ซึ่งรองรับโปรโตคอลได้หลากหลายและมีความสามารถเพิ่มเติมในหลายด้าน โดยในหัวข้อถัดไปเราจะมาทำความรู้จักกับไลบรารี IRMP พร้อมเรียนรู้การติดตั้งและการใช้งานเบื้องต้นต่อไป

VDO สรุปเนื้อหา : https://youtu.be/OB4jAc2033o?si=GaObkulKh877TxtA

Source : IR Remotes Revisited – 2023

รีโมตคอนโทรลแบบอินฟราเรด

IR Remote ตอนที่ 2: NEC Protocol เจาะลึกภาษาลับของรีโมต IR ที่ไมโครคอนโทรลเลอร์เข้าใจ
my avatar

Pawinphat

Founder of Bunpajarn.com • Electronics & Embedded Systems

Leave a Reply

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