AF PSN for DC Reciever

以前,SSB送信用のAF PSN をdsPICで製作した.
その後,受信用もできないかと気になりつつも,ずいぶん時間が経ってしまった.
もちろん,dsPIC33FJ64GP802にこだわらなければ何とでもなるが,
このdsPIC  1個でできれば面白いと思う.

よく知られているとおり,PSN受信機の構成は以下のようになる.

r01.jpg

AF PSNの部分をdsPIC33FJ64GP802 1個で構成したいのだが,
ADCが12bitであることと、2ch同時サンプルができないことが課題.
特に,12bitでは受信用としてダイナミックレンジが満足できない気がして,
いま一つやる気が起きなかったが,ようやく,「とりあえずやってみるか」
という気分になってきた.

受信用も,送信用のAF PSN同様,複素係数フィルタを使う.
r02.jpg

解析信号でブロック図を書くと以下のとおりで,送信用AF PSNもそうだが,
本質的にはフィルタ式と同じ.r03.jpg

 

結論から言えば,以下のような構成で,受信用AF PSNを実現できた.
r04.jpg

r06.jpg

r07b.jpg

r08b.jpg

一応設計通り動作している様子.
実際に受信機として使い物になるかどうかは,後日評価したい.

 

以下は詳細.

1.AD変換
送信用は,入力信号がほぼ話者の声だけと考えられるので,
アンチエイリアスフィルタが無くてもほぼ問題なかったが
受信用はそういうわけにはいかず,AD変換前にナイキスト周波数以上の成分を
十分に除去しなければならない.
カットオフ周波数がナイキスト周波数(1/2サンプリング周波数)に近い
シャープな切れ味のLPFを使って,
サンプリング周波数をあまり上げることなく十分な帯域をとりたいところだが,
そのようなフィルタは,カットオフ付近の移相量が大きく素子感度が高いため
温度変化など環境変化やその他様々な要因で特性が変化しやすい.
一番の問題は,そのようなフィルタが2個(I, Q)必要なことと,
それらが常に同じ特性でなければならないこと.
したがって,素子感度を下げ2個フィルタの特性のばらつきをできるだけ抑えたい.

そのためには,カットオフ付近で位相がなだらかに変化するフィルタが望ましいので,
ベッセルフィルタがよいと思う.
当然,カットオフ(振幅)特性もなだらかになり,シャープな切れ味にはならないので,
アンチエイリアスの能力は低下する.
そこでサンプリング周波数をできるだけ高くする.今回は100kHzとした.
また,dsPIC33FJ64GP802は48MHzのオーバークロックで動作させる.

I,Q 2ch同時サンプルはできず,2μs程度の遅延がありサンプリングタイミングがずれる.
2μsは,例えば3kHzにおいては,位相で 2.16deg に相当する.
これは無視できるレベルではないので,後段の複素係数FIRフィルタで
この遅延を補正することにした.

 

2.デシメーション用 IIRフィルタ
100kHzサンプリングですべて処理できればいいのだが,
dsPIC33FJ64GP802の性能では難しそうなので,
サンプリング周波数を1/8(12.5kHz)に下げる.
そのためには,後段の複素係数フィルタのナイキスト周波数(6.25kHz)以上の成分を
十分に除去しなければならない.
(このIIRフィルタのサンプリング周波数は100kHz)
I,Q 2chのフィルタが必要だが,ディジタルフィルタなので,
特性に違いが生じたり変化する心配はない.
できるだけシャープなカットオフ特性をもったLPFを使いたいので,
今回は,4次Elliptic LPF にしてみた.
IIRフィルタは設計が面倒だが,動作時はFIRより少ない計算量で済む.

2次IIRフィルタは以下のような構成になる.4次はこれを2段直列に接続する.

r05.jpg
kは本来不要なパラメータだが(k=1でよい),dsPICのように固定小数点演算の場合は,
計算途中で結果がオーバーフローしないようにk>1とする必要がある.
今回は k=4 とする.

IIRフィルタの設計には,GNU Octave (フリーウェア)を使った.
設計用のスクリプト ( IIR_ellip_LPF_design.m ) を実行すれば,
b0/k, b1/k, b2/k, a1/k, a2/k, k を定義するヘッダファイルが生成される.
signal パッケージを使うので,Octaveを起動したらコマンドラインで,

pkg load signal

とタイプしておく必要がある.

次に,dsPICでIIRフィルタを実行するソースコード(dsPIC33,DSPライブラリ使用)を
以下に記載しておく.

//— IIR ———————————–
//4th IIR Elliptic LPF coeff.
//fs=100000[Hz],  fc=3000[Hz]
//Ripple=1[dB],  Att=70[dB]

fractional _XDATA(2) IIR_coef0[] =
//{b0/k, b1/k, b2/k, a1/k, a2/k, log2(k) }
{ 53, -26, 53, 15311, -7199,  2};

fractional _XDATA(2) IIR_coef1[] =
//{b0/k, b1/k, b2/k, a1/k, a2/k, log2(k) }
{720, -1161, 720, 15706, -7794,  2};

fractional _YBSS(2) Z_Re_0[5];
fractional _YBSS(2) Z_Re_1[5];
fractional x, y;

