หน้าแรก ดูโปรเจกต์ทั้งหมด
Expert

โปรเจกต์ การพัฒนา IR Remote และ Software Controller

ในบทความนี้เราพัฒนา IR Remote ทดแทนสำหรับ Speakers และ Projectors ซึ่งตัว IR Remote ถูกควบคุมโดย .NET application

โปรเจกต์ การพัฒนา IR Remote และ Software Controller

รายการอุปกรณ์และเครื่องมือ

1x Laser cutter (generic)
-
1x Infrared LED 940nm
-

รายละเอียดและวิธีทำ

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

เรามีชุดลำโพง Vision AV-1000 ซึ่งเป็นลำโพง active แบบติดตั้งบนผนัง เชื่อมต่อกับโปรเจคเตอร์ EPSON รีโมทของโปรเจคเตอร์นั้นหาได้ง่าย แต่รีโมทของ AV-1000 เลิกผลิตไปแล้ว ตัวลำโพงเองก็ไม่มีปุ่มควบคุมแบบ manual สำหรับเลือก input หรือปรับเสียง bass/treble ฯลฯ มีเพียงปุ่มปรับระดับเสียงที่ด้านหลังเท่านั้น

ทางออกคืออะไร?

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

แนวคิดนั้นง่ายมาก คือเราจะดักจับสัญญาณ IR จากรีโมทลำโพงที่ยังเหลืออยู่ แล้วบันทึกคำสั่งที่ถูกส่งออกมา

เราทำสิ่งนี้โดยการเชื่อมต่อ IR Receiver เข้ากับ Arduino ตัว Receiver มี 3 Pins เรียงจากซ้ายไปขวาคือ GND, +5V, SIGNAL และใช้งาน Arduino IRRemote library

รันตัวอย่าง Examples > IRRemote > IRrecvDumpv2 (ดูรูปด้านล่างที่เชื่อมต่อ IR Receiver เข้ากับ Arduino Uno สำหรับการทำต้นแบบ คุณสามารถใช้ Arduino nano ได้ แต่ต้อง upload/reset sketches เวลาทดสอบ)

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

เปิด Arduino serial monitor และคุณควรจะเห็นข้อมูลที่ได้รับแสดงออกมา (ดูรูปด้านล่าง)

โชคดีสำหรับเราที่โปรโตคอลที่รีโมทลำโพงใช้ถูกระบุว่าเป็น NEC protocol ขนาด 32 bits ซึ่ง IRRemote library มีฟังก์ชันในตัวสำหรับส่งข้อมูลนี้ซ้ำได้อยู่แล้ว ตอนนี้สิ่งที่เราต้องทำคือไล่กดรีโมทลำโพงทีละปุ่มเพื่อบันทึกรหัสของแต่ละปุ่มไว้ (ข้อมูลด้านล่าง)

RESET: 827D58A7


MUTE: 827DD827


INPUT 1: 827D708F


INPUT 2: 827D48B7


TREBLE UP: 827DF20D


TREBLE DOWN: 827DCA35


BASS UP: 827DF00F


BASS DOWN: 827DC837


VOLUME DOWN:
827D40BF


VOLUME UP: 827DC03F

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

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

ขั้นตอนต่อไปคือการเชื่อมต่อ IR LED และ Resistor เข้ากับ Arduino Board โดย IRRemote library จะส่งสัญญาณผ่าน Pin 3 ซึ่งเป็นวงจรที่พื้นฐานมากในการเชื่อมต่อ ในการใช้ Arduino nano ผมได้บัดกรี Resistor เข้ากับขาข้างหนึ่งของ IR LED และอีกด้านต่อเข้ากับ Pin บน Board โดยตรง ซึ่งมันทำงานได้สมบูรณ์แบบ เพราะคุณสามารถดันตัว LED ลงบน Board ให้แนบสนิทได้พอดี

เราจะใช้โปรแกรม VB.NET ง่ายๆ ในการสื่อสารกับ Arduino โดยมันจะเขียนข้อมูลไปยัง serial port และส่ง byte ออกไป – ใน Arduino sketch เราจะเฝ้าดู serial port เพื่อหา byte ที่เข้ามาและจับคู่พวกมันกับรหัสที่จะถูกส่งออกไปทาง IR ง่ายมาก!

Arduino Sketch ของเรา

