SRLLによるパケット通信

作成:2003年8月18日
更新:2005年8月17日
このページに関するお問い合わせは,cute@lss.mes.titech.ac.jp

Contents
1. SRLLを手軽に楽しむために
2. SRLL構成
3. 物理層
4. データリンク層
5. サンプルサウンド
6. 受信データの解析
7. 受信状況
8. ベリカードについて
受信報告 [現在12局が受信成功!]
緑字は,JI1IZR眞田さん作成SRLL-AVR-TNCキットでの受信局です.
2003/9/13
JA1GDE
2004/11/16
JA0AQZ
2003/9/15
JH1TVN
2004/11/27
JA6APJ
2003/10/11
JH4XSY
2004/11/27
JH6DXK
2003/10/20
JA6PL
2004/12/13
JH3BUM
2003/11/04
JH0JMA
2005/7/9
JE1FQV
2003/11/08
JH4DHX
2004/4/4
JI1IZR

SRLL関連リンク集
JA6PL井地さんのSRLL受信用TNC製作記
http://www1.bbiq.jp/ja6pl/cubesat02.html

JH1TVN渕山さんのSRLL資料室
http://www.yk.rim.or.jp/~tvn/memo/srll.html

JI1IZR眞田さんの衛星通信に関する技術情報
http://ji1izr.atnifty.com/

JH4XSY岩本さんのアマチュア衛星通信の世界(CUTE-Iを受信する)
http://www.asahi-net.or.jp/~sx7h-iwmt/jh4xsy/sat.html#P3-3

1. SRLLを手軽に楽しむために

  CUTE-Iの通信プロトコルは,Table 1.1のように構成されています.

 物理層には,Bell202規格に準拠したFSK変調,430MHz帯アマチュアバンドを利用したFM変調を行っています.
 データリンク層としては,アマチュア無線のパケット通信で一般的に利用されているAX.25又は,東京工業大学・無線研究部によるオリジナルプロトコルであるSRLLのどちらかを使用します.
 アプリケーション層には,CUTE-Iの各種テレメトリを載せています.

Table 1.1
アプリケーション層
CUTE-I テレメトリ情報
データリンク層
SRLL 又は AX.25
物理層
Bell202副搬送波変調 ,FM437.47MHz

 SRLLは,東京工業大学・無線研究部(JA1YAD)の,船田悟史氏により開発されました.
PRUG96プロジェクトの成果を踏まえて,AX.25における様々な問題点を改良し,誤り率が高い無線通信に最適化された通信プロトコルです.
 しかし,AX.25とはプロトコルが異なるため,一般に発売されているTNCでデコードすることができません.

 CUTE-I管制局では,Figure 1.1に載せました,オリジナルTNCを使用してSRLLのデコードを行っております.
 このページでは,このTNCのごく基本的な機能だけを取り出した,より簡単なTNCを手作りする方法をご紹介したいと思います.このページでは,秋月電子通商で購入可能なAki-H8を利用していますが,プログラムを対応するように書き換えていただければ,H8以外のマイコンでも作成可能です.(JI1IZR眞田さんからは,AVRマイコンを使用したTNCを製作していただき,受信報告を頂きました.)
 なお,SRLLに関する詳細は,次のページをご覧下さい.http://musenken.net/funada/yadtnc/

SRLLはアマチュアの技術です.
金銭上の利益を伴う場合を除き,自由に利用し,改良することを歓迎いたします.
また,より良いプロトコルを目指して,みなさんでいろいろ議論することができるよう務めて参ります.

This module is using the technology of the PRUG96 Project of PRUG.
Copyright (c) 1998 by Shin-ichi KANNO. All rights reserved.


Figure 1.1
設計:東工大無線研(JA1YAD) 船田悟史,大中邦彦

 


2. SRLL構成

 CUTE-IのSRLLは,以下の内容で構成されています.

