タイトル : VB シリアル通信で受けた文字列を配列に格納したい 投稿日 : 2017/08/30(Wed) 19:18 投稿者 : MSAKA
お世話になります 環境 Windows 7(64Bit) VB2010 No1868でお助けいただき順調に進めてきたのですがシリアル通信で受けた文字列を 2次元配列に格納できなくて壁にぶつかってしまいました 目的は無線機内の情報を初期設定値として取り込み、必要に応じてその値をPC側で使い 時には配列の内容を書き換えるために2次元配列として格納 保持しておきたいのです そのために好ましくないと言われる幾つかグローバル変数を使っています (変数は 同一 Class Form1 内のみで使います) 今回は確認試験なのでコードは無線機から6つの情報文字列を取り出すことにしています 下記コード(***1) で 1番目のコマンドをPortに書き込み 受信イベントで受けた文字列が目的のものかを確認して配列BandRegSTR(n, m)に書き込む 下記コード(***3) 続いて2番目の・・・・ と6番目まで順次コマンドをPortに書き込みます 受信したら 配列の番号をBandRegSTR(2, 1)→BandRegSTR(2, 2)→ BandRegSTR(2, 3)→BandRegSTR(3, 1) ・・・・・と指定してに書き込み・・を繰り返します 配列には順番に書き込まれるものと作ったのですが 実行結果は最後に書き込んだ BandRegSTR(3,3)に6つの文字列全てが格納されて それ以前の配列は BandRegSTR(2, 1)には”1”BandRegSTR(2, 2)には”2”など数値のみで文字列は格納されていません 最後に書き込んだBandRegSTR(3,3)は以下のように格納されています 1 2 3 1 2 3 3 FD2300008508008508000000020300070200000303011A6600FEFEFD0303011A0066FEFE FD2300008508008508000000020400070426000203011A6600FEFEFD0203011A0066FEFE FD2300008508008508000000010000071600000103011A6600FEFEFD0103011A0066FEFE FD2300008508008508000000020300035221500302011A6600FEFEFD0302011A0066FEFE FD2300008508008508000000020000035374300202011A6600FEFEFD0202011A0066FEFE FD2300008508008508000000010000036020000102011A6600FEFEFD010201 便宜上改行して記述していますが 3 FD23・・・以降は連なって400文字以上になります 最初に無線機から呼び込み書き込まれた文字列が一番末尾でそれ以降も順番に追記され並んで います、連結はされていますが目的の値とは一致しています ただ最初の文字列に送信コマンドの一部 1A0066FEFE が欠落しています) 1つの配列に格納されるべく文字列は 3 FD2300008508008508000000020300070200000303011A6600FEFEFD0303011A0066FEFE 形式となることを目指しています 疑問1 何故 最後の配列変数のみにまとめて格納されるのでしょうか どこで6個の文字列を連結されるのでしょうか ここが原因? 疑問2 コマンドをPortに書き込む間隔を System.Threading.Thread.Sleep(200)で 制御しないとまったく取り込めないのですが SerialPort1.Read はそうした 動きをするものでしょうか 何か他の方法で確実に受け取ることはできないもの でしょうか(時間200が最適かは試していませんがこの使い方は正しいでしょうか) お願い コマンンドを書き込む方法 下記コード ***1 以降はもっとスマートに できないものでしょうか 9×3 で27回分を記述しなければなりませんので 上記3点 ご教授いただければ幸いです 以下 コードです(解読に関係がなさそうな部分は省略しました) Public Class Form1 Public BandRegOld As Integer = 1 Public BandRegBandNo As Integer = 1 Public BandRegSTR(9, 3) As String Public TestCount As Integer = 0 Private Delegate Sub Delegate_RcvDataToTextBox(data As String) '受信イベント Private Sub SerialPort1_DataReceived(sender As Object, e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived 'シリアルポートをオープンしていない場合 IF ・・・ Try '受信したデータ Dim receivedData(SerialPort1.BytesToRead - 1) As Byte SerialPort1.Read(receivedData, 0, receivedData.L使い方ength) Invoke(New Action(Of Byte())(AddressOf Me.RcvDataToTextBox), receivedData) Catch ex As Exception MsgBox(ex.Message) End Try End Sub ***3 Private Sub RcvDataToTextBox(data() As Byte) '受信データをテキストボックスに追記する. Dim StrCov As String = BitConverter.ToString(data).Replace("-", "") Dim Lenx As Integer = Len(StrCov) Dim RecStr As String = "" Dim DD As String Dim CC As Integer = 0 Dim X As Integer = -1 Dim Y As Integer = -1 TestCount = TestCount + 1 'イベント回数チェック 試験用 For i = 1 To Lenx Step 2 DD = Mid(StrCov, i, 2) RecStr = DD & RecStr Next CC = Len(RecStr) '目的の値であるかの条件1 X = RecStr.IndexOf("011A6600FEFE") ' 条件 2 Y = RecStr.IndexOf("FD") ’目的条件に合致すれば配列に格納 If CC > 40 And X > 10 Then BandRegSTR(BandRegBandNo, BandRegOld) = BandRegOld & RecStr End If TextBox1.Text = "回数 " & Str(TestCount) ' TextBox2.AppendText(BandRegSTR(BandRegBandNo, BandRegOld) & " " & vbCrLf) End Sub ***1 Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click '無線機からデータを収集するためコマンドを順次呼び出しPortに書き込む System.Threading.Thread.Sleep(200) ' BandRegInfGet31() ’実際のコマンド コード ***2 System.Threading.Thread.Sleep(200) BandRegInfGet32() System.Threading.Thread.Sleep(200) BandRegInfGet33() System.Threading.Thread.Sleep(200) BandRegInfGet71() System.Threading.Thread.Sleep(200) BandRegInfGet72() System.Threading.Thread.Sleep(200) BandRegInfGet73() System.Threading.Thread.Sleep(200) '試験なのでとりあえず6つのコマンドを送る End Sub ’***2 Private Sub BandRegInfGet31() ' 無線機に送るコマンド −1 バンドレジスト3.5 1 Try BandRegBandNo = 2 BandRegOld = 1 RbytOut(0) = &HFE RbytOut(1) = &HFE RbytOut(2) = &H66 RbytOut(3) = &H0 RbytOut(4) = &H1A RbytOut(5) = &H1 RbytOut(6) = &H2 RbytOut(7) = &H1 RbytOut(8) = &HFD SerialPort1.Write(RbytOut, 0, RbytOut.Length) Catch ex As Exception MsgBox(ex.Message) End Try End Sub Private Sub BandRegInfGet32() ' 無線機に送るコマンド −2 バンドレジスト3.5 2 Try BandRegBandNo = 2 BandRegOld = 2 RbytOut(0)〜RbytOut(5)、RbytOut(8)はSub BandRegInfGet31で 設定したものを使っている(こうした方法はよくないとかですが) RbytOut(6) = &H2 RbytOut(7) = &H2 SerialPort1.Write(RbytOut, 0, RbytOut.Length) Catch ex As Exception MsgBox(ex.Message) End Try End Sub 以下 配列のBandRegBandNo BandRegOld と RbytOut(6) = &H2 RbytOut(7) = &H2 を変更するのみなので内容は省略します Private Sub BandRegInfGet33() Private Sub BandRegInfGet71() Private Sub BandRegInfGet72() Private Sub BandRegInfGet73() その他のコード 省略 End Class |