การเขียนโปรแกรมด้วย Visual Basic เพื่อติดต่อพอร์ตอนุกรมและคัสตอมคอนโทรล MSComm

คอนโทรล MSComm
สำหรับการใช้งาน Visual Basic ตั้งแต่เวอร์ชัน 2 เป็นต้นมา ใน Visual Basic จะมีคัสตอมคอนโทรลสำหรับการสื่อสารอนุกรมผ่านทางพอร์ตอนุกรมของคอมพิวเตอร์มาให้ โดยใน Visual Basic เวอร์ชัน 2 และเวอร์ชัน 3 จะใช้ชื่อว่า MSCOMM.VBX ส่วนเวอร์ชัน 4 ใช้ชื่อว่า MSCOMM16.OCX สำหรับการทำงานกับระบบปฏิบัติการ 16 บิตและ MSCOMM32.OCX สำหรับการทำงานกับระบบปฏิบัติการ 32 บิต สำหรับใน Visual Basic เวอร์ชัน 5 จะมีเพียง MSCOMM32.OCX เท่านั้นเพราะถูกออกแบบมาให้ใช้งานกับระบบปฏิบัติการ 32 บิต
MSComm จัดเตรียมทางเลือกเอาไว้ 2 ทางเพื่อความสะดวกในการสื่อสารข้อมูล ทางแรกคือ การสื่อสารข้อมูลที่กระตุ้นด้วยเหตุการณ์ (event-driven communications ) เป็นรูปแบบการใช้งานที่มีประสิทธิภาพมากสำหรับการตอบสนองแบบทันทีทันใด เช่น เมื่อตัวอักษรถูกส่งมาที่พอร์ตอนุกรมหรือเกิดการเปลี่ยนแปลงที่ขา Data Carrier Detect (DCD) หรือขา Request To Send (RTS) เหตุการณ์ ONCOMM ของ MSComm จะสามารถตรวจจับสัญญาณนั้นได้ทันที ซึ่งจะกล่าวถึงรายละเอียดในหัวข้อคุณสมบัติ CommEvent ต่อไป ส่วนทางเลือกที่สองเป็นการคอยตรวจสอบค่าเหตุการณ์และความผิดพลาดที่เกิดขึ้นด้วยการดูค่าที่เปลี่ยนแปลงภายในคุณสมบัติ CommEvent หลังจากให้โปรแกรมทำงานในฟังก์ชั่นต่างๆ ไปเรียบร้อยแล้ว ซึ่งวิธีนี้ใช้งานได้ดีในกรณีที่โปรแกรมมีขนาดเล็ก
คอนโทรล MSComm 1 ตัวสามารถควบคุมการทำงานของพอร์ตอนุกรมได้ 1 พอร์ต ถ้าในโปรแกรมที่ใช้งานต้องการติดต่อกับพอร์ตอนุกรมมากกว่า 1 พอร์ตจะต้องใช้คอนโทรล MSComm มากกว่า 1 ตัวเพื่อควบคุมพอร์ตอนุกรมในแต่ละพอร์ต แอดเดรสของพอร์ตอนุกรมและแอดเดรสของการเกิดอินเตอร์รัปต์สามารถเปลี่ยนแปลงได้จากการแก้ไขค่าที่ Control Panel
ถึงแม้ว่า คอนโทรล MSComm จะมีคุณสมบัติ (property) มากมายหลากหลายตัว แต่สามารถทำความเข้าใจได้ไม่ยากดังนี้
CommPort
ใช้ในการกำหนดและอ่านค่าพอร์ตอนุกรมที่ติดต่ออยู่ (COM1,COM2 ,COM3,COM4)
รูปแบบการใช้งาน
object.CommPort[ = value ]
โดย Value เป็นค่าของพอร์ตอนุกรม ชนิดของข้อมูลเป็น Integer ค่า Value สามารถกำหนดได้ในช่วง 1-16 (ค่าเริ่มต้นกำหนดไว้ที่ 1) เมื่อมีการกำหนดค่าแล้วทำการเปิดพอร์ตโดยใช้คุณสมบัติ PortOpen แต่ว่าพอร์ตนั้นไม่มีอยู่ในระบบ MSCOMM จะสร้างสัญญาณแสดงข้อผิดพลาด error 68 ขึ้นมา ซึ่งหมายถึง อุปกรณ์ตัวนี้ไม่มีอยู่ในระบบ ดังนั้นการเขียนโปรแกรมจึงจำเป็นต้องกำหนดตำแหน่งของพอร์ตอนุกรมก่อนที่ใช้คำสั่ง OpenPort

