【VB.NET】2ポート同時受信データ間の同期精度測定<バッファ最小がよい>

USBシリアルポート4ポートまで同時受信できたのはいいのですが、同時に受信されたデータ間で時刻同期のずれがどの程度発生しているかを実験してみました。

※2023年7月追記
本記事3年前の入門時の記事で、未だ未熟な内容となります。未熟ながら必死で実現しようとした努力賞ものですが、シリアル受信自体がマルチスレッドでそれを更に複数ポート受信するのは、難易度が高いし品質の保証がないので、現在では、USB2ポートは、1ポートのプログラムを2個起動してWIN10のマルチタスク機能をつかって、2ポート受信をしてます。素人がマルチスレッドプログラムを苦労して不完全なマルチスレッドプログラムをつくるより、1ポートをきちんと受信できるプログラムを作ってそれを、2個同時に動作させれば、2ポート受信は可能です。3ポートでも5ポートでもPCの能力次第で、多ポートできます。データは、それぞれのCOM番号をつけたCSVファイルに保存しておけばログができます。
最新の1ポート送受信プログラム例です。

【STA23】C#BlueToothシリアルでRTKログ操作Pgm作った<マルチスレッドで小技有>

 


※本実験では、リアルタイムグラフ描画無しPgmでCSVファイルログデータで精度検証をしております。MultiPortのリアルタイムグラフでは、リアルタイム速度が次第に遅くなる現象が発生しております。CSVファイルではデータ落ちはありませんが、VB側データ処理速度が厳しくなっているのかもしれません。同じプログラムで1ポートだと問題はないので、マルチポートにバグがあるかもしれませんので、後日デバッグしてみますが、マルチポートは、未だ、計測実績がないので、しばらくお待ちください。
※追記2020年10月3日
その後、2ポート16CHプログラムのデバッグを行って結論がでましたので、下記リンクの記事が最終結論となります。
2ポート受信について、リアルタイム同期を安定させるためには、プログラム全体がリアルタイム性が必要です。ですので、PCの描画速度がが重要なポイントになります。詳細は、下記実験記録をご覧ください。

【VB.NET】リアルタイム受信Pgmの処理別速度測定した<描画速度ネック>

以下の記事は、あまり参考になりませんので、スルーしてください。

 

■実験方法
 マイコン2個を同期信号線とリセット信号線の2本で接続して、マスターマイコンから10msecタイミングで同期信号を送信してカウンタをリセット、1秒に1回リセット信号を送って、両者のタイマーをリセットする。

①オシロでタイミングを確認
COM6のL432KCがタイミング信号とリセット信号
を発生します
黄線がタイミング信号
=>HIGHがAD7194で6CH読み込み中、LOWがprintfデータ転送
  青線がリセット信号
=>printfデータ転送直前にリセットHIGHをいれて次のリセットの直前で
リセットをLOWに戻してます。
COM8受信側マイコンは、立ち上がりエッジでピン割り込みをかけてます。

②マイコンプログラム
マスターマイコンのNucleoL432KC+AD7194のプログラムは備忘録としてGISTにおいてあります。
https://gist.github.com/dj1711572002/970d1d04091af54b1102c35a467928b5

スレーブマイコンのNUcleo F446ZEの受信プログラムもGISTにおいてあります。
https://gist.github.com/dj1711572002/98c6b42265c7674484ae5efbdeafce5b

③VB.NET複数ポート受信部
同時受信の方法2種類で測定しました。
SerialPort1が230400bps   SerialPort2が115200bpsの設定
=>AD7194が遅いため10msecちょうどに合わせるためボーレートを上げた
A:複数タスク受信
=>ポート毎にタスクを複数立ち上げて、データを1つにまとめて受信

