手習ひデジタル信号処理(113) Scilab、クロックリカバリ?ASK信号を復調

Joseph Halfmoon

信号処理素人の老人が勝手に自前関数など作っているのは他でもありません、手元のScilabにインストールしたツールボックスcomm_tbxが思うように動作してくれない、というその一点のため。個別に追及していくと何とか動いたりもするので初期設定の何かがオカシイ?しかしま、拙い自前関数を作ることも手習ひであると。ホントか?

※「手習ひデジタル信号処理」投稿順 Indexはこちら

※Windows11上で、Scilab6.1.1およびScilab上のツールボックス Scilab Communication Toolbox 0.3.1(以下comm_tbx)を使用させていただいとります。

comm_tbxのclock_rec_process

今回「うごかん」関数はクロックリカバリの部の中心関数と思われる clock_rec_process関数です。サンプルプログラム例通りに一連の入力をしていった中でもほれこのようにエラーがでます。clockRecProcessERROR

あれあれ、frac_delay()関数とclock_rec_process()関数の両方で何か「補間」でもするらしい関数がundefinedでコケてますなあ。多分、この関数の在処を探し出し、無理やり動作するように環境を整えてやれば今回もまた動きそうな雰囲気はあり。でもまあ、今回も見送り。もっと素朴な方法の自前関数で「クロックリカバリ」的な処理を行ってみようと思います。

被テスト信号波形

前回、自前関数のごたごたFixの中、ようやく生成できるようになった被テスト信号波形の生成手順が以下に。元は、サンプリング周波数Fs=500kHz、キャリア周波数Fc=38kHz(赤外線リモコンのサブキャリア周波数のイメージ)、シンボル周波数Fsym=2kHzのASK波形です。その振幅を3角波を乗じて「減衰」させたうえで、自前関数を使って包絡線検波して、2値化したものが今回の入力です。詳しくは前回ご参照くだされ。

Fs=500e3;
Fc=38e3;
Fsym=2e3;
Flev=10;
m=1;
b=prbs(100);
askwave100=genASK(Fs, Fc, Fsym, m, b);
[t0, TW0]=genTriangular(Fs, length(askwave100), Flev, 180, 1);
twave = askwave100.*TW0';
te=detectEnvelop(Fs, Fc/4, twave);
tb=makeBIN(Fs, Fsym, 0.1, 0.2, te);
拙く素朴な自前関数で「クロック再生」して0/1のビット列まで復調

今回作成の自前関数は、上記の処理にて既に包絡線検波して結果を2値化した波形を入力にとります。すでに0なのか1なのかは分かっておる、と。しかし、信号のタイミング(クロック)は不明なためにどこで0/1サンプリングしたらよいのかは不明。という感じっす。そこで以下のようにしてみました。

    1. 入力した2値信号の変化点をとらえて「0と1の変わり目」と認識してカウンタを初期化
    2. そこからカウントを進め規定のシンボルレートから計算した「真ん中辺」で信号をサンプリングして0か1を確定
    3. 0や1が続く場合は、進行するカウンタ値からもとめた「シンボル」の真ん中辺で次々確定していく
    4. 0と1の変化点が到来したらその度にカウンタを初期化して0から再開

まあね、本格的にやるならもっとVCO的な要素を含むPLL的ロジックで到来する入力信号のクロックをリカバリして追従するべきなのだろうけれども。自前なので素朴な「フェーズあわせ。」お楽が良いのよ。

自前関数のソースが以下に。

// demodulation BIN wave
// Fs: Sampling frequency [Hz]
// Fsym  Symbol rate [Hz]
// w: input BIN wave
// abit: output binary sequence
function abit=demodBINw(Fs, Fsym, w)
    itvl=int(Fs/Fsym);
    itvlHalf=int(itvl/2);
    nSym=length(w);
    counter = 1;
    nCnt = 1;
    abit=[];
    samplingflag = %t;
    for n=1:nSym-1
        counter = counter + 1
        if w(n) <> w(n+1) then
            counter = 1
        end
        if samplingflag then
            if modulo(counter, itvl) > itvlHalf then
                disp(nCnt)
                abit(nCnt)=w(n);
                nCnt = nCnt + 1;
                samplingflag = %f;
            end
        else
            if modulo(counter, itvl) == 1 then
                samplingflag = %t;
            end
        end 
    end
endfunction
被テスト波形に適用してみる

上記自前関数を被テスト波形に適用し、グラフ化するシーケンスが以下に。

b2=demodBINw(Fs, Fsym, tb);
clf();
subplot(3,1,1); plot_binary(b); title('original');
subplot(3,1,2); plot(twave); title('modulated');
subplot(3,1,3); plot_binary(b2); title('demodulated');

描いたグラフは以下です。一番上のoriginalが元の疑似乱数系列。真ん中は、上記の疑似乱数系列で変調した38kHz搬送波のASK波形の振幅を三角波で減衰させたもの(包絡線検波前の波形。)ただしx軸方向は疑似乱数系列とズレているので、ちょっと短めっす。3番目のdemodulatedが、今回の自前関数処理までの処理を通しで行ったもの。demodulatedSignal

三角の先っぽの振幅がスレッショルドより小さいところを除き、元に戻っているようです。大丈夫か、そんなんで。

手習ひデジタル信号処理(112) Scilab、自前関数の更新、2件 へ戻る

手習ひデジタル信号処理(114) Scilab、自前ASK変調関数でBPSK変調? へ進む