スタートフラグ(4byte) 0xab,0x31,0x4c,0xe5
SRLLデータ テレメトリデータ 32byte
CRC 2 byte

 スタートフラグは,上記の4バイトを各バイトの下位ビットから順次送信しています.NRZI変換などは行っていませんので,FSKを復調したビット列からそのまま吸い出すことが可能です.
 SRLLは固定長なので,スタートフラグを検出したあとの,34バイトを連続して受信することで,1フレームを取得することができます.SRLLデータの34バイトについては,インターリーブを行い,本来のデータがバラバラになっていますので,必ず34バイト受信する必要があります.

 スタートフラグは4byteですが,その前に80byteの同期信号(0x55)を送信しています.実際の受信では,この信号を取りながら,クロックの同期を取ることができます.


3.  物理層

 3-1. 必要な素子類

 FMについては,お手持ちの無線機で復調してください.FSKの復調には,Bell202に準拠したモデムチップが必要となります.例えば,以下のような製品があります.
 管制局で使用しているモデムチップはTCM3105ですが,今回はMX-614を使用して製作します.

TEXAS INSTRUMENTS TCM3105
MX-COM MX614
ConsumerMicrocicuits FX614
沖電気 MSM6947

 

 データリンク層の処理には,Aki-H8 ( H8/3048F )を使用します.秋月電子通商で購入できるAki-H8マザーボードキットがあると便利です.
 今回は, マザーボード上の空きスペースを利用して,モデムチップを配置しました.素子をはんだ付けし,電源を確保し,無線機の外部スピーカ端子から音声信号を取り出せるようにします.


Figure 3.1
今回作成するSRLL対応TNC ( Aki-H8使用 )

 

 3-2. 配線例-1 (MX614, FX614)

 モデムチップは,FSKを復調することが目的ですので,無線機の外部スピーカー端子と,モデムチップのAF-IN(モデムチップによって,RXAなどと表記が変わります.)を接続し,RXDをマイコン(今回はH8)の入力ポートに接続します.

 サンプルプログラムでは, PORT5をLED出力,PORT4をデータ入出力に使用しています.Aki-H8では,PORT5にLEDが接続されていますので,PORT4のみ配線する必要があります.
 PORT4は,以下のように配線します.

7
6
5
4
3
2
1
0
PORT4 NC NC NC NC

RXDに接続

TXDに接続 M1に接続 M0に接続

 必ず配線する必要があるのは,BIT3のみです.
 M1,M0は,MX614互換チップで使用します.M1 = 1,M0 = 0とすると受信モードとなります.はじめから受信のみに限定して使用するのであれば,モデムチップのM1 にVDD,M0にGNDを接続します.この場合,TXDも接続の必要はありません.

 PORT5の動作は,デフォルトプログラムではデコード検知でハイレベルとなるLED用端子です.Aki-H8マザーボードをご利用の方は,すでにLEDが接続されておりますので,配線不要です.

7
6
5
4
3
2
1
0
PORT5 NC NC NC NC

NC

NC スタートフラグ検知で点灯 0x55検知で点灯

 

 3-3. 配線例-2 (TCM3105)

 サンプルプログラムでは, PORT5をLED出力,PORT4をデータ入出力に使用しています.Aki-H8では,PORT5にLEDが接続されていますので,PORT4のみ配線する必要があります.
 PORT4は,以下のように配線します.

7
6
5
4
3
2
1
0
PORT4 NC NC NC NC

RXDに接続

TXDに接続 NC NC

 受信のみであれば,TXDの接続との接続は不要となります.
 サンプルプログラムでは,PORT5も使用しております.これはLED点灯用の端子ですので,3-2.と共通となります.

 配線例を,Figure 3.2に示します(png形式,13kB).この写真,及び配線図は,アマチュア無線家のJH1TVNさんに提供していただきました.ありがとうございます.

Figure 3.2
作成 :JH1TVNさん
配線図はこちら

 

 3-4. 配線例-3 (MSM6947)

 MSM6947は5V,12Vの2電源を必要とします.チャージポンプICを利用するのもひとつの手ですし,Aki-H8はマザーボードに12Vを使用しますので,これを利用することもできます.

 PORT4は,以下のように配線します.

7
6
5
4
3
2
1
0
PORT4 NC NC NC NC

RXDに接続

