尝试在SerialPort_DataReceived事件下调用多个函数

时间:2012-08-07 08:42:00

标签: vb.net function serial-port

我正在尝试做什么:(文字的大墙,所以我标记了每个部分以便于阅读)

你好,我正在VS 2010中制作一个应用程序,用于RFID控制的磁门锁电路,它通过串口接收RFID标签ID,从数据库验证它(SQL server 2005),发送信号到通过串口电路,并将当前时间和ID保存到数据库中。

我设计的微控制器电路如下工作:从RFID模块读取标签ID>按下电路上的按钮,通过串口将标签ID发送到PC>接收一串数据,“接受”或“拒绝”>根据收到的数据字符串打开红色LED或取消激活磁力锁。

我做了什么:

我将上述任务划分为函数 - CheckValidate()来验证来自DB的ID,SendData()将数据字符串发送到我的电路,Intermediate()从DB中获取ID的相应Name和SaveData()以保存ID ,名称和当前时间进入数据库。

问题:

当我单独执行它们时,它们各自都能正常工作,但我需要它们在一个事件(一个SerialPort_DataReceived事件)下一个接一个地执行。我试着在DataReceived事件的sub下一个接一个地调用所有函数。我尝试在DataReceived事件下调用第一个函数,然后将其他函数嵌套在一起。两者都没有工作,第一个函数执行,我的应用程序停止响应。

我的完整代码:

Imports System.Data.Sql
Imports System.Data.SqlClient
Imports System.IO.Ports

Public Class Form1
    Dim sqlcon As New SqlConnection
    Dim Chars(11) As Char
    Dim CharsCnt As Integer
    Dim currtime As String
    Dim savename As String

Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        CharsCnt += SerialPort1.Read(Chars, CharsCnt, Chars.Length - CharsCnt)
        If CharsCnt = Chars.Length Then
            Me.Invoke(New SetReceivedText(AddressOf SetText))
            CharsCnt = 0
        End If
End Sub

Delegate Sub SetReceivedText()

Private Sub SetText()
        CheckValidate()
End Sub

Private Sub CheckValidate()
        Dim cmd As New SqlCommand
        cmd.Connection = sqlcon

        If (sqlcon.State = ConnectionState.Closed) Then
            sqlcon.Open()
        End If

        cmd.CommandText = "select Name from masterdata where ID = '" & Chars & "'"

        Dim da As New SqlDataAdapter
        Dim dt As New DataTable

        da.SelectCommand = cmd
        da.Fill(dt)

        If (dt.Rows.Count = 0) Then
            TextBox2.Text = "REJECTED"
            dt.Dispose()
        Else
            TextBox2.Text = "ACCEPTED"
        End If

        sqlcon.Close()

        SendData()
End Sub

Private Sub SendData()

        If SerialPort1.IsOpen Then
            SerialPort1.Close()
        End If

        Using com1 As IO.Ports.SerialPort = My.Computer.Ports.OpenSerialPort("COM2")
            com1.WriteLine(TextBox2.Text)
        End Using

        If TextBox2.Text = "ACCEPTED" Then
            Intermediate()
        End If
End Sub

Private Sub Intermediate()
        TextBox1.Text = Chars

        Dim cmd As New SqlCommand
        cmd.Connection = sqlcon

        cmd.CommandText = "select Name from masterdata where ID = '" & Chars & "'"

        If (sqlcon.State = ConnectionState.Closed) Then
            sqlcon.Open()
        End If

        Dim ds As New DataSet
        Dim da As New SqlDataAdapter
        Dim dt As New DataTable

        da.SelectCommand = cmd
        da.Fill(ds)
        da.Fill(dt)

        DataGridView1.DataSource = ds.Tables(0)

        sqlcon.Close()

        SaveData()
End Sub

Private Sub SaveData()
        currtime = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss tt")
        savename = DataGridView1.CurrentRow.Cells(0).Value.ToString

        Dim cmd As New SqlCommand
        If (sqlcon.State = ConnectionState.Closed) Then
            sqlcon.Open()
        End If
        cmd.Connection = sqlcon

        cmd.CommandText = "insert into logdata values('" & Chars & "','" & savename & "','" & currtime & "')"

        Dim ds As New DataSet
        Dim da As New SqlDataAdapter

        da.SelectCommand = cmd
        da.Fill(ds)

        sqlcon.Close()
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        For Each s In System.IO.Ports.SerialPort.GetPortNames()
            ListBox1.Items.Add(s)
        Next s
        Label1.Text = "All COM ports are closed."

        sqlcon.ConnectionString = "Data Source=localhost;User ID=TAS; password = TAS123; database=secure"
        sqlcon.Open()
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Try
            If SerialPort1.IsOpen Then
                SerialPort1.Close()
            End If

            If ListBox1.SelectedIndex = -1 Then
                MessageBox.Show("Please Select a Port.", "", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Exit Sub
            Else
                SerialPort1.BaudRate = 9600
                SerialPort1.DataBits = 8
                SerialPort1.Parity = IO.Ports.Parity.None
                SerialPort1.StopBits = IO.Ports.StopBits.One
                SerialPort1.PortName = ListBox1.SelectedItem.ToString
                SerialPort1.Open()
                Label1.Text = "'" & ListBox1.SelectedItem.ToString & "' COM port is Open"
            End If
        Catch
            MessageBox.Show("Could not open Port, please try again!", "", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
End Sub
End Class

当我想要做的事情时:(使用按钮分别执行每个功能)

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        SendData()
End Sub

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        If TextBox2.Text = "ACCEPTED" Then
            Intermediate()
        End If
End Sub

Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
        SaveData()
End Sub

有关如何在一个DataRecieved事件下执行所有功能的任何帮助将不胜感激。

感谢。

1 个答案:

答案 0 :(得分:0)

得到一个解决方案,问题在于:

Using com1 As IO.Ports.SerialPort = My.Computer.Ports.OpenSerialPort("COM2")
     com1.WriteLine(TextBox2.Text)
End Using

删除使用语句并将端口保留为开。仅用:

SerialPort1.WriteLine(TextBox2.Text)