【问题标题】:Vb.Net Weight Scale ReadingVb.净重秤读数
【发布时间】:2021-09-20 05:30:03
【问题描述】:

大家晚上好,我一直在开发一个通过串口读取余额的应用程序,经过很长时间试图读取数据,我很高兴得到了结果,但是数据不同步,它更改权重需要无限时间,并且在处理数据时会删除不需要的字符,因为秤按如下方式发送数据:ww0000.00kg,经过一些更改后,我设法将其更改为00.00kg。重量必须实时同步: 它应该按以下方式工作,当放置一个砝码时,秤必须是它的值,例如13.75kg,然后打印然后移除砝码并在不到 3 秒内恢复正常 (00.00kg)。

代码:

Dim decWeightReading As Decimal, strScaleCommand As String
    Dim strSerialData As String
    Dim strSerialDataNew As String
    Dim strFirstData As String
    Dim cnt As Integer
    Dim diffDate As TimeSpan    
    Dim initRunning As Integer
    Dim IntWeightReading As Integer
    Dim DecWeightReadingLast As Decimal
    Dim datetime1 As Date, datetime2 As Date

表单加载:

Private Sub Menufrm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        SerialPort1.Open()
        Timer1.Start()
    End Sub

TickTimer:

Private Sub TickTimer2()
    decWeightReading = CDec("0.000")
    strScaleCommand = "IP" + vbCrLf
    strFirstData = ""
    SerialPort1.WriteLine(strScaleCommand)
    strSerialData = SerialPort1.ReadLine
    strSerialDataNew = ""
    cnt = 0
    Do Until cnt = 10
        SerialPort1.WriteLine(strScaleCommand)
        strSerialDataNew = SerialPort1.ReadLine
        If strSerialDataNew = strSerialData Then
            cnt = cnt + 1
        Else
            strSerialData = strSerialDataNew
            strSerialDataNew = ""
            cnt = 0
        End If
        datetime2 = DateTime.Now
        diffDate = datetime2.Subtract(datetime1)
    Loop

End Sub

Time Tick and Trim the ww00:

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
TickTimer2()
Dim header As String = strSerialData
strSerialData = (header)
Weight.Text = (strSerialData)
strSerialData.Trim({"w"c, "w"c, "0"c})
Weight.Text = (header.Trim({"w"c, "w"c, "0"c}))

结束子

我面临的另一个困难是,当从天平读取数据以在 TextBox 中打印时,过程变得非常缓慢,甚至很难单击按钮或查看 ComboBox 中的值列表。

如果有人有任何帮助,我将不胜感激

【问题讨论】:

  • 这些是 C# 文章,但它们会有所帮助。 Serial Comms in C# for Beginners, Communicating With Serial Port In C#
  • 谢谢,但我找不到与我的问题相关的任何内容。我已经可以读取余额数据了。
  • 我介绍了它作为事件驱动的串行端口读取的示例,它不是软件循环,并将接收到的结果从子线程写入TextBox。如果您在 I/O 过程中做得很好,唯一的问题是它需要时间,那么您将不得不进行试验并找出瓶颈所在。
  • 秤的品牌和型号是什么?我不太清楚您所说的以下内容是什么意思:“重量必须实时同步:它应该以下列方式工作,放置重量时,秤必须是它的值,例如 13.75kg 并打印然后删除体重并在不到 3 秒内恢复正常(00.00kg)。” “打印”是什么意思?在文本框中显示值?您是从秤上移走物体还是在物体仍在秤上的情况下尝试将其归零?为什么要循环 10 次?

标签: vb.net serial-port scale trim


【解决方案1】:

以下显示如何使用 SerialPort 读取数据 - 它订阅 DataReceived 事件。在 VB.NET 中,订阅事件有两种不同的选项。

选项 1(WithEvents)

Private WithEvents Port As SerialPort = Nothing

Public Function Connect(ByVal comPort As String, ByVal Optional baudRate As PortBaudRate = PortBaudRate.Baud9600) As String
    
    Dim result As String = String.Empty

    If Port Is Nothing Then

        'create new instance
        Port = New SerialPort(comPort)

    End If
                   ...

    Return result

End Function

订阅 Port.DataReceived 事件:

Private Sub Port_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) Handles Port.DataReceived

End Sub

选项 2(AddHandler)

Private Port As SerialPort = Nothing

