ArmマイコンUSB バーチャルコムポート(VCP)にはまる。


写真はNECLEO STM32F446RE評価ボードとUSB-シリアル変換モジュールでシリアル通信の様子。

2024.12.11

はじめに
 今回は、STM32F446のUARTとUSB-シリアル変換モジュールを使いPCとバイナリーデータ通信をする際に、はまったトラブル内容とその解決過程を紹介します。
 今回のトラブル例は、Web上でもほとんど紹介されていませんが、参考になれば幸いです。

テストプログラムの概要
 SDR#4号機トランシーバー用、基本動作確認用プログラムとして以下の内容でテストしています。
-1.STM側てオーディオ入力信号を、40kHzでサンプリングしAD値をバイナリデータで4096byteずつPCのバーチャルコムポート(VCP)へ送る。
-2.STMとPC間には、USB-シリアル変換モジュール(FTDI)を挟んで、2Mbpsで通信。
-3.PC側はデータ再生用としてSDRStudy(RFWorld#22)にシリアル通信入力対応の追加改造したソフト使用。
-4.シリアル通信確認用としてAcknowrichを使用。

トラブルの内容
-1.STM32F446から、AD値をバイナリデータ4096byte分PCへ送る仕様だが、成功する場合と途中で終了してしまう場合がある。
-2.STMとPC間の通信時間が、想定時間より大幅にかかる。
-3.PC側でデータ再生時、正常データ再生数十秒後に異常データとなり、叉正常に戻ったりする。
 

原因追究と対策
-1.原因調査として、Acknowrichで繰り返し受信している場合、きちんと4096byte分受信出来ているので、原因はPC側にありそうです。
 PC側では4096Byteの受信完了を、SerialPortプロパティのReceivedBytesThresholdで設定していますが、この設定値以前にデータにEOF(End of File) が含まれていると受信は終了してしいます。EOFの値は0x1Aなので、PC側はデータ中の0x1Aを受信した時点で終了になってしまいます。

対策として、EOFを無効にする方法を調べましたが判りませんでした。とりあえず左図ソース(クリックで拡大)の様にAD結果データに0x1Aが含まれていると、強制的にデータから +1加算した値に書き換えています。
 実運用上問題ありませんが、やはりEOFそのものを無効にしたいところです。

 

-2.4096Byteの受信が安定したところで、以下の通信フロー全体の実行時間を調査すると時間が想定より大幅にかかっています。
 フローは、PC側からデータ要求コマンド送信->STM側でコマンド受信し、データ4096Byte分送信スタート、同時にSTMボード内LED ON->PC側で4096Byte受信割り込み データ処理、完了でSTM側にLED OFFコマンド送信->STM側でLED OFF。LED点灯時間が目標時間以下であること、で調べてみると
 目標仕様50ms以下に対し、実際には80ms〜90ms程度かかっています。
 調査の結果、原因はUSB-シリアル変換モジュールの送信遅延時間でした。送信バイト数が64バイト以下の場合、遅延時間はデフォルト設定で16msになっています。 今回のコマンド送信ではせいぜい1〜2バイトしか送信しないので、コマンドを送る毎に16msの遅延が発生することになっていました。

対策として、左図(クリックで拡大)COMポートの詳細設定の送信待ち時間を16msから1msに変更しました。
COMポートの詳細設定は、デバイスマネージャー>COMポートのプロパティ―>ポートの設定>詳細設定から行えます。

 

-3.波形異常時、再生振幅が大きくなるので、ある値以上になったらプログラムにブレークポイントを設定して、データを確認してみると、受信データが1Byte分 ずれて、下位バイトと上位バイトが入れ替わっています。
 原因は、ReceivedBytesThresholdの設定ミスで、4096に設定するところ、0-4095のつもりで4095に設定していた為、最後の1Byteが受信出来たり出来なかったり していました。

対策として、左図(クリックで拡大)serialPortのプロパティーReceivedBytesThresholdを4096に書き換え、ようやく安定してデータ再生が出来るように なりました。

 

今後の進め方
 今回のデバッグには1.5カ月も掛かりましたが、解決出来たときの満足感はとても大きく、少しづつSDR完成に向かっています。
今回の実験ではADデータを16384パケットの固定データにしたので、データのつなぎ目で不連続点が発生します。実際のSDRに組み込みの場合は、 16bit IQデータを25us毎に連続して送ることになるので、引き続き連続したデータの通信などの確認を進めていきます。

USB-シリアル変換に戻る

   Top Menu