‘***************************************************************************************************************************
‘******************************DataReceiving********************************************************************************
‘***************************************************************************************************************************
Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceivedIf CheckBox9.Checked = True And com1_None = 0 Then
Try
ReceivedData1 = SerialPort1.ReadLine ‘データを受信します
‘ReceivedData2 = SerialPort2.ReadLine
‘ ReceivedData3 = ReceivedData1 & ReceivedData2
Catch ex As Exception
ReceivedData1 = ex.Message ‘例外処理を行います
End Try
‘Invokeメソッドにより実行されるメソッドへのデリゲートの宣言を行い、受信データを表示します
Dim adre As New DataDelegate(AddressOf PrintData)
Me.Invoke(adre, ReceivedData1)
End If
End SubPrivate Sub SerialPort2_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceivedIf CheckBox9.Checked = True And com2_None = 0 Then
Try
ReceivedData2 = SerialPort2.ReadLine ‘データを受信しますCatch ex As Exception
ReceivedData2 = ex.Message ‘例外処理を行います
End Try
‘Invokeメソッドにより実行されるメソッドへのデリゲートの宣言を行い、受信データを表示します
Dim adre As New DataDelegate(AddressOf PrintData)
Me.Invoke(adre, ReceivedData2)
End IfEnd Sub


B:1つのタスク内で複数ポート順次受信
Receivedata3=Receiveddata1 & Receiveddata2として、長いSTRINGで
渡しますが、vbcrがついているので、CSVファイルでは2行で保存されます。

‘***************************************************************************************************************************
‘******************************DataReceiving********************************************************************************
‘***************************************************************************************************************************
Private Sub SerialPort1_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceivedIf CheckBox9.Checked = True And com1_None = 0 Then
Try
ReceivedData1 = SerialPort1.ReadLine ‘データを受信します
ReceivedData2 = SerialPort2.ReadLine
ReceivedData3 = ReceivedData1 & ReceivedData2
Catch ex As Exception
ReceivedData3 = ex.Message ‘例外処理を行います
End Try
‘Invokeメソッドにより実行されるメソッドへのデリゲートの宣言を行い、受信データを表示します
Dim adre As New DataDelegate(AddressOf PrintData)
Me.Invoke(adre, ReceivedData3)
End IfEnd Sub


④測定用プログラムCSVファイルLOGGING部
ファイル名を日時にして、ポートOPENと同時に自動ログして
ポートCLOSEでファイルもクローズする方法です。
ソースコードはGISTにあります。
https://gist.github.com/dj1711572002/5956d6f0b78e21cb66b33fa8be66a23a

■測定結果

A:複数タスク受信でのデータ同期精度
COM6がタイミングを発生させてからCOM8が受信して動作するのですが
30-40msecCOM8の受信動作が遅れてしまってばらばらなデータ受信となってます。これを整理するのは大変面倒なので、複数タスクはNGとしました。

B:1つのタスク内で複数ポート順次受信の同期精度
AがNGだったので、別の方法として1つのタスク内で、マルチポート受信を順次行って、結果をひとまとめのSTRING変数に収納して、print関数に渡す方法で同期精度測定した結果は、1個違いですが、隣同士で同期がとれてましたので、±10msec精度で受信できるデータとなるので使い勝手がいいのでこの方法を採用します。

追伸 9月27日 USBシリアル2ポート受信16CHプログラム完成
2ポートで、データ間のリアルタイム同期を実現するためには、本記事の方法に追加してシリアル受信バッファを定期的に空にする操作が必須です。読込周期の間にバッファ空にすることで、両CH間の受信タイミングずれは

1周期以内に収まって、リアルタイムグラフで同期がとれた波形をみることができます。 

デバッグ中で、未だ同期は完成しておりません。

【VB.NET】USB2ポート16CHリアルタイムモニター作った<PCの性能次第>

 

●以後
VB.NETでリアルタイム計測システムを組む場合、マルチタスクを常に考えておかないとデータの信頼性が崩れてしまうので
マルチタスクを学習しながらやっていくのと同時にタイミング関係の精度を実験して検証することが必須だと感じました。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です