Public Function Connect(ByVal comPort As String, ByVal Optional baudRate As PortBaudRate = PortBaudRate.Baud9600) As String
    
    Dim result As String = String.Empty

    If Port Is Nothing Then

        'create new instance
        Port = New SerialPort(comPort)

        'subscribe to events (add event handlers)
        AddHandler Port.DataReceived, AddressOf Port_DataReceived
        AddHandler Port.ErrorReceived, AddressOf Port_ErrorReceived

    End If
                   ...

    Return result

End Function

订阅 Port.DataReceived 事件:

Private Sub Port_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)

End Sub

以下是创建一个新的 Windows 窗体 (WinForms) 项目的步骤,该项目使用 SerialPort 读取数据以及必要的代码。

创建一个 WinForms 项目

VS 2017

  • 打开 Visual Studio
  • 点击文件
  • 选择新建
  • 选择项目
  • 展开已安装
  • 展开Visual Basic
  • 点击Windows桌面
  • 选择 Windows 窗体应用程序 (.NET Framework)
  • 指定项目名称(名称:ReadSerialPort)
  • 点击确定

VS 2019

  • 打开 Visual Studio
  • 点击无代码继续
  • 点击文件
  • 选择新建
  • 选择项目
  • Visual Basic Windows 桌面
  • 单击Windows 窗体应用程序(.NET Framework)
  • 点击下一步
  • 指定项目名称(名称:ReadSerialPort)
  • 点击创建

注意:从现在开始,VS 2017 和 VS 2019 的流程相同。

给Form1添加一些控件

打开属性窗口

  • 在VS菜单中,选择查看
  • 选择属性窗口

打开解决方案资源管理器

  • 在VS菜单中,选择查看
  • 选择解决方案资源管理器
  • 在解决方案资源管理器中,双击 Form1.vb 以打开设计器。

将“连接”按钮添加到 Form1

  • 在VS菜单中,选择查看
  • 选择工具箱
  • 选择按钮
  • 点击 Form1 将按钮添加到表单中
  • 在属性窗口中,为“button1”设置(名称):btnConnect;设置文本:连接
  • 在“属性”窗口中,单击(事件)。双击单击将事件处理程序添加到 Form1.vb

将“断开连接”按钮添加到 Form1

  • 在VS菜单中,选择查看
  • 选择工具箱
  • 选择按钮
  • 点击 Form1 将按钮添加到表单中
  • 在属性窗口中,对于“button1”,设置 (name):btnDisconnect;设置文字:断开连接
  • 在属性窗口中,单击(事件)。双击单击将事件处理程序添加到 Form1.vb

将文本框添加到 Form1

  • 在VS菜单中,选择查看
  • 选择工具箱
  • 选择文本框
  • 点击 Form1 将按钮添加到表单中

将“Load”事件处理程序添加到 Form1

  • 在“属性”窗口中,对于“Form1”,单击(事件)。双击加载以将事件处理程序添加到 Form1.vb

将“FormClosing”事件处理程序添加到 Form1

  • 在“属性”窗口中,对于“Form1”,单击 (事件)。双击 FormClosing 将事件处理程序添加到 Form1.vb

添加类:HelperSerialPort

  • 在 VS 菜单上,选择 项目
  • 选择添加类(名称:HelperSerialPort.vb)

选项 1(WithEvents)

HelperSerialPort.vb

Imports System.IO.Ports

Public Enum PortBaudRate As Integer
    Baud1200 = 1200
    Baud2400 = 2400
    Baud4800 = 4800
    Baud9600 = 9600
    Baud14400 = 14400
    Baud19200 = 19200
    Baud28800 = 28800
    Baud38400 = 38400
    Baud56000 = 56000
    Baud76800 = 76800
    Baud115200 = 115200

End Enum

