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

7か月ぶりに、C#のモニタープログラムいじり始めました。ハード周りが収束してきたので、フィールド測定用に使い勝手の良いモニタープログラムを作りました。TeraTermの速度と信頼性と安定性には及びませんが、測定作業にぴったりの仕様なので、見やすさとかログ後の処理はTeraTermよりよくなってます。
●概仕様
COMポートを指定してOPENすると自動的にタイムスタンプ名のCSVファイルを作成してログ開始
データの表示は、RTK測位電波状態、Base,Rover,IMUの運動データを4つのTextBoxに分けてみれるようにしました。
teratermだと一かたまりで順次表示されるので、デバイス毎に状態が見えるようにしました。
ボタンは、
a=電源オンで、待機状態になっているマイコン側プログラムを動作させるコマンド
p=測定がFIXしたら、pを押すと基線長測定をして500点サンプリングして平均と標準偏差の計算をして、測定の基準点を決める
s=SDカードへのログ開始
d=SDログを終了して、プログラムをリセットして、SDカードのディレクトリを表示して、現在のログファイルの確認をする
t=モニターのデータ周期を1200msecと120msecで切り替える
未だ、ボタンは作ってませんが、以下の操作文字があります。
u=UPLOAD SDカードの最新のファイルを読み込んで、BTSPP経由でアップロードします。
b=mHeadとIMU yaw角の差を補正
n=FIXしてなくてもSDログができるようにする
 

①スタートでは、GPSのTimePulseが受信できてないうちは、IMUの測定タイミングが決まらないので
IMUの表示は空欄になってます。t1200_Modeは、1200msecで表示を更新するモードです。

②t-Stopモードなので、表示をとめて、120msec周期でログだけしてます。

●C# マルチスレッドシリアル送受信プログラムの課題
受信するだけなら、大昔から出来ているのですが、今回は、RTKBoxへBTSPP経由でコントロール文字を送って測定操作をするために、受信しながら、送信する場合、データ表示スレッドと受信スレッドのBUSY次第で、送信割り込みできたりできなかったりします。
chatGPTに送受信のやり方を聞いて、受信スレッドのBUSYの時にフラグを立てて、フラグが下がっているときのみ送信するという方法を教えてもらいました。その時は、動作したので、記事に残してあります。
【VS2022】シリアル受信中に送信する方法<chatGPTに教えてもらった>

◆ボタン割り込みが動作しなくなる現象発生
データ表示スレッドが軽い時(1200msec周期で表示)は、ボタン割り込みで送信ができたのですが、データ表示周期が120msecになると、途端に送信ボタンが効かなくなりました。
ボタン割り込みが動かなくなる現象が発生しました。
StopWatchで各メソッドへの時刻を測定したのですが、受信スレッドがバッファまとめて、受信したあと、行毎に分割して、表示スレッドに送ってきているので、まとめて受信したり、ちょっと受信したりバラバラなタイミングでデータを渡してきていることが分りました。
受信で60msec  表示で50msecくらいと全部で120msecの周期で2分して使っていました。黄色の部分で、ボタンを押すと送信できるはずですが、今度は、表示スレッドとボタンスレッドがぶつかるみたいで、表示スレッドの周期が速くなるとボタンが効かなくなる現象がでました。多分delegateで指定された動作が間断なく入っていて、スレッドとなっているのでボタン押しスレッドと表示スレッドとdelegateするスレッドで三つ巴になって余裕がなくなっているのではないかと思います。
●後日の解決策
未だボタン押しでハングする現象がでるので、いろいろ手を打ってみました。
■新な手:ボタンを押し送信前に受信バッファを空にして、1秒待ってから送信して、送信後1秒待って、受信を開始する=>この方法だと、ほとんどのボタン動作正常に送信できますが、1か所だけダメな使い方があります。
周期120msecでSDログとPCログと表示を同時にやっている場合tボタンが効かなくなります。SDログ中なので脱出するには、マイコンのリセットが通常ルーチンなので、マイコンの電源オフかモニタープログラムリセットで対応することで暫定対策としました。

=>やり方
SerialPort1.DiscardInBuffer ()で受信バッファを空にして、1秒Delayさせてから送信します。送信後1秒待って受信開始です。 コードは、こちらです。https://gist.github.com/dj1711572002/95dd85de3259fea2b148ca653b9421a2

■追加対策:更に、ダメ押しで、richTextBox表示をタイマー式にして、30秒から5分まで表示して止まるLOOK機能をつけた
=>常に見ているわけでないので、見たい時だけLOOKボタンをおして所定の秒数見るほうが、プログラムへの負荷がすくなくなって
トラブルの確率が減る対策としました。

 ●表示スレッドとボタンスレッドの衝突対策
120msec周期で表示スレッドを回すことを諦めて、120msecになったら、表示ストップというやり方にしました。表示は、1200msec周期の場合のみ表示することにすると、ボタン割り込みが動作しなくなる現象は無くなりました。要するに、表示スレッドが重いということでした。
ソースは、GISTにおいてあります。グラフィックとかDGV使ってないので短いプログラムです。.NET Framework 4.8で作ってあります。
.NET6.0は、シリアルが標準でないので、面倒なので、4.8を使ってます。
https://gist.github.com/dj1711572002/44806577833dada589f783748b72c751
●測定テスト
 庭でスキー靴にVCBLアンテナをつけて並進動作させる実験で使ってみました。
●以後
SDログ時にバグがあったので、直して今週末あたりから、実験に使っていきます。
左右のブーツにシステムを実装してラジオハーネスで歩行測定は来週以降となります。
どのようにデータをモニタしてもとめるかをじっくりと考えていきます。
歩行が終わったら野沢温泉スキー場へ行く準備しますが、この暑さでスキーどころではないので
お盆過ぎくらいからスキーに行こうかと思ってます。

 

コメントを残す

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