void IIR_Ellip_LPF(void)
{
//– 1st stage——————————————
Z_Re_0[0]=x;
y=VectorDotProduct(5, &Z_Re_0[0], &IIR_coef0[0]);
y<<=IIR_coef0[5];
Z_Re_0[2]=Z_Re_0[1];  Z_Re_0[1]=Z_Re_0[0];
Z_Re_0[4]=Z_Re_0[3];  Z_Re_0[3]=y;

//– 2nd stage——————————————
Z_Re_1[0]=y;
y=VectorDotProduct(5, &Z_Re_1[0], &IIR_coef1[0]);
y<<=IIR_coef1[5];
Z_Re_1[2]=Z_Re_1[1];  Z_Re_1[1]=Z_Re_1[0];
Z_Re_1[4]=Z_Re_1[3];  Z_Re_1[3]=y;
//output:  y;
}

DSPライブラリ関数にはIIRフィルタもあるが,処理速度が遅かったので
VectorDotProduct 関数を使って自作してみた.
これはI chのみなので,もう一組IIRフィルタが必要となる.

伝達特性(設計値)は,以下のとおり
(横軸はナイキスト周波数50kHzで正規化)r09.jpg

 

3.複素係数FIRフィルタ(PSN)
サンプリング周波数とタップ数が違うだけで送信用と同じ.
今回128タップとしている(これが限界).

FIRの係数を求める際,AD変換の遅延を補正するよう考慮している.
具体的には,遅延をTとして Im側にのみ周波数特性にexp(- j2πf T) を掛けている.
(設計用のスクリプト    Calc_Coeff_of_CPLXBPF_adj.m )

 

P.S.
動作確認レベルのプログラムなので,これを公開する予定はありませんが,
もしご希望の方がいましたら,ご連絡いただければ検討いたします.

FIRフィルタ

前回AF PSNを複素係数のFIRフィルタで作成したが,その係数を変えれば任意の周波数特性を持ったフィルタが作れることはいうまでもなく,AF PSN はその一例にすぎない.

FIRフィルタの係数は,周波数特性を逆フーリエ変換すれば得られるので手間はかからない.とはいえ手計算できるものでもないので,AF PSN 作成の際に,係数を求めるために作ったツールをここにUPしておいた(Calc_Coeff_of_CPLXBPF.m).

これは,拡張子mが示すようにMATLAB,GNU Octave 上で動くスクリプトである.
GNU Octave はフリーウェアでこちらから入手でき,Windows の場合,octave-4.4.0-w64_1-installer.exe ならインストールは容易かと思う.

スクリプト内でパスバンドの周波数を書き換えて実行すれば,その特性を実現する係数を定義するヘッダファイルが自動生成される.
これをincludeしてコンパイルすれば,設定どおりのパスバンドを持ったBPFが実現できる.
複素係数フィルタであるが,実数部のみ使用すれば普通のフィルタと同じである.

 

さて,前回製作したAF PSNであるが,パスバンド内のリップルとパスバンド外の減衰特性が気になった.周波数特性を求めたところ下図のようになった.

Rect

理由は,窓関数を使用していなかった(=矩形窓)ためである.
そこで,フィルタ係数に窓関数を掛けてみた.
(窓関数はスクリプト内で指定できるようにしてある)

 

Hann 窓
han

Hamming 窓
hamming

Blackman 窓
blackman

Bartlett 窓
bartlett

使用する窓関数としては Hamming か Blackman になるだろう.
Blackman のほうが減衰特性がなだらかであるが,それでも十分急峻な減衰特性なのでこれがよいと思う.
(ヘッダファイルとCソースファイルを更新しているので,日付を確認の上ご利用願います)

音響ホーン

以前は40KHzのトランスデューサ(写真左)を使ってバットディテクターを製作していたが,
40KHz付近しか観測できない,という制約があった.
今回のバットディテクターでは,
広帯域で超音波を観測するためにMEMSマイク(写真右)を使っている.
ただ,トランスデューサは40KHz付近の感度は高く,
40KHzに限った感度の比較では,MEMSマイクは今一つな感じがする.

20180311_133045~2

写真を見ればわかるように,
MEMSマイクの音響ホールは直径0.5mmしかない.
トランスデューサの方は,内部の振動板らしきものは,直径8mmほどある.
開口面積がMEMSマイクの方が格段に小さいため,
感度が悪いのも無理はない.

そこで,音響ホーンを用いて開口面積を大きくし,感度の向上を試みた.

20180311_131230~2

3Dプリンタで作成した超音波用の音響ホーン.

定量的なデータはとっていないが,聞き比べた感じでは,
トランスデューサと同等以上の感度が得られているようだ.

バットディテクタ

知人からの相談がきっかけで,
新しい方式のバットディテクターを開発,試作した.

詳細はこちら

バットディテクターは,コウモリの出す超音波を可聴音に変換するもので,
主な方式として次の3種類のものが従来からある.

・ヘテロダイン式 (Heterodyne)
・フリークエンシーディビジョン式(Frequency Division:周波数分周式)
・タイムエキスパンション式(Time Expansion:時間軸延長式)
Wikiより.

これらの方式では,

・ヘテロダイン式
チューニング操作による探索が必須.周波数が大きく異なるものは同時観測できない.
・周波数分周式
レベルが最も高い信号しか観測できない.周波数以外の情報が失われる.
・時間軸延長式
リアルタイムで観測できない.

といった短所がある.

今回開発したのものは,
超音波領域の信号のスペクトルを周波数方向に圧縮し
全てを可聴音の領域に詰め込む方法.
「スペクトラム圧縮式」としておく.
この方式では,従来方式の上記欠点が改善される.
つまり,チューニング操作不要で,
周波数に関わらず同時に複数対象を
リアルタイムに観測できる.

sc01

信号処理方法としては,下記のように2種類考えられる.
今回は,下の方法で試作をしてみた.
20171212-2