/*
* IRremote: AV_Controller
* An IR LED must be connected to Arduino PWM pin 3.
* Version 0.1 01/04/16
*/

#include

IRsend irsend;
byte byteRead;

void(* resetFunc) (void) = 0; //declare reset function @ address 0

void setup() {
Serial.begin(9600);
Serial.println("***********************");
Serial.println("** AV-CONTROLLER **");
Serial.println("***********************");
Serial.println("Waiting for commands...");
}

void loop() {
if (Serial.available()) {
byteRead = Serial.read();
processResponse(byteRead);
}
}

void processResponse(byte byteInput) {
switch (byteInput) {
case '4':
Serial.println("Sending Command: TEST 4");
// irsend.sendNEC(0x827DD827, 32);
delay(40);
return;
break;
case 'a':
Serial.println("Sending Command: RESET");
irsend.sendNEC(0x827D58A7, 32);
delay(40);
Serial.println("Command Sent.");
return;
break;
case 'b':
Serial.println("Sending Command: MUTE");
irsend.sendNEC(0x827DD827, 32);
delay(40);
Serial.println("Command Sent.");
return;
break;
case 'c':
Serial.println("Sending Command: INPUT1");
irsend.sendNEC(0x827D708F, 32);
delay(40);
Serial.println("Command Sent.");
return;
break;
case 'd':
Serial.println("Sending Command: INPUT2");
irsend.sendNEC(0x827D48B7, 32);
delay(40);
Serial.println("Command Sent.");
return;
break;
case 'e':
Serial.println("Sending Command: TREBLE UP");
irsend.sendNEC(0x827DF20D, 32);
delay(40);
Serial.println("Command Sent.");
return;
break;
case 'f':
Serial.println("Sending Command: TREBLE DOWN");
irsend.sendNEC(0x827DCA35, 32);
delay(40);
Serial.println("Command Sent.");
return;
break;
case 'g':
Serial.println("Sending Command: BASS UP");
irsend.sendNEC(0x827DF00F, 32);
delay(40);
Serial.println("Command Sent.");
return;
break;
case 'h':
Serial.println("Sending Command: BASS DOWN");
irsend.sendNEC(0x827DC837, 32);
delay(40);
Serial.println("Command Sent.");
return;
break;
case 'i':
Serial.println("Sending Command: VOLUME DOWN");
irsend.sendNEC(0x827D40BF, 32);
delay(40);
Serial.println("Command Sent.");
return;
break;
case 'j':
Serial.println("Sending Command: VOLUME UP");
irsend.sendNEC(0x827DC03F, 32);
delay(40);
Serial.println("Command Sent.");
return;
break;
case 'x':
Serial.println("Resetting System...");
resetFunc();
return;
break;

break;
case 't':
Serial.println("OK");
return;
break;

break;
default:

break;
}
Serial.println("Unknown command.");
}

หลักการพื้นฐานของ sketch คือ เราจะตรวจจับข้อมูลที่เข้ามาทาง serial port หาก byte นั้นตรงกับตัวเลือกใน switch case ของเรา เราจะส่งคำสั่ง IR ที่เกี่ยวข้องออกไป หากไม่ตรง เราจะแสดงข้อความว่าเป็นคำสั่งที่ไม่รู้จัก

เราสามารถทดสอบโค้ดด้านบนได้โดยการเชื่อมต่อกับ COM port ของเราโดยใช้ PuTTy ให้เปิด PuTTy ขึ้นมาแล้วระบุ COM port ที่ Arduino เชื่อมต่ออยู่ เมื่อเชื่อมต่อแล้ว คุณควรจะเห็นผลลัพธ์จาก Serial println ในฟังก์ชัน setup()

ลองพิมพ์ตัวอักษร 'a' เพื่อส่งคำสั่ง RESET แล้วคุณควรจะเห็นผลลัพธ์ที่ตอบกลับมา คุณสามารถทดสอบกับชุดลำโพงได้เลย มันควรจะทำการ RESET ระดับเสียง/bass/treble ฯลฯ คุณสามารถดูผลลัพธ์ที่คาดหวังได้จาก screenshot ด้านล่าง

PuTTy

ตอนนี้เรามีแอปพลิเคชันที่ใช้งานได้แล้ว เราต้องทำให้มันดูสวยงามขึ้น เราคงไม่คาดหวังให้ผู้ใช้ทั่วไปมาเปิด PuTTy เข้า Serial port เพื่อส่งคำสั่งหรอกใช่ไหม? เราจะมาเริ่มออกแบบ Desktop application กัน