Public Class HelperSerialPort
    Implements IDisposable

    Private WithEvents Port As SerialPort = Nothing

    'events that can be subscribed to
    Public Event DataReceived(ByVal sender As Object, ByVal data As String)
    Public Event ErrorReceived(ByVal sender As Object, ByVal errMsg As String)

    Sub New()

    End Sub

    Public Function Connect(ByVal comPort As String, ByVal Optional baudRate As PortBaudRate = PortBaudRate.Baud9600) As String
        Dim errMsg As String = String.Empty
        Dim portName As String = String.Empty
        Dim result As String = String.Empty

        If String.IsNullOrEmpty(comPort) Then
            errMsg = "COM port not selected"
            Throw New Exception(errMsg)
        End If

        Try
            If Port Is Nothing Then

                'create new instance
                Port = New SerialPort(comPort)

            End If

            If Not Port.IsOpen Then

                'set properties
                Port.BaudRate = baudRate
                Port.Handshake = Handshake.None

                'if parity is even or odd, then set DataBits = 7
                'if parity is none, set DataBits = 8
                Port.Parity = Parity.Even 'Even, None, Odd 
                Port.DataBits = 7

                Port.StopBits = StopBits.One
                Port.ReadTimeout = 200
                Port.WriteTimeout = 50
                Port.DtrEnable = True 'enable Data Terminal Ready
                Port.RtsEnable = True 'enable Request to Send

                'open port
                Port.Open()

                result = "Status: Connected"
            Else
                result = "Status: Already Connected"
            End If

        Catch ex As Exception
            errMsg = "Error: " & ex.Message
            result = errMsg 'set value
            Debug.WriteLine(errMsg)
            Throw ex
        End Try

        Debug.WriteLine(result)

        Return result
    End Function

    Public Sub Disconnect()
        Dispose()
    End Sub

    Public Sub Dispose() Implements System.IDisposable.Dispose
        If Port IsNot Nothing Then

            Port.Dispose()
            Port = Nothing
        End If
    End Sub

    Private Sub Port_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) Handles Port.DataReceived
        'read SerialPort data
        Dim data As String = String.Empty

        data = Port.ReadExisting()
        'data = Port.ReadLine

        Debug.WriteLine("Data: " & data)

        'raise event
        RaiseEvent DataReceived(Me, data)
    End Sub

    Private Sub Port_ErrorReceived(ByVal sender As Object, ByVal e As SerialErrorReceivedEventArgs) Handles Port.ErrorReceived
        Dim errMsg As String = e.EventType.ToString()

        Debug.WriteLine("Error: " & errMsg)

        'raise event
        RaiseEvent ErrorReceived(Me, errMsg)
    End Sub

    Public Sub WriteToSerialPort(ByVal data As String)
        Dim errMsg As String = String.Empty

        Try
            If Port.IsOpen Then

                'convert string to Byte array
                Dim hexArr As Byte() = System.Text.Encoding.ASCII.GetBytes(data)

                For Each hexVal As Byte In hexArr

                    'convert byte to byte array
                    Dim tempArr As Byte() = New Byte() {hexVal}

                    'write 
                    Port.Write(tempArr, 0, 1)

                    'add 1 ms delay before writing next byte
                    System.Threading.Thread.Sleep(1)
                Next
            Else
                errMsg = "Error: Port is not open. Please open the connection and try again."
                Debug.WriteLine(errMsg)
                Throw New Exception(errMsg)
            End If
        Catch ex As Exception
            errMsg = "Error: " & ex.Message
            Debug.WriteLine(errMsg)
            Throw ex
        End Try

    End Sub
End Class

修改Form1.vb代码

  • 在解决方案资源管理器中,右键单击 Form1.vb
  • 选择查看代码

Form1.vb

Imports System.IO.Ports

Public Class Form1

    Private WithEvents helper As HelperSerialPort = New HelperSerialPort

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

        'get port names
        For Each portName In SerialPort.GetPortNames()
            Debug.WriteLine("portName: " & portName)
        Next

    End Sub

    Private Sub Connect(ByVal comPort As String, ByVal Optional baudRate As PortBaudRate = PortBaudRate.Baud9600)
        If helper IsNot Nothing Then
            Debug.WriteLine("comPort: " & comPort & " baudRate: " & baudRate.ToString())
            helper.Connect(comPort, baudRate)
        End If
    End Sub

    Private Sub Helper_DataReceived(ByVal sender As Object, ByVal data As String) Handles helper.DataReceived
        Debug.WriteLine("Data: " & data)

        'set value
        Dim tempData As String = data

        If tempData.StartsWith("ww") AndAlso tempData.EndsWith("kg") Then
            tempData = tempData.Substring(2, data.Length - 4)
        End If

        'If tempData.StartsWith("ww") Then
        'tempData = tempData.Substring(2)
        'End If

        'If tempData.EndsWith("kg") Then
        'tempData = tempData.Substring(0, tempData.IndexOf("kg"))
        'End If

        'set text in TextBox
        TextBox1.Invoke(New MethodInvoker(Sub()
                                              TextBox1.Text = tempData
                                              TextBox1.Refresh()
                                          End Sub))

    End Sub

    Private Sub Helper_ErrorReceived(ByVal sender As Object, ByVal errMsg As String) Handles helper.ErrorReceived
        Debug.WriteLine(errMsg)
    End Sub

    Private Sub Disconnect()
        If helper IsNot Nothing Then
            helper.Disconnect()
        End If
    End Sub

    Private Sub btnConnect_Click(sender As Object, e As EventArgs) Handles btnConnect.Click
        Connect("COM1", PortBaudRate.Baud9600)
    End Sub

    Private Sub btnDisconnect_Click(sender As Object, e As EventArgs) Handles btnDisconnect.Click
        Disconnect()
    End Sub

    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
        'dispose
        If helper IsNot Nothing Then
            helper.Dispose()
        End If
    End Sub
