Proto Knowledge
PC Interface โดย : กฤษดา ใจเย็น
ต�ดตออุปกรณภายนอกผาน พอรต USB ดวยบอรด UCON-UART ก่อนหน้านี้การอินเตอร์เฟสระหว่างคอมพิวเตอร์กับอุปกรณ์ภายนอกท�าได้ง่ายๆ ผ่าน พอร์ตอนุกรมหรือพอร์ตขนาน แต่เมื่อพอร์ตอนุกรมและพอร์ตขนานถูกตัดสิทธิ์ ไม่มีให้ใช้ งานเหลือเพียงพอร์ต USB ซึ่งเข้าถึงได้ยาก บอร์ด UCON-UART จึงถือก�าเนิดขึ้นเพื่อแก้ ปัญหานี้ โดยแปลงกายตัวเองให้เปนพอร์ตอนุกรม มาดูกันว่าการเขียนโปรแกรมควบคุม จะง่ายเหมือนกับพอร์ตอนุกรมหรือไม่
บอร์ด UCON-UART บอร์ด UCON-UART เปนบอร์ดแปลงพอร์ต USB ให้เปน พอร์ตอนุกรมหรือ COM PORT โดยหัวใจหลักคือชิปเบอร์ FT232RL ของบริษัท FTDI สามารถเขียนโปรแกรมติดต่อได้ 2 รูปแบบคือ VCP (Visual Com Port) ที่จ�าลองการท�างานของพอร์ตอนุกรมสมบูรณ์ แบบมีขาสัญญาณออกมาให้ใช้งานครบทั้ง 9 เส้น และแบบ D2xx ที่ก�าหนดขาพอร์ตให้เปนอินพุตเอาต์พุตได้อย่างอิสระ ในบทความ ตอนนี้จะใช้งานในรูปแบบของ VCP ก่อน โดยรูปร่างของบอร์ด UCON-UART และขาต่อใช้งานต่างๆ ในโหมด VCP แสดงในรูปที่ 1
รูปที่ 1 บอร์ด UCON-UART และข�สำ�หรับต่อใช้ง�น
RTS DTR TxD
VUSB
3.3V
VUSB
Tx
USB
รูปที่ 2 วงจรแสดงก�รเชื่อมต่อบอร์ด UCON-UART เข้�กับ LED เพื่อทดสอบก�รส่งค่�เอ�ต์พุต
The Prototype Electronics
USB to UART Converter
Rx
Rx
52
UCON-UART
SLEEP TXDEN PWREN TXLED RXLED RESET GND
R3 510
GND VUSB 3.3V TxD DTR RTS RxD RI DSR DCD CTS
SLEEP TXDEN PWREN TXLED RXLED RESET GND
LED3
R2 510
USB to UART Converter
FTDI
LED2
R1 510
UCON-UART
FTDI
LED1
VUSB 3.3V TxD DTR RTS RxD RI DSR DCD CTS
3.3V
GND
รูปที่ 3 แสดงก�รเชื่อมต่อวงจรจริงบนเบรดบอร์ด
Tx
USB
Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim Port_Name As String() Dim Name_ As String
รูปที่ 4 หน้าต่างเริ่มต้นขั้นตอนการสร้างโปรเจ็กต์ ของ Visual Basic Express
รูปที่ 5 การวางคอนโทรลต่างๆ สำ�หรับโปรแกรม ที่ 1
‘=========================================== ‘ กำ�หนดชื่อให้กับคอนโทรลต่างๆ ‘===========================================
Me.Text = “Simple Digital Output” GroupBox1.Text = “Serial Port” Button1.Text = “Connect” Button2.Text = “E&xit” GroupBox2.Text = “Digital Ouput” Button3.Text = “TxD “ Button4.Text = “DTR “ Button5.Text = “RTS “
‘=========================================== ‘ ค้นหาพอร์ตอนุกรมที่ติดตั้งภายในคอมพิวเตอร์ ‘===========================================
ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList ComboBox1.Sorted = True Port_Name = IO.Ports.SerialPort.GetPortNames() For Each Name_ In Port_Name ComboBox1.Items.Add(Name_) Next ComboBox1.SelectedIndex = 0 SerialPort1.PortName = ComboBox1.Text End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click If SerialPort1.IsOpen Then ‘ ปิดการสื่อสารของพอร์ตอนุกรม ถ้าพอร์ตนั้นเปิดอยู่ SerialPort1.Close() Button1.Text = “Connect” ComboBox1.Enabled = True Else SerialPort1.Open() ‘ เปิดการสื่อสารของพอร์ตอนุกรม Button1.Text = “Disconnect” ComboBox1.Enabled = False SerialPort1.DtrEnable = True ‘ ส่งลอจิก “0” ให้ขา DTR SerialPort1.RtsEnable = True ‘ ส่งลอจิก “0” ให้ขา RTS SerialPort1.BreakState = True ‘ ส่งลอจิก “0” ให้ขา TxD End If End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click If SerialPort1.IsOpen Then ‘ ปิดการสื่อสารของพอร์ตอนุกรมและออกจากโปรแกรม SerialPort1.Close() End If End End Sub Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged SerialPort1.PortName = ComboBox1.Text ‘ เลือกของตำ�แหน่งของพอร์ตอนุกรมที่ต้องการ End Sub Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click SerialPort1.BreakState = Not SerialPort1.BreakState ‘สลับบิตที่ส่งไปยังขา TxD End Sub Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click SerialPort1.DtrEnable = Not SerialPort1.DtrEnable ‘สลับบิตที่ส่งไปยังขา DTR End Sub Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click SerialPort1.RtsEnable = Not SerialPort1.RtsEnable ‘สลับบิตที่ส่งไปยังขา RTS End Sub End Class
รูปที่ 6 หน้าต่างโปรแกรม Simple Digital Output เมื่อสั่งรันให้ทำ�งาน
ขา 1 2 3 4 5 6 7 8 9
ชื่อ DCD RxD TxD DTR GND DSR RTS CTS RI
หนาที่ Data Carrier Detect Receive Data Transmit Data Data Terminal Ready Signal Ground Data Set Ready Request to Send Clear to Send Ring Indicator
ทิศทาง อินพุต อินพุต เอาตพุต เอาตพุต กราวด อินพุต เอาตพุต อินพุต อินพุต
ตารางที่ 1 ตำ�แหน่งขามาตรฐานของพอร์ต อนุกรมและทิศทางของขาพอร์ต
โปรแกรมที่ 1 โปรแกรมสำ�หรับทดสอบส่งค่าลอจิกไปยังขา TxD,DTR และ RTS ของบอร์ด UCON-UART ขาสัญญาณของพอร์ตอนุกรม
การเขียนโปรแกรมควบคุม
กอนจะใชงานบอรด UCON-UART จะตอ ง รูจ กั หนาทีข่ องขาตา งๆ ของพอรตอนุกรมกนั กอ น โดยขาสญ ั ญาณของพอรตอนุกรม 9 ขาแบงเปนขา อินพุต 5 ขา ขาเอาตพตุ 3 ขา อีก 1 ขาเปนกราวด ดังแสดงรายละเอียดในตารางที่ 1 ซึง่ ขาเหลานีใ้ น อดีตถูกออกแบบมาเพื่อเชื่อมตอกับโมเด็ม การ ใชงานปกติจะใชขา TxD ในการสง ขอ มูล และขา RxD ในการรบั ขอ มูล สวนขาอนื่ ๆ ท�ำหนาทีเ่ ปน ขาตรวจสอบการสอื่ สารขอ มูลหรือทเี่ รียกวาแฮนด เซ็ก และเมื่อจ�ำแนกขาสัญญาณออกเปนสอง ประเภทคอื ขาอนิ พุตและขาเอาตพตุ เราสามารถ เขียนโปรแกรมเพือ่ ควบคุมขาเหลานีไ้ ดอยางอสิ ระ โดยโปรแกรมทใี่ ชเขียนทดสอบกค็ อื Visual Basic Express 2008 ซึง่ เคยแนะน�ำการใชงานไปแลวใน TPE ฉบับที่ 2
ทดสอบการขับอุปกรณ์เอาต์พุต ทดสอบโปรแกรมรูปแบบแรกด้วยการส่ง ค่าลอจิก “0” และลอจิก “1” ออกไปยังอุปกรณ์ ภายนอกกันก่อน วงจรในรูปที่ 2 เป็นวงจรน�ำเอา ขา DTR, RTS และขา TxD มาต่อเข้ากับ LED เพือ่ ให้เห็นสถานะลอจิก “0” (LED ดับ) และลอจิก “1” (LED ติดสว่าง) รูปที่ 3 จะแสดงการเชือ่ มต่อจริง โดย ใช้เบรดบอร์ดแผ่นจิว๋ มาต่อวงจร (1) เปดโปรแกรม Visual Basic Express 2008 (2) สรางโปรเจ็กตใหม โดยเรียกจากเมนู File > New Project เลือกสรางโปรเจ็กตเปนแบบ Windows Forms Application ดังร ูปท ี่ 4 (3) ตั้งชื่อโปรเจ็กตในที่นี้ตั้งชื่อวา Simple Digital Output The Prototype Electronics
53
PC Interface : UCON-UART UCON-UART
GND
SW2 RI
SW3 DSR
R4 10k
SW4 DCD
R5 10k
3.3V
VUSB
Rx
Tx
VUSB
Tx
USB
USB
SW5 CTS
(4) ลาก คอนโทรล ต่างๆ มา วางลง บน ฟอร์ม ใน ต�าแหน่ง ดัง รูป ที่ 5 โดย ส่วน ส�าคัญที่สุด คือ คอนโทรล SerialPort1 ซึ่ง ใช้ ใน การ สื่อสาร กับ บอร์ด UCON-UART (5) เขียน โปรแกรม ให้ กับ คอนโทรล ต่างๆ ตามที่ แสดง ใน โปรแกรม ที่ 1
รูปที่ 8 แสดงก�รเชื่อมต่อ วงจรจริงบนเบรดบอร์ด
โปรแกรมยอย Button3_Click() Button4_ Click() Button5_Click() จะใชเพื่อสลับลอจิกที่
การเขียนโปรแกรมรับค่าจากสวิตช์ 5 ช่อง
รันโปรแกรม
(2) สร้างโปรเจ็กต์ใหม่ โดยเรียกจากเมนู File > New Project เลือกสร้างโปรเจ็กต์เปนแบบ Windows Forms Application
ขา TxD DTR และ RTS ตามลําดับ
หลังจาก ตอ่ วงจร เรียบร้อย ให้รนั โปรแกรม จะ พบ หน้าต่าง โปรแกรม ดงั รปู ท ี่ 6 เรา จะ ตอ้ ง เลือก ต�าแหน่ง พอร์ ตอน กรุ ม ท เี่ ปน ตา� แหน่ง ของ UCONการท�างานของโปรแกรม UART จากนัน้ กดปุม Connect เพือ่ เปด พอร์ต โปรแกรมยอย Form_Load() อนุกรม ข้อความ ท ปี่ มุ จะ แสดง Disconnect จะ จะเริ่ ม ต้ น จากก� า หนดค่ า คุ ณ สมบั ติ ข อง เห็นว่า LED ทีต่ อ่ อยู ท่ งั้ 3 ดวง ดบั ทงั้ หมด ทดสอบ คอนโทรลต่างๆ ที่ใช้บนฟอร์มเมื่อโหลดขึ้นมาใช้ กดปุม TxD DTR และ RTS จะ เห็น LED ติด และ งานครั้งแรก จากนั้นจะค้นหาพอร์ตอนุกรมที่ติด ดับ ตาม การ กด คยี ์ จากนัน้ กดปุม Disconnect ตั้งอยู่ภายในเครื่องคอมพิวเตอร์ โดยแสดงรายชื่อ เพือ่ ปด พอร์ต อนุกรม และ กด Exit เพือ่ ออกจาก COMPORT ที่ตรวจพบใน ComboBox โดยจะรอ โปรแกรม ให้ผู้ใช้กดเลือกเพื่อเลือแล้วกดปุม Button1 เพื่อ ทดสอบการรับค่าอินพุต ใช้เชื่อมต่อ โปรแกรมยอย ComboBox1_SelectedInde- ขา รับสัญญาณ อินพุต ของ พอร์ต อนุกรม Changed() จะเกิดเหตุการณ (Event) เมือ่ มีการ มี มาก ถงึ 5 ขา การ ทดลอง น จี้ ะ เชือ่ ม ตอ่ สวิตช์ เปลีย่ นแปลงการเลือกตําแหนงพอรตอนุกรมภายใน ทัง้ หมด 5 ตัว เพือ่ อา่ น คา่ จาก ขา อนิ พุต ทงั้ 5 ขา ComboBox โดยจะกําหนดใหตําแหนงพอรตอนุกรม โดย แสดง วงจร การ เชือ่ ม ตอ่ ดงั รปู ท ี่ 7 ส่วนใน รปู ที่ 8 เปนการ ตอ่ ใช้งาน จริง บน เบรด บอร์ด จวิ๋ สวิตช์ ทงั้ เปนตําแหนงทีถู่ กเลือก 5 ตัว เปน สวิตช์ กด ตดิ ปล่อย ดบั ต่อตัว ตา้ นทาน พลู โปรแกรมยอย Button1_Click() จะตรวจสอบ อัพ คา่ 10kΩ เพือ่ ให้ สถานะ ท ไี่ ม่ กด สวิตช์ ม ลี อจิก พอรตอนุกรมตําแหนงปจจุบนั วาถูกเปดใชอยูห รือไม เปน “1” ถาไมจะทําเปดพอรตอนุกรม ในตําแหนงทีร่ ะบุผา น การ อ่าน ค่า อินพุต ส�าหรับ พอร์ต อนุกรม นี้ มี ComboBox และสงลอจิก “0” ใหกบั ขาเอาตพตุ ข้อจ�ากัด ด้วย อปุ นิสยั ดงั้ เดิม ของ ขา พอร์ต เหล่านี้ ทัง้ 3 ขาโดย กล่าว คอื มนั จะ ม วี รรณะ ท ไี่ ม่ เท่ากัน โดย ถา้ ม กี าร ขา TxD ควบคุมดวยคําสั่ง BreakState กด สวิตช์ ท ขี่ า CTS (Clear To Send) ค้าง เอา ไว้ ขา DTR ควบคุมดวยคําสั่ง DTREnable สถานะ ท ขี่ า DCD และ DSR จะ ไม่ สามารถ คง คา้ ง ค่า เอา ไว้ ได้ เนือ่ งจาก เมือ่ CTS ท�างาน ขา เหล่านี จ้ ะ ขา RTS ควบคุมดวยคําสั่ง RTSEnable ถูก เคลียร์ สถานะ ไป ดว้ ย แต่ อย่างไร กต็ าม เมือ่ ไม่ม ี ถาขาเหลานี้เปน TRUE จะใหเอาตพุตเปน การ ใช้งาน ทบั ซอ้ นกัน ขา พอร์ต เหล่านี ก้ ท็ า� หน้าที ่ ลอจิก “0” เปน ขา อนิ พุต ได้ อย่าง ดี โปรแกรมยอย Button2_Click() ใชเพื่อออกจาก โปรแกรม
The Prototype Electronics
3.3V
Rx
รูปที่ 7 วงจรเชื่อมต่อสวิตช์เข้�กับบอร์ด UCON-UART เพื่อทดสอบรับค่�อินพุต
54
SLEEP TXDEN PWREN TXLED RXLED RESET GND
R3 10k
FTDI
SW1 RxD
R2 10k
USB to UART Converter
SLEEP TXDEN PWREN TXLED RXLED RESET GND
R1 10k
VUSB 3.3V TxD DTR RTS RxD RI DSR DCD CTS
UCON-UART
USB to UART Converter
FTDI
GND
VUSB 3.3V TxD DTR RTS RxD RI DSR DCD CTS
(1) เปดโปรแกรม Visual Basic Express 2008
(3) ตั้งชื่อโปรเจ็กต์ในที่นี้ตั้งชื่อว่า Simple Digital Input (4) ลากคอนโทรลต่างๆ มาวางลงบนฟอร์ม ในต�าแหน่งดังรูปที่ 9 (5) เขี ย นโปรแกรมให้ กั บ คอนโทรลต่ า งๆ ตามที่แสดงในโปรแกรมที่ 2
การท�างานของโปรแกรม ในโปรแกรมที่ 2 มีหลายโปรแกรมย่อยที่ ท�างานเช่นเดียวกับโปรแกรมที่ 1 ดังนั้นจะอธิบาย เฉพาะโปรแกรมย่อยที่เพิ่มเติมขึ้นมา ประกอบ ด้วย
โปรแกรมยอย SerialPort1_PinChanged() โปรแกรมย่ อ ยนี้ จ ะถู ก เรี ย กขึ้ น มาท� า งาน เมื่อเกิดเหตุการณ์ การเปลี่ยนแปลงที่ขาอินพุต โดยจะให้ค่า Eventype ออกมา เพื่อแจ้งสถานะ ของขาต่าง ๆ โดยค่า Eventype เปนค่าตัวเลข ค่าที่เกี่ยวข้องกับขาทั้ง 5 ขามีดังนี้ Eventype = 8 ขา CTS มีลอจิก “0” Eventype = 16 ขา DSR มีลอจิก “0” Eventype = 32 ขา DCD มีลอจิก “0” Eventype = 64 ขา RxD มีลอจิก “0” Eventype = 256 ขา RI มีลอจิก “0” โดยค่ า เหล่ า นี้ ส ามารถใช้ ตั ว แปรเหล่ า นี้ แทนได้ IO.Ports.SerialPinChange.Brake = ขา RxD IO.Ports.SerialPinChange.Ring = ขา RI
Public Class Form1 Dim Even_ As Integer Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim Port_Name As String() Dim Name_ As String
‘=========================================== ‘ กำ�หนดชื่อให้กับคอนโทรลต่�งๆ ‘===========================================
รูปที่ 9 ก�รว�งคอนโทรลต่�งๆ สำ�หรับ โปรแกรมที่ 2
Me.Text = “Simple Digital Input” GroupBox1.Text = “Serial Port” Button1.Text = “Connect” Button2.Text = “E&xit” GroupBox2.Text = “Digital Input” RadioButton1.Text = “RxD” RadioButton2.Text = “RI” RadioButton3.Text = “DSR” RadioButton4.Text = “DCD” RadioButton5.Text = “CTS” Timer1.Interval = 200 Timer1.Enabled = False
‘=========================================== ‘ ค้นห�พอร์ตอนุกรมที่ติดตั้งภ�ยในคอมพิวเตอร์ ‘===========================================
ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList ComboBox1.Sorted = True Port_Name = IO.Ports.SerialPort.GetPortNames() For Each Name_ In Port_Name ComboBox1.Items.Add(Name_) Next ComboBox1.SelectedIndex = 0 SerialPort1.PortName = ComboBox1.Text End Sub
รูปที่ 10 หน้�ต่�งโปรแกรม Simple Digital Input เมื่อสั่งรันให้ทำ�ง�น IO.Ports.SerialPinChange.CDChanged = ขา DCD IO.Ports.SerialPinChange.DSRChanged = ขา DSR IO.Ports.SerialPinChange.CTSChanged =ขา CTS
หน้ า ที่ ห ลั ก ของโปรแกรมย่ อ ยจะน� า ค่ า Eventype ที่เกิดขึ้นส่งให้กับตัวแปร Even_ เพื่อ ให้ Timer1 เปนตัวแสดงสถานะที่ RadioButton แทน
โปรแกรมยอย Timer1_Tick()
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click If SerialPort1.IsOpen Then ‘ ปิดก�รสื่อส�รของพอร์ตอนุกรม ถ้�พอร์ตนั้นเปิดอยู่ Timer1.Enabled = False SerialPort1.Close() Button1.Text = “Connect” ComboBox1.Enabled = True Else SerialPort1.Open() ‘ เปิดก�รสื่อส�รของพอร์ตอนุกรม Button1.Text = “Disconnect” ComboBox1.Enabled = False Timer1.Enabled = True End If End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click If SerialPort1.IsOpen Then ‘ ปิดก�รสื่อส�รของพอร์ตอนุกรมและออกจ�กโปรแกรม SerialPort1.Close() End If End End Sub Private Sub SerialPort1_PinChanged(ByVal sender As Object, ByVal e As System.IO.Ports. SerialPinChangedEventArgs) Handles SerialPort1.PinChanged Even_ = e.EventType End Sub Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick If Even_ = IO.Ports.SerialPinChange.Break Then RadioButton1.Checked = True Else RadioButton1.Checked = False End If If Even_ = IO.Ports.SerialPinChange.Ring Then RadioButton2.Checked = True Else RadioButton2.Checked = False End If RadioButton3.Checked = SerialPort1.DsrHolding RadioButton4.Checked = SerialPort1.CDHolding RadioButton5.Checked = SerialPort1.CtsHolding End Sub End Class
ไทเมอร์เปนคอนโทรลที่ออกแบบมาเพื่อให้ เกิดเหตุการณ์ตามช่วงเวลาที่ก�าหนด (Interval) ซึ่งส�าหรับโปรแกรมนี้ตั้งค่า Interval ไว้เท่ากับ 200 ซึ่งหมายถึงจะมีเหตุการณ์เกิดทุกๆ 0.2 วินาที โดยจะท�าการน�าค่าตัวแปร Even_ ที่อ่าน ค่าได้มาเปรียบเทียบ แล้วไปแสดงสถานะที่ปุม โปรแกรมที่ 2 โปรแกรมทดสอบรับค่�จ�กข�อินพุตของพอร์ตอนุกรม RadioButton แต่ส�าหรับขา CTS DCD และ DSR ไม่จ�าเปนต้องเปรียบเทียบค่าผ่านตัวแปร Even_ ทดสอบการท�างาน ก็ได้ เนื่องจากทั้ง 3 ขา มีค�าสั่งเฉพาะที่เรียกตรวจ เมื่อต่อวงจรเรียบร้อย และเขียนโปรแกรมตามโปรแกรมที่ 2 แล้ว ให้สั่งรันโปรแกรมเพื่อทดสอบ สอบค่าได้โดยตรง ประกอบด้วย การท�างาน หน้าจอของโปรแกรมจะแสดงดังรูปที่ 10 จากนั้นทดลองกดสวิตช์ไล่ล�าดับทีละตัว สังเกตการ SerialPort1.CtsHolding เปลี่ยนแปลงของสถานะที่หน้าจอ SerialPort1.CdHolding จากโปรแกรม 2 โปรแกรมนี้ก็คงพอเปนไอเดีย นําเอาพอรต USB ไปควบคุมอุปกรณภายนอกอยาง
SerialPort1.DsrHolding
งายๆ ไดแลวนะครับ
ดังนั้นเฉพาะ 3 ขานี้ในโปรแกรมจึงใช้การ ตรวจสอบค่าโดยตรงไปยัง RadioButton
The Prototype Electronics
55