ผู้เขียน หัวข้อ: [VB6] การอ่านค่าจากเครื่องชั่งน้ำหนักผ่านพอร์ทอนุกรม (RS232)  (อ่าน 204 ครั้ง)

ออฟไลน์ ทองก้อน ทับทิมกรอบ

  • Administrator
  • *****
  • กระทู้: 245
  • เพศ: ชาย
  • Webmaster G2GNet
[VB6] การอ่านค่าจากเครื่องชั่งน้ำหนักผ่านพอร์ทอนุกรม (RS232)



ก็เรียกได้ว่างานนี้ต้องใช้จินตนาการค่อนข้างสูงมากล่ะครับ เพราะเครื่องชั่งน้ำหนักผมก็ไม่มี แต่อาศัยหลักการวิธีคิดก่อนเขียนโปรแกรมคือ ติดต่อผ่านพอร์ทอนุกรม ตามมาตรฐาน GMM เอ้ย RS232 จากนั้นก็ทำการรับข้อมูลสมมุติ (สมมุติว่ามันเป็นเลขจำนวนเต็ม) เพราะผมก็ไม่รู้ฟอร์แมตจริงๆของเครื่องชั่งน้ำหนัก (แต่เอาไว้ทีหลังได้) เข้ามาจากพอร์ทที่ตั้งค่าเอาไว้ในแบบวินาที (ทดสอบ) ...

มาดูโค้ดกันเถอะ
Option Explicit

' Initial ListView
Sub SetupListView()
    With Me.lvwData
        ' Coding with Run Time
        .View = lvwReport
        .Arrange = lvwNone
        .LabelEdit = lvwManual
        .BorderStyle = ccFixedSingle
        .Appearance = cc3D
       
        .HideColumnHeaders = False
        .HideSelection = False
        .LabelWrap = False
        .MultiSelect = False
        .Enabled = True
        .AllowColumnReorder = True
        .Checkboxes = False
        .FlatScrollBar = False
        .FullRowSelect = True
        .GridLines = True
        .HotTracking = False
        .HoverSelection = False
       
        '.Sorted = True
        .SortKey = 0
        .SortOrder = lvwAscending 'lvwDescending
       
        ' Add header
        .ColumnHeaders.Add , , "ครั้งที่", .Width \ 3 - 600
        .ColumnHeaders.Add , , "น้ำหนัก", .Width \ 3 - 600, lvwColumnRight
        .ColumnHeaders.Add , , "วันที่ - เวลา", .Width \ 3 + 600, lvwColumnRight
    End With
   
End Sub

' #####################################################
' เริ่มต้นการทำงาน
' #####################################################

Private Sub Form_Load()

    Me.Move (Screen.Width - Me.Width) \ 2, (Screen.Height - Me.Height) \ 2
   
    txtWeight.Text = ""
    ' ตั้งค่า ListView
    Call SetupListView
    ' ค้นหา COM Port ที่ติดตั้งในเครื่องคอมพิวเตอร์
    Call ScanCommPort
   
    With Timer1
        ' ตั้งค่า 1 วินาที เมื่อ 1000 millisecond= 1 second
        ' การใช้งานจริงอาจจะต้องปรับให้ค่าเวลาในการอ่านนานมากขึ้นน่ะครับ

        .Interval = 2000
        .Enabled = True
    End With

End Sub

' #####################################################
' โปรแกรมย่อยใช้ในการค้นหา COM Port ที่ติดตั้งไว้ในเครื่องคอมพิวเตอร์
' #####################################################

Sub ScanCommPort()
' ไม่ต้องสนใจ Error ครับ ...
On Error Resume Next

' ตัวแปรเพื่อทดสอบ COM Port ไหนบ้างใช้งานได้ (1 - 4)
Dim PortNumber As Byte

' ตัวแปรสร้างไฟล์ชั่วคราวขึ้นมา เพื่อทำการทดสอบการส่งข้อมูลออกจาก Port
Dim iFileNum As Integer
   
    ' ทดสอบจำนวน 4 Port มาตรฐาน คือ COM1, COM2, COM3 และ COM4
    For PortNumber = 1 To 4
       
        ' สร้างไฟล์ทดสอบชั่วคราวขึ้นมาก่อน เพื่อจะลองส่งข้อมูลออก Port นี้
        iFileNum = FreeFile
       
        ' พยายามเปิด COM Port ดู (ส่ง Binary ออกไปยังช่องทางการติดต่อสื่อสาร)
        Open "COM" & CStr(PortNumber) For Binary Shared As #iFileNum
        ' เอาไว้ลองดูผลหมายเลข Err.Number ได้เลยครับ ... พี่น้อง
        ' Debug.Print Err.Number

       
        ' หาก Port สามารถใช้งานได้ ค่า Err.Number = 0
        ' หากค่า Err.Number <> 0 (ตัวอย่างนี้ คือ Err.Number = 53 หรือ File not found)

        If Err.Number = 0 Then
       
            ' ปิดไฟล์ไปเลย
            Close #iFileNum
           
            ' หาก Port ใช้งานได้ก็ให้เพิ่มรายการเข้าสู่ ComboBox เช่น COM1
            cmbCommPort.AddItem "COM" & PortNumber
           
        End If
       
    Next
   
   ' หากมี COM Port อย่างน้อย 1 Port ก็ตั้งค่าให้อยู่ที่ COM1 เป็น Default เอาไว้ก่อน
    If cmbCommPort.ListCount > 0 Then cmbCommPort.ListIndex = 0