Setting
ใช้ในการกำหนดและอ่านค่าอัตราบอด, พาริตี้, จำนวนของบิตข้อมูล , จำนวนของบิตปิดท้าย
รูปแบบการใช้งาน
object.Settings [ = value ]
ค่า Value มีชนิดข้อมูลเป็นแบบ String มีรูปแบบเป็น “BBBB,P,D,S” โดย BBBB เป็นค่าอัตราบอด, P เป็นค่าพาริตี้, D เป็นจำนวนของบิตข้อมูล และ S เป็นจำนวนของบิตปิดท้าย ปกติแล้วค่านี้ถูกกำหนดไว้เป็น “9600, N, 8, 1”

PortOpen
ใช้ในการกำหนดและอ่านค่าสถานะของพอร์ตอนุกรม เพื่อเปิดและปิดพอร์ตอนุกรม
รูปแบบการใช้งาน
object.PortOpen [ = value ]
ค่า Value มีชนิดข้อมูลเป็นแบบบูลีนคือ True กับ False โดย True หมายถึงการเปิดพอร์ตอนุกรมและ False หมายถึงการปิดพอร์ตอนุกรม สำหรับการปิดพอร์ตนั้นจะมีการเคลียร์บัฟเฟอร์รับข้อมูลและบัฟเฟอร์ส่งข้อมูลด้วย คอนโทรล MSComm จะปิดพอร์ตอนุกรมโดยอัตโนมัติเมื่อออกจากโปรแกรม ก่อนที่จะใช้คุณสมบัติ PortOpen ต้องตรวจสอบให้แน่ใจก่อนว่าคุณสมบัติ CommPort นั้นได้ทำการกำหนดตำแหน่งของพอร์ตอนุกรมไว้ถูกต้องหรือไม่ มิเช่นนั้น MSComm จะแสดงข้อผิดพลาด Error 68 แจ้งแก่ผู้ใช้งาน
ถ้าคุณสมบัติ DTREnable หรือ RTSEnable ถูกกำหนดให้เป็น True ก่อนที่จะทำการเปิดพอร์ต ค่าคุณสมบัติของ DTREnable หรือ RTSEnable จะถูกเซตเป็น False หลังจากปิดพอร์ต แต่ถ้าเซตเป็น False หลังจากปิดโปรแกรมแล้ว ค่าที่กำหนดไว้จะเป็นค่าเดิม

Input
อ่านค่าและลบค่าขบวนข้อมูลจากบัฟเฟอร์ภาครับ
รูปแบบการใช้งาน
object.Input
คุณสมบัติ InputLen เป็นตัวกำหนดจำนวนของตัวอักษรที่จะอ่านโดยคุณสมบัติ Input การกำหนดค่าให้ InputLen เท่ากับ 0 เป็นการกำหนดให้คุณสมบัติ Input ทำการอ่านค่าข้อมูลในบัฟเฟอร์รับข้อมูลทั้งหมด
คุณสมบัติ InputMode เป็นตัวกำหนดชนิดของข้อมูลที่คุณสมบัติ Input รับเข้ามา ถ้า InputMode ถูกกำหนดเป็น comInputModeText คุณสมบัติ Input จะส่งค่าข้อมูลกลับมาในรูปแบบของข้อความชนิดข้อมูลเป็นแบบ Variant ถ้า InputMode กำหนดเป็น comInputModeBinary คุณสมบัติ Input จะส่งข้อมูลกลับมาในรูปของไบนารี่และชนิดข้อมูลเป็นแบบ Variant ในตัวอย่างโปรแกรมที่ 4-1 แสดงให้เห็นถึงวิธีในการรับข้อมูลจากบัฟเฟอร์รับข้อมูล