TXDに接続 NC NC

 受信のみであれば,TXDの接続との接続は不要となります.
 サンプルプログラムでは,PORT5も使用しております.これはLED点灯用の端子ですので,3-2.と共通となります.

 配線例を,Figure 3.3に示します(png形式,12kB).この写真,及び配線図は,アマチュア無線家のJH1TVNさんに提供していただきました.ありがとうございます.

Figure 3.3
作成 :JH1TVNさん
配線図はこちら

 

 3-5. PCとの接続

 デコードされた信号は,シリアル通信でPCに転送されます.シリアル通信の形式は,プログラムにより柔軟に設定できます.以下で説明するプログラムでは,

7
6
5
4
3
2
1
0
SMR1

0

0
0
0

0

0
0
0
調歩同期式
8bit
ノンパリティ
1ストップビット
クロックセレクト

のように設定されています.
 ボーレートは,BRR1 = 51ですので,上記の設定では9,600bpsです.通信速度の変更は,この数字を変更することで可能となります.主な通信速度は,以下の通りです.

PCとの通信速度
BRR1
2400
207
4800
103
9600
51
38400
12

 

void sci1_init(void)
{
     int k;
     SCR1 = 0x00;
     SMR1 = 0x00;
     BRR1 = 51;

     for(k= 0; k<0xffff; k++);

     SCR1 = 0x30;
     SSR1 &=0x80;
     return;
}

 


4. データリンク層

 4-1. Aki-H8について

 今回は,データリンク層の処理にH8マイコンを使用します.モデムチップのRXD端子から出される信号を,入力ポートより取り込みます.
 H8については,秋月電子通商のAki-H8キットを使用すると便利です.今回はAki-H8 ( 3048F )を使用していますが,基本的にはこれ以外でも動作するはずです.

 4-2. gccによるコンパイル

 TNCのソフトウェアは,C言語で開発しました.ここでは,gcc(GNU C Compiler)を利用したコンパイル方法について簡単に説明します.詳しい説明は,こちらがわかりやすいかと思いますので,参考にしてみてください.
http://strawberry-linux.com/h8/

 gccは,UNIXのソフトウェアですので,Windowsを使用している方は,cygwinをインストールする必要があります.今回作成するTNCも,Windows + cygwinで開発しました.
 cygwinがインストールできましたら,上記サイトより,
  ・binutils-2.11.2.tar.gz (9,702KB)
  ・gcc-2.95.3.tar.gz (12,609KB)
  ・newlib-1.9.0.tar.gz (3,288KB)
 をダウンロードして,インストールしてください. これで開発環境が整います.

 ついでに,H8への書き込みソフトである,h8writeもダウンロードすると便利です.このソフトは,Windows上で動作し,関連付けを行うことにより,ダブルクリックでH8への書き込みが行えます.

 なお,コンパイル済みの書き込みファイル(モトローラS形式)も用意しましたので,ご利用ください.
 このファイルをダウンロードすれば,H8へ書き込みをするだけで動作します.

受信TNCソースファイル一式 ver.1.0 srll_rx.lzh
コンパイル済み・書き込みファイル ver.1.0 srll_rx.mot
2003.9.14 version 1.0 として公開しました.
  PCとの通信速度は9600bpsです.

H8 SRLL Communicator ver.0.99 h8srllcomm-0.99.zip
2004.3.21 送信,受信が可能です.テスト版です.
  PCとの通信速度は9600bpsです.

 ソースファイル一式をダウンロードしたら,作業フォルダを作成し,すべてのファイルを解凍してください.
 次に,cygwinのプロンプトで,srll_rx.c および prug96_encode.cをコンパイルします.2つのファイルより構成されますので,まずはオブジェクトのみ作成します.

 $ h8300-hms-gcc -mh -mint32 -nostdlib srll_rx.c -c
 $ h8300-hms-gcc -mh -mint32 -nostdlib prug96_encode.c -c 

 これらのコマンドを実行した後に,何も表示がなければ,コンパイルは成功です.次に,作成された2つのオブジェクトファイルをリンクします.

 $ h8300-hms-gcc -mh -mint32 -nostdlib srll_rx.o prug96_encode.o -lc -lgcc -T 3048.lds 3048crt0.S

 これで,作業フォルダにa.outというファイルができあがります.これはCOFF形式になっていますので,H8で実行できるように,モトローラS形式に変換する必要があります.
 この作業には,オブジェクトコンバータを使用します.以下のコマンドを実行してください.

  $ h8300-hms-objcopy -O srec a.out srll_rx.mot

 作業フォルダに,srll_rx.motというファイルが作成されれば,すべての作業が終了です.あとは,ライタソフトを使って,H8に書き込みを行ってください.

 4-3. プログラム解説

  この節では,先ほどコンパイルしたソースコードについて,簡単に解説します.一部のみ引用していますのでご注意ください.

