今更ながら、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 件のコメント:
コメントを投稿