โปรแกรมที่ 4-1
Private Sub Command1_Click()
Dim InString as String
‘ Retrieve all available data.
MSComm1.InputLen = 0
‘ Check for data.
If MSComm1.InBufferCount Then
‘ Read data.
InString = MSComm1.Input
End If
End Sub

Output
ใช้ในการส่งขบวนของข้อมูลไปยังบัฟเฟอร์ส่งข้อมูล
รูปแบบการใช้งาน
object.Output [ = value ]
ค่า value เป็นค่าของตัวอักษรที่เขียนไปยังบัฟเฟอร์ส่งข้อมูล คุณสมบัติ Output สามารถใช้ในการส่งข้อมูลตัวอักษรหรือข้อมูลไบนารี่ก็ได้ โดยการส่งข้อมูลเป็นรูปแบบตัวอักษรจะต้องกำหนดข้อมูลเป็นแบบ Variant และมีข้อมูลภายในเป็นแบบ String สำหรับการส่งข้อมูลไบนารี่จะต้องกำหนดชนิดของข้อมูลเป็นแบบ Variant และมีข้อมูลภายในเป็นแบบ Byte ตัวอย่างโปรแกรมที่ 4-2 เป็นการส่งค่าที่ป้อนจากคีย์บอร์ดทุก ๆ ตัวไปยังพอร์ตอนุกรม

โปรแกรมที่ 4-2
Private Sub Form_KeyPress (KeyAscii As Integer)
Dim Buffer as Variant
‘ Set and open port
MSComm1.CommPort = 1
MSComm1.PortOpen = True
Buffer = Chr$(KeyAscii)
MSComm1.Output = Buffer
End Sub

DTREnable
ใช้ในการอีนาเบิลขา Data Terminal Ready (DTR) โดยสัญญาณของขา DTR จะส่งจากคอมพิวเตอร์ไปยังโมเด็มเพื่อแสดงว่าคอมพิวเตอร์พร้อมที่จะรับข้อมูลแล้ว ชนิดของข้อมูลเป็นแบบ Boolean
รูปแบบการใช้งาน
object.DTREnable[ = value ]
ค่า Value เป็นค่าสถานะ True หรือ False เพื่ออีนาเบิลหรือดิสเอเบิลขา DTR โดย
True หมายถึง อีนาเบิลขา DTR
False หมายถึง ดิสเอเบิลขา DTR (เป็นค่าปกติ)
เมื่อขา DTR ถูกกำหนดสถานะให้เป็น True ที่ขา DTR จะมีสถานะลอจิก “1” เมื่อทำการเปิดพอร์ตและจะมีสถานะเป็น “0” เมื่อมีการปิดพอร์ต เมื่อขา DTR ถูกกำหนดสถานะเป็น False ที่ขา DTR จะมีสถานะลอจิก “0” ตลอดเวลาไม่ว่าจะใช้คำสั่งเปิดพอร์ตหรือปิดพอร์ต
สำหรับการใช้งานกับโมเด็ม การทำให้ขา DTR เป็นลอจิกต่ำหรือ “0” จะเป็นการวางหูโทรศัพท์หรือยกเลิกการติดต่อ

RTSEnable
ใช้เพื่ออีนาเบิลขา Request To Send (RTS) โดยขา RTS จะเป็นสัญญาณที่ส่งจากคอมพิวเตอร์ไปยังโมเด็มเพื่อร้องขอส่งข้อมูล ชนิดของข้อมูลเป็นแบบ Boolean
รูปแบบการใช้งาน
object.RTSEnable[ = value ]
ค่า Value เป็นค่าสถานะ True หรือ False เพื่ออีนาเบิลหรือดิสเอเบิลขา RTS โดย
True หมายถึง อีนาเบิลขา RTS
False หมายถึง ดิสเอเบิลขา RTS (เป็นค่าปกติ)
เมื่อขา RTSEnable ถูกกำหนดให้เป็น True ขา RTS จะมีสถานะลอจิก “1” เมื่อเปิดพอร์ตและมีสถานะลอจิก “0” เมื่อปิดพอร์ต