/*タイマ割り込み処理*/
#pragma interrupt
void int_imia0(void)
{
     cnt++;
     TSR0 &= ~0b001;
}

/*タイマの初期化*/

void timer_init(int i)
{
     TCR0 = 0x23;
     GRA0 = i;
     TSTR = 0;

     return;
}

/*カウンタクリア,タイマスタート*/
void timer_start(void)
{
     TSTR = 0x00;
     TCNT0 = 0x0000;
     TSTR = 0x01;

     return;
}

 プログラムでは,タイマ割り込みを使用します.割り込み処理には,
#pragma interrupt
と記述する必要があります.また,割り込みが発生した場合に実行すべき関数の名前は,リンカスクリプトに記述されます.

 割り込みは,1200bpsの1クロック内で2回発生させています.発生させる割合は,関数
     timer_init(int i)
により指定します.Aki-H8は16MHz動作です.ここでは,これを8分周で動作させているので,0.5usecでカウンタが進んでいきます.カウンタが1666となったとき,スタートからおよそ1/1200秒となります.今回は,2回の割り込みを発生させるので,カウンタが833となったときに動作を停止させます.
 この機能は,ITUのコンペアマッチを使って実現できます.

 割り込みが発生すると,グローバル変数であるcntがインクリメントされます.

/*0x5555を検出*/
while(r != 0x5555)
{
     if(cnt > 1)
     {
          if((P4DR & 0x08) == 0)
              r = (r>>1) & 0x7fff;
          else
               r = (r>>1) | 0x8000;

          cnt = 0;
     }
}

 割り込みが発生し,cntが2になると実行されます.P4の下位4ビット目(RXD)を読み,2byteの変数rに格納していきます.下位ビットから送信されるので,最上位ビットに代入して,1ビットづつシフトしていきます.
 この処理で,80バイト連続して送られる同期信号を検出します.

while(receivestate == WAIT)
{
     if(cnt >1)
     {
          syncflag >>= 1;
          if((P4DR & 0x08) == 0)
               syncflag &= 0x7fffffff;
          else
               syncflag |= 0x80000000;

          if( ++j > 700)
          {
               receivestate = WAIT;
               cnt = 0;
               TIER0 = 0;
               break;
          }

          flagtemp = syncflag ^ 0xe54c31ab;
          flagcount = 0;
          for(i = 0;i<32; i++)
          {
               if((flagtemp & 1)== 1)
               flagcount++;

               flagtemp >>= 1;
          }
          if(flagcount < 4)
          {
               cnt = 0;
               receivestate = DETECT;
               break;
          }
          cnt = 0;

     }

     if(bitstate != ((P4DR & 0x08) >> 3) & 0x01)
     {
          if(((cnt==0)&&(TCNT0 > 750)) || ((cnt==1)&&(TCNT0 < 80)) )
          timer_start();

     }
     bitstate = ((P4DR & 0x08) >> 3) & 0x01;
}

 ここでは,スタートフラグを検出します.スタートフラグは0xab,0x31,0x4c,0xe5です.各バイトごとに下位から送られてくるので,long型変数のsyncflagの最上位に代入し,1ビットづつシフトしていきます. 0xe54c31abが得られれば,スタートフラグです.
 ただし,3ビットまでの伝送誤りは許容できるので,1ビットづつ比較してそれが4より小さければ,スタートフラグとみなします.
 またここでは同時にクロックの同期もとっています.同期信号は0x55(01010101)ですので,ビットの変わり目でタイマカウンタが750〜833の間,もしくは0〜80の間であれば,クロックがずれたとみなし,タイマをリセットします.
 スタートフラグを発見できなかった場合,この処理を抜けることができないので,700回( = 80 byte以上)受信してもスタートフラグを検出できない場合は,breakを使って強制的に抜けます.

