投稿者 魔界の仮面弁士  (社会人) 投稿日時 2017/7/10 08:46:37
> 今、次のコードで意図することができたような気がしています。
>> ※意図する動作
>> 送信側は、FF FF FF 03が繰り返されるのですが、
>> 受信側は、FFを2回受信したら、そこから2バイト受信して、2バイトのデータを10進数に変換。

受信開始位置のパケット区切りが分からないという点はどうなりましたか?


>> 送信データ(FF FF FF 03が繰り返される)のどこから受信をし始めるかによって
>> データが変わってしまいます。
>>
>>Aパターン
>>①FF-03-FF-FF
>>Bパターン
>>①FF-FF-FF-03


FF,FF,xx,yy 形式の 4 バイトでデータが送出される形式で、
xx は 00~FF の範囲、yy は 00~03 というのが今回の仕様ですよね。


ということは、FF,FF,xx,yy,FF,FF,xx,yy,…と
連続して送られてくるデータを 4 バイト単位で読む際に
 Ⓐ FF,FF,xx,yy
 Ⓑ FF,xx,yy,FF
 Ⓒ xx,yy,FF,FF
 Ⓓ yy,FF,FF,xx
という 4 パターンのズレ方があるわけです。

今回は xx = FF なわけですから、そうすると今のコードだと
Ⓐ → FF,FF の後の [FF,03] を読み取って 1023
Ⓑ → FF,FF の後の [03,FF] を読み取って 65283
Ⓒ → FF,FF で始まらないので、2 バイトが読み捨てられ、次回からⒶになる
Ⓓ → FF,FF で始まらないので、2 バイトが読み捨てられ、次回からⒷになる
という結果になる気がします。


それを踏まえて、こんな感じでどうでしょうか。
TextBox ではなく、ListBox に表示させています。

'直前の読み残しを保持しておく変数 
Private cache As Byte() = {}
Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
If Not SerialPort1.IsOpen Then
    Return
End If

Dim size As Integer = SerialPort1.BytesToRead
If size + cache.Length >= 4 Then
    Dim bin(3) As Byte
    Array.Copy(cache, bin, Math.Min(4, cache.Length))
    SerialPort1.Read(bin, Math.Min(4, cache.Length), Math.Max(0, 4 - cache.Length))
    cache = New Byte() {}

    Dim pattern As Integer = 0
    For n = 0 To 3
        pattern *= 10
        If bin(n) = &HFF Then
            pattern += 1
        End If
    Next

    Dim value As UShort = UShort.MaxValue
    Select Case pattern
        Case 1100, 1110     'Ⓐパターン 
            value = BitConverter.ToUInt16(bin, 2)
            cache = New Byte() {}
        Case 1001, 1101     'Ⓑパターン 
            value = BitConverter.ToUInt16(bin, 1)
            cache = New Byte() {bin(3)}
        Case 11, 1011       'Ⓒパターン 
            value = BitConverter.ToUInt16(bin, 0)
            cache = New Byte() {bin(2), bin(3)}
        Case 110, 111       'Ⓓパターン 
            cache = New Byte() {bin(1), bin(2), bin(3)}
        Case Else           'Ⓔパターン 
            '想定しないデータなので仕切り直し 
            cache = New Byte() {}
    End Select

    If value <> UShort.MaxValue Then
        Invoke(Sub() ListBox1.Items.Insert(0, value))
    End If
End If