EOFEnable
เป็นการกำหนดให้ MSComm รอสัญลักษณ์แสดงส่วนท้ายสุดของไฟล์ (End of file : EOF) ระหว่างการรับอินพุตเข้ามา ถ้าพบสัญลักษณ์ EOF ภาคอินพุตจะหยุดรับข้อมูล และเหตุการณ์ OnComm จะถูกกระตุ้นให้ทำงาน คุณสมบัติ CommEvent จะมีค่าเท่ากับ 7 หรือ ComEvEOF
รูปแบบการใช้งาน
object.EOFEnable [ = value ]
โดย value เป็นค่าสถานะ True หรือ False เพื่ออีนาเบิลหรือดิสเอเบิลการทำงานของเหตุการณ์ OnComm เมื่อตรวจพบสัญลักษณ์ EOF โดย
True หมายถึง เหตุการณ์ OnComm จะถูกกระตุ้นให้ทำงานด้วย EOF
False หมายถึง เหตุการณ์ OnComm จะไม่ถูกกระตุ้นให้ทำงานด้วย EOF (เป็นค่าปกติ)
เมื่อ EOFEnable กำหนดให้เป็น False ส่วนควบคุมจะไม่มีการตรวจสอบสัญลักษณ์ EOF

CTSHolding
ผู้ใช้งานสามารถตรวจสอบการทำงานของขา Clear To Send (CTS) ได้ว่ามีสถานะลอจิก “0” หรือ “1” โดยค่าที่อ่านได้จะเป็นบูลีน True และ False ถ้าค่า CTSHolding เป็น True ขา CTS จะมีสถานะลอจิกเป็น “1” ถ้าค่า CTSHolding เป็น False ขา CTS จะมีสถานะลอจิกเป็น “0”
รูปแบบการใช้งาน
object.CTSHolding
เมื่อขา CTS เป็นลอจิก “0” (CTSHolding = False) และเกิดไทม์เอาต์ คอนโทรล MSComm จะกำหนดให้คุณสมบัติ CommEvent มีค่าเป็น comEventCTSTO (Clear To Send Timeout) และกระตุ้นให้เกิดเหตุการณ์ OnComm

CDHolding
ผู้ใช้งานสามารถตรวจสอบการทำงานของขา Data Carrier Detect (DCD) ได้ว่ามีสถานะลอจิกเป็น “1” หรือ “0” โดยค่าที่อ่านได้จะเป็นบูลีน True และ False ถ้าค่า CDHolding เป็น True ขา DCD จะมีสถานะลอจิก “1” ถ้าค่า CDHolding เป็น False ขา DCD จะมีสถานะลอจิก “0”
รูปแบบการใช้งาน
object.CDHolding
เมื่อขา DCD มีลอจิก “1” (CDHolding = True) และเกิดไทม์เอาต์ คอนโทรล MSComm จะกำหนดให้คุณสมบัติ CommEvent มีค่าเป็น comEventCDTO (Carrier Detect Timeout Error) และกระตุ้นให้เกิดเหตุการณ์ OnComm

DSRHolding
ผู้ใช้งานสามารถตรวจสอบการทำงานของขา DSR (DSR) ได้ว่ามีสถานะลอจิก “1” หรือ “0” โดยค่าที่อ่านได้จะเป็นบูลีน True และ False ถ้าค่า DSRHolding เป็น True ขา DSR จะมีสถานะลอจิก “1” ถ้าค่า DSRHolding เป็น False ขา DSR จะมีสถานะลอจิก “0”
รูปแบบการใช้งาน
object.DSRHolding
เมื่อขา DSR เป็นลอจิก “1” (DSRHolding = True) และเกิดไทม์เอาต์ คอนโทรล MSComm จะกำหนดให้คุณสมบัติ CommEvent มีค่าเป็น comEventDSRTO (Data Set Ready Timeout) และกระตุ้นให้เกิดเหตุการณ์ OnComm

