panda's tech note

Advent Calendar 2020: ソフトウェア無線

注意LimeSDR などのソフトウェア無線は技術基準適合証明(通称,技適)を受けていないため,これらの機器を日本国内で無線機として利用することは電波法により禁じられています。無線機として使用するためには,実験試験局免許を取得するか電波暗室・シールドボックスなどの設備を使用する必要があります。または,アンテナの代わりにケーブルとアッテネータを用い有線接続をし電波を発しないようにすることで,無線通信ではなく有線通信とはなりますが実験することができます(この場合も電波が漏れないように注意してください)。このページを参照される方は,実験される国や地域の法令などを遵守するようにご注意ください。また,実験等はご自身の責任でお願いします。

Day 12: オリジナルプロトコルの実装 (2)

今日はオリジナルプロトコルの物理層の部分を実装します。物理層のフレームは 10日目 に扱った通り,以下のようになります。

+------------+------------+-------------+------------+------------+-----------+
| Preamble   | Preamble   | Modulation/ | Reserved   | Length     | CRC16     |
| (SYNC)     | (SFD)      | Code rate   |            |            |           |
+------------+------------+-------------+------------+------------+-----------+
 128 symbols  16 symbols   8 bits        8 bits       16 bits      16 bits

上記の物理層のヘッダは BPSK により変調するため,BPSK の変調関数を実装します。

"""
Modulate
"""
def modulate_bpsk(data):
    return np.exp( 1j * math.pi * np.array(data, np.complex64) ).astype(np.complex64)

引数には bitstring.BitArray 型の変調するビット列 data を指定します。返り値は NumPy 形式の配列で SDR で送信するサンプル列となります。BPSK による変調なので,ビット 0 に対しては \( e^0 = 1\),ビット 0 に対しては \( e^i = -1 \) となります。ただし,正確には,指数関数の計算誤差のため \( e^i \) は \( -1 \) にはならず,少しずれた値となります。

次に,上記物理層のヘッダで使うビット列を bitstring.BitArray 型で以下のように定義します。

PREAMBLE = bitstring.BitArray(hex='aa') * 16
SFD = bitstring.BitArray(hex='2bd4')
MODULATION_BPSK = bitstring.BitArray(hex='01')
BYTE_ZERO = bitstring.BitArray(hex='00')

PREAMBLE および SFD はプリアンブルの同期を取るための 10 が交互に現れるビットパターンとフレームの開始位置を表すビットパターンを定義しています。 MODULATION_BPSK はこのヘッダの後ろに続くフレームの変調方式・符号を定義します。今回は物理層と同じBPSKによる変調を 0x01 としています。BYTE_ZERO は予約領域などで使うための 0x00 の1バイトを定義しています。

つまり,このヘッダに続くデータ長(シンボル数)を length とすると,チェックサム付きの物理層のヘッダ phy は以下のように計算することができるため,これを modulate_bpsk() 関数により変調して,build_phy() 関数として定義します。

"""
Build phy header
"""
def build_phy(length):
    # Physical layer
    hdr = MODULATION_BPSK + BYTE_ZERO + bitstring.BitArray(int=length, length=16)
    # CRC-16
    cksum = crc16_checksum(hdr.bytes)
    phy = PREAMBLE + SFD + hdr + bitstring.BitArray(bytes=cksum, length=16)
    # Modulate
    return modulate_bpsk(phy)

今日のまとめと明日の予定

今日はBPSKによる変調関数と物理層のヘッダ構築を実装しました。明日はデータリンク層の実装を行います。