tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
[ツリー表示へ]  [ワード検索]  [Home]

タイトル 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   

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。