End Class

选项 2(AddHandler)

HelperSerialPort.vb

Imports System.IO.Ports

Public Enum PortBaudRate As Integer
    Baud1200 = 1200
    Baud2400 = 2400
    Baud4800 = 4800
    Baud9600 = 9600
    Baud14400 = 14400
    Baud19200 = 19200
    Baud28800 = 28800
    Baud38400 = 38400
    Baud56000 = 56000
    Baud76800 = 76800
    Baud115200 = 115200

End Enum

Public Class HelperSerialPort
    Implements IDisposable

    Private Port As SerialPort = Nothing

    Public Event DataReceived(ByVal sender As Object, ByVal data As String)
    Public Event ErrorReceived(ByVal sender As Object, ByVal errMsg As String)

    Sub New()

    End Sub

    Public Function Connect(ByVal comPort As String, ByVal Optional baudRate As PortBaudRate = PortBaudRate.Baud9600) As String
        Dim errMsg As String = String.Empty
        Dim portName As String = String.Empty
        Dim result As String = String.Empty

        If String.IsNullOrEmpty(comPort) Then
            errMsg = "COM port not selected"
            Throw New Exception(errMsg)
        End If


        Debug.WriteLine("comPort: " & comPort)

        Try
            If Port Is Nothing Then
                Debug.WriteLine("creating new instance of SerialPort")

                'create new instance
                Port = New SerialPort(comPort)

                'subscribe to events (add event handlers)
                AddHandler Port.DataReceived, AddressOf Port_DataReceived
                AddHandler Port.ErrorReceived, AddressOf Port_ErrorReceived

            End If

            If Not Port.IsOpen Then

                Debug.WriteLine("Port isn't open")

                'set properties
                Port.BaudRate = baudRate
                Port.Handshake = Handshake.None

                'if parity is even or odd, then set DataBits = 7
                'if parity is none, set DataBits = 8
                Port.Parity = Parity.Even 'Even, None, Odd 
                Port.DataBits = 7

                Port.StopBits = StopBits.One
                Port.ReadTimeout = 200
                Port.WriteTimeout = 50
                Port.DtrEnable = True 'enable Data Terminal Ready
                Port.RtsEnable = True 'enable Request to Send

                'open port
                Port.Open()

                result = "Status: Connected"
            Else
                result = "Status: Already Connected"
            End If

        Catch ex As Exception
            errMsg = "Error: " & ex.Message
            result = errMsg 'set value
            Debug.WriteLine(errMsg)
            Throw ex
        End Try

        Debug.WriteLine(result)

        Return result
    End Function

    Public Sub Disconnect()
        Dispose()
    End Sub

    Public Sub Dispose() Implements System.IDisposable.Dispose
        If Port IsNot Nothing Then

            'unsubscribe from events (remove event handlers)
            RemoveHandler Port.DataReceived, AddressOf Port_DataReceived
            RemoveHandler Port.ErrorReceived, AddressOf Port_ErrorReceived

            Port.Dispose()
            Port = Nothing
        End If
    End Sub

    Private Sub Port_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
        'read SerialPort data
        Dim data As String = String.Empty

        data = Port.ReadExisting()
        'data = Port.ReadLine

        Debug.WriteLine("Data: " & data)

        'raise event
        RaiseEvent DataReceived(Me, data)
    End Sub

    Private Sub Port_ErrorReceived(ByVal sender As Object, ByVal e As SerialErrorReceivedEventArgs)
        Dim errMsg As String = e.EventType.ToString()

        Debug.WriteLine("Error: " & errMsg)

        'raise event
        RaiseEvent ErrorReceived(Me, errMsg)
    End Sub

    Public Sub WriteToSerialPort(ByVal data As String)
        Dim errMsg As String = String.Empty

        Try
            If Port.IsOpen Then

                'convert string to Byte array
                Dim hexArr As Byte() = System.Text.Encoding.ASCII.GetBytes(data)

                For Each hexVal As Byte In hexArr

                    'convert byte to byte array
                    Dim tempArr As Byte() = New Byte() {hexVal}

                    'write 
                    Port.Write(tempArr, 0, 1)

                    'add 1 ms delay before writing next byte
                    System.Threading.Thread.Sleep(1)
                Next
            Else
                errMsg = "Error: Port is not open. Please open the connection and try again."
                Debug.WriteLine(errMsg)
                Throw New Exception(errMsg)
            End If
        Catch ex As Exception
            errMsg = "Error: " & ex.Message
            Debug.WriteLine(errMsg)
            Throw ex
        End Try

    End Sub
