2018年11月21日水曜日

DTMF FFT

 ソフトDTMFデコーダを作ってる。
 時間軸と周波数軸を比較する予定。
 とりあえず時間軸では動くようになったので、周波数軸で計算してる。



 DTMFで1, 2, 3, A, 1, 7, *, 1, 5, 9, Dを送ったときのFFTの波形。
 横軸が時間(秒)、奥行き(俯瞰は縦軸)が周波数(Hz)、高さがpower。

 FFTに入れる前にオフセットしてやらないと強烈にDC成分が出る。そりゃそーだ。
 12bitADCで2048をオフセットしても若干DC成分が出てるけど、無視できるレベル。
 もっとも、DTMFのデコードではDC成分は見ないので、オフセットするだけ計算リソースの無駄な気もするが。

 8kSPS128ポイントだと微妙に分解能が悪いんだよなぁ。8kSPS256ポイントとかあればだいぶマシだけど、波形を集めるのに32msecかかるので、短いDTMF信号は取り逃すことになってしまう。

***

 メモリの使用量は、ADC周りで520バイト、時間軸で4104バイト、周波数軸で1048バイト、とのこと(それぞれのclassをsizeofして計測)。
 時間軸での計算には、FIRで強烈なBPFを作ってるので、そのバッファでメモリがガッツリ食われる。
 FFTは入力と出力にFFTポイント分の配列が必要だが、4byte*128point*2なので1024バイト+α程度で処理できる。

 感覚的には、時間軸で処理したほうが信頼性が高い気がするんだが、まだ比較してないので、なんとも言えない。

追記
 時間軸で処理した場合は3700usec、周波数軸で処理した場合は280usec、という感じ。どちらも64MHzのC-M4Fコア。
 そんなに差があるのかぁ。時間的リソースは消費電力に直結するので、低消費電力が重要な今回の用途には時間軸は無理っぽい。RAM消費リソースもすごいしね。
 もっとも、素直にFFTを使おうとするとアホのようにデカいROMテーブルを使うので、Flashが小さいチップだと厳しいけど。

 とりあえず、時間軸を使うヤツはお先真っ暗だけど、誤検出とかの比較はしておきたいな。
 無線電話に通すならホワイトノイズ耐性はほしいし。

追記2
 試しに時間軸と周波数軸の両方に入力信号を通して結果を表示してみた。
 明らかにFFT方式はホワイトノイズ耐性が低い。時間軸の方はほぼ全く誤検知しない。

 ただ、FFT方式はもう少し工夫の余地がありそうな気がする。例えばホワイトノイズなら全体的にスペクトルが出ているはずなので、全体の平均と、検出した信号のピークの比を判断に使う、といったことができるはず。ただあんまりやりすぎると弱い信号を取れなくなるんだよなー。

 それと、誤検出したとしてもランダムエラーが主で、バーストエラーはほぼ発生しない。発生したとしても同じコードではなく、いくつかのコードが出てくるはず。
 ということは、チャタリング対策みたいな感じで、例えば3回以上同じコードが出ていれば正しいDTMFコードとして扱う、みたいにすればいいはず。
 1区間は1sec/8000sps*128point = 16msecなので、3回なら48msecになる。大抵はこの期間以上は出るはず。DTMFの仕様としては最小50msec以上送信しなきゃいけないらしいので、48msecはギリギリで受けれる。タイミングによっては無理だけど、まぁ送信側で最低限100msec以上送る、みたいな運用にすれば問題ないはず。

 あと、計算時間の計測は、信頼性がちょっと怪しい。たぶん3700と280の比は問題ないはずだけど、絶対値(usec)として扱えるかは怪しいところ。
 オシロでビジーのパルス幅を見ると2.5msec/divより狭いので、3700usecはだいぶ長過ぎる。ちょうど2倍ずれてるかも。とすると1850usec対140usecか。それだと合わせて2msecくらいなので、2.5msec/divより狭い点の説明ができる。

0 件のコメント:

コメントを投稿