End Sub

Private Sub cmdExit_Click()
    Set frmScalesWeight = Nothing
    End
End Sub

Private Sub Form_Resize()
    On Error Resume Next
    If Me.WindowState = vbMinimized Then Exit Sub
End Sub

Private Sub Timer1_Timer()
    ' เลือก Com Port ที่ต้องการ ก็คือ MSComm1.CommPort = ตัวเลขจำนวนเต็ม (เริ่มต้นจาก 1)
    ' แต่ ListIndex ของ ComboBox ตัวแรกเริ่มต้นด้วยค่า 0 ดังนั้นเราเลยต้องบวก 1 เข้าไปด้วย
    ' นั่นหมายความว่า MSComm1.CommPort = 1 <-- COM1 (ListIndex = 0)
    ' หรือ MSComm1.CommPort = 2 <-- COM2 (ListIndex = 1)

    MSComm1.CommPort = cmbCommPort.ListIndex + 1
   
    ' ทดสอบว่ามีการเปิด Port ค้างไว้หรือไม่ หากเงื่อนไขเป็นจริง สั่งให้ปิดช่องการสื่อสารหมายเลข Port นี้ก่อน
    If MSComm1.PortOpen = True Then MSComm1.PortOpen = False
   
    With MSComm1
        ' กำหนดมาตรฐาน (Protocol) ในการติดต่อสื่อสารผ่าน COM Port ระหว่างผู้รับและผู้ส่ง
        ' 9600 = อัตราการรับส่งข้อมูล (Baud Rate)
        ' N = None Parity คือ ไม่มีการตรวจสอบความถูกต้องของข้อมูล
        ' 8 = ขนาดข้อมูลจำนวน 8 บิต
        ' 1 = มี Stop Bit ปิดท้ายอีก 1 บิต

        .Settings = "9600,N,8,1"
       
        ' สั่งเปิด Port
        .PortOpen = True
       
        ' txtWeight จะรอรับค่า Input มาจาก Com Port ตามเวลาของ Timer ที่เราตั้งไว้
        ' แต่เนื่องจากว่าเราไม่ได้ต่อเข้ากับเครื่องชั่งน้ำหนักโดยตรง  ดังนั้นจึงล่ะคำสั่งนี้ไว้ก่อน จนกว่าจะต่อเครื่องชั่ง
        ' txtWeight.Text = MSComm1.Input

       
        Dim LV As ListItem
        ' พอค่าใน txtWeight มันเปลี่ยน
        If Trim(txtWeight.Text) <> "" Then
            ' ใช้การนับจำนวนแถวใน ListView Control
            Set LV = lvwData.ListItems.Add(, , lvwData.ListItems.Count + 1)
            LV.SubItems(1) = txtWeight.Text
            ' Date/Time
            LV.SubItems(2) = FormatDateTime(Now, vbGeneralDate)
            ' Get next value
            txtWeight.Text = ""
        End If
       
        ' ปิดการใช้งาน Port
        .PortOpen = False
       
    End With
End Sub

Private Sub txtWeight_KeyPress(KeyAscii As Integer)
    ' หากเป็น 0 - 9 ก็จะรับค่า KeyAscii ตัวมันเองกลับมา หากไม่ใช่ก็จะรับค่า 0 หรือไม่มีการกดคีย์ใดๆ
    KeyAscii = CheckDigitOnly(KeyAscii)
End Sub

' / ฟังค์ชั่นในการดักคีย์ให้รับค่าเฉพาะ 0 - 9 กับ Backspace และ Enter
' / ถ้าหากอยู่ในเงื่อนไข ก็ส่งค่าคืนกลับตัวมันเอง (Index)
' / แต่ถ้าหากไม่อยู่ในเงื่อนไขต้องส่งค่า 0 กลับ หมายความว่าไม่มีการกดคีย์ใดๆเลย

Function CheckDigitOnly(Index As Integer) As Integer
    ' เหตุใดผมไม่เลือก IF THEN ELSE ก็ลองเอาไปคิดต่อน่ะครับ
    Select Case Index
        Case 48 To 57
            ' คืนค่า Index (หรือ ASCII Code) ตัวมันเองกลับไป
            ' หมายความว่า เรายอมรับให้เกิดการกดคีย์นั้นๆได้

            CheckDigitOnly = Index
        Case 8  ' Back Space
            ' การไม่เขียนโค้ด ก็คือการส่งค่า Index ตัวเดิมกลับคืนไปนั่นเอง
        Case 13
            ' Enter
        Case Else
            Index = 0
    End Select
    ' คืนค่าจากฟังค์ชั่นกลับ
    CheckDigitOnly = Index
End Function

ดาวน์โหลดโค้ดต้นฉบับ VB6 ได้ที่นี่

บันทึกการเข้า
สิ่งที่ดีกว่าการให้ คือการให้แบบไม่มีที่สิ้นสุด

ออฟไลน์ naien

  • Newbie
  • *
  • กระทู้: 36
ขอบคุณครับ

บันทึกการเข้า

ออฟไลน์ Mr.Den

  • Jr. Member
  • **
  • กระทู้: 73
  • เพศ: ชาย
ขอบพระคุณอย่างสูงครับอาจารย์

บันทึกการเข้า