'************************************************************************** ' ' グライダー移動体管理システム GPRS: Glider Position Reporting System ' PIC I/F Box Firmwear Ver.WPT_070409 ' ' 位置表示(WPT管理版/高度管理版(要20字*4行LCD) ) ' ' Copyrighted by Kazuo Nakazawa kazuo@valley.ne.jp ' ' ' 受信したIC-U1のGPS NMEAデータへGGAセンテンスからWPLセンテンスを追加し、 ' GPSへ送信することで、受信した他機の平面位置が確認できる。 ' 20字*4行LCDを追加することで、最大8機まで高度(GPS高度1m単位切捨)が確認出来る。 ' ' <課題> ' 通信が設定できなかった場合、位置更新は設定された間隔のn倍の間隔で遅れる。 ' 通信が途絶えると、最後の位置で固定される。ただし8局まで。<対応済み050201> ' 非同期通信のため、通信が輻輳した時のデータは保証できない。 ' ' ' ' ==IC-U1設定== ' シリアル設定は4800bps,8bit DATA, 1bit STOP, Non Parity ' NMEAはGGAセンテンスのみの ' PICの自動送出を使う場合はIC-U1の自動送信設定を行わない。(PTTコントロールプラグを使わない) ' (IC-U1で管理する場合はGPSデータは30秒間隔(最小)の自動送信。送信が輻輳する場合は間隔を空ける) ' Call Sign, Massageは","含めて44字(8+1+35)<050205仕様変更> ' Massage最初の6桁に機体番号(******)またはフライトサービス名(******)を6桁で入力 ' ' ==エラー処理== ' 少しでもおかしいデータはハングアップ防止のために使わない。 ' NMEAは最初の"$"が無いと認識をしない。 ' NMEAは一行が72字を超えたらエラーとして読み飛ばす(64-72)。WPL出力無し。 ' Call Sign, Massageは合計44字(,含む)に達したら切り捨て。WPL出力無し。 ' Serial Time Outでデータが連続では、上限で読み飛ばされる。WPL出力無し。 ' DATA途中欠落でCRまたはLFある場合、WPL出力無し。 ' DATA構造に問題ある場合、WPL出力無し。 ' GGAで非測位フラッグがある場合、WPL出力無し。 ' 管理機数回数ロストした場合、その局はギニア湾(N00/E00)へ移動する。<050202> ' ただし、同時受信9局目からは管理出来ない。超えたものでロストすると染み付く。 ' ' ==バグ修正== ' 高度999mまでしか対応していなかったのを修正<050202> ' 配列容量不足でMassageを40字へ削減<050202> ' 配列容量不足で最大管理機数を9->8へ削減<050202> ' ロスト処理が繰り返されるのを修正<050202> ' 配列容量不足でMassageを30字へ削減<050204> ' GGAの高度データ部分の解釈が間違っていたのを修正<050204> ' Call Sign, Massageは","含めて44字(8+1+35)<050205仕様変更> ' LCDへ受信状態、機番、高度を2列*4行で8局表示をするようにした。(二次開発分)<050204> ' Massage構文チェックが抜けていたのを修正。<050207> ' Massage最小字数管理を行うようにした。<050207> ' LCDの表示を改善した。<050208-9,13> ' −高度の処理を追加した。<050213> ' REMARKを追加・修正<050214> ' 国籍管理を止めた。機番の下4桁のみ使用。アルプスでの重複は仕方ない。<050214> ' NMEA出力設定ミス対策を強化。<050216> ' 最後の1機もロスト処理を行えるようにした。PTT2サイクル受信できないと3サイクル目にロスト処理する。<050221> ' 国籍管理復活。通信不安定の際、コメント行の頭が途切れ化けデータが来ることが多いため、これでチェックする。<050228> ' シリアル受信時のWaitを整理した。GGAセンテンスで80msかかるので200msとして、Sleepも200msとした。<050228> ' オリジナルNMEA(GGA)/CALL Signスルー出力止めた。<050414> ' PTTのホールドタイムを25msから200msにして動作を安定させた。<050414> ' 処理が増えてPTT間隔が長くなっていたのを修正。<050414> ' Call Sign, Massageのフォーマットを短くして29字とした<050419> ' GGAの時間でPTTコントロールをしようとしたがうまく行かない<050419> ' GGAの時間でPTTコントロールするようにした。毎0秒から2秒間隔でPTT。間隔はファームを書き換える<050420> ' 結局上手く行かず中途半端<050511> ' GGAの時間でPTTコントロールするようにした。NMEAから時間を取って、オフセットで管理。時間が取れない場合は強制動作<050512> ' 050512でテストの結果、1秒間隔では同期が不安定のため、マージンを増やして60秒で30機程度の管理を考慮するルーチンを検討<050513> ' ' ===メジャーチェンジ=== ' <051006> ' 自位置の送信PTTコントロールと他局の信号処理を1個のPICで処理することを諦め、別系統とすることにした。 ' 自位置の送信PTTコントロールは、自らのGPSのNMEAラインを分岐してPTT処理専用PICでGGAセンテンスから得、20秒間隔で10局(1局当たりPTT間隔は2秒)とした。 ' これに伴い、ケーブルを修正した。 ' GPS-TxDを2分岐してPTT処理専用PICと位置表示処理PICへ結線。 ' 位置表示処理PICから出ていたPTTコントロール線は切断し、PTT処理専用PICから出す。 ' <051012> ' NMEA信号を待っている間はLEDを消し、処理中はONにする。 ' ' ' <070403> ' ---------高度処理が不完全だったので、051012へ戻す-------- ' <051121> ' Lat/Lonの度数を3桁可能にし、全世界対応にした。(これまで2桁/3桁のみ) ' "JA"で機番チェックをしていたがやめた。 ' 機番は2+4桁とし、表示は後半4桁とした ' --------- ' ' <070403> ' 移動局が遠くなった際にコールサインの文字化けが多くなるのは、Serin pb4800,200のwaitが100となっていた点を疑い、200msecに直す。 ' ' <070404> ' NMEAセンテンスのチェックを外していたものを再度採用し厳しくした。 ' 機番部分は数字と大文字アルファベットに限定した。 ' これで明らかにおかしいエラーは無くなるが、もっともらしいエラーは残る。 ' ' ' <070404> ' ロストした際にGPS上の位置をギニア沖へ飛ばし擬似的に消去したがこれを変更し、LCDの機番IDの頭に"X"を付け、最後にロストしたところを残すようにした。 ' これによって救援等の対策が取れる。 ' 機番を機番IDとして2桁の二重送信にし照合チェックを入れた。そのためLCD表示も2桁化した。 ' LCDの表示に2桁余裕が出来たので、表示を少し変えた。 ' ' ' ' ' ' ----------------------------------------------------------------------- ' $GPGGA,165554,3653.0322,N,13797.3792,E,1,08,0.9,545.2,M,46.3,M,,*42 ' 12345678,JA50MB12345678901234567890123456789 ' ----------------------------------------------------------------------- ' <上記の変換例> ' ----------------------------------------------------------------------- ' $GPWPL,3653.0322,N,13797.3792,E,JA50MB* ' $GPGGA,165554,3653.0322,N,13797.3792,E,1,08,0.9,545.2,M,46.3,M,,*42 ' 12345678,JA50MB12345678901234567890123456789 ' ----------------------------------------------------------------------- ' ' ' ' ' ・長さ ' Call Sign(8)+,(1)+ Massage(20) = 29 ' ・内容 ' Call Sign(8) :アマチュア無線コールサイン ' ,(1) :区切り記号 ' Massage(20) :1-6 6字 機体番号(JA****) ' :7-10 4字 GPRS-ID(0000-9999左0詰) ' :11-14 4字 IDENT(0000-9999左0詰,トランスポンダに準拠する) ' :15-18 4字 メッセージ相手機番(デフォルト9999) ' :19-20 2字 ポーリング要求コマンド(00-99:未定) '--070409-- '機番を機番IDとして2桁*2回送信としてエラーチェックするようにした。 ''12345678,JAMBMB78901234567890 (全44字=8+1+20) '"JA"の部分2桁の使い方は今後考える。 ' ' ' ' ' '************************************************************************** '初期化 Dim nmea_s(75) As Byte 'NMEA Dim call_s(32) As Byte 'Call Sign Dim l As Byte 'カウンター Dim tc As Byte 'Timeカウンター Dim n As Byte 'カウンター Dim m As Byte '移動体配列カウンター Dim m_ob_0(9) As Byte '移動体管理用配列、更新頻度 1(アップデート)、99(ロスト) Dim m_ob_1(9) As Byte '移動体管理用配列、機番1桁目 Dim m_ob_2(9) As Byte '移動体管理用配列、機番2桁目 Dim m_ob_3(9) As Byte '移動体管理用配列、機番3桁目 Dim m_ob_4(9) As Byte '移動体管理用配列、機番4桁目 Dim m_ob_5(9) As Word '移動体管理用配列、高度データ(二次開発用リザーブ) '移動体管理用配列を" "でクリアしておく。 For n=0 To 8 m_ob_1(n)=32 Next n For n=0 To 8 m_ob_2(n)=32 Next n For n=0 To 8 m_ob_3(n)=32 Next For n=0 To 8 m_ob_4(n)=32 Next n Initlcd 'LCDイニシャライズ Serclear 'シリアル・バッファ・クリア tc=0 'Timeカウンターに0をセット ' High RD.Bit7 'RD.Bit7をHigh(PTT OFF)にする。PTTへ配線必要。 ' High RD.Bit6 'RD.Bit6をHigh(LED ON)にする。LEDへ配線必要。 Low RD.Bit6 'RD.Bit6をLow(LED OFF)にする。LEDへ配線必要。 Setpos 0,0:Putlcd "_Glider Position" Setpos 0,1:Putlcd " Reporting System_" Setpos 0,2:Putlcd "_Copyrighted by" Setpos 0,3:Putlcd " kazuo@valley.ne.jp_" Setpos 19,3 Sleep 1000 '************************************************************************** main: 'メインルーチン '************************************************************************** 'MNEA行を読む。 'DVのシリアル実効速度は約950bpsなので、GGAを74byte読んだ場合、約80ms掛かる。>>>計算一桁違う?? 'したがって、2倍以上マージンとって、シリアルのWaitは200msとする。 Low RD.Bit6 'RD.Bit6をLow(LED OFF)にする。NMEA信号を待っている間はLEDを消し、処理中はONにする。 l=0 '受信time outでロスト処理に使うためリセットしておく wait_top: '行頭("$")を待つ。 tc=tc+1 '"$"待ちカウンター、1サイクルでインクリメント If tc>150 Then tc=1:Gosub sub_time_out '150(PTT間隔の20秒)になったら受信time out動作。tcリセットしてから動作。 '相手局の受信を待つが、受信が無かったらロスト処理する。 'GGA受信が処理のトリガーのため、最後の1局はこの強制処理が必要。 Serin pb4800,200,nmea_s(1) If nmea_s(1)<>36 Then Goto wait_top '"$"が来るまで待つ High RD.Bit6 'RD.Bit6をHigh(LED ON)にする tc=1 'NMEAが来たので受信time out処理はリセット。 n=2 '"$"をチェックしたので2桁目から行末まで読む。 nmea_read: If n>74 Then Goto error '一行が74(76-2)字を超えたらエラーとして読み飛ばし。GGA前提。 Serin pb4800,200,nmea_s(n) If nmea_s(n)<>10 Then n=n+1:Goto nmea_read 'LFだったら行末として終了。 If 66>n Then Goto error '一行が64(66-2)より短かったらエラーとして読み飛ばし。GGA前提。 '構造エラーチェック(GGAセンテンス用) '#PGGGAを前提にチェックしているが、判断を入れれば他のセンテンスもチェック出来る '#その上で分岐すれば、例えばRMCセンテンスを使えば対地速度、進行方位も出せる If nmea_s(2)<>71 Then Goto error 'Gでなければエラー If nmea_s(3)<>80 Then Goto error 'Pでなければエラー If nmea_s(4)<>71 Then Goto error 'Gでなければエラー If nmea_s(5)<>71 Then Goto error 'Gでなければエラー If nmea_s(6)<>65 Then Goto error 'Aでなければエラー If nmea_s(13)<48 Or nmea_s(13)>57 Then Goto error '数字か? GPS時間の1秒部分のチェック If nmea_s(14)<>44 Then Goto error ',か? If nmea_s(15)<48 Or nmea_s(15)>57 Then Goto error '数字か? If nmea_s(16)<48 Or nmea_s(16)>57 Then Goto error '数字か? If nmea_s(17)<48 Or nmea_s(17)>57 Then Goto error '数字か? If nmea_s(18)<48 Or nmea_s(18)>57 Then Goto error '数字か? If nmea_s(19)<>46 Then Goto error '.か? If nmea_s(20)<48 Or nmea_s(20)>57 Then Goto error '数字か? If nmea_s(21)<48 Or nmea_s(21)>57 Then Goto error '数字か? If nmea_s(22)<48 Or nmea_s(22)>57 Then Goto error '数字か? If nmea_s(23)<48 Or nmea_s(23)>57 Then Goto error '数字か? If nmea_s(24)<>44 Then Goto error ',か? If nmea_s(25)<>78 And nmea_s(25)<>83 Then Goto error 'NでもSでも無いならエラー If nmea_s(26)<>44 Then Goto error ',か? If nmea_s(27)<48 Or nmea_s(27)>57 Then Goto error '数字か? If nmea_s(28)<48 Or nmea_s(28)>57 Then Goto error '数字か? If nmea_s(29)<48 Or nmea_s(29)>57 Then Goto error '数字か? If nmea_s(30)<48 Or nmea_s(30)>57 Then Goto error '数字か? If nmea_s(31)<48 Or nmea_s(31)>57 Then Goto error '数字か? If nmea_s(32)<>46 Then Goto error '.か? If nmea_s(33)<48 Or nmea_s(33)>57 Then Goto error '数字か? If nmea_s(34)<48 Or nmea_s(34)>57 Then Goto error '数字か? If nmea_s(35)<48 Or nmea_s(35)>57 Then Goto error '数字か? If nmea_s(36)<48 Or nmea_s(36)>57 Then Goto error '数字か? If nmea_s(37)<>44 Then Goto error ',か? If nmea_s(38)<>69 And nmea_s(38)<>87 Then Goto error 'EでもWも無いならエラー If nmea_s(39)<>44 Then Goto error ',か? If nmea_s(40)<>49 And nmea_s(40)<>50 Then Goto error '1-単独、2-DGPSでなければエラー '以降高度をチェックする際は可変長になるので要注意。 '************************************************************************** 'Call Sign行を29字または行末まで読む。 'GGAの次はCallSignのはずだがセッティングの間違いを想定してNMEAから読みをするかチェックする '美しくない方法なので、行単位のチェックとしてサブルーチン化して全面的に書き換える必要有り n=1 call_read_chk: Serin pb4800,200,call_s(n) '1文字読んでみる If call_s(n)<>36 Then n=2:Goto call_read '"$"でなければたぶんCallSignなので処理に移る call_read_chk_LF: '"$"なので"LF"まで空読みする Serin pb4800,200,call_s(n) '1文字読んでみる If call_s(n)<>10 Then Goto call_read_chk_LF '"LF"でなければ"LF"が来るまで空読みする Goto call_read_chk '続いて次行をチェックする 'Call Sign行読み本体 '1文字目は上のチェックで読んでいるので、2文字目から読むようにジャンプして来ている call_read: If n>30 Then Goto error '30字以上はエラーとして読み飛ばし。 Serin pb4800,200,call_s(n) If call_s(n)<>13 Then n=n+1:Goto call_read 'CRだったら行末として終了。 '構造エラーチェック '構造チェックは9文字目の","と長さチェックくらいしか方法が無い 'Call Signの最初の2文字が"JA"または"NA"で無いとエラー、構造に問題あればエラー ←止め '12345678,JA50MB78901234567890 (全44字=8+1+20) ←止め 'フライトサービスを"NAGANO"と想定しているため"NA"でチェックしている ←止め '--070409-- '機番を機番IDとして2桁*2回送信としてエラーチェックするようにした。 ''12345678,JAMBMB78901234567890 (全44字=8+1+20) '"JA"の部分2桁の使い方は今後考える。 ' '機番までの長さが15(8+1+6)無ければエラー '機番は数字または大文字英数字でなければエラー If call_s(9)<>44 Then Goto error '9文字目が","でなかったらエラー 'If call_s(11)<>65 Then Goto error '11文字目がAでなければエラー 'If call_s(10)<>74 And call_s(10)<>78 Then Goto error '10文字目がJまたはNでなければエラー If n<16 Then Goto error '15文字未満だったらエラー If call_s(12)<48 Or call_s(12)>90 Then Goto error '12文字目が数字または大文字英数字でなければエラー If call_s(12)>57 And call_s(12)<65 Then Goto error '12文字目が数字または大文字英数字でなければエラー If call_s(13)<48 Or call_s(13)>90 Then Goto error '13文字目が数字または大文字英数字でなければエラー If call_s(13)>57 And call_s(13)<65 Then Goto error '13文字目が数字または大文字英数字でなければエラー If call_s(14)<48 Or call_s(14)>90 Then Goto error '14文字目が数字または大文字英数字でなければエラー If call_s(14)>57 And call_s(14)<65 Then Goto error '14文字目が数字または大文字英数字でなければエラー If call_s(15)<48 Or call_s(15)>90 Then Goto error '15文字目が数字または大文字英数字でなければエラー If call_s(15)>57 And call_s(15)<65 Then Goto error '15文字目が数字または大文字英数字でなければエラー If call_s(12)<>call_s(14) Then Goto error '12と14文字目が同じでなければエラー If call_s(13)<>call_s(15) Then Goto error '13と15文字目が同じでなければエラー '************************************************************************** 'NMEAセンテンス出力 make_wpl: 'このLCDコントロールにシリアルが使われているためシリアルの処理と重ならない様にwaitを入れる。 'シリアルのwaitが200msなので、Sleepも200ms入れるが、シリアルはタイムアウトした場合、以前の '受信内容を持っているため、LCDのコントロールで化けないまでも、正しくない可能性はある。 'Sleepの値の計算がおかしいように思うが、Sleep を入れないとごみが入る。 Sleep 200 '************************************************************************** 'WPL出力前にWPT管理を行う。 Gosub sub_chk_m_ob 'WPTの更新状況を確認する。 Gosub move_lost '管理機数回数の未受信があったら、ロスト処理(としてギニア湾(N00/E00)へ移動) 'ロスト処理は070409に変更あり。 '************************************************************************** 'WPLセンテンスを出力。(固定長決め打ち,GARMIN Viat/Legend/GPS V(E/J)/Geko201/GPMAP60CS等) Serout pb4800,"$GPWPL," n=15 'GGAセンテンスの経緯度は15番目から始まる。決め打ち。 wpl_serout: Serout pb4800,chr$(nmea_s(n)) '繰り返し出力 If nmea_s(n)<>69 And nmea_s(n)<>87 Then n=n+1:Goto wpl_serout 'E or Wなら経緯度出力終了、","を付けて、Call Sign出力へ Serout pb4800,",+" 'GPS表示の頭に"+"を付けた。 'n=10 '10文字目からJAナンバー分の6文字を出力する。国籍管理版。 n=12 '12文字目から"国籍"を抜いて4文字をGPSへ出力する。 'GPSの画面が煩い場合有効だが、GPSのWPT管理でソートしても並ばない。 '変更時はロスト処理の"国籍"抜きも忘れずに。 wpl_call: Serout pb4800,chr$(call_s(n)) If n<>13 Then n=n+1:Goto wpl_call Serout pb4800,"*",chr$(13),chr$(10) '"*"+CR+LF '************************************************************************** 'オリジナルNMEA(GGA)センテンス出力 ' n=1 'nmea_gga_serout: ' Serout pb4800,chr$(nmea_s(n)) ' If nmea_s(n)<>13 Then n=n+1:Goto nmea_gga_serout 'CRまで出力する。 ' Serout pb4800,chr$(10) 'LFがあるか不明なのでCRで止め、LFを追加する。 '************************************************************************** 'オリジナルCALL Sign出力 ' n=1 'u1_call_serout: ' Serout pb4800,chr$(call_s(n)) ' If call_s(n)<>13 Then n=n+1:Goto u1_call_serout 'CRまで出力する。 ' Serout pb4800,chr$(10) 'LFがあるか不明なのでCRで止め、LFを追加する。 '************************************************************************** 'LCD表示用サブルーチンへ Gosub sub_lcd '更新した結果をLCDへ表示する。 '************************************************************************** Goto main 'サイクル終了、最初へ。 '************************************************************************** error: 'エラー処理 '現在、何も処理なし。 Serclear 'LCDコントロールのためのシリアル制御が残っているといけないので、一応シリアルをクリアしておく。 Goto wait_top '************************************************************************** '************************************************************************** 'サブルーチン群 '************************************************************************** 'NMEAセンテンス待ち受け中に受信time out動作のためのサブルーチン sub_time_out: l=l+1 If l<2 Then Return '受信time outサイクルだけで動いている場合は、lがインクリメントされる。 'これが"2"(PTT間隔2回、40秒)より大きくなったらどこからも受信出来ないとして、総をロスト処理する。 l=0 time_lost_until_ptt: '更新カウンター m_ob_0(l)を見て、受信経歴があってロスト処理していないところを総てロスト処理する。 '99(ロスト)扱いのところをロスト処理して、100(ロスト+1)にして、作業重複を避ける。 'm_ob_0(m)=99,100がロスト。99は無線受信でロスト処理されたもの。100は受信time outでロスト判断されたもの。 'If m_ob_0(l)>0 And m_ob_0(l)<99 Then m_ob_0(l)=100:Serout pb4800,"$GPWPL,0000.0000,N,00000.0000,E,",chr$(m_ob_1(l)),chr$(m_ob_2(l)),chr$(m_ob_3(l)),chr$(m_ob_4(l)),"*",chr$(13),chr$(10) If m_ob_0(l)>0 And m_ob_0(l)<99 Then m_ob_0(l)=100 'ロストした時にギニア湾沖へ移動しないパターン l=l+1 If l<8 Then Goto time_lost_until_ptt Gosub sub_lcd '更新した結果をLCDへ表示する。 Return '元へ戻る '************************************************************************** 'NMEA受信、WPL出力前にWPT管理を行うサブルーチン sub_chk_m_ob: 'WPT管理のSTART If m_ob_0(0)=0 Then Gosub sub_add_m_ob:Return '最初は新規追加をしてメインへ戻る。 'WPT_Add管理のルーチン n=0 'n=0は新規の意味 m=0 chk_m_ob_add: 'WPT_Add管理のーチン If m_ob_1(m)=call_s(12) And m_ob_2(m)=call_s(13) Then If m_ob_3(m)=call_s(14) And m_ob_4(m)=call_s(15) Then n=n+1 If m_ob_0(m)=0 Then If n=0 Then Gosub sub_add_m_ob:n=n+1 '更新チェック確認して同じもの無ければ新規追加をして次へ。 m=m+1 If m<8 Then Goto chk_m_ob_add '0〜7=8機を超えたら次へ。全8機管理が前提。 'WPT_Update管理のルーチン m=0 chk_m_ob_update: 'WPT_Update管理のルーチン Gosub sub_chk_update '異なれば更新チェックに+1する、同じなら1(アップデート)にする。 m=m+1 If m_ob_0(m)=0 Then Return If m>7 Then Return '0〜7=8機を超えたら次へ。全8機管理が前提。 Goto chk_m_ob_update '繰り返し '************************************************************************** 'WPT管理関係サブルーチン '機番を追加して、更新チェックを1(アップデート)にする。 sub_add_m_ob: m_ob_0(m)=1 '更新チェックを1(アップデート) m_ob_1(m)=call_s(12) '機番を追加 m_ob_2(m)=call_s(13) '機番を追加 m_ob_3(m)=call_s(14) '機番を追加 m_ob_4(m)=call_s(15) '機番を追加 '機番追加に併せて、高度の表示設定を行う。−高度は(NULm)にセットする。 '10mレベル If nmea_s(51)=46 Then If nmea_s(49)=45 Then m_ob_5(m)=0:Return Else m_ob_5(m)=(nmea_s(49)-48):Return '100mレベル If nmea_s(52)=46 Then If nmea_s(49)=45 Then m_ob_5(m)=0:Return Else m_ob_5(m)=(nmea_s(49)-48)*10+(nmea_s(50)-48):Return '1000mレベル If nmea_s(53)=46 Then If nmea_s(49)=45 Then m_ob_5(m)=0:Return Else m_ob_5(m)=(nmea_s(49)-48)*100+(nmea_s(50)-48)*10+(nmea_s(51)-48):Return '10000mレベル If nmea_s(54)=46 Then If nmea_s(49)=45 Then m_ob_5(m)=0:Return Else m_ob_5(m)=(nmea_s(49)-48)*1000+(nmea_s(50)-48)*100+(nmea_s(51)-48)*10+(nmea_s(52)-48):Return m_ob_5(m)=0 'フォーマットに一致しないので、高度を0(NULm)にセットする。 Return 'm番の機番が異なるチェックする。異なれば更新チェックに+1する。 sub_chk_update: If m_ob_1(m)<>call_s(12) Then If m_ob_0(m)=99 Then Return Else m_ob_0(m)=m_ob_0(m)+1:Return '異なるので更新チェックに+1して戻る。99(ロスト)なら+1しない。 If m_ob_2(m)<>call_s(13) Then If m_ob_0(m)=99 Then Return Else m_ob_0(m)=m_ob_0(m)+1:Return '異なるので更新チェックに+1して戻る。99(ロスト)なら+1しない。 'If m_ob_3(m)<>call_s(14) Then If m_ob_0(m)=99 Then Return Else m_ob_0(m)=m_ob_0(m)+1:Return '異なるので更新チェックに+1して戻る。99(ロスト)なら+1しない。 'If m_ob_4(m)<>call_s(15) Then If m_ob_0(m)=99 Then Return Else m_ob_0(m)=m_ob_0(m)+1:Return '異なるので更新チェックに+1して戻る。99(ロスト)なら+1しない。 '機番のチェック(4文字)をして、同じなら下で高度の更新を行う。 '機番チェックに併せて、高度の更新を行う。−高度は(NULm)にセットする。 '10mレベル If nmea_s(51)=46 Then If nmea_s(49)=45 Then m_ob_5(m)=0:m_ob_0(m)=1:Return Else m_ob_5(m)=(nmea_s(49)-48):m_ob_0(m)=1:Return '100mレベル If nmea_s(52)=46 Then If nmea_s(49)=45 Then m_ob_5(m)=0:m_ob_0(m)=1:Return Else m_ob_5(m)=(nmea_s(49)-48)*10+(nmea_s(50)-48):m_ob_0(m)=1:Return '1000mレベル If nmea_s(53)=46 Then If nmea_s(49)=45 Then m_ob_5(m)=0:m_ob_0(m)=1:Return Else m_ob_5(m)=(nmea_s(49)-48)*100+(nmea_s(50)-48)*10+(nmea_s(51)-48):m_ob_0(m)=1:Return '10000mレベル If nmea_s(54)=46 Then If nmea_s(49)=45 Then m_ob_5(m)=0:m_ob_0(m)=1:Return Else m_ob_5(m)=(nmea_s(49)-48)*1000+(nmea_s(50)-48)*100+(nmea_s(51)-48)*10+(nmea_s(52)-48):m_ob_0(m)=1:Return m_ob_5(m)=0 'フォーマットに一致しないので、高度を0(NULm)にセットする。 m_ob_0(m)=1:Return '機番が同じなので更新チェックを1(アップデート)にして戻る。 '************************************************************************** '管理機数回数の未受信があったら、ロストとしてギニア湾(N00/E00)へ移動するためのサブルーチン '#もうちょっとスマートな方法がないかと思うが・・・ move_lost: m=0 n=1 m_ob_count: '管理している機数をカウントする ' If m_ob_0(m)>0 And m_ob_0(m)<=99 Then n=n+1 '総管理機数 If m_ob_0(m)>0 And m_ob_0(m)<99 Then n=n+1 'アクティブ管理機数。受信出来ている機数だけのカウントで考えれば良い。 m=m+1 If m<8 Then Goto m_ob_count '管理機数回数の間+1回、未受信があったら、ロストとしてギニア湾(N00/E00)へ移動した上でm_ob_0(m)=99として処理する。 'n+0で上記の条件。順番を1回遅れてもロストにならないが、2回目はロスト扱いになる。 m=0 chk_move_lost: '下の判断基準を変えるとロスト処理の猶予が変わる。 'ただしLCDは1桁しか表示を取っていないので表示を検討すること。 'If m_ob_0(m)>n+0 And m_ob_0(m)<99 Then m_ob_0(m)=99:Gosub sub_move_lost '--070409-- If m_ob_0(m)>n+0 And m_ob_0(m)<99 Then m_ob_0(m)=99 ':Gosub sub_move_lostしないことで、ロストした際にギニア沖へ飛ばさない。 '--070409-- '国籍管理版は"JA"の部分を国に合せて決め打ちで使う。WPLセンテンスを出力ルーチンの修正も忘れずに。 'If m_ob_0(m)>n+0 And m_ob_0(m)<99 Then m_ob_0(m)=99:Serout pb4800,"$GPWPL,0000.0000,N,00000.0000,E,JA",chr$(m_ob_1(m)),chr$(m_ob_2(m)),chr$(m_ob_3(m)),chr$(m_ob_4(m)),"*",chr$(13),chr$(10) 'If m_ob_0(m)>n+0 Then m_ob_0(m)=99 'ロスト処理したものは99として処理外にする。 m=m+1 If m_ob_0(m)<>0 Then Goto chk_move_lost 'm_ob_0(m)=0:データなしまで行ったら戻る。それまでは管理機数をカウントしながらロスト処理。 Return '************************************************************************** '--070409--でこのツーチンを使わなくした。他で$GPWPLの出力時の変更をする。 'ロストした際、ギニア湾(N00/E00)へ移動させるためのWPLセンテンスを発行するサブルーチン 'ここをDIPスイッチの設定で変えるようにすれば、ロスト位置を残すように出来る。 'm_ob_0(m)=99であるので、これを変え、LCDの判断を変えればロストした時の状況別の表示が可能。 '遭難救助を目的として、最後のロスト位置を"x****"と言うような表示で残すことも検討したい。<暇が出来たらね。 sub_move_lost: Serout pb4800,"$GPWPL,0000.0000,N,00000.0000,E,",chr$(m_ob_1(m)),chr$(m_ob_2(m)),chr$(m_ob_3(m)),chr$(m_ob_4(m)),"*",chr$(13),chr$(10) 'ロストした時にギニア湾沖へ移動しないパターンは、上の行のコメントアウト Return '************************************************************************** 'LCD表示用サブルーチン '管理している機の更新数、機番、高度をLCDへ表示。(二次開発分) '高度は1/10m単位、桁数を見て右詰にしている。 '高度はWPT管理サブルーチンで代入している。数値の最初に"-"がある場合は"0(NULm)"をセットしている。 'デバッグのために項目1桁目に更新頻度を入れている。実際にはロスト時のみの出力が良い。<現在そうしている。 '例) If m_ob_0(0)=99 Then "*" Else " " '2元配列が使えないため、見苦しいが位置を変えながら繰り返しになっているだけ。 'm_ob_0(m)=99,100がロスト。99は無線受信でロスト処理されたもの。100は受信time outでロスト判断されたもの。 sub_lcd: Initlcd 'LCDイニシャライズ、更新毎にLCDをクリアして書き直す。 '1行目、1列 (受信1番目) Setpos 0,0 '更新頻度 1(データアップデート:表示"・")、99以上(ロスト,表示"x")、その他は空白 If m_ob_0(0)=1 Then Putlcd "・" Else If m_ob_0(0)>=99 Then Putlcd "x" Else Putlcd " " Setpos 8,0 If m_ob_0(0)=1 Then Putlcd "・" Else If m_ob_0(0)>=99 Then Putlcd "x" Else Putlcd " " Setpos 1,0 'Putlcd chr$(m_ob_1(0)),chr$(m_ob_2(0)),chr$(m_ob_3(0)),chr$(m_ob_4(0)) '機番 Putlcd chr$(m_ob_1(0)),chr$(m_ob_2(0)) '機番ID '高度(m)の桁数をカウントして右詰をしている。高度があれば高度を、高度が10m(未満)は"-"を、それ以外は"?"を表示。?はありえない? '機番ID化で高度表示を2桁左へずらした。 'If m_ob_5(0)>999 Then Setpos 5,0 Else If m_ob_5(0)>99 Then Setpos 6,0 Else If m_ob_5(0)>9 Then Setpos 7,0 Else Setpos 8,0 If m_ob_5(0)>999 Then Setpos 5,0 Else If m_ob_5(0)>99 Then Setpos 6,0 Else If m_ob_5(0)>9 Then Setpos 5,0 Else Setpos 6,0 If m_ob_5(0)>0 Then Putlcd (m_ob_5(0)),"0" Else If m_ob_5(0)=0 Then Putlcd " -" Else Putlcd " ?" '機番ID化の変更処理は他も同様に変更した。履歴残さず。 '1行目、2列 (受信2番目) Setpos 10,0 If m_ob_0(1)=1 Then Putlcd "・" Else If m_ob_0(1)>=99 Then Putlcd "x" Else Putlcd " " Setpos 18,0 If m_ob_0(1)=1 Then Putlcd "・" Else If m_ob_0(1)>=99 Then Putlcd "x" Else Putlcd " " Setpos 11,0 Putlcd chr$(m_ob_1(1)),chr$(m_ob_2(1)) If m_ob_5(1)>999 Then Setpos 15,0 Else If m_ob_5(1)>99 Then Setpos 16,0 Else If m_ob_5(1)>9 Then Setpos 15,0 Else Setpos 16,0 If m_ob_5(1)>0 Then Putlcd (m_ob_5(1)),"0" Else If m_ob_5(1)=0 Then Putlcd " -" Else Putlcd " ?" '2行目、1列 (受信3番目) Setpos 0,1 If m_ob_0(2)=1 Then Putlcd "・" Else If m_ob_0(2)>=99 Then Putlcd "x" Else Putlcd " " Setpos 8,1 If m_ob_0(2)=1 Then Putlcd "・" Else If m_ob_0(2)>=99 Then Putlcd "x" Else Putlcd " " Setpos 1,1 Putlcd chr$(m_ob_1(2)),chr$(m_ob_2(2)) If m_ob_5(2)>999 Then Setpos 5,1 Else If m_ob_5(2)>99 Then Setpos 6,1 Else If m_ob_5(2)>9 Then Setpos 5,1 Else Setpos 6,1 If m_ob_5(2)>0 Then Putlcd (m_ob_5(2)),"0" Else If m_ob_5(2)=0 Then Putlcd " -" Else Putlcd " ?" '2行目、2列 (受信4番目) Setpos 10,1 If m_ob_0(3)=1 Then Putlcd "・" Else If m_ob_0(3)>=99 Then Putlcd "x" Else Putlcd " " Setpos 18,1 If m_ob_0(3)=1 Then Putlcd "・" Else If m_ob_0(3)>=99 Then Putlcd "x" Else Putlcd " " Setpos 11,1 Putlcd chr$(m_ob_1(3)),chr$(m_ob_2(3)) If m_ob_5(3)>999 Then Setpos 15,1 Else If m_ob_5(3)>99 Then Setpos 16,1 Else If m_ob_5(3)>9 Then Setpos 15,1 Else Setpos 16,1 If m_ob_5(3)>0 Then Putlcd (m_ob_5(3)),"0" Else If m_ob_5(3)=0 Then Putlcd " -" Else Putlcd " ?" '3行目、1列 (受信5番目) Setpos 0,2 If m_ob_0(4)=1 Then Putlcd "・" Else If m_ob_0(4)>=99 Then Putlcd "x" Else Putlcd " " Setpos 8,2 If m_ob_0(4)=1 Then Putlcd "・" Else If m_ob_0(4)>=99 Then Putlcd "x" Else Putlcd " " Setpos 1,2 Putlcd chr$(m_ob_1(4)),chr$(m_ob_2(4)) If m_ob_5(4)>999 Then Setpos 5,2 Else If m_ob_5(4)>99 Then Setpos 6,2 Else If m_ob_5(4)>9 Then Setpos 5,2 Else Setpos 6,2 If m_ob_5(4)>0 Then Putlcd (m_ob_5(4)),"0" Else If m_ob_5(4)=0 Then Putlcd " -" Else Putlcd " ?" '3行目、2列 (受信6番目) Setpos 10,2 If m_ob_0(5)=1 Then Putlcd "・" Else If m_ob_0(5)>=99 Then Putlcd "x" Else Putlcd " " Setpos 18,2 If m_ob_0(5)=1 Then Putlcd "・" Else If m_ob_0(5)>=99 Then Putlcd "x" Else Putlcd " " Setpos 11,2 Putlcd chr$(m_ob_1(5)),chr$(m_ob_2(5)) If m_ob_5(5)>999 Then Setpos 15,2 Else If m_ob_5(5)>99 Then Setpos 16,2 Else If m_ob_5(5)>9 Then Setpos 15,2 Else Setpos 16,2 If m_ob_5(5)>0 Then Putlcd (m_ob_5(5)),"0" Else If m_ob_5(5)=0 Then Putlcd " -" Else Putlcd " ?" '4行目、1列 (受信7番目) Setpos 0,3 If m_ob_0(6)=1 Then Putlcd "・" Else If m_ob_0(6)>=99 Then Putlcd "x" Else Putlcd " " Setpos 8,3 If m_ob_0(6)=1 Then Putlcd "・" Else If m_ob_0(6)>=99 Then Putlcd "x" Else Putlcd " " Setpos 1,3 Putlcd chr$(m_ob_1(6)),chr$(m_ob_2(6)) If m_ob_5(6)>999 Then Setpos 5,3 Else If m_ob_5(6)>99 Then Setpos 6,3 Else If m_ob_5(6)>9 Then Setpos 5,3 Else Setpos 6,3 If m_ob_5(6)>0 Then Putlcd (m_ob_5(6)),"0" Else If m_ob_5(6)=0 Then Putlcd " -" Else Putlcd " ?" '4行目、2列 (受信8番目) Setpos 10,3 If m_ob_0(7)=1 Then Putlcd "・" Else If m_ob_0(7)>=99 Then Putlcd "x" Else Putlcd " " Setpos 18,3 If m_ob_0(7)=1 Then Putlcd "・" Else If m_ob_0(7)>=99 Then Putlcd "x" Else Putlcd " " Setpos 11,3 Putlcd chr$(m_ob_1(7)),chr$(m_ob_2(7)) If m_ob_5(7)>999 Then Setpos 15,3 Else If m_ob_5(7)>99 Then Setpos 16,3 Else If m_ob_5(7)>9 Then Setpos 15,3 Else Setpos 16,3 If m_ob_5(7)>0 Then Putlcd (m_ob_5(7)),"0" Else If m_ob_5(7)=0 Then Putlcd " -" Else Putlcd " ?" Setpos 19,3 'カーソルが左上にあるのは綺麗でないので、右下へ下げるだけ Serclear 'LCDコントロールのためのシリアル制御が残っているといけないので、一応シリアルをクリアしておく。 Return '**************************************************************************