« APRSの軌跡取得実験ーその1 | トップページ | Yaesu FT3D APRSビーコン パケットデータの解析 »

2022年11月29日 (火)

PICO TNCの製作

PICO TNC製作の記録。徐々に追記していく予定。>> このスレッドが長くなったので続きはPICO TNCの製作その2へ。

Img03051_hdr_small

PICO TNCの情報は以下GitHubから入手。
https://github.com/amedes/pico_tnc

当初はうまく動作しなかった。

反省点1:USB-Serialケーブル不良。RxDが動作しなかった。これがわかるのに半日消費。動作実績のないUSB-Serialケーブルは使わず、すCOMポートからのストレートケーブルが安心。

反省点2:Picoがイネーブルにしている入力端子はオープン状態にしないこと。ADC0(31ピン)をオープンのままにしていたらBeacon送信しなかった。これはADC0が入力有と判断して、入力処理を頻繁に繰り返していたためと思われる(要確認)。入力端子をプルアップ/プルダウンしたら問題は解消した。

動作確認中のブレッドボード。右がシリアルケーブル。デスクトップPCのCOMポートに接続(USB-Serialではない)。奥にある四角いケースがGPSセンサー。D-subコネクタ左側にあるチップユニットはRS232Cレベルコンバーター。Picoは3.3Vなので3.3V - RS232Cレベルに変換している。

Img03052_burst01_small

BeaconのPWM出力。PWM出力は波形テーブル(特定の出力周期でのPWM出力パターンテーブル)に従ってPWMレジスターにDMAで送られる。
Pwm

PWM出力幅が徐々に変化していく様子がわかる。
Pwm_20221129090601

このPWM出力をローパスフィルターで整形すると以下の波形になる(時間軸は異なる)。
Ds1z_quickprint1

ソフトウエア構造:

  • 送信フレームをsend_queue上に作り、その内容をsend()がPWMにDMAで送り込む。
  •  

main(){

   tty_write_str()  // opening msgをuart_queueにセット

   white(1){

      receive()   //Rig(SP)から受信したアナログ信号をADCにてデジタル化しDMAにて取り込み復調。
                //digipeatの場合はアドレス情報を生成
                      //受信データをuart_queueにセット(シリアルターミナル上に表示)

      send()      //送出フレームデータをRig(MIC)へPWMにてFSK信号を送信。
                     //send_start()がPTT ONしDMAトリガーオン、queue上のデータをPWMレジスターに転送開始
                     //DMAハンドラーがqueueデータを全部送出したらPTT OFF

      serial_input()    //uartとgpsからのシリアル・データ入力、unprotoでqueue上にフレームデータ作成

      serial_output()  //uart_queueの中身をuartへ出力

      beacon()  //send_unproto()でqueue上に送出フレームデータを生成

  }  

動作確認方法:

FSK変調済み送出データ(リグMIC入力)を受信データ(リグSP出力)にループバック接続して送出パケットを受信するとともにターミナル画面表示する。

GPSデータ:

GPSの出力データ:以下データを1秒ごとに出力している。GPS出力(RX)をターミナルのRxDに接続してターミナル画面上に出力した。

$GNGLL,3540.78870,N,13738.11970,E,065545.00,A,A*72
$GNRMC,065546.00,A,3540.78872,N,13738.11967,E,0.068,,291122,,,A*69
$GNVTG,,T,,M,0.068,N,0.126,K,A*36
$GNGGA,065546.00,3540.78872,N,13738.11967,E,1,12,0.82,511.8,M,36.5,M,,*44
$GNGSA,A,3,31,22,26,25,32,29,16,196,195,194,,,1.50,0.82,1.25*27
$GNGSA,A,3,73,70,71,82,83,,,,,,,,1.50,0.82,1.25*10
$GPGSV,4,1,13,02,04,103,,03,12,304,,12,01,051,10,16,14,237,25*79
$GPGSV,4,2,13,22,78,256,20,25,31,048,18,26,44,253,31,29,48,092,31*7D
$GPGSV,4,3,13,31,62,336,38,32,56,170,26,194,86,198,33,195,17,167,22*7E
$GPGSV,4,4,13,196,34,198,20*70
$GLGSV,2,1,08,70,42,205,15,71,53,289,24,72,16,331,,73,52,316,28*67
$GLGSV,2,2,08,74,19,273,,81,09,028,,82,24,074,25,83,17,120,20*6E

 

GPSデータが送出パケットのInformationフィールドに反映されない問題:

ソフトウエア構造を見る限り、送出フレームバッファはsend_unproto()が生成するフレームが唯一だと思う。

serial_input()でGPS_ENABLEの場合、gps_input()が呼ばれる。gps_input()は入力文字がLFの場合、GPSデータを送出フレームのInformationにセットするようsend_unproto()をコールする。これにより送出フレームができる。

しかし、この後にmain()でCallされるbeacon()によって送出フレームが上書きされる。

whileループが頭に戻り、send()がコールされるとパケットフレームがPWMで送出されるが、この時のパケットフレームはbeacon()にて生成されたもの。このフレームではInformationは事前設定されたbtextになる。

^^^この解釈は間違い^^^

gps_send()のsend_unproto()コールの後に必ずbeacon()のsend_unproto()がコールされるわけではない。これらの動作はそれぞれが設定されたインターバルで実行される。つまり、gps_send()は3分間隔、beacon()は1分間隔で独立して送出される。

beacon()はユーザー設定のインターバルでsend_unproto()がコールされる。

void beacon(void)
{
    if (!param.beacon) return;

    if (tnc_time() - beacon_time < param.beacon * 60 * 100) return; // convert minutes to 10 ms

    send_unproto(&tnc[BEACON_PORT], param.btext, strlen(param.btext));
    beacon_time = tnc_time();
}

gps_send()はコード内に設定されたGPS_INTERVAL (3 x 60 x 100 = 3min)でsend_unproto()がコールされる。

static void gps_send(uint8_t *buf, int len)
{
    static uint32_t gps_timer = 0;

    if (tnc_time() - gps_timer < GPS_INTERVAL) return;

    if ((param.gps == GPGGA && !strncmp("$GPGAA", buf, 6))
    || (param.gps == GPGLL && !strncmp("$GPGLL", buf, 6))
    || (param.gps == GPRMC && !strncmp("$GPRMC", buf, 6))) {

       send_unproto(&tnc[GPS_PORT], buf, len);
       gps_timer = tnc_time();
    }
}

問題は上記赤字部分。今回接続しているGPSはこのヘッダー文字列のデータ出力がないのが原因。。。。。

$GNGGA, $GNGLL, $GNRMCを追加した。結果、GPSデータが送出されるようになった。

JA0WBT>JA0WBT-1:<03><f0>make my day
JA0WBT>JA0WBT-1:<03><f0>$GNGGA,141400.00,3540.78609,N,13738.11321,E,1,12,0.90,522.8,M,36.5,M,,*49<0d><0a>
JA0WBT>JA0WBT-1:<03><f0>make my day
JA0WBT>JA0WBT-1:<03><f0>make my day
JA0WBT>JA0WBT-1:<03><f0>make my day
JA0WBT>JA0WBT-1:<03><f0>$GNGGA,141700.00,3540.78648,N,13738.11733,E,1,12,0.84,528.2,M,36.5,M,,*4D<0d><0a>
JA0WBT>JA0WBT-1:<03><f0>make my day
JA0WBT>JA0WBT-1:<03><f0>make my day

 

cmakeが出来ない件:

pico_sdk_import.cmakeに要修正箇所あり。以下赤字部分を削除。

LINE6 if ( DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))

