投稿者 魔界の仮面弁士  (社会人) 投稿日時 2017/8/22 12:01:11
> Dim xbyte As UShort = BitConverter.ToUInt16(datax, 0)
変数名を xbyte にしていますが、"byte" という語は、
8bit なデータ型を連想させるので、適切では無いと思います。


> Private Sub RcvXDataToTextBox(xdec As String)
>  Invoke(New Delegate_RcvDataToGraph(AddressOf RcvDataToGraph), X)
> End Sub

RcvXDataToTextBox は UI スレッドで呼ばれているのに、
何故、そこからさらに「Invoke」しなおしているのでしょうか?


> Invoke(New Delegate_RcvXDataToTextBox(AddressOf RcvXDataToTextBox), xdec)
> Invoke(New Delegate_RcvYDataToTextBox(AddressOf RcvYDataToTextBox), ydec)

2 つのデータをそれぞれ別々に Invoke するのは、実行コストが高くなります。



1 回の受信で、 x 値 と y 値 の 2 つを同時に受け取れるのであれば、
その 2 つをまとめて渡すためのデリゲートを用意しておき、それを
SerialPort1_DataReceived イベントのスレッドから Invoke するようにします。


処理イメージとしてはこんな感じ。

Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
 Dim bin(0 To 5) As Byte
 ' :
 ' :
 Dim x = BitConverter.ToUInt16({bin(2), bin(1)}, 0)
 Dim y = BitConverter.ToUInt16({bin(4), bin(3)}, 0)
 Received(x, y)
End Sub


'受信データを画面に表示するためのメソッド
Private Sub Received(x As UShort, y As UShort)
 If InvokeRequired Then

  '別スレッドからの呼び出しなので、Invoke しなおします
  Invoke(New Action(Of UShort, UShort)(AddressOf Received), x, y)

 Else
  '同じスレッドからの呼び出しならそのまま実行

  'AddXY メソッドの引数は本来 Double 型ですが、
  'UShort → Double への拡大変換は自動的に行われるので
  'CDbl 等での変換は省略して構いません。
  Chart1.Series(要素).Points.AddXY(x, y)

  'AppendText メソッドの引数は String 型なので
  '数値から文字列への変換は明示的に行う必要があります。
  RcvXTextBox.AppendText(Str(x))
  RcvYTextBox.AppendText(Str(y))

  'TextBox に履歴的に追記するのではなく、
  '常に最新値を表示したいのであれば、下記のようにします。
  'RcvXTextBox.Text = CStr(x)
  'RcvYTextBox.Text = CStr(x)
 End If
End Sub



※注1※
今までのコードを見ていると、何のために Invoke しているのかを
ただしく理解していないように思えたので、多少冗長的ではありますが、
あえて InvokeRequired プロパティで判定するような処理にしてみました。

SerialPort1_DataReceived のスレッドが UI スレッドでない事は明確なので、
InvokeRequired で判定したりせず、元のように、DataReceived イベントの時点で
Invoke するようにしても構いません。


※注2※
今回のコードでは、TextBox に渡すために文字列化する際に、
Convert.ToString や CStr ではなく、Str を使っています。

これはたとえば、「12」「14」「13」が渡されて来たときに、
TextBox に " 12 14 13" と空白付きで表示させて、
データの区切りを分かりやすくするためです。

もしも Convert.ToString や CStr を使っていると、"121413" になりますが、
これだと、「12」「14」「13」なのか「1」「2」「141」「3」なのか
判断できないと思ったので手を加えていますが、もしも
空白が無い方が都合が良いのであれば、適宜見直してください。