私がやろうとしていること:(テキストの壁が大きいので、読みやすくするために各部分にラベルを付けました)
こんにちは、VS 2010 で、RFID 制御の磁気ドア ロック回路用のアプリケーションを作成しています。これは、シリアル ポート経由で RFID タグ ID を受信し、データベース (SQL サーバー 2005) からそれを認証し、シリアル ポートに接続し、現在の時刻と ID をデータベースに保存します。
私が設計したマイクロコントローラ回路は次のように動作します: RFID モジュールからタグ ID を読み取る > 回路のボタンを押すとシリアル ポート経由で PC にタグ ID を送信する > "ACCEPTED" または "REJECTED" のいずれかのデータ文字列を受信する > 電源をオンにする受信したデータ文字列に応じて、赤色 LED または磁気ロックを無効にします。
私がしたこと:
上記のタスクを関数に分割しました-DBからIDを認証するCheckValidate()、データ文字列を回路に送信するSendData()、IDに対応する名前をDBからフェッチするIntermediate()、ID、名前、および保存するSaveData() DB への現在の時刻。
問題:
それらを個別に実行すると、それぞれが完全に機能しますが、SerialPort_DataReceived イベントという 1 つのイベントの下で 1 つずつ実行する必要があります。DataReceived イベントのサブの下で、すべての関数を次々と呼び出してみました。そして、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
1 つの DataRecieved イベントですべての関数を実行する方法についてのヘルプをいただければ幸いです。
ありがとう。