この赤字部分が何処で定義されてるべきか不明。とりあえず、ここの部分を外さないとSDKのパスが設定できない。

なお環境変数は以下で設定している
 PICO_SDK_PATH=../../pico-sdk  

 

バグ情報:

バグを発見(赤字部分)。

void serial_init(void)
{
    queue_init(&uart_queue, sizeof(uint8_t), UART_QUEUE_LEN);
    assert(uart_queue != NULL);

    uint baud = uart_init(uart0, UART_BAUDRATE);

    //printf("UART0 baud rate = %u\n", baud);

    uart_set_fifo_enabled(uart0, true);

    gpio_set_function(0, GPIO_FUNC_UART);
    gpio_set_function(1, GPIO_FUNC_UART);

#ifdef GPS_ENABLE
    // GPS
baud = uart_init(uart1, GPS_BAUDRATE);

//printf("UART1 baud rate = %u\n", baud);

    uart_set_fifo_enabled(uart0, true);
    gpio_set_function(4, GPIO_FUNC_UART);
    gpio_set_function(5, GPIO_FUNC_UART);
#endif
}

しかしSDK Documentを見る限り、DefaultはEnableなので、バグは動作に影響しないようにも思える。
Uart_set_fifo_enabled

 

Buildエラーについて:

flash.cにて参照エラーが出てbuildができなかったがsdkを再インストールしてbuildが出来るようになった。

ただし、以下を修正した。

flash.c

修正前 Line8  //#inlcude "hardware/sync.h"   

修正後 Line8  #inlude "hardware/sync.h"

なぜこのinclude行がコメントアウトされていたかは不明。これがコメントアウトされると save_and_disable_interruptsとrestore_interruptsが外部参照エラーになる。

pico_tnc.uf2は/home/pi/pico/pico_tnc/build/pico_tncに作られていた。

 

GGAフォーマットについて:GT-902P

Ggaformat

« APRSの軌跡取得実験ーその1 | トップページ | Yaesu FT3D APRSビーコン パケットデータの解析 »

無線と実験」カテゴリの記事

ツールの使い方」カテゴリの記事

ラズパイ日記」カテゴリの記事

工作」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

« APRSの軌跡取得実験ーその1 | トップページ | Yaesu FT3D APRSビーコン パケットデータの解析 »