受信は、どないする? その2
1.スペクトログラム
信じられませんが、マイクを通した後の、私の声の、スペクトログラムです。
10KHz超えた成分がある !!!、ほんまかいな ???
この下のグラフは、上の声を、fir 80taps Lowpass filter に、通してから、観測したものです。
16KHz付近の成分は、サンプリング周波数成分及び、信号のエリアス成分です。(大したフィルタを通してないもんで....)
この、素晴らしいソフトは、akJ Audiotools (音声ツール Rich Client Platform)
作者様、御礼申し上げますm(__)m
私の声は、全く、普通の声と、思いますが、こんな周波数成分を含んで居りますとは...
恥ずかしながら、マイクを通した、私の声です。(こんな、か弱い声では、パイルアップ時など、絶対に、勝てませんな...涙、涙...)
これは、SSB発生器を通した、私の声です......
.やっぱり、声が、一番、わかりやすいので、お許しくだされたく候。
尚、マイクは、PC用の、ヘッドセットの、マイクです。
(Andrea NC-80 と、書いてある、Andrea社 有名らしいぞ ...IBMの音声入力ソフトに、付いていた。)
2.こうする手もある
前節では、PSNの理屈を、探りました。
R8C/15マイコンでは、チョイ、荷が重そうです。
そんで、一計。
普通の、やり方だと、思うのですが、
フィルタで、SSBにしたのですから、復調でも、このフィルタを使います。
しかし、
いきなり、ベースバンドに落として、複素フィルタに通す と、言う手は、まだ、理解できていません。
そんで、私の採った手は
1.中間周波数から、Fs/4に、周波数変換する。
この時、一方のサイドバンドだけ、残す(外部のフィルタで、カット)
2.SSB発生の時と、全く同じフィルタを通す。
これで、逆サイドバンド等が、取れます。
3.ここで、ベースバンドに周波数変換する。
(他にも、目的信号のエリアスあります、記入漏れあり。)
目的信号のエリアスは、外部フィルタで、カットします。
問題は、filterのエリアス内に、不要信号がある時です。
ご覧のように、ベースバンドの目的信号に、混ざってしまいます。
しっかし、今回使用のフィルタの、サンプリング周波数は、大体15.48KHzです。
そうすると、filterのエリアス内に入る、不要信号は、
目的信号とは、 Fs/2=7.74KHz位の周波数差が、ありますので
これは、455KHzの中間周波数のフィルタで、ある程度、除去可能です。(例えば村田製作所のセラフィルのHシリーズ -6dB=6KHz)
(あんまし、強力な不要信号では、とても、無理ですが...)
目的信号のエリアスも、Fsから考えて、可聴周波数内に、あります。
これは、外部フィルタで、カットすると、言うことで、あかんやろか?
エリアス対策用のフィルタを、R8C/15マイコンに、計算させるのは、サンプリング周波数の制約から、無理だからです。
3.まだ、課題が残っている
先ほどの説明は、目的信号より、周波数的に高い、周波数の不要信号に適します。
実は、中間周波数から、Fs/4に周波数変換する時に、
目的信号より、下側に不要信号がある時、この不要信号は、周波数ゼロの所で折り返されて
完全に、目的信号に、折り重なる時が、あります、頭痛いわ。
これは、以下のように、解決します。
(他にも、目的信号のエリアスあります、記入漏れあり。)
先ほどのフィルタと、同じ特性の、Fs/4を境に、全く対称なフィルタを作ります。
以下の処理は、先ほどのフィルタの所で、説明したのと、同じです。
何?、サイドバンドが逆になる?
仰るとおりです。
これは、455KHzからFs/4に、周波数変換時に、局発をずらすことにしては、如何でしょう、汗、汗...
不完全では、ありますが、何とか、凌いでいると、思います、大汗.....
[ベースバンドへ落とす時に、ずらさなあかんので、この手は、失敗や....]
4.実装は、簡単です。
以前作った、SSB発生器のプログラムが、ほとんど、そのまま使えます。
タイマーCの割り込みの所の、少しの変更だけです。
前提: 455KHzから、Fs/4への周波数変換、及び、フィルタ操作は、外部回路で実施済み
#pragma interrupt comp1_int (vect=16)
void comp1_int(void)
{
while(adst==1);
data_ad =(ad & 0x03ff) - 0x202;
data[159-i] = data[79-i] =
data_ad; //変調しないで、そのまま、配列に入れる
total=rmpa_w(0, 80, fir, data+79-i); //下側のフィルタに掛ける
total=total>>14;
if( (i%4==2) || (i%4==3))total=-total;
//ベースバンドに周波数変換する。 Fs/4の局発
tm0=(int)(total+ 0x202); //13 cycles
if (++i==80)i=0;
adst=1;
}
念のため、プログラム全体を、ここに、置いておきます。
5. firフィルタを、切り替えるには
単に、firフィルタの係数を、入れ替えればよい、のですが
フィルタの係数を、一々、入れ替えるのは、面倒ですよね。
それで、
予め、firフィルターを、2,3作っておいて (例えば fir1[80],fir2[80])
ある入力ポートの状態(0 or 1)によって、
firの係数の配列の、先頭だけを、ポインタを使って切り替えて、やればよいのです。
int* fir_skelton; ポインタを宣言しておく
int fir1[80]
int fir2[80]
これの操作は、メイン関数のところで
void main(void)
{
.....................
fir_skelton=fir1; //fir_skeltonで、fir, fir2を切り替える (ポインタを使うと、速い)
while(1) //ここで、入力ポートの状態によって、帯域を切り替える
{
if( p3_3==p_former);
//入力ポートの状態が、切り替わったか、どうか?
else
{
if (p3_3)
fir_skelton=fir2;
else
fir_skelton=fir1;
p_former=p3_3;
}
}
}
そして、割り込みの所では
void comp1_int(void)
{
while(adst==1);
data_ad =(ad & 0x03ff) - 0x202;
if( (i/2)%2 ) data_ad =-data_ad;
data[159-i] = data[79-i] = data_ad;
total=rmpa_w(0, 80, fir_skelton, data+79-i);
//fir_skeltonによって、帯域を切り替える
total=total>>14;
tm0=(int)(total+ 0x202); //13 cycles
if (++i==80)i=0;
adst=1;
}
送信の途中でも、スイッチの切り替えひとつで、帯域を切り替えることができます。
H.17.9.6