WSPRコードの生成はPCのソフトで行いますが、PCをつかわず送信機単体か外部コントローラーのPIC内で生成できないものか模索中です。
幸いなことにWSPRのソースコードは公開されておりユーザーマニュアルにWSPRコード生成の概要が記されていますが、ソースコードやマニュアルを見ても拘束長?畳み込み?などなど素人の自分には最初なんのこっちゃわかりませんでした。
ネットで手がかりを探った結果、G4JNT Andy Talbot氏のサイトにWSPRコーディングに関する具体的な手順の解説を見つけました。あと、前方誤り訂正(Forward Error Correction ; FEC)も少し勉強してようやくつかんできました。
備忘録としてソースコードを読んで解説を訳しながらまとめてみることにします。
1.送出キャラクタの圧縮
基本様式は、コールサイン(原則6文字)、グリッドローケータ(4文字)、送出電力(2文字)の計12文字(=12バイト=96ビット)ですが、これらをまとめて50ビットに圧縮します。
1)コールサイン部の数値化
①文字の種類と対応する番号
数字、アルファベット、スペース記号を0から36の数値に割り当てます。
i)数字(0~9)⇒ 0~9
ii)アルファベット(A~Z) ⇒ 10~35
iii)スペース記号 ⇒ 36
②注意点
コールサインの1文字目はスペースを含め全キャラクタ使用可能
コールサインの2文字目はスペース記号のみ使用不可
コールサインの3文字目は数字以外使用不可
サフィックス(4~6文字目)はいずれも数字は使用不可
③ユニーク数
37 x 36 x 10 x 27 x 27 x 27 = 262177560 < 268435456 = 2^28 = 28ビット
④各数値化キャラクタをCh1~Ch6とすると、数値化コールサインNは、
N = ((((Ch1 x 36 + Ch2) x 10 + Ch3) x 27 + (Ch4 - 10)) x 27 + (Ch5 - 10)) x 27 + (Ch6 - 10)
2)グリッドローケータ部と送出電力部の数値化
①文字の種類と対応する番号
i)数字(0~9)⇒ 0~9
ii)アルファベット(A~R) ⇒ 0~17
②グリッドローケータ部の数値化
ユニーク数は、
AA00~RR99 ⇒ 18 x 18 x 10 x 10 = 32400通り < 32768 = 2^15 = 15ビット
各数値化キャラクタをLoc1~Loc4とすると、数値化グリッドローケータM1は、
M1 = (179 - (Loc1 x 10 + Loc3)) x 180 + Loc2 x 10 + Loc4
(余談:素直にM1 = (((Loc1 x 18) + Loc2) x 18 + Loc3) x 10 +Loc4にしなかったのはなぜなのでしょう?^^;)
③送出電力部と数値化グリッドローケータ部の組み合わせ
電力値Pwr(dBm) = 0~60 (ただし、一桁目が0,3,7のみソフトで認識されます)
数値化グリッドローケータと電力部の組み合わせ値Mは、
M = M1 x 128 + Pwr + 64
で、最大値が4124287 < 4194304 = 2^22 = 22ビット となります。
(余談:最後の「+ 64」は、拡張用の予備部分なのかもしれませんが未確認)
これで数値化コールサイン部と数値化グリッドローケータ・電力部で
N28ビット + M22ビット = 50ビット
に圧縮されました。
2.1バイト値1元配列化
後の前方誤り訂正処理(FEC)を行うため、圧縮した50ビットを1バイト値の1元配列として割り当てます。 FECに入力するデータの大きさは拘束長32、レート1/2から50 + 32 - 1 = 81ビットになります。したがって11バイト = 88ビットの器が必要になります。
その器に上から数値化コールサインNと数値化グリッドローケータ・電力Mを隙間無く入れ、残りの器(7番目の3ビット目以降)はすべて0とします。
3.FECエンコード
32ビット長のシフトレジスタを2つ用意して、データの最初のバイトのMSBから1ビットとりだして、各々のシフトレジスタを右に1シフトさせてからLSBに格納します。そして、一つ目のシフトレジスタと0xF2D05351とのANDをとり、ビット間のXORをとった結果を別のレジスタに格納。もうひとつのシフトレジスタと0xE4613C47とのANDをとって同様にビット間のXORをとった結果をレジスタに格納。この操作を81回繰り返すことによって162ビットのコードが生成されます。
4.インターリーブ
無線による信号伝送においてランダムエラーとバーストエラーに対してFECはランダムエラーには強いが、バーストエラーにはあまり強くないのでインターリーブを施します。
ビットの並びをある法則によってシャッフルして隣同士のビットを離すことによりバーストエラーに対抗する手法です。
WSPRの場合は、
まず符号なし8ビット整数0から255まで順番にビット並びを反転します。
たとえば、"1"なら、b00000001 ⇒ b10000000 = "128"
"18"なら、b00010010 ⇒ b01001000 = "72"
ビット並びを反転した整数が162未満の場合、その整数の番号の位置にFEC処理したコードを順番に1対1で割り当てていきます。
これをコード数である162回繰り返します。
これで162ビットのデータシンボルが生成完了です。
5.同期シンボルとの連結
最後にあらかじめ求められた擬似ランダム同期シンボルとデータシンボルを連結して1シンボル2ビット(4階調)の最終送出データが完成します。
【162ビット同期シンボル】
1 1 0 0 0 0 0 0 1 0 0 0 1 1 1 0 0 0 1 0 0 1 0 1 1 1 1 0 0 0
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 0 1 1 0 0 1 1 0 1 0 0 0 1
1 0 1 0 0 0 0 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0 1 0 1 1 0 0 0 1
1 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 1 1 0 1 1 0 0 1 1
0 1 0 0 0 1 1 1 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 1 1 0
1 0 1 1 0 0 0 1 1 0 0 0
最終送出データシンボル(n) = 同期シンボル(n) + データシンボル(n) x 2
間違っているところがあるかもしれないので逐一修正しますが、この手順をCでコーディングしてみようと考えています。