tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルVB シリアル通信で受けた文字列を配列に格納したい
記事No11891
投稿日: 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   

[ツリー表示へ]
タイトルRe: VB シリアル通信で受けた文字列を配列に格納したい
記事No11893
投稿日: 2017/08/31(Thu) 15:55
投稿者魔界の仮面弁士
> No1868でお助けいただき順調に進めてきたのですが

それを言うなら No11868 ですよね。
No1868 は下記ですが、レスはついていないようで。

[2005/07/01 15:04](aa さん)【VBからエクセルのシートにラベルを作成】
http://www.hanatyan.sakura.ne.jp/vbnetbbs/wforum.cgi?mode=allread&no=1868


> SerialPort1.Read(receivedData, 0, receivedData.L使い方ength)

化けてますね。(^^;


> 最後に書き込んだBandRegSTR(3,3)は以下のように格納されています

各行のインデックスが不明ですが、こういう状態なのでしょうか?

BandRegSTR(0, 0) = "1"
BandRegSTR(0, 1) = "2"
BandRegSTR(0, 2) = "3"
BandRegSTR(0, 3) = "1"
BandRegSTR(1, 0) = "2"
BandRegSTR(1, 1) = "3"
BandRegSTR(1, 2) = "3 FD23000085080085080000000203000702000(以下略)"
BandRegSTR(1, 3) = Nothing
BandRegSTR(2, 0) = Nothing
BandRegSTR(2, 1) = Nothing
BandRegSTR(2, 2) = Nothing
BandRegSTR(2, 3) = Nothing
BandRegSTR(3, 0) = Nothing
BandRegSTR(3, 1) = Nothing
BandRegSTR(3, 2) = Nothing
BandRegSTR(3, 3) = Nothing


>         Dim StrCov As String = BitConverter.ToString(data).Replace("-", "")
>         Dim Lenx As Integer = Len(StrCov)
>         For i = 1 To Lenx Step 2
>             DD = Mid(StrCov, i, 2)
>             RecStr = DD & RecStr
>         Next

おそらくは、
 Dim data As Byte() = {1, 2, 3, 4, 5, 6, 7, 8, 9}
というデータがあった場合に、
 Dim RecStr As String = "090807060504030201"
を得ることが目的なのだと思いますが、それならばループ処理などせずとも、
 Dim RevData As Byte() = data.Reverse().ToArray()
 Dim RecStr As String = BitConverter.ToString(RevData).Replace("-", "")
だけで済みますよ。

あるいは、data そのものの順番も逆転して良いのであれば、
 Array.Reverse(data)
 Dim RecStr As String = BitConverter.ToString(data).Replace("-", "")
と書くこともできます。


> X = RecStr.IndexOf("011A6600FEFE")  '  条件 2

この検索方法だと、4bit 分の桁ずれが生じる可能性がありそうですが、大丈夫でしょうか?

RecStr = "11A6600FEFE000" 'X = -1 が返される(想定どおり)
RecStr = "011A6600FEFE00" 'X = 0 が返される(想定どおり)
RecStr = "0011A6600FEFE0" 'X = 1 が返されるが、本来は X = -1 になるべきでは?
RecStr = "00011A6600FEFE" 'X = 2 が返される(想定どおり)
RecStr = "00011A6600FE00" 'X = -1 が返される(想定どおり)


あえてそういう仕様にしているのならば良いのですが、もしもそうではなく、
1 バイト単位(16進数表現で 2 文字分)の位置を調べたかったのであれば、
たとえば BitConverter の "-" をあえて潰さずに、
 Dim RevData As Byte() = data.Reverse().ToArray()
 Dim RecStr As String = "-" & BitConverter.ToString(RevData)
 X = RecStr.IndexOf("-01-1A-66-00-FE-FE")
 Y = RecStr.IndexOf("-FD")
のように探索するという手もあります。これなら桁ズレは発生しません。

この方法では、1 バイトが 2 文字ではなく 3 文字で表現されているので、
変数 X (と Y) の使いみちによっては、上記の後に追加で
 If X >= 0 Then
  X = 2 * X \ 3
 End If
のような補正が必要かも知れません。適宜調整してください。


> If CC > 40 And X > 10 Then
And 演算子ではなく、AndAlso 演算子を使う癖をつけましょう。


> 疑問1  何故 最後の配列変数のみにまとめてを格納されるのでしょうか
>      どこで6個の文字列を連結されるのでしょうか  ここが原因?

『BandRegSTR(n,m) に文字列を格納する処理』が書かれているのは、
> If CC > 40 And X > 10 Then 
>   BandRegSTR(BandRegBandNo, BandRegOld) = BandRegOld & RecStr
> End If
の部分だけなのですね。であればこの部分を

If CC > 40 AndAnslo X > 10 Then 
 Debug.Write(BandRegBandNo)
 Debug.Write(", ")
 Debug.Write(BandRegOld)
 Debug.Write(" = 文字数:")
 Debug.WriteLine((BandRegOld & RecStr).Length)
 BandRegSTR(BandRegBandNo, BandRegOld) = BandRegOld & RecStr
End IF

のように書き換えて、それぞれの変数(特に BandRegBandNo と BandRegOld)の値が
どの時点で期待から外れた値になってしまうのか、出力ウィンドウで確認してみましょう。



> 疑問2  コマンドをPortに書き込む間隔を System.Threading.Thread.Sleep(200)で
>      制御しないとまったく取り込めないのですが SerialPort1.Read はそうした
>      動きをするものでしょうか 何か他の方法で確実に受け取ることはできないもの  
>      でしょうか(時間200が最適かは試していませんがこの使い方は正しいでしょうか)

正しい使い方ではありません。

コンソール アプリケーションで Sleep を呼ぶような使い方は OK ですが、
UI スレッド(Form/Button/TextBox などを利用するスレッド)から
Sleep メソッドを呼び出すことは タブー です。

そもそも Sleep は待機のための命令ではなく、自分自身を一定時眠らせることで、
処理を他のスレッドに明け渡すことを目的としています。

対処方法としては:

(対処案A) メインスレッドから書き込むために、
 Timer を使って Tick イベントから Write する。

(対処案B) 送信処理専用のワーカースレッドを用意し、
 その中で Sleep で待ち合わせて Write する。


> お願い  コマンンドを書き込む方法 下記コード ***1 以降はもっとスマートに
>      できないものでしょうか 9×3 で27回分を記述しなければなりませんので

下記を見る限り、それぞれの変更箇所は一部分だけなのですよね?

>   以下 配列のBandRegBandNo  BandRegOld と
>        RbytOut(6) = &H2
>             RbytOut(7) = &H2  を変更するのみなので内容は省略します

その場合、それぞれの差異となる部分のみを切り出して、
それを引数として渡すようにすれば、処理をまとめることができるでしょう。

 BandRegInfGet( データ1, データ2, … )

引数を使う方法では、渡すデータが多くなりすぎるというのであれば、
データ受け渡しのためのクラス(または構造体)を設けて、
 Dim arg As New Hoge()
 arg.SetOut(6, &H2)
 arg.SetOut(7, &H2)
   :
 BandRegInfGet( arg )
などという構成にすることもできるかと思います。

そして、その引数セットが 27 回あるというのなら、
 Dim args(0 To 26) As Hoge
などで管理しておけば済むでしょう。

また、送信するコマンド情報は、現在のコード内に埋め込んでおく方法のほか、
外部ファイルなどから読み込ませる方式にするということもできるかと思います。

[ツリー表示へ]
タイトルRe^2: VB シリアル通信で受けた文字列を配列に格納したい
記事No11899
投稿日: 2017/09/04(Mon) 11:49
投稿者MSAKA
魔界の仮面弁士さん
早々アドバイス有難うございます すっかり遅くなり申し訳ありません

> それを言うなら No11868 ですよね。
恐れ入りますそのとおりです 10000円忘れていました
>
> > SerialPort1.Read(receivedData, 0, receivedData.L使い方ength)
> 化けてますね。(^^;
??どうして化けた 私の書き込み時のミスかも知れません
>
> > 最後に書き込んだBandRegSTR(3,3)は以下のように格納されています
>
> 各行のインデックスが不明ですが、こういう状態なのでしょうか?
>
> BandRegSTR(0, 0) = "1"
> BandRegSTR(0, 1) = "2"
> BandRegSTR(0, 2) = "3"
> BandRegSTR(0, 3) = "1"
> BandRegSTR(1, 0) = "2"
> BandRegSTR(1, 1) = "3"
> BandRegSTR(1, 2) = "3 FD23000085080085080000000203000702000(以下略)"

いいえ BandRegSTR(n, m) の添え字は2,1〜 3,3(0は使わず)を指定しているので
添字 0,0 や 1,0 の配列は空です 想定とおり ただしその他は

BandRegSTR(0, 0) =Nothing  
BandRegSTR(0, 1) =Nothing  
BandRegSTR(0, 2) =Nothing  
BandRegSTR(0, 3) =Nothing  
BandRegSTR(1, 0) =Nothing  
BandRegSTR(1, 1) =Nothing  
BandRegSTR(1, 2) =Nothing  
BandRegSTR(1, 3) =Nothing  
BandRegSTR(2, 0) =Nothing
BandRegSTR(2, 1) =Nothing  
BandRegSTR(2, 2) =Nothing  
BandRegSTR(2, 3) =Nothing  
BandRegSTR(3, 0) =Nothing
BandRegSTR(3, 1) =Nothing
BandRegSTR(3, 2) =Nothing
BandRegSTR(3, 3) =  3FD23000085080085080000000203000 ・・・略
BandRegSTR(4, 0) =Nothing  以下同じ

受信した文字列を結合されて最後に書き込んだ配列3,3のみ格納されていると言うことです
たとえば2,1〜2,3まで送信コマンドを送ったときは最後の配列2,3に3個分結合されて
います それ以前の配列は空です
(先回 途中の配列には数字だけが格納されて文字はないと言いましたが私の確認ミスで
数字も書き込まれていない つまり 書き込み作業が行われていないと思われます)

> おそらくは、
>  Dim data As Byte() = {1, 2, 3, 4, 5, 6, 7, 8, 9}
> というデータがあった場合に、
>  Dim RecStr As String = "090807060504030201"
> を得ることが目的なのだと思いますが、それならばループ処理などせずとも、
>  Dim RevData As Byte() = data.Reverse().ToArray()
>  Dim RecStr As String = BitConverter.ToString(RevData).Replace("-", "")
> だけで済みますよ。
>
> あるいは、data そのものの順番も逆転して良いのであれば、
>  Array.Reverse(data)
>  Dim RecStr As String = BitConverter.ToString(data).Replace("-", "")
> と書くこともできます。
Array.Reverse(data)
 Dim RecStr As String = BitConverter.ToString(data).Replace("-", "")
を早々使うことにしました  便利ですね
>
> > X = RecStr.IndexOf("011A6600FEFE")  '  条件 2
>
> この検索方法だと、4bit 分の桁ずれが生じる可能性がありそうですが、大丈夫でしょうか?
>
> RecStr = "11A6600FEFE000" 'X = -1 が返される(想定どおり)
> RecStr = "011A6600FEFE00" 'X = 0 が返される(想定どおり)
> RecStr = "0011A6600FEFE0" 'X = 1 が返されるが、本来は X = -1 になるべきでは?
> RecStr = "00011A6600FEFE" 'X = 2 が返される(想定どおり)
> RecStr = "00011A6600FE00" 'X = -1 が返される(想定どおり)
なるほど そこまで考えが及びませんでした 想定外です
>
> あえてそういう仕様にしているのならば良いのですが、もしもそうではなく、
> 1 バイト単位(16進数表現で 2 文字分)の位置を調べたかったのであれば、
> たとえば BitConverter の "-" をあえて潰さずに、
>  Dim RevData As Byte() = data.Reverse().ToArray()
>  Dim RecStr As String = "-" & BitConverter.ToString(RevData)
>  X = RecStr.IndexOf("-01-1A-66-00-FE-FE")
>  Y = RecStr.IndexOf("-FD")
> のように探索するという手もあります。これなら桁ズレは発生しません。
>
> この方法では、1 バイトが 2 文字ではなく 3 文字で表現されているので、
> 変数 X (と Y) の使いみちによっては、上記の後に追加で
>  If X >= 0 Then
>   X = 2 * X \ 3
>  End If
> のような補正が必要かも知れません。適宜調整してください。
この方法がミスがないのですね Xを使うのに頭が痛くなりますね  課題にします
>
> > If CC > 40 And X > 10 Then
> And 演算子ではなく、AndAlso 演算子を使う癖をつけましょう。
ハイ 分かりました
>
> > 疑問1  何故 最後の配列変数のみにまとめてを格納されるのでしょうか
> >      どこで6個の文字列を連結されるのでしょうか  ここが原因?
>
> 『BandRegSTR(n,m) に文字列を格納する処理』が書かれているのは、
> > If CC > 40 And X > 10 Then 
> >   BandRegSTR(BandRegBandNo, BandRegOld) = BandRegOld & RecStr
> > End If
> の部分だけなのですね。であればこの部分を
>
> If CC > 40 AndAnslo X > 10 Then 
>  Debug.Write(BandRegBandNo)
>  Debug.Write(", ")
>  Debug.Write(BandRegOld)
>  Debug.Write(" = 文字数:")
>  Debug.WriteLine((BandRegOld & RecStr).Length)
>  BandRegSTR(BandRegBandNo, BandRegOld) = BandRegOld & RecStr
> End IF
>
> のように書き換えて、それぞれの変数(特に BandRegBandNo と BandRegOld)の値が
> どの時点で期待から外れた値になってしまうのか、出力ウィンドウで確認してみましょう。
出力ウィンドウに何も表示されませんでした 私の知識不足です  開発には不可欠なものなので
勉強します    とりあえず今回色々な確認をした結果で問題は解決しそうです
末尾に経過を報告します

> 疑問2  ・・・・・ System.Threading.Thread.Sleep(200)の使い方
>             この使い方は正しいでしょうか)
>正しい使い方ではありません。
ヤッパリ だめなんですね 
>
> コンソール アプリケーションで Sleep を呼ぶような使い方は OK ですが、
> UI スレッド(Form/Button/TextBox などを利用するスレッド)から
> Sleep メソッドを呼び出すことは タブー です。
> > 対処方法としては:
> (対処案A) メインスレッドから書き込むために、
>  Timer を使って Tick イベントから Write する。
Timerで処理することにしました 上手く動いています

>
> > お願い  コマンンドを書き込む方法 下記コード ***1 以降はもっとスマートに
> >      できないものでしょうか 9×3 で27回分を記述しなければなりませんので
>
> 下記を見る限り、それぞれの変更箇所は一部分だけなのですよね?
そのとおりです
>
> >   以下 配列のBandRegBandNo  BandRegOld と
> >        RbytOut(6) = &H2
> >             RbytOut(7) = &H2  を変更するのみなので内容は省略します
>
> その場合、それぞれの差異となる部分のみを切り出して、
> それを引数として渡すようにすれば、処理をまとめることができるでしょう。
>
>  BandRegInfGet( データ1, データ2, … )
>
> 引数を使う方法では、渡すデータが多くなりすぎるというのであれば、
> データ受け渡しのためのクラス(または構造体)を設けて、
>  Dim arg As New Hoge()
>  arg.SetOut(6, &H2)
>  arg.SetOut(7, &H2)
>    :
>  BandRegInfGet( arg )
> などという構成にすることもできるかと思います。
>
> そして、その引数セットが 27 回あるというのなら、
>  Dim args(0 To 26) As Hoge
> などで管理しておけば済むでしょう。
>
> また、送信するコマンド情報は、現在のコード内に埋め込んでおく方法のほか、
> 外部ファイルなどから読み込ませる方式にするということもできるかと思います。
構造体と聞いただけで頭が痛くなります(扱っている値がどこにあるか迷子になります)
外部ファイルなどから読み込ませる方法が簡単かも 研究課題とします

その後の状況
Timerを使うようにした後 何故かしら 条件に合致するものがなくなってしまいました
配列に全く書き込まなくなったのです
変だな?と思い条件なしで受け取ったものをそのときの配列添え字を先頭に付加して
全てをTextBoxに表示して確認しました

Private Sub RcvDataToTextBox(data() As Byte)
  一部省略
   Array.Reverse(data)
        Dim RecStr As String = BitConverter.ToString(data).Replace("-", "")
 
   TextBox2.AppendText(BandRegBandNo & BandRegOld & " " & RecStr & vbCrLf)
End Sub
結果は以下です 

21 0066FEFE
21 FEFD0102011A
21
21 1A6600FE
21
21 850800000002000003544000010201
21 FD230000850800
22 1A0066FEFE
22
22 FEFD020201
22 1A6600FE
22
22 0800000002030003522150020201
22 FD23000085080085

以下 3,3まで 同じように 同一配列添え字 たとえば(2,1)で7回も受け取って
います 空のときもあります
(ひとつのコマンドに対して無線機からの文字列は幾つかに分かれて送られているらしい)
念のために受信処理部にカウンターをつけて確認したところPCからの6つのコマンドに
対する受信完了までの間に41回前後を示します

また 上記のバラバラの文字列の配列添え字が同じ(例えば 2,2)をつなぎ合わせると
FD2300008508008508000000020000035440000202011A6600FEFEFD0202011A0066FEFE
となり期待値になります

そこで選択条件を無くして同一添え字の配列の間は受信した文字列をその配列に追加書き込みを
するようにしてみました
Private Sub RcvDataToTextBox(data() As Byte)
  一部省略
 Array.Reverse(data)
  Dim RecStr As String = BitConverter.ToString(data).Replace("-", "")
   
 BandRegSTR(BandRegBandNo, BandRegOld) = RecStr & BandRegSTR(BandRegBandNo, BandRegOld) ここで追記
   
 TextBox2.AppendText(BandRegBandNo & BandRegOld & " " & RecStr & vbCrLf) ここはTextBoxへの書き込み
End Sub

結果配列変数
2,0 は空 (使っていないので正解)
2,1には  FD2300008508008508000000010000036020000102011A6600FEFEFD0102011A0066FEFE
2,2には  FD2300008508008508000000020000035440000202011A6600FEFEFD0202011A0066FEFE
2,3には  FD2300008508008508000000020300035221500302011A6600FEFEFD0302011A0066FEFE
3,0 は 空(使っていないので正解)
3,1には  FD2300008508008508000000010000071529900103011A6600FEFEFD0103011A0066FEFE
以下 3,3 まで同じ結果です
受け取った内容は順次変わっていきます
たとえば32文字目から6文字が 360200,354400,352215 などと正解と思われる文字列が
格納されるようになりました

無線機から初期値として呼び込み配列に書き込む国的は達成できたことになります

たまたま 呼び込みたい初期値は同じコマンド(位置情報のみ変わる)で且つ同じ形式文字列で
返してくること この間は無線機の操作を行わず 余計なイベントが発生しないことなどで
上手く働くだけで未だ課題は多くありそうです
何故文字列が最後の配列に合体してしまうのか?については未確認ですし

とりあえず今回ご指導いただいたおかげで一つの壁は乗り越えることができました
大変有難うございました  残されている課題でまたひっかるかも知れません その際はまた
お世話になります

[ツリー表示へ]
タイトルRe^3: VB シリアル通信で受けた文字列を配列に格納したい
記事No11900
投稿日: 2017/09/04(Mon) 14:23
投稿者魔界の仮面弁士
おめでとうございます。まずは山をひとつ越えましたね。


> 無線機から初期値として呼び込み配列に書き込む国的は達成できたことになります
× 国的(KOKUTEKI)
○ 目的(MOKUTEKI)



> 開発には不可欠なものなので勉強します

そうですね。Debug クラスや Trace クラスの使い方は身に付けておいたほうが良いでしょう。

簡単なデバッグなら、一時停止からのステップ実行で事足りるのですが、
Timer 処理や SerialPort 通信で一時停止させるのは都合が悪いでしょうし。


> >  Debug.Write(BandRegBandNo)
> 出力ウィンドウに何も表示されませんでした 私の知識不足です

[ツール]-[オプション] をクリックして、「デバッグ」タブにある
 「出力ウィンドウの文字をすべてイミディエイト ウィンドウにリダイレクトする」
のチェックを確認してみてください。

On になっている場合は [イミディエイト] ウィンドウに表示され、
Off になっているなら [出力] ウィンドウに表示される仕様です。


開発環境設定が "Visual Basic 開発設定" になっている場合の既定値は On です。
開発環境設定が "Visual C# 開発設定" や "全般的な開発設定" の既定値は Off です。

※この開発環境設定は、Visual Studio の初回起動時の選択によって決まりますが、、
 [ツール]-[設定のインポートとエクスポート]→[すべての設定をリセット]
 を使えば、いつでも再変更できます。

[ツリー表示へ]
タイトルRe^4: VB シリアル通信で受けた文字列を配列に格納したい
記事No11901
投稿日: 2017/09/06(Wed) 09:14
投稿者MSAKA
魔界の仮面弁士さん

一山超えたのですが未だ先は長そうです

> > 無線機から初期値として呼び込み配列に書き込む国的は達成できたことになります
> × 国的(KOKUTEKI)
> ○ 目的(MOKUTEKI)
すみません キーボード打ち込みミスです 
>
> > 開発には不可欠なものなので勉強します
>
> そうですね。Debug クラスや Trace クラスの使い方は身に付けておいたほうが良いでしょう。
>
> 簡単なデバッグなら、一時停止からのステップ実行で事足りるのですが、
> Timer 処理や SerialPort 通信で一時停止させるのは都合が悪いでしょうし。
>
>
> > >  Debug.Write(BandRegBandNo)
> > 出力ウィンドウに何も表示されませんでした 私の知識不足です
>
> [ツール]-[オプション] をクリックして、「デバッグ」タブにある
>  「出力ウィンドウの文字をすべてイミディエイト ウィンドウにリダイレクトする」
> のチェックを確認してみてください。
>
> On になっている場合は [イミディエイト] ウィンドウに表示され、
> Off になっているなら [出力] ウィンドウに表示される仕様です。
>
>
> 開発環境設定が "Visual Basic 開発設定" になっている場合の既定値は On です。
> 開発環境設定が "Visual C# 開発設定" や "全般的な開発設定" の既定値は Off です。
>
> ※この開発環境設定は、Visual Studio の初回起動時の選択によって決まりますが、、
>  [ツール]-[設定のインポートとエクスポート]→[すべての設定をリセット]
>  を使えば、いつでも再変更できます。
そうですか 今度確認してみます

勉強することが多くて・・・のんびりやります
大変有難うございました

[ツリー表示へ]