End Class

修改Form1.vb代码

  • 在解决方案资源管理器中,右键单击 Form1.vb
  • 选择查看代码

Form1.vb

Imports System.IO.Ports

Public Class Form1

    Private helper As HelperSerialPort = Nothing

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

        'create new instance
        helper = New HelperSerialPort()

        'subscribe to events (add event handlers)
        AddHandler helper.DataReceived, AddressOf Helper_DataReceived
        AddHandler helper.ErrorReceived, AddressOf Helper_ErrorReceived

        'get port names
        For Each portName In SerialPort.GetPortNames()
            Debug.WriteLine("portName: " & portName)
        Next

    End Sub

    Private Sub Connect(ByVal comPort As String, ByVal Optional baudRate As PortBaudRate = PortBaudRate.Baud9600)
        If helper IsNot Nothing Then
            Debug.WriteLine("comPort: " & comPort & " baudRate: " & baudRate.ToString())
            helper.Connect(comPort, baudRate)
        End If
    End Sub

    Private Sub Helper_DataReceived(ByVal sender As Object, ByVal data As String)
        Debug.WriteLine("Data: " & data)

        'set value
        Dim tempData As String = data

        If tempData.StartsWith("ww") AndAlso tempData.EndsWith("kg") Then
            tempData = tempData.Substring(2, data.Length - 4)
        End If

        'If tempData.StartsWith("ww") Then
        'tempData = tempData.Substring(2)
        'End If

        'If tempData.EndsWith("kg") Then
        'tempData = tempData.Substring(0, tempData.IndexOf("kg"))
        'End If

        'set text in TextBox
        TextBox1.Invoke(New MethodInvoker(Sub()
                                              TextBox1.Text = tempData
                                              TextBox1.Refresh()
                                          End Sub))

    End Sub

    Private Sub Helper_ErrorReceived(ByVal sender As Object, ByVal errMsg As String)
        Debug.WriteLine(errMsg)
    End Sub

    Private Sub Disconnect()
        If helper IsNot Nothing Then
            helper.Disconnect()
        End If
    End Sub

    Private Sub btnConnect_Click(sender As Object, e As EventArgs) Handles btnConnect.Click
        Connect("COM1", PortBaudRate.Baud9600)
    End Sub

    Private Sub btnDisconnect_Click(sender As Object, e As EventArgs) Handles btnDisconnect.Click
        Disconnect()
    End Sub

    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
        'dispose
        If helper IsNot Nothing Then
            helper.Dispose()
        End If
    End Sub
End Class

资源

【讨论】:

  • 如果有兴趣,下面的帖子展示了如何在 C# 中使用 SerialPort 读取数据:stackoverflow.com/questions/65957066/…
  • 谢谢,能给我你的电子邮件、Skype、Telegram 或 Whatsapp 吗?
猜你喜欢
  • 2018-09-21
  • 2017-01-24
  • 1970-01-01
  • 2017-05-27
  • 1970-01-01
  • 2012-03-29
  • 1970-01-01
  • 2022-01-23
  • 2012-02-03
相关资源
最近更新 更多