while(srll_rx_bitpos < 12)
{
    if(cnt == 2)
      {
            temp = ((P4DR & 0x08) >> 3) & 0x01;

          temp = (prug96_ScrBook[((rxdatabit_count>>3)&0x00ff)] >> (rxdatabit_count&0x7)) ^ (temp & 1);
          rxdatabit_count++;

          rawdata[rxcount ] >>= 1;
         if((temp & 1) == 0)
               rawdata[rxcount] &= 0x7fff;
          else
               rawdata[rxcount] |= 0x8000;

          rxcount++;

          if(rxcount >= rxframe_len)
          {
               rxcount = 0;
               srll_rx_bitpos++;
          }

          cnt = 0;
     }
}
TIER0 = 0xF8;
for(i=0; i<34; i++)
{
     upper[i] = (rawdata[i]>>12) & 0x0f;
     lower[i] = (rawdata[i]>>4) &0xff;

     data[i] = prug96ll_DecodeBook[(rawdata[i] >> 4)&0x0fff];
}

 この部分で,SRLLデータの解析を行います.SRLLは固定長ですので,スタートフラグを検出したあとの34バイトを連続して取り込みます.詳しい処理は,http://musenken.net/funada/yadtnc/ をご覧下さい.
 最後に,データ部分(lower[i])と,誤り訂正符号(upper[i])に分離します.ただしこれは,誤り訂正処理を行っていません.誤り訂正を行った後の,より正確なデータは,data[i]に格納されます.

for(i = 0;i<34; i++)
{
      check_u = prug96_EncodeBook[data[i]] ^ upper[i];
      check_l = data[i] ^ lower[i];

     for(j = 0;j<8; j++)
     {
          if((check_l & 1)== 1)
               checkcount++;
          check_l >>= 1;
     }
     for(j = 0;j<4; j++)
     {
          if((check_u & 1)== 1)
              checkcount++;
          check_u >>= 1;
     }
}


 本来,lower[i]およびupper[i]は不要なデータです.伝送誤りが発生していなければ,lower[i]とdata[i]は一致します.ここでは,誤り訂正を行ったあとの,本来送信されたと思われるデータ(data[i])から,再度誤り訂正符号を作成し,受信したままのデータlower[i]およびupper[i]と比較します.
 これにより,伝送誤りが発生したと思われるビット数を数えることができます.これは,checkcountという変数に格納されます.

r = 0xFFFFU;
for (i = 0; i < 32; i++)
{
      r ^= data[i];
     for (j = 0; j < 8; j++)
      {
           if (r & 1)
                  r = (r >> 1) ^ CRCPOLY;
           else
                  r >>= 1;
       }
}
crc = r ^ 0xFFFFU;

data[34] = (unsigned char)((crc & 0xff00)>>8);
data[35] = (unsigned char)(crc & 0x00ff);
data[36] = checkcount;

for(i= 0; i<37; i++)
     sci1_tx(data[i]);

 最後に,受信データの32バイト目までのCRCを計算します.33バイト目,34バイト目は,CUTE-Iが計算したCRCです.これらと比較して,正確に一致していれば,伝送誤りがなかったと判断することができます.ただし,この判断は利用者に任せるとして,ここでは34バイトの連続するデータのあとに,2バイトのCRCを付加することにします.
 37バイト目には,先ほど計算したcheckcountを送信します.
 
 


5. サンプルサウンド

SRLLのサンプルサウンドを用意しました.
写真のようにオーディオ出力をそのまま取り込むことが可能です.
(写真は,H8/3664Fを使用したタイプです.H8/3048Fとの互換性はありませんが,プログラムはほぼ同じです.)

SRLL SAMPLE

