· 

ASK変調のスペクトル(2)

まずは、「ASK変調のスペクトル(1)」の通りにnumpyで計算してみます。nは1から7までです。

import matplotlib.pyplot as plt
import numpy as np

# よく使う変数
pi=np.pi

def generate_element(n,omega_B,t,t_0B):
    rval=(np.sin((2*n-1)*omega_B*(t+t_0B)))/(2*n-1)
    return rval

def generate_baseband(f_baseband,t_start,t_stop,t_step):
    omega_B=2*pi*f_baseband
    # 計算する範囲と刻みで計算ポイントを作る
    t=np.arange(t_start,t_stop,t_step)
    f1_t=generate_element(1,omega_B,t,0)
    f2_t=generate_element(2,omega_B,t,0)
    f3_t=generate_element(3,omega_B,t,0)
    f4_t=generate_element(4,omega_B,t,0)
    f5_t=generate_element(5,omega_B,t,0)
    f6_t=generate_element(6,omega_B,t,0)
    f7_t=generate_element(7,omega_B,t,0)
    f_t=2/pi*(f1_t+f2_t+f3_t+f4_t+f5_t+f6_t+f7_t)+0.5
    return t,f_t

def generate_Tx(f_carrier,f_baseband,t_start,t_stop,t_step):
    omega_c=2*pi*f_carrier
    t,f_t=generate_baseband(f_baseband,t_start,t_stop,t_step)
    amp_t=np.sin(omega_c*t)*f_t
    return t,f_t,amp_t

def main():
    f_carrier=433.92e6
    f_baseband=1e6
    t_start=0
    t_stop=10e-6
    t_step=1e-10
    t,f_t,amp_t=generate_Tx(f_carrier,f_baseband,t_start,t_stop,t_step)
    number_of_samples=t.size
    # fftする
    amp_f=np.fft.fft(amp_t)/(number_of_samples/2)
    amp_f=np.abs(amp_f)
    #amp_f=20*np.log10(np.abs(amp_f)) #1Vrmsを0dBとしてdB表示(になっているんじゃないかと思う)
    freq=np.fft.fftfreq(number_of_samples,t_step)

    # プロット
    fig=plt.figure()
    fig.add_subplot(3,1,1)
    plt.plot(t,f_t)
    fig.add_subplot(3,1,2)
    plt.plot(t,amp_t)
    fig.add_subplot(3,1,3)
    plt.plot(freq[0:int(number_of_samples/2)],amp_f[0:int(number_of_samples/2)])
    plt.xlim(f_carrier-10e6,f_carrier+10e6)
    plt.show()

main()

その結果は

フーリエ級数で生成した矩形波がいい味出してます(自己満足)。

よくわからんけど、振幅はVpと一致した値で出ているようです。

中心から周波数が高い方に離れていくと(下に向かっても当然同じ)ピークは

1/2=0.5 , 1/π=0.318 , 1/(3π)=0.106 , 1/(5π)=0.064 , ...

ってなっていると思います。「ASK変調のスペクトル(1)」の式の各周波数の振幅と同じになっています。たぶん。

次は、ふつうにやってみる。

import matplotlib.pyplot as plt
import numpy as np

# よく使う変数
pi=np.pi
deg2rad=pi/180.0
twopi=2*pi

# シンボル列を引き延ばす
def extend_symbol_to_simulation_sampling_rate(symbols,t_symbol,t_simulation_sampling):
    # シンボル数
    size_of_symbols=symbols.size
    # 最後のシンボルが終わる時間
    end_time=size_of_symbols*t_symbol
    # 計算タイミング
    t=np.arange(0,end_time,t_simulation_sampling)
    # 各シンボルの開始(終了)時間
    t_periods_of_symbols=np.append(0,np.arange(1,size_of_symbols,1)*t_symbol)
    # 結果データ領域確保
    ex_symbols=np.zeros_like(t)
    # 先頭データは入れておく
    ex_symbols[0]=symbols[0]
    # 各シンボルについて、その期間のインデックスを取得し、データを入れ込む
    for i in range(0,size_of_symbols):
        ex_symbols[np.where(t>t_periods_of_symbols[i])]=symbols[i]
    return ex_symbols,end_time
        
def generate_ask(f_carrier,f_sym,f_samp_generation,phase_carrier_initial,symbols_in_base):
    t_sym=1/f_sym
    t_samp_generation=1/f_samp_generation
    omega_carrier=twopi*f_carrier
    # シンボルを計算用に拡張
    [symbols,t_end]=extend_symbol_to_simulation_sampling_rate(symbols_in_base,t_sym,t_samp_generation)
    # 計算するタイミング
    t=np.arange(0,t_end,t_samp_generation)
    # 波形生成
    amp_t=np.exp(1j*omega_carrier*t+phase_carrier_initial)*symbols
    return t,symbols,amp_t

def main():
    # 設定
    f_carrier=433.92e6            # 搬送波周波数 in Hz
    f_sym=2e6                 # シンボルレート in Hz
    f_samp_generation=1e10     # 計算のサンプリングレート in Hz
    t_samp_generation=1/f_samp_generation
    phase_initial=0*deg2rad  # 搬送波の初期位相(何でもいい) in rad
    symbols_in_base=np.array([1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0])
    t,baseband_t,amp_t=generate_ask(f_carrier,f_sym,f_samp_generation,phase_initial,symbols_in_base)
    #今回の計算は実部だけでやったので
    amp_t=np.real(amp_t)

    number_of_samples=t.size
    # fftする
    amp_f=np.fft.fft(amp_t)/(number_of_samples/2)
    amp_f=np.abs(amp_f)
    freq=np.fft.fftfreq(number_of_samples,t_samp_generation)

    # プロット
    fig=plt.figure()
    fig.add_subplot(3,1,1)
    plt.plot(t,baseband_t)
    fig.add_subplot(3,1,2)
    plt.plot(t,amp_t)
    fig.add_subplot(3,1,3)
    plt.plot(freq[0:int(number_of_samples/2)],amp_f[0:int(number_of_samples/2)])
    plt.xlim(f_carrier-10e6,f_carrier+10e6)
    plt.show()

    amp_f=20*np.log10(amp_f)
    fig=plt.figure()
    plt.plot(freq[0:int(number_of_samples/2)],amp_f[0:int(number_of_samples/2)])
    plt.xlim(f_carrier-10e6,f_carrier+10e6)
    plt.ylim(-50,0)
    plt.show()

main()

普通にやっても同じ結果です。、、、いや、そうでしょ。

dB表示がこちら。1Vpが0dBになってるんだと思う。計算では中心から高周波側に向けて(低周波側に向かっても同じ)、

-6.021dB, -9.943dB, -19.485dB, -23.922dB

ってなっているはずで、大体そうなっている。

ピークの振幅まで議論した文書はあまり見ないので、なんとなくいいことした気がする。まぁ、式の通りなんだけど。実は以前にも似たような記事を書いたけど、ちょろっと触れただけだった。

あ、単位が電圧(VpやらdBVpやら)なので、気を付けてください。スペアナで測定する50Ω終端の電力(dBm)ではない。

今年も残りわずかです。今年のうちにもうちょっと頑張りたい。来年は体がもたない気がする。