pico_tnc 2200Hz(Space)でPhaseをずらす件の備忘録
GitHubからダウンロードしたpico_tncのsend.cのsend_byte()についての考察記録
なぜ、mark_tabのサイズは121なのか,、そしてspace_tabのサイズは96なのか。
« 2022年11月 | トップページ | 2023年1月 »
GitHubからダウンロードしたpico_tncのsend.cのsend_byte()についての考察記録
なぜ、mark_tabのサイズは121なのか,、そしてspace_tabのサイズは96なのか。
PICOのPIOを使ったPWM信号出力をDMAで動作させる方法について備忘録
注:PIOを使ったPICOのPWM機能をDMAで動作させる方法はいまいちわからなかった。(というか、PIOのTX FIFOにデータを送った場合、PIOはGPIOピンに0/1信号しか出せず、PWMレジスターに値を書き込めない。そもそもDMAには自己完結型のDREQインターバル設定ができるので、DMAでPWMレジスターに値を書き込むだけなら、PIOは特に必要ないかも。。。)
ここではPIOに32ビットデータを1ビットずつ設定した周期でGPIO出力させることでPWM信号を作る方法について備忘録する。
======= Program 1 DMAだけ、IRQなし =======
Main C Program
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/dma.h"
#include "hardware/pio.h"
#include "hardware/clocks.h"
#include <hello.pio.h>
int main()
{
PIO pio = pio0;
uint state_machine_id = 0;
uint offset = pio_add_program(pio, &pio_dac_program);
pio_dac_program_init(pio, state_machine_id, offset, PICO_DEFAULT_LED_PIN, 2000.f);
int pwm_dma_chan = dma_claim_unused_channel(true);
dma_channel_config dma_chan_config = dma_channel_get_default_config(pwm_dma_chan);
channel_config_set_transfer_data_size(&dma_chan_config, DMA_SIZE_32);
channel_config_set_read_increment(&dma_chan_config, true);
channel_config_set_write_increment(&dma_chan_config, false);
channel_config_set_dreq(&dma_chan_config, pio_get_dreq(pio, state_machine_id, true)); // pio sm, TX
dma_channel_configure(
dma_chan,
&dma_chan_config,
&pio0_hw->txf[state_machine_id],
data_table,
256,
false
);
dma_channel_set_read_addr(dma_chan, mark_tab, true); // DMAをスタートする
while(true) {
tight_loop_contents();
}
}
PIO Program
.program pio_dac
.wrap_target
out pins, 1
.wrap
% c-sdk {
static inline void pio_dac_program_init(PIO pio, uint sm, uint offset, uint pin, float fs) {
pio_sm_config c = pio_dac_program_get_default_config(offset);
sm_config_set_out_shift(&c, true, true, 32);
sm_config_set_out_pins(&c, pin, 1);
// sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); これはなくても動作は同じ
sm_config_set_clkdiv(&c, (float)clock_get_hz(clk_sys) / fs);
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}
%}
======= Program 2 DMAとIRQの両方 =======
Main C Program
|
inlinestatic |
Set the DMA initial read address.
channel | DMA channel |
read_addr | Initial read address of transfer. |
trigger | True to start the transfer immediately |
cmake_minimum_required(VERSION 3.16) //使っている環境が3.16だからとりあえず3.16に設定
include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)
project(led_fade C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()
add_subdirectory(led_fade)
add_executable(led_fade
led_fade.c
)
pico_generate_pio_header(led_fade ${CMAKE_CURRENT_LIST_DIR}/hello.pio)
target_link_libraries(led_fade
pico_stdlib
hardware_pio
hardware_dma
)
pico_add_extra_outputs(led_fade)
======= Program 3 文字列を波形出力する =======
検証にあたってはこのブログを参考にした。
Raspberry Pi PicoのPIOについて調べてみたので備忘録。
Raspberry Pi Picoはメインプログラムとは別にアセンブラレベルコードを実行することができる。これはメインプログラムとは別に(並行して)動作するプログラムのようだ。基本アセンブラレベルのコードを書くことになる。これはかなり強力な機能で、メインプログラムでタイミングを意識することなく、決まったサイクルでオペレーションを実行できることになる。
その1からその2まで記録。。。
その1ーーー
開発手順
ここではオンボードLEDを点滅するPIOを書いてみる。
hello.pioディレクトリに以下を配置
+ CMakeLists.txt
+ hello-pio
+ hello.pio
+ hello-pio.c
+ CMakeLists.txt
+ build
buildディレクトリにて以下を実行してbuildする。
$ cmake ..
$ make
以下、実際に書いたコード。
参考になった情報1と情報2。ただし、情報1の通りコードを書いてもLEDはブリンクしない(サイクルが短すぎて点灯しっぱなしに見える)。
hello.pio
.program hello
loop:
;.wrap_target
set pins, 1 [19] ; Turn LED on and wait another 19 cycles
nop [19] ; Wait 20 cycles
nop [19] ; Wait 20 cycles
nop [19] ; Wait 20 cycles
nop [19] ; Wait 20 cycles
set pins, 0 [19] ; Turn LED off and wait another 19 cycles
nop [19] ; Wait 20 cycles
nop [19] ; Wait 20 cycles
nop [19] ; Wait 20 cycles
nop [19] ; Wait 20 cycles
;.wrap
jmp loop
// 上記loopのwrapも同じ結果になる
% c-sdk {
static inline void hello_program_init(PIO pio, uint sm, uint offset, uint pin) {
// Configオブジェクトを定義する
pio_sm_config config = hello_program_get_default_config(offset);
// Configオブジェクトにgpioピンpinを割り当てる
pio_gpio_init(pio, pin);
sm_config_set_set_pins(&config, pin, 1); // pinから1ピンを連続割当、ここでは1ピンのみの割当。
// pinから1ピンを出力に設定。ここでは1ピンのみを設定。
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
// クロック分割数を決める。divの分だけsysclkがマスクされる。これをやらないとLED ON/OFFが早すぎてLED点灯しっぱなしに見える。
static const float pio_freq = 2000;
float div = (float)clock_get_hz(clk_sys) / pio_freq;
sm_config_set_clkdiv(&config, div);
// 初期化とイネーブ
pio_sm_init(pio, sm, offset, &config);
pio_sm_set_enabled(pio, sm, true);
}
%}
hello-pio.c
#include <stdio.h>
#include <stdbool.h>
#include <pico/stdlib.h>
#include <hardware/pio.h>
#include "hardware/clocks.h" // hello.pioでclk_sysを参照しているので必要
#include <hello.pio.h> // hello.pioから生成されるヘッダーファイルをincludeする
#define LED_BUILTIN 25 // オンボードLEDのGPIO
int main() {
stdio_init_all();
PIO pio = pio0;
uint state_machine_id = 0;
// hello.pioで定義したhelloはhello_programと自動的に命名される。
uint offset = pio_add_program(pio, &hello_program);
hello_program_init(pio, state_machine_id, offset, LED_BUILTIN);
while(1) {
// Cプログラムで何かをやっていたとしても、これとは並行してpioが動作している
}
}
CMakeLists.txt(hello.pioディレクトリ)
cmake_minimum_required(VERSION 3.12)
include(pico_sdk_import.cmake)
#project(pico_examples C CXX ASM)
project(hello-pio C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()
add_subdirectory(hello-pio)
CMakeLists.txt(hello-pioディレクトリ)
add_executable(hello-pio
hello-pio.c
)
# CMAKE_CURRENT_LIST_DIRはCMAKEによって自動設定される
pico_generate_pio_header(hello-pio ${CMAKE_CURRENT_LIST_DIR}/hello.pio)
target_link_libraries(hello-pio
pico_stdlib
hardware_pio
)
# hexファイルやuf2ファイルを生成する
pico_add_extra_outputs(hello-pio)
hello.pio.h
CMakeLists.txtのpico_generate_pio_header()によって以下のヘッダーファイルが生成される。
// -------------------------------------------------- //
// This file is autogenerated by pioasm; do not edit! //
// -------------------------------------------------- //
#pragma once
#if !PICO_NO_HARDWARE
#include "hardware/pio.h"
#endif
// ----- //
// hello //
// ----- //
#define hello_wrap_target 0
#define hello_wrap 10
static const uint16_t hello_program_instructions[] = {
// .wrap_target
0xf301, // 0: set pins, 1 [19]
0xb342, // 1: nop [19]
0xb342, // 2: nop [19]
0xb342, // 3: nop [19]
0xb342, // 4: nop [19]
0xf300, // 5: set pins, 0 [19]
0xb342, // 6: nop [19]
0xb342, // 7: nop [19]
0xb342, // 8: nop [19]
0xb342, // 9: nop [19]
0x0000, // 10: jmp 0
// .wrap
};
#if !PICO_NO_HARDWARE
static const struct pio_program hello_program = {
.instructions = hello_program_instructions,
.length = 11,
.origin = -1,
};
static inline pio_sm_config hello_program_get_default_config(uint offset) {
pio_sm_config c = pio_get_default_sm_config();
sm_config_set_wrap(&c, offset + hello_wrap_target, offset + hello_wrap);
return c;
}
static inline void hello_program_init(PIO pio, uint sm, uint offset, uint pin) {
pio_sm_config config = hello_program_get_default_config(offset);
pio_gpio_init(pio, pin);
sm_config_set_set_pins(&config, pin, 1);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
static const float pio_freq = 2000;
float div = (float)clock_get_hz(clk_sys) / pio_freq;
sm_config_set_clkdiv(&config, div);
pio_sm_init(pio, sm, offset, &config);
pio_sm_set_enabled(pio, sm, true);
}
#endif
その2ーーー
sm_config_set_out_shiftについて
.program hello
.wrap_target
out pins, 1 ; 結果的に1ワード分のデータを右シフトで1ビットずつ出力される。
.wrap
% c-sdk {
static inline void hello1_program_init(PIO pio, uint sm, uint offset, uint pin, float fs) {
pio_sm_config c = pio_dac_program_get_default_config(offset);
// TX FIFOからデータをpullするまでのビットシフト実行指定、右向きに32ビットまでシフトする。
// つまり32ビット全部をpinに順次送り出し、全て送り出したらTX FIFOから自動で新しいデータをpullする。
sm_config_set_out_shift(&c, true, true, 32);
// pinから1ピンをoutに設定する
sm_config_set_out_pins(&c, pin, 1);
// クロックマスク周期を設定する(動作速度を調整する)
sm_config_set_clkdiv(&c, (float)clock_get_hz(clk_sys) / fs);
SDKドキュメントは以下のとおり。
|
inlinestatic |
Setup 'out' shifting parameters in a state machine configuration.
c | Pointer to the configuration structure to modify |
shift_right | true to shift OSR to right, false to shift OSR to left |
autopull | whether autopull is enabled |
pull_threshold | threshold in bits to shift out before auto/conditional re-pulling of the OSR |
KENWOODハンディトランシーバー対応。トランシーバーはTH-K20、ちょっと(かなり)古い。
KENWOOD対応のヘッドセットのケーブル・ジャックを活用しようとして驚いた。ケーブルを切ったのはこのヘッドセット。
まぁ、幾分細いワイヤーがはいっているんだろうと思ったら、、、なんと超極細エナメル線を編んだワイヤーが4本入っていた。これはどうしたものやら。とりあえずカッターナイフで極細エナメル線の被覆を削り落としてクリップを付けて配線を確認した。
KENWOOD ハンディのスピーカーマイク配線は以下のとおり。
つまりMICラインとPTTラインは分けないといけない。ここがYaesuと違う所。そこで、ビーコン発生機のジャック端子の真ん中(Ring)にPTT信号を割り当てる改造を実施。
この結果、ハンディのスピーカーマイク端子とビーコン発生機に差し込むジャックとの配線は以下のようになった。マイク信号線はマイク端子(Tip)へ、MIC/PTT共通信号線はPTT端子(Ring)へ、PTT/GND信号線はGND端子(Sleeve)へ接続した。
これでとりあえず動くようになった。
しかし、トランシーバーから電波を出すとPicoが誤動作し、PTTが切れない。つまり電波が出っぱなしになる。この状態で今回作ったケーブルを手で覆い隠すと誤動作(PTTオン)が止まる。つまり、トランシーバーからの電波に対してビーコン発生機をシールドする必要がある。
Picoが誤動作している可能性があると思い、ケーブルのビーコン発生機ジャック根元部分にコアを入れてみたが効果なし。
今度はトランシーバー側にコアを入れてみた。こちらは効果があり、安定的に動作するようになった。ちなみにコアはFT-114-43、バラン用に購入してあったもの。
以上でKENWOOD Handy対応も目処がたった。
追加のノイズ対策
今回の誤動作はPTTがオンになりっ放しになるというもの。スピーカーマイクケーブルのトランシーバー側にコアを入れて改善したことから、このケーブルを介してノイズがビーコン発生機に入ってきていることが想像できる。そして、ビーコン発生機のPTT信号出力トランジスターを誤動作させているということだろうか。であれば、トランジスター自体にノイズ対策を施すことは効果がありそうだ。
それで以下の対策を施した。
Q1のベース・エミッター間にR3 10KΩ抵抗を入れた。この抵抗がない状態ではベースに入ってきたノイズ電流によってQ1が誤動作する場合が有り得るが、そのノイズ電流をGNDに流す役割をするのがR3になる。仮に0.01mAのノイズ電流がベースに入ってきたしても、10KΩに流れたとして電圧は0.1Vとなりベース・エミッター間飽和電圧(大体0.8V)よりも十分小さいのでQ1を動作させることはないがノイズ電流はGNDに流すことができる。
試しにコアを取り外してみたが、やっぱりコアが無いとPTTがオンになったままになる。ということで、上記R3の追加は決定的な対策にはならないことが判明。
PICO TNC製作の続編その2。
事前設定したインターバルで、ハンディ―トランシーバーのマイク端子経由にてMic-EフォーマットでGPSデータを送信することができるようになった。
PICO TNC コマンドの使い方
以下がdispコマンド実行結果。MYALIASは設定しなくてもよい。
disp
ECHO ON
TXDELAY 100
GPS $GNGGA
TRace OFF
MONitor ALL
DIGIpeater ON
BEACON On EVERY 6
UNPROTO SUTPW8 V WIDE1-1
MYCALL JA0WBT-7
MYALIAS JA0WBT
BTEXT HelloWorld
OK
cmd:
送信されるパケットデータ
PICOの出力(トランシーバーのマイク入力)を入力(トランシーバーのスピーカ出力)にループさせてPICO TNCにて自分の出力を自分でデコードさせた。さらに実際にトランシーバー(FT-70D)のマイク入力に接続し、電波送信してI-Gateにて受信した。その受信した結果が以下:
17:43:53R JA0WBT-7>SUTPW8,WIDE1-1 Port=1 <UI C Len=24>:
`AB'l l[/`"9L}HelloWorld
17:43:53R JA0WBT-7>SUTPW8,WIDE1-1 Port=2 <UI C Len=24>:
`AB'l l[/`"9L}HelloWorld
17:43:55R JA0WBT-7>SUTPW8,WIDE1-1* Port=1 <UI C Len=24>:
`AB'l l[/`"9L}HelloWorld
17:43:55R JA0WBT-7>SUTPW8,WIDE1-1* Port=2 <UI C Len=24>:
`AB'l l[/`"9L}HelloWorld
I-Gateは2ポート設定しているので(1ポートにする方法がわからん)、同じ電波信号をPort1とPort2で2回取り込んでいる。最初のペアがPICO TNCが生成したフレームで、次のペアがPICO TNC内でループバックして再送信した信号になる。ループバックした信号はデジピートしたことになるのでWIDE1-1の後ろに*が付加されている。
Digipeaterとしての機能
Digipeaterとしの機能を確認する。FT3Dからビーコンを送信し、それをFT-70Dで受信。FT-70DのSpeakerをPICO TNCの入力に接続し、MicをPICO TNCの出力に接続した。
結果は、FT3Dからのビーコン(上図①)はFT-70Dでビーコン再送(上図④)された。そのビーコンはFT3Dで受信することができた(以下写真)。一方、UI-VIEW32はFT3Dからのビーコン(上図①)は受信表示したが、FT-70Dからのビーコン再送(上図④)は受信表示されなかった。
考察として、UI-VIEW32はオリジナル信号を受信した後に、そのデジピート信号を受信した場合、それは受信表示しないのではないかと思われる。もしそれを許したら、同じ信号をデジピートの分だけ何度もI-Gateしてしまうから。一方、FT3Dは自分が発信した信号のデジピートであっても自分以外の送信機からの信号なのでそのまま表示したのだと思う。
UI-VIEW32のTerminalで確認したところ、上記の通りと判断できる。以下がTerminalの表示内容。3つ目のWIDE1-1に*が付いているのでデジピートされた信号と判断される。デジピートしたのはPico TNCになるので、Pico TNCはちゃんとデジピートしているのだけれど、それをUI-VIEW32がInternetには送り出さなかったということだ。
19:34:21R JA0WBT-7>SUTPW7,WIDE1-1 Port=1 <UI R Len=17>:
`AB(l!m[/`"9l}_0
19:34:21R JA0WBT-7>SUTPW7,WIDE1-1 Port=2 <UI R Len=17>:
`AB(l!m[/`"9l}_0
19:34:22R JA0WBT-7>SUTPW7,WIDE1-1* Port=2 <UI R Len=17>:
`AB(l!m[/`"9l}_0
乾電池駆動について
この実験に際して、PICO TNCを単四乾電池2本で駆動した。5分インターバルで一晩ビーコンを出し、朝停波。その状態で実験を続けていたところ午後3時ころには電池がなくなった(Watchdog Timer Failure発生)。結構電力を消費している。
基板への実装とケースへの取り付け
ブレッドボードに作った回路を
この回路をユニバーサル基板に配置する。
ダイソーの3個100円のケースにいれる。RS232Cのボードもユニバーサル基板に実装した。
実験結果はまずまず良好で、基本機能が動作することを確認できた。
ヤフオク!で落としたDiamond GS-3000 13.8V MAX30A電源が届いた。
動作させたところ電圧は13.78V、しかし電流は4A程度で電流制限が働いで電源OFFになる。
良くある故障モードとして可変抵抗器の劣化が考えられる。
GS-3000の故障に関する情報から、VR1が電流制限調整VRであることが判明した。
VR1を拡大する。この写真では8時方向をむいているが、入手時点では12時方向を向いていた。
とりあえず、VR1を何度か回してまずは、3時方向にセットし負荷を繋いでみた。4Aよりも小さな負荷で電流制限が発生。そこで8時方向まで回してみたところ、8Aの負荷でも電流制限は作動しなかった。30A負荷を与えることができればVR1の位置は追い込めるが、そのような負荷がないので、とりあえずこれで様子を見てみる。
考察:
この電源、カバーを外してみると結構きれいな感じだったが、基板の隅の方を見るとシルク印刷が隠れるほど埃がこびりついている。つまり、この電源の出品に当たって掃除をしたということだろうと思う。ひょっとしたらその際にVR1の位置が変わってしまったのかもしれない。いずれにせよVR1の調整だけで問題は解決したように見える。
考察のやり直し:
電流が出ないというか過電流保護が働いて出力電流制限されている理由が分かった。4つあるパワートランジスタの内3つのエミッターに繋がるワイヤーが断線していた。半田にクラックが入って取れたように見えた。VR1を変化させて制限電流値が増えたのは残っていた1つのパワートランジスターの最大電流(0.1Ω抵抗に流れる電流量)を増やしたため、ということのようだ。
エミッター端子の半田面が割れて剥がれたような半田断面にみえる。
こちらも同様。
本来は4個のパワートランジスターで出力しているところを1個のパワートランジスターで制御したため、過電流制御が働いてしまったようだ。エミッターへケーブルを半田付けしなおした(黄丸)。
この結果、電流制御用のVRを元の位置に戻しても、問題なく動作するようになった。また、電流計は剥がれがケーブルの先に繋がっていたので当初は電流表示が出来なかったがケーブルを半田付けしなおすことで、電流計も動作するようになった。
考察
もうちょっとちゃんと構造を調べて見たくて、今一度理解を深めるためにJH7LUC局のブログなど先人の知恵を参考に自分で回路図を書いてみた。
構成はダーリントン接続のトランジスターが3段になっていて、ツェナーダイオードで定電圧としている。リセットIC TA8505Pの入力にサーモスタットにかかる電圧を接続し、ある程度の抵抗値(温度)になったらリセットICがリセット信号を出力し、その信号によってファンモーターnの駆動制御を行っている。TA8505PはVCC=5Vを必要とするので三端子レギュレータTA78006PでVCCを作っている。過電圧(ツェナー電圧)となるとツェナー電流が流れリレーが働いてパワートランジスタへの入力をカットする。
定電圧の原理は以下の通りと理解した。Q2のエミッター電圧Veq2はZDのツェナー電圧Vzdで決まる。Q2のベース電圧は、ベース・エミッター間電圧をVbeq2とするとVzd+Vbeq2となる。この電圧はVout(R2/(R1+R2))であたえられるので、Vout=(Vzd+Vbeq2)((R1+R2)/R1)となるようにQ1が帰還制御される。
よくわからなかったのが過電流制御部分。ここは以下の通り解釈した。
VEQ5=VEQ3-R2xIOUT : IOUTが大きくなるとR2による電圧降下が大きくなるのでVEQ5(Q5のエミッター電圧)は小さくなる。
VBQ5はVRの値によって変化する。
VBQ5-VEQ5>VBE となればQ5はONになる。つまりIOUTが大きくなるとQ5はONになる。その閾値はVRで変化する。
Q1のベース電圧からみると、Q3のエミッター電圧はQ1からQ3のベース・エミッター間電圧の合計分低いことになる。Q5がオンになるとその電圧差がなくなるので、Q1からQ3へのベース・エミッター間に電流が流れなくなる。
解釈が正しいかイマイチ不安な部分があるけれども、出力電流による0.1Ω抵抗の電圧降下とVR1の値のバランスでQ5がONされることには違いない。
FT-70DとかFT3Dとかのハンディトランシーバーではマイク端子とPTT端子が一つにまとめられている。
MICとPTTが一本の線にまとめられているってどういう事なんだろうってことで調べてみた。
Yaesu スピーカーマイクSSM-17Aのピンジャックの信号配列は以下のようになっているようだ。他の資料などを見るとSPとMIC/PTTの間の電極はDATA/Cloneとなっているが、このスピーカーマイクでは未使用だと思う。
MIC/PTTとGNDの間の抵抗値をテスターで測ってみた。PTTを押さない場合は絶縁状態、PTTを押すと633Ωとなった。
いろいろな資料を見てみて、この仕組みを回路にまとめると以下のようだ。テスターで測定した633Ωは回路図のR01にあたる。つまり、PTTを押すとMICラインが633Ωで接地されるわけだ。トランシーバー側はこのMICラインがPNPトランジスタのベースに繋がっているようで、PTTが押されるとトランジスタがオンになる。これがトランシーバー内でSEND信号になるようだ。一方MICはコンデンサーCを介してAC成分だけがMIC信号として取り出される。ここでR01の抵抗値はトランシーバー内のR02との関係で適切な値に設定し、ベース電流が流れるようにしないといけない。実験ではR01が2KΩではPTTが効いたが、10KΩではPTTが効かなかった。
とりあえずR01はスピーカーマイクでの測定値に近い680Ω位に設定すれば安心なんだろうと思う。
スピーカーマイクの代わりにTNCを取り付けた場合、PTT信号を使って以下の回路を構成すればよい。この回路ではPTTオンがHIGHを前提としている。
実験の結果680Ωでこの回路でも動作を確認した。
GPSトラックログファイル(GPXファイル)をGoogle Map上に表示する方法の備忘録。
GPSトラックログファイルはヤマレコの山行記録からダウンロードした。対象とする山行記録を選んでマップ昨日からGPXファイルをダウンロードを選ぶ。
ダウンロードされるGPXファイルはこんな感じになっている。
<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.topografix.com/GPX/1/0" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" creator="Yamareco Android 6.2.2 - www.yamareco.com">
<trk><name>track</name><number>1</number><trkseg>
<trkpt lat="35.5110116" lon="137.6645703"><ele>1040</ele><time>2022-11-17T23:46:07Z</time></trkpt>
<trkpt lat="35.5109365" lon="137.6644874"><ele>1041</ele><time>2022-11-17T23:46:17Z</time></trkpt>
<trkpt lat="35.5107415" lon="137.6643537"><ele>1045</ele><time>2022-11-17T23:46:30Z</time></trkpt>
<trkpt lat="35.5106972" lon="137.6642274"><ele>1048</ele><time>2022-11-17T23:47:24Z</time></trkpt>
<trkpt lat="35.5092595" lon="137.6552615"><ele>1284</ele><time>2022-11-18T00:28:01Z</time></trkpt>
<trkpt lat="35.509086" lon="137.6537141"><ele>1300</ele><time>2022-11-18T00:31:16Z</time></trkpt>
LatitudeとLongitudeがUTC付きで記録されている。
次にGoogle Mapを開き、自分のGoogleアカウントでログインする。その後メニューをだどって地図を作成を実行。
メニュー -> マイプレイス -> マイマップ -> 地図を作成
以上。
FT3Dが送信しているAPRSパケットデータの解析をしたので、その記録。
以下がUI_VIEW32のTerminal出力に表示されたFT3DのAPRSビーコンデータ:
JA0WBT-7>SUTPW9,WIDE1-1 Port=1 <UI R Len=17>:`AB(l T[/`"9a}_0
FT3DはMic-E形式でAPRSパケットを送出している。FT3DのMic-EはDestination AddressとInformationにGPS座標情報(Latitude/Logitude)、高度情報(Altitude)、無線機形式(Radio Type code)で構成されている。
まずはDestination Address(以下の赤字部分)の分析から。ちなみにFT3DのGPS座標は北緯35度40.79分、東経137度38.12分。
JA0WBT-7>SUTPW9
Byte | Latitude | Msg A/B/C | N/S | Longitude offset | E/W |
S | 3 | A=1 | |||
U | 5 | B=1 | |||
T | 4 | C=1 | |||
P | 0 | N | |||
W | 7 | +100 | |||
9 | 9 | E |
SUTPW9は1バイト目からAPRSスペックの44ページに掲載される以下の表でデコードできる。1バイト目からこの表を見ながらその意味を解釈するとデータ並びのASCII Char順に以下となる。
ちなみにMessage A/B/C = 111はスペックの45ページの表(以下)Off Duty(無線機の前に運用者は不在)という意味になる。
FT5DのマニュアルにあるMessageの解釈は以下の通り。
次にInformationに記載されたデータの解釈を行う。
`AB(l T[/`"9a}_0
結論を先に書くと、これは以下の3つのパート(青、赤、緑)で構成されている。
`AB(l T[/`"9a}_0
`AB(l T[/ : Logitude + Speed/Course + Symbol Code
Information Fieldのフォーマットはスペックの46ページに掲載されている。
この表に従ってデータを解釈する。
`"9a} : Altitude
Altitudeは最も深い海の底(10,000メートル)からの標高で表現する。なので海抜に10,000メートルを加算する。この標高を基数91で表現する。例えば標高61メートルだと、10,061メートルとなるので、
10,061 / (91*91) = 1 あまり1,780
1,780 / 91 = 19, あまり51
つまり基数91表現で119あまり51となる。これに33を加算し3バイトで表現すると、Byte1=1+33=34、Byte2=19+33=42、Byte3=51+33=84となる。受信したビーコンはこの逆の方法で計算する。
_0 : Radio Type code
Mic-E Type Codeによると_0はYaesu FT3Dのモデルコード。
Beacon Textについて
FT3DのBeacon ステータステキストにHello WorldをセットしてBeaconを送信してみた。以下、ピンクの所に挿入された。つまり。モデルコードの前。モデルコードがビーコン情報の最後に位置するようだ。言い換えるとAPRSスペック1.01に記載されているフォーマットに付加される形でモデルコードが追加されたことがわかる。
06:07:04R JA0WBT-7>SUTPW9,WIDE1-1 Port=1 <UI R Len=28>:`AB(l-=[/`"9N}Hello World_0
結果
以上より、FT3Dから発信されているビーコン情報は以下のとおりとなる。
北緯 35度40.79分
東経 137度38.12分
速度 0ノット
進路 56度
シンボル RUNNER
海抜 529m
無線機コード Yaesu FT3D
以上