PCのスピーカ出力から二分岐させ,TNC,外部スピーカにそれぞれ接続

 


6. 受信データの解析

 PCに取り込まれたデータは,CUTE-I FM Packet Analyzerを用いて解析可能です.ソフトウェアは以下のリンクよりダウンロードしてください.
http://lss.mes.titech.ac.jp/ssp/cubesat/soft/soft.html

 サンプルプログラムでは1パケット受信に対して,37バイトのデータを出力します.これを,シリアルコマンドエクスプローラ2などのターミナルで受信し,ログ保存してください.ここでは,アマチュア無線家のJA1GDEさんにより取得された以下のパケットを参考に解説していきます.

06:09:31 受信→
[00h,83h,E8h,EEh,72h,00h,EFh,EFh,7Fh,2Ah,
F4h,7Eh,7Ah,9Fh,AAh,27h,01h,00h,00h,ADh,
DBh,87h,D9h,4Ah,00h,00h,0Ah,00h,AAh,50h,
02h,33h,01h,FDh,01h,FDh,00h]
データ受信:JA1GDEさん
2003年9月12日

 00よりはじまるデータを,順番にCUTE-I FM Packet Analyzerに入力していきます.32バイトまでがデータですので,ここでは,33hまでとなります.全て入力して,解析ボタンを押すと,以下のように解析結果が表示されます.
 試しに ,衛星時刻を見てみると,864484.6 secとなっています.これは,前回のリセットからの経過時間です.ただし,SRAMに書き込まれた過去の状態をダウンリンクしている場合は,その時の衛星時刻が表示されます.SRAMに記録された過去の時刻なのか,それとも現在の時刻なのかは,Memory Statusを見てください.ここが,
  Memory Status: No Access
になっていれば,SRAMへのアクセスは行っていませんので,現在の衛星時刻であることが判断できます.

 

 フレームの最後の5バイトは,以下の通りです.

バイト
内容
33
CUTE-Iが計算したCRC
34
35
TNCが32バイト目までを計算したCRC
36
37
誤りビットを訂正した数

 33〜34の2バイトが,CUTE-Iが送信データに対して計算したCRCの値です.35〜36の2バイトが,受信した32バイトに対してTNCが計算したCRCの値です.これらの値が一致していれば,その受信データが,誤りなく受信できたかどうかがわかります.さきほどのデータでは,

33 34 35 36
01h FDh 01h FDh

となっていましたので,この受信データは正常にデコードできたことがわかります.

 37バイト目は,TNCが誤り訂正を行ったビット数です.ただし,SRLLでは1バイトにつき1ビットまでの誤りまでしか訂正を行うことはできません.それ以上の誤りが発生した場合,何ビットの誤りが発生したのかを検出することはできなくなります.CRCが一致しないときの37バイト目の値は,正確な数値にはならない可能性がありますので,あらかじめご了承願います.
 CRCが一致したものの中では,現在0Ah(=10)までを確認しております.これは,1パケットに10ビットの誤りが発生したが,TNCにより正しく訂正することができたということを意味しています.

 


7. 受信状況

 東工大局での受信状況です.
 グラフの意味については,下の表をご覧下さい.

エラーなく取得 全34バイトのデータ,及び17バイトの訂正符号が完全に受信され,
誤り訂正を行うことなく受信できたパケット数.
訂正して取得 1フレームに数ビットの誤りが発生したが,訂正符号により訂正を
行うことができたパケット数.

 東工大局周辺の電波環境は,平均して10^-3程度です.これは4パケットにつき1ビットの誤りが発生するのと同じ確率です.
また,早朝,夕方の時間帯や,日によって大きく変わります.

 SRLLデコーダを製作いただいた方でデータを持ち寄って,電波環境の違いによる取得状況を比較してみると面白いと思います.
ご意見をお待ちしております.


8. ベリカードについて

 SRLLをデコードされた方は,SRLL受信確認証を発行致します.(現在,新しいデザインのものをお配りしております.)
ベリカード配布についてをお読みの上,お申し込みください.(電波形式 FM/SRLLとご記入ください.)