Break
ใช้ในการเซตและเคลียร์ค่าสัญญาณ Break ชนิดของข้อมูลเป็นแบบ Boolean
รูปแบบการใช้งาน
object.Break [ = value]
โดย value เป็นค่า Boolean ถ้า Value = True หมายถึง การส่งสัญญาณ Break ออกไป ถ้า Value = False หมายถึงการเคลียร์สัญญาณ Break
เมื่อกำหนดให้สัญญาณ Break เป็น True จะเป็นการหยุดการส่งข้อมูลชั่วคราวจนกว่าจะมีการสั่งให้สัญญาณ Break เป็น False ตัวอย่างโปรแกรมที่ 4-3 เป็นวิธีการส่งสัญญาณ Break ออกไปเป็นช่วงเวลาสั้นๆ ที่ 1/10 ของวินาที

โปรแกรมที่ 4-3
‘ Set the Break condition.
MSComm1.Break = True
‘ Set duration to 1/10 second.
Duration! = Timer + .1
‘ Wait for the duration to pass.
Do Until Timer > Duration!
Dummy = DoEvents()
Loop
‘ Clear the Break condition.
MSComm1.Break = False

ค่าคงที่คุณสมบัติของคอนโทรล MSComm

ค่าคงที่สำหรับคุณสมบัติ Handshake
ค่าคงที่ ค่า รายละเอียด
comNone 0 ไม่ใช้การตรวจสอบแฮนด์เชก
comXonXoff 1 ใช้การตรวจสอบแฮนด์เชกแบบ XOn/XOff
comRTS 2 ใช้การตรวจสอบแฮนด์เชกผ่านทางขา Request-to-send และ
clear-to-send
comRTSXOnXOff 3 กำหนดการตรวจสอบแฮนด์เชกทั้งแบบ request-to-send , clear
to-send และ XOn/XOff

ค่าคงที่สำหรับคุณสมบัติ OnComm
ค่าคงที่ ค่า รายละเอียด
comEvSend 1 ส่งค่าเหตุการณ์ (send event)
comEvReceive 2 รับค่าเหตุการณ์ (receive event)
comEvCTS 3 มีการเปลี่ยนแปลงที่ขา CTS
comEvDSR 4 มีการเปลี่ยนแปลงที่ขา DSR
comEvCD 5 มีการเปลี่ยนแปลงที่ขา DCD
comEvRing 6 ตรวจจับสัญญาณกระดิ่งของโทรศัพท์
comEvEOF 7 ตรวจพบตำแหน่งท้ายสุดของไฟล์ (End of file)

ค่าคงที่สำหรับคุณสมบัติ Error
ค่าคงที่ ค่า รายละเอียด
comEventBreak 1001 ได้รับสัญญาณ Break
comEventCTSTO 1002 ขา CTS เกิดไทม์เอาต์
comEventDSRTO 1003 ขา DSR เกิดไทม์เอาต์
comEventFrame 1004 เกิดข้อผิดพลาดที่เฟรมข้อมูล (Framing error )
comEventOverrun 1006 พอร์ตอนุกรมเกิดโอเวอร์รัน (Port overrun)
comEventCDTO 1007 ขา DCD เกิดไทม์เอาต์
comEventRxOver 1008 บัฟเฟอร์รับข้อมูลเกิดโอเวอร์โฟลว
comEventRxParity 1009 เกิดข้อผิดพลาดที่พาริตี้ (Parity error)
comEventTxFull 1010 บัฟเฟอร์ส่งข้อมูลเต็ม

ค่าคงที่สำหรับคุณสมบัติ InputMode
ค่าคงที่ ค่า รายละเอียด
comInputModeText 0 ข้อมูลที่รับมีคุณสมบัติเป็นข้อความ (ค่าปกติ)
comInputModeBinary 1 ข้อมูลที่รับเข้ามาเป็นข้อมูลไบนารี่

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

