NOAA受信システムをPINE64で構築(2)
ひと月試行しながらNOAA受信システムを改良
ハードウェア
USBチューナー(SDRドングル)
右側のチューナーを使用
左側のチューナーでは受信感度が悪い(HDSDRで受信するなら問題は無い)
BPF(バンドパスフィルター)
137MHzのBPFをAliexpressから調達
前後の電波は完全に遮断される(使用するとFM放送は受信不可)が,5dBも低下するのでRFアンプでゲイン向上させないと厳しい
LNA(ローノイズアンプ:低ノイズのRFアンプ)
Amazonから3種調達して比較
評価 | 製品 | 仕様 | 試行画像 |
〇 |
0.1-2000MHz 30dB 9-12V 9V時16mA(実測) (注)12Vでは高ゲインのためかノイズが増加 |
||
0.01-4000MHz 21dB 5V 5V時157mA(実測) 3.3V時138mA(実測) |
|||
◎ |
5-6000MHz 20dB 5V 5V時64mA(実測) |
鮮明なのは一番上だが9Vのため次点とした
残り2つは5Vで変わり映えしないので消費電力の低い方を選択
電源
(PINE64)
DC-INピン(USB電源ラインと直結)から5Vを供給(最終的にはDCDCで5V)
電力は無線LAN,チューナー込みで起動時1.3A程度必要,安定時は600mA位となる
NOAA受信時はチューナーの約300mAとLNAの64mAが加算されるので1Aは必要
長時間の待機時はシステムをサスペンドさせることも検討中
(LNA・FAN)
LNAは受信時以外は必要ないのでGPIOで電源制御する(チューナーは受信起動されていないと省電力)
熱の問題も予想できるのでFANの制御も追加
当初はLNAもFANと同じFETスイッチにしていたが,LNAの回路が絶縁(Gndがアンテナ~チューナー経由で接続)されていなかったためリードスイッチを使用
LNA給電時は赤のLEDを点灯するようにした
ソフトウェア
OS
debianベースの「Armbian_22.08.1_Pine64_bullseye_current_5.15.63.img」を使用した場合
・初期のrootパスワードは「1234」
・hostname, CPUの設定など
$ sudo armbian-config
・フォントの導入
$ sudo apt install task-japanese
$ sudo apt install fonts-vlgothic
・wifi設定
$ sudo armbian-config
ドライバの設定が自動的に行われる
APの設定で完了
GPIO
LNA・FANの電源を制御するためGPIO(PC7, PC8)を使用
GPIOのセットアップ
$ sudo armbian-config
System→Hardwareからpps-gpioを有効にする(スペースキーで有効・無効の切り替え)を行い再起動
一般ユーザがGPIOを利用できるようにする
$ ls -l /dev/gpio*
crw------- 1 root root 254, 0 11月 3 15:46 /dev/gpiochip0
crw------- 1 root root 254, 1 11月 3 15:46 /dev/gpiochip1
crw------- 1 root root 254, 2 11月 3 15:46 /dev/gpiochip2
$ sudo chmod 666 /dev/gpio
起動後に作成されるデバイスなので以下でパーミッションを変更
$ sudo vi /etc/rc.local
gpioは直接操作でなくコマンド経由が推奨されている
$ sudo apt install gpiod
コマンド |
説明 |
gpiodetect |
システムの gpiochips,それらの名称,ラベル,GPIOライン数を一覧表示 |
gpioinfo |
指定した gpiochips の pin番号と名称,ライン番号、アクティブ状態,フラグを一覧表示 |
gpioget |
指定した gpiochips の GPIOの値を読み取る |
gpioset |
指定した gpiochips の GPIOの値を設定 |
gpiofind |
ライン名で gpiochip とオフセットを検索 |
gpiomon |
GPIOでイベントを監視,終了する前に処理するイベントの数,またはイベントを指定 |
コマンドで指定するためGPIOのPC7とPC8のライン番号を探す
gpiochipsを表示
$ gpiodetect
gpiochip0 [1f02c00.pinctrl] (32 lines)
gpiochip1 [1c20800.pinctrl] (256 lines)
gpiochip2 [axp20x-gpio] (2 lines)
それぞれの gpiochips の一覧を表示
(gpiochip0)
$ cat /sys/kernel/debug/pinctrl/1f02c00.pinctrl/pins
registered pins: 13
pin 352 (PL0) 0:1f02c00.pinctrl
pin 353 (PL1) 1:1f02c00.pinctrl
pin 354 (PL2) 2:1f02c00.pinctrl
pin 355 (PL3) 3:1f02c00.pinctrl
pin 356 (PL4) 4:1f02c00.pinctrl
pin 357 (PL5) 5:1f02c00.pinctrl
pin 358 (PL6) 6:1f02c00.pinctrl
pin 359 (PL7) 7:1f02c00.pinctrl
pin 360 (PL8) 8:1f02c00.pinctrl
pin 361 (PL9) 9:1f02c00.pinctrl
pin 362 (PL10) 10:1f02c00.pinctrl
pin 363 (PL11) 11:1f02c00.pinctrl
pin 364 (PL12) 12:1f02c00.pinctrl
(gpiochip1)
$ cat /sys/kernel/debug/pinctrl/1c20800.pinctrl/pins
registered pins: 103
pin 32 (PB0) 32:1c20800.pinctrl
pin 33 (PB1) 33:1c20800.pinctrl
・
・
・
pin 70 (PC6) 70:1c20800.pinctrl
pin 71 (PC7) 71:1c20800.pinctrl
pin 72 (PC8) 72:1c20800.pinctrl
pin 73 (PC9) 73:1c20800.pinctrl
・
・
・
pin 235 (PH11) 235:1c20800.pinctrl
(gpiochip2)
$ cat /sys/kernel/debug/pinctrl/axp20x-gpio/pins
registered pins: 2
pin 0 (GPIO0) 0:axp20x-gpio
pin 1 (GPIO1) 1:axp20x-gpio
PC7とPC8は gpiochip1 の 71と72のラインであることが判る
PC7 FAN ON/OFF
$ gpioset gpiochip1 71=0 #OFF
$ gpioset gpiochip1 71=1 #ON
PC8 ON/OFF
$ gpioset gpiochip1 72=0 #OFF
$ gpioset gpiochip1 72=1 #ON
NOAA受信用シェルスクリプト
表示情報の追加もあり改良
スケジューリング用スクリプト①(schedule_all.sh)
- 変更なし
スケジューリング用スクリプト②(schedule_satellite.sh)
#!/bin/bash
#
# $1 = NOAA [15|18|19]
# $2 = 周波数
# $3 = 出力ディレクトリ
#
# 近接時刻の仰角0~最大~0までのリストから最初と最後を取り出す
PREDICTION_START=`/usr/bin/predict -t /srv/predict/weather.tle -p "${1}" | head -1`
PREDICTION_END=`/usr/bin/predict -t /srv/predict/weather.tle -p "${1}" | tail -1`
# 最後のUTC(var2)
var2=`echo $PREDICTION_END | cut -d " " -f 1`
# 最大仰角度と経度
MAXANGLE=`/usr/bin/predict -t /srv/predict/weather.tle -p "${1}" | awk -v max=0 '{if($5>max){max=$5;kei=$9}}END{print max, kei}'`
# 現地時間で終了が本日
while [ `date --date="TZ=\"UTC\" @${var2}" +%D` = `date +%D` ]
do
# 最大仰角度(MAXELEV),最大時の経度(KEIDO)
MAXELEV=`echo $MAXANGLE | cut -d " " -f 1`
KEIDO=`echo $MAXANGLE | cut -d " " -f 2`
# 衛星の開始と終了緯度
BGIDO=`echo $PREDICTION_START | cut -d " " -f 8`
ENIDO=`echo $PREDICTION_END | cut -d " " -f 8`
if [ $MAXELEV -gt 19 ]
then
# 最初の時刻
START_TIME=`echo $PREDICTION_START | cut -d " " -f 3-4`
# 最初のUTC(var1)
var1=`echo $PREDICTION_START | cut -d " " -f 1`
# 全体時間(秒)
TIMER=`expr $var2 - $var1`
# ローカル日時でファイル名を作成(日付-時刻)
OUTDATE=`date --date="TZ=\"UTC\" $START_TIME" +%Y%m%d-%H%M%S`
# list: $3/schedule.list
# Satellite-Name begin-time end-time maxelev file-name
echo ${1//" "} `date --date="TZ=\"UTC\" @${var1}" +%H:%M:%S` `date --date="TZ=\"UTC\" @${var2}" +%H:%M:%S` $MAXELEV $OUTDATE $var1 $BGIDO $ENIDO $KEIDO >> ${3}/schedule.list
echo "/srv/predict/receive_and_process_satellite.sh \"${1}\" $2 /srv/predict/weather/${OUTDATE}-${1//" "} /srv/predict/weather.tle $var1 $TIMER $3" | at `date --date="TZ=\"UTC\" $START_TIME" +"%H:%M %D"`
fi
# 前回最後の時刻に+1分後以降のリスト
nextpredict=`expr $var2 + 60`
PREDICTION_START=`/usr/bin/predict -t /srv/predict/weather.tle -p "${1}" $nextpredict | head -1`
PREDICTION_END=`/usr/bin/predict -t /srv/predict/weather.tle -p "${1}" $nextpredict | tail -1`
var2=`echo $PREDICTION_END | cut -d " " -f 1`
MAXANGLE=`/usr/bin/predict -t /srv/predict/weather.tle -p "${1}" $nextpredict | awk -v max=0 '{if($5>max){max=$5;kei=$9}}END{print max, kei}'`
done
- 衛星の移動方向を判断するための情報(最大仰角度と経度など)を取得
スケジュールされた受信用スクリプト(receive_and_process_satellite.sh)
#!/bin/bash
# $1 = Satellite Name
# $2 = Frequency
# $3 = FileName base
# $4 = TLE File
# $5 = EPOC start time
# $6 = Time to capture
# $7 = Output directory
# 衛星(NOAA)からFM変調画像を受信
/usr/bin/gpioset gpiochip1 72=1
timeout $6 /usr/local/bin/rtl_fm -f ${2}M -s 160k -g 48 -p 55 -E wav -E deemp -F 9 - | sox -t wav - $3.wav rate 11025
/usr/bin/gpioset gpiochip1 72=0
if [ -e $3.wav ]
then
# MAP作成時刻(時刻をずらすため+90してる訳ではなく範囲に収めている)
PassStart=`expr $5 + 90`
# 受信画像に合わせたMAPを作成
/usr/local/bin/wxmap -T "${1}" -H $4 -p 0 -l 0 -o $PassStart ${3}-map.png
# タイプ別の衛星画像を作成(5種)
for TYPE in MCIR MSA HVCT therm MB
do
# 衛星画像を作成
/usr/local/bin/wxtoimg -B 180 -L 540 -A -n -c -m ${3}-map.png -e $TYPE $3.wav ${3}-${TYPE}.png
# 画像作成が正常か画像サイズから判断
WIDTH=`identify ${3}-${TYPE}.png | cut -d " " -f 3 | cut -d "x" -f 1`
if [ $WIDTH -lt 1200 ]
then
# サムネイル画像を作成
convert -resize 200x800 ${3}-${TYPE}.png ${3}-${TYPE}-s.png
convert -gravity center -crop 200x100+0+0 ${3}-${TYPE}-s.png ${3}-${TYPE}-s.png
# 公開サイトに画像を移動
mv ${3}-${TYPE}.png $7
mv ${3}-${TYPE}-s.png $7
else
rm ${3}-${TYPE}.png
fi
done
fi
- LNAの電源ON・OFFを追加
- 作成画像が正常か(画像サイズから)判断
省電力モード(サスペンドなど)
PINE64は電源管理が実装されているので「rtcwake」が使える
60秒サスペンドして復帰
$ sudo /sbin/rtcwake -m mem -s 60
rtcwake: assuming RTC uses UTC ...
rtcwake: wakeup from "mem" using /dev/rtc0 at Sun Nov 13 11:17:39 2022
$ (復帰)
指定時間に復帰
$ sudo /sbin/rtcwake -m mem -l -t $(date +%s -d "2022-11-13 20:30")
rtcwake: wakeup from "mem" using /dev/rtc0 at Sun Nov 13 11:30:00 2022
$ (復帰)
ラズパイでは電源管理が実装されていないのでPINE64の優位となる機能である
最終的にはバッテリー運用となるため省電力化に有効としているが,画像の公開運用サーバ(リバースプロキシの実装が前提)としてどうかも考えているのでサスペンドさせない運用となることもある