แอปพลิเคชัน .NET

สิ่งแรกที่ต้องทำคือการสื่อสารกับ serial port จริงๆ แล้วเราเพิ่งเขียนบทความเกี่ยวกับเรื่องนี้ไปเมื่อเร็วๆ นี้ ลิงก์อยู่ที่นี่ คุณจะเห็นว่าเราตรวจหาโดยอัตโนมัติว่าควรใช้ COM port ไหนโดยการส่งสตริงตรวจสอบ แอปพลิเคชันจะวนลูปผ่าน COM ports ที่มีอยู่และส่งสตริง 't' ออกไป หาก COM port ใดตอบกลับมาว่า 'OK' แสดงว่าเราเจอพอร์ตที่ถูกต้องแล้ว วิธีนี้ช่วยให้ผู้ใช้ไม่ต้องมาคอยเลือกพอร์ตเอง

การส่งคำสั่งจะถูกรวมไว้ในฟังก์ชันเล็กๆ ที่ชื่อว่า sendCommand โค้ด .NET อยู่ด้านล่าง (มันยังทำหน้าที่สลับสีของ Picturebox เพื่อเลียนแบบการกะพริบของไฟ LED บนรีโมทด้วย)

 Sub sendCommand(data As String)
PictureBox2.BackColor = Color.Green
If connected = True Then
If data <> "" Then
Try
Using com As IO.Ports.SerialPort =
My.Computer.Ports.OpenSerialPort(comPort)
com.WriteLine(data)
com.Close()
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End If
End If
PictureBox2.BackColor = Color.White
End Sub

โค้ดส่วนที่เหลือคุณสามารถดูได้ที่ด้านล่าง มันเป็นเพียงแค่การใช้ sendCommand('a') หรือสตริงอื่นๆ ที่คุณต้องการส่งไปยัง COM port ส่วนที่เหลือของแอปพลิเคชันเป็นเพียง GUI สวยๆ โค้ดและ screenshot ของแอปพลิเคชันขณะทำงานอยู่ด้านล่าง

คุณสามารถดูโค้ดแอปพลิเคชัน .NET ฉบับเต็มได้ที่ด้านล่าง พัฒนาโดยใช้ VS 2015 Community

Imports System.Threading

Public Class Form1
Dim connected As Boolean
Dim comPort As String

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
portConfig()
End Sub

Sub portConfig()
For Each p As String In My.Computer.Ports.SerialPortNames
Try
Using com As IO.Ports.SerialPort =
My.Computer.Ports.OpenSerialPort(p)
com.ReadTimeout = 1000
com.WriteLine("t")
Dim data As String = com.ReadLine()
If InStr(data, "OK") Then
lblConnection.Text = "Connected to " &amp; p
comPort = p
connected = True
End If
com.Close()
End Using
Catch ex As Exception

End Try
Next
End Sub

Sub sendCommand(data As String)
PictureBox2.BackColor = Color.Green
If connected = True Then
If data &lt;&gt; "" Then
Try
Using com As IO.Ports.SerialPort =
My.Computer.Ports.OpenSerialPort(comPort)
com.WriteLine(data)
com.Close()
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End If
End If
PictureBox2.BackColor = Color.White
End Sub

Private Sub ConnectToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ConnectToolStripMenuItem.Click
portConfig()
End Sub

Private Sub ResetDeviceToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ResetDeviceToolStripMenuItem.Click
sendCommand("x")
End Sub

Private Sub ExitToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ExitToolStripMenuItem.Click
Application.Exit()
End
End Sub

Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
Label1.Parent = PictureBox1
Label1.BackColor = Color.Transparent

Label2.Parent = PictureBox1
Label2.BackColor = Color.Transparent

Label3.Parent = PictureBox1
Label3.BackColor = Color.Transparent

Label4.Parent = PictureBox1
Label4.BackColor = Color.Transparent

Label5.Parent = PictureBox1
Label5.BackColor = Color.Transparent

Label6.Parent = PictureBox1
Label6.BackColor = Color.Transparent

Label7.Parent = PictureBox1
Label7.BackColor = Color.Transparent

Label8.Parent = PictureBox1
Label8.BackColor = Color.Transparent

Label9.Parent = PictureBox1
Label9.BackColor = Color.Transparent