โปรแกรมที่ 4-4
Private Sub MSComm_OnComm ()
Select Case MSComm1.CommEvent
‘ Handle each event or error by placing
‘ code below each case statement
‘ Errors
Case comEventBreak ‘ A Break was received.
Case comEventCDTO ‘ CD (RLSD) Timeout.
Case comEventCTSTO ‘ CTS Timeout.
Case comEventDSRTO ‘ DSR Timeout.
Case comEventFrame ‘ Framing Error
Case comEventOverrun ‘ Data Lost.
Case comEventRxOver ‘ Receive buffer overflow.
Case comEventRxParity ‘ Parity Error.
Case comEventTxFull ‘ Transmit buffer full.
‘ Events
Case comEvCD ‘ Change in the CD line.
Case comEvCTS ‘ Change in the CTS line.
Case comEvDSR ‘ Change in the DSR line.
Case comEvRing ‘ Change in the Ring Indicator.
Case comEvReceive ‘ Received RThreshold # of chars.
Case comEvSend ‘ SThreshold number in the ‘transmit buffer.
Case comEvEof ‘ An EOF charater was found in the input stream
End Select
End Sub

การใช้ MSComm เพื่อการติดต่อฮาร์ดแวร์
จากรายละเอียดของ MSComm ที่กล่าวไปในตอนต้นนั้น จะเห็นได้ว่าวิธีการที่จะอ่านค่าหรือเขียนค่าไปยังขาสถานะและขาควบคุมของพอร์ตอนุกรมสามารถทำได้ง่ายดายมาก โดยใช้คำสั่งเหล่านี้
DTREnable สำหรับสั่งให้ขา DTR มีลอจิก “0” หรือ “1”
RTSEnable สำหรับสั่งให้ขา RTS มีลอจิก “0” หรือ “1”
CTSHolding สำหรับอ่านค่าสถานะจากขา CTS ว่ามีลอจิก “0” หรือ “1”
CDHolding สำหรับอ่านค่าสถานะจากขา CD ว่ามีลอจิก “0” หรือ “1”
DSRHolding สำหรับอ่านค่าสถานะจากขา DSR ว่ามีลอจิก “0” หรือ “1”
Break สำหรับการสั่งให้ขา Txd มีมีลอจิก “0” หรือ “1”

การทดลองที่ 5 การติดต่อพอร์ตอนุกรมโดยใช้ MSComm ด้วยการเขียนโปรแกรมบน Visual Basic
เครื่องมือและอุปกรณ์
1. บอร์ด ST-29 Serial port interfacing starter board
2. คอมพิวเตอร์ PC ที่มีพอร์ตอนุกรมอย่างน้อย 1 พอร์ต (แนะนำควรมี 2 พอร์ต) ติดตั้งระบบปฏิบัติการวินโดวส์ 95/98 และโปรแกรม Visual Basic V5.0 ขึ้นไป
3. สายต่อวงจร
การทดลอง
1. ทำการเชื่อมต่อบอร์ด ST-29 เข้ากับคอมพิวเตอร์ โดยต้องเลื่อนสวิตช์ I2C BUS ENABLE ไปยังตำแหน่ง OFF เพื่อดิสเอเบิลการติดต่อกับบัส I2C
2. เปิดโปรแกรม Visual Basic รันโปรแกรม RS232_TEST.VBP (บรรจุอยู่ในแผ่นดิสก์โปรแกรมตัวอย่าง) จะปรากฎหน้าจอดังแสดงในรูปที่ 5A
3. ใช้สายต่อวงจรต่อขา DSR, DCD และ CTS ลงกราวด์ สังเกตผลที่กรอบ Input ของโปรแกรม RS232_TEST
4. ใช้สายต่อวงจรต่อขา DSR, DCD และ CTS เข้ากับแรงดัน +5V สังเกตผลที่กรอบ Input ของโปรแกรม RS232_TEST
5. ในกรอบ Output ให้ทดลองกดปุ่ม TxD,DTR และ RTS สังเกตผลการเปลี่ยนแปลงของ LED ที่บอร์ด ST-29 ในตำแหน่ง TxD,DTR และ RTS
6. การทำงานของคำสั่ง MSComm1.RTSEnable = Not MSComm1.RTSEnable โปรแกรมย่อย Command2_Click() ทำงานอย่างไร ให้ผลเกิดขึ้นที่บอร์ด ST-29 อย่างไรบ้าง