2019年4月25日木曜日

DTMFデコーダー

 今更ながら、DTMFデコーダーで遊んでる。
 このブログを検索してみると、18年11月にもエントリを書いてるので、久しぶりに、といったところか。



 既存のフリーソフトだと使いづらかったので、正弦波を出すプログラムも作ったり。各ch間で出力の同期をしてないので、DTMFを出すには手間がかかるけど、ある周波数にn%のオフセットを与える、みたいなのが出しやすい。
 この図では、DTMFの8種類、それぞれ±2%で、計24個の周波数を出せるようにしている(自由に増減できるけど)。

 DTMFの定格としては、周波数誤差は1.5%以内までらしい。とりあえず2%のエラーでもデコードできてる。

 周波数の計測は、FFTを通してから低群と高群のパワースペクトルの重心を求めている。周波数計測誤差がある程度あるので、その余裕を見た枠を設定する必要がある(FFTの結果は、スペクトルの重心が周波数、面積が信号の強さ、として扱える)。

 まずはデコードするのが優先で、まだ細かいチューニングはしていない。
 ホワイトノイズを入れればミスデコードする、というほど脆弱ではないが、DTMFにホワイトノイズを入れると、時々デコードできなくなる。ノイズが乗るとDTMFコードに高周波成分が出るような結果になるので、デコードした結果が3-5サンプル程度連続すれば正しい結果、というふうに扱えば、ノイズの影響は減らせるかもしれない。


 窓関数は、Hann, Hamming, Blackmanを目視で比較した程度では、それほど違いはない気がする。Noneだと明らかにミスデコード率が高いので、何らかの窓関数は必須だろう。とはいえ、一旦生成してしまえばあとは配列の積だから、各窓関数で使用リソースの差はないはず。しいて言えば、実行時計算だと初期化時間とROM使用量の差があるかな、程度だけど、C++のコンパイル時生成でやれば関係ないし。


 C#のコードだと、いろいろいじれるようにしているが、STM32とかで実装する場合は、サンプリングレート8kSPS固定である程度ハードコードしてしまう、とかすれば、それなりに計算リソースは減らせるはず。ハードコードするとあとから大変そうだけど、まぁADCサンプリングレートを細かく動かす、って事態は早々無いだろう… とかたかをくくってるとコア周波数に引きづられてADCサンプリングレートが中途半端な値に… みたいな事態を招くわけだが。。。
 forループをコンパイラ展開とかできたら楽でいいのにねぇ。


 DTMFはコード長が任意なのでデコードもやりやすいし、エンコーダーを作るのはすげー楽だけど、データレートが低いのが扱いづらいところ。
 本命はBPSKとかQAMあたりで、そっちにも手を出したいんだけど、なかなかやる気が出てこない。どうしたものか。OFDMのOOKとかならデータ長は任意になるから楽かな? まずはそっちから手を出してみるか。

0 件のコメント:

コメントを投稿