Label10.Parent = PictureBox1
Label10.BackColor = Color.Transparent
End Sub

Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click
sendCommand("a")
End Sub

Private Sub Label2_Click(sender As Object, e As EventArgs) Handles Label2.Click
sendCommand("b")
End Sub

Private Sub Label3_Click(sender As Object, e As EventArgs) Handles Label3.Click
sendCommand("c")
End Sub

Private Sub Label4_Click(sender As Object, e As EventArgs) Handles Label4.Click
sendCommand("d")
End Sub

Private Sub Label5_Click(sender As Object, e As EventArgs) Handles Label5.Click
sendCommand("e")
End Sub

Private Sub Label6_Click(sender As Object, e As EventArgs) Handles Label6.Click
sendCommand("f")
End Sub

Private Sub Label7_Click(sender As Object, e As EventArgs) Handles Label7.Click
sendCommand("g")
End Sub

Private Sub Label8_Click(sender As Object, e As EventArgs) Handles Label8.Click
sendCommand("h")
End Sub

Private Sub Label9_Click(sender As Object, e As EventArgs) Handles Label9.Click
sendCommand("j")
End Sub

Private Sub Label10_Click(sender As Object, e As EventArgs) Handles Label10.Click
sendCommand("i")
End Sub

Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles Me.Resize
If Me.WindowState = FormWindowState.Minimized Then
NotifyIcon1.Visible = True
NotifyIcon1.Icon = SystemIcons.Application
NotifyIcon1.BalloonTipIcon = ToolTipIcon.Info
NotifyIcon1.BalloonTipTitle = "AV Controller"
NotifyIcon1.BalloonTipText = "Controller is minimized. Click the icon in the tray to open."
NotifyIcon1.ShowBalloonTip(50000)
ShowInTaskbar = False
End If
End Sub

Private Sub NotifyIcon1_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles NotifyIcon1.MouseDoubleClick
ShowInTaskbar = True
Me.WindowState = FormWindowState.Normal
NotifyIcon1.Visible = False
End Sub
End Class

กล่องใส่อุปกรณ์

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

เราใช้โปรแกรม 2D Design เพื่อออกแบบกล่องใส่ที่เรียบง่ายมาก

อย่างที่คุณเห็นจาก screenshot ของ 2D Design ทางด้านซ้าย มันเป็นการออกแบบที่พื้นฐานมาก เชื่อมต่อเข้าด้วยกันด้วยพลาสติกแบบมีเกลียว (สอดผ่านรู) ผลงานที่ผ่านการตัดด้วยเลเซอร์อยู่ด้านล่าง:

ผลิตภัณฑ์สำเร็จรูป

เราทำสิ่งต่างๆ ต่อไปนี้สำเร็จสำหรับโปรเจกต์นี้:

  • ดักจับข้อมูล IR ของรีโมทเดิมได้
  • พัฒนาอุปกรณ์ (Arduino & IR LED) เพื่อส่งข้อมูลนี้กลับออกไป
  • ออกแบบกล่องใส่เพื่อให้วางข้างๆ PC ได้อย่างสวยงาม

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

ต้นทุนรวมของโปรเจกต์นี้อยู่ที่ประมาณ 4 ปอนด์ โดยส่วนประกอบส่วนใหญ่หามาจาก eBay


อ่านเพิ่มเติม

Code

🔒 ปลดล็อก Code

สนับสนุนเพื่อรับ Source Code หรือแอปพลิเคชันสำหรับโปรเจกต์นี้

รหัสอ้างอิงโปรเจกต์: developing-an-ir-remote-and-software-controller-4fc954
1120 บาท
PromptPay QR Code

ประเมิน Project

อยากได้งานคล้ายโปรเจคนี้? กดไปหน้าประเมินราคา

เอาฟอร์มยาวออกจากท้ายหน้า Project แล้ว เหลือเป็นปุ่มให้กดไปกรอกหน้าเดียว ตัวใหญ่ เว้นบรรทัดเยอะ อ่านง่ายกว่า

รีวิวจากคนใช้งานจริง

รีวิวจากลูกค้าและคนที่เคยใช้งาน

ถ้าเคยสั่งงาน เคยอ่านหน้านี้แล้วได้ประโยชน์ หรือมีข้อเสนอแนะ ฝากรีวิวไว้ได้เลย

กำลังโหลดรีวิว...