'************************************************************************** ' ' グライダー移動体管理システム G-PRS: Glider Position Reporting System ' PIC I/F(PTT) Box Firmwear Ver.PTT_051209 ' ' PTTコントロール専用版 ' ' Copyrighted by Kazuo Nakazawa kazuo@valley.ne.jp ' ' ************************************************************************* ' PTTコントロール専用Firm ' ************************************************************************* ' 05/10/06 ' GGAセンテンスから60秒時計を得て、20秒に1回のPTTのみ出す。 ' nmea_s(12)、nmea_s(13)が60秒部分。 ' tc_pttがIDに相当する。使用中でも変更可能なように、デジタルスイッチ入力に将来する。 ' 05/10/09 ' RB4,5,6,7を入力ポートとし、デジタルスイッチ入力でtc_ptt値を外部から切り替えする。 ' 端子はプルアップされている。0で1111。 ' 05/10/10 ' RB4,5,6,7を入力ポートとしていたのを、RD3,2,1,0へ変更した。 ' 05/11/28 ' 奇数秒を繰り上げて処理していたが、実処理は1秒遅れでのため次の局の送信をマスクする場合があった。 ' 奇数秒はPTT処理に1秒Waitを入れて遅らせて偶数秒の実時間で処理することにした。 ' 05/12/09 ' 奇数秒の処理に誤りがあったので修正。 ' ' ' ' ' ----------------------------------------------------------------------- ' $GPGGA,105124,3513.0423,N,13757.3870,E,1,07,1.5,594.4,M,36.4,M,,*46 ' $GPGSA,A,3,03,07,08,,19,20,,24,27,,,,3.4,1.5,3.0*37 ' $GPGSV,3,3,10,27,18,227,43,28,43,312,00*79 ' $GPGLL,3513.0423,N,13757.3870,E,105124,A,A*4D ' $GPBOD,,T,,M,,*47 ' $GPVTG,0.0,T,7.4,M,0.0,N,0.0,K*4D ' $PGRME,5.9,M,14.3,M,15.4,M*24 ' $PGRMZ,1815,f*39 ' $PGRMM,WGS 84*06 ' $HCHDG,,,,7.4,W*16 ' $GPRTE,1,1,c,*37 ' $GPRMC,105126,A,3513.0419,N,13757.3869,E,0.0,340.5,051005,7.4,W,A*00 ' $GPRMB,A,,,,,,,,,,,,A,A*0B ' ----------------------------------------------------------------------- ' ' '************************************************************************** '初期化 Dim nmea_s(75) As Byte 'NMEA Dim n As Byte 'カウンター Dim tc_gps As Byte 'Timeカウンター(from GPS's NMEA) 'NMEAの時間(60秒)を1/2しておく。 '奇数秒は1足して1/2して0-29の30ステップ。 Dim tc_ptt As Byte 'PTT制御Timeカウンター '0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29 '!!!!ユニークなID扱い!!!! '60秒時計、パラメータとしては0-29。 'NMEAが1回/2秒のため、最小2秒間隔として、30PTT/分あたり管理が限界。 '3PTT*10局/分(1局あたり1PTT/20秒)の管理で設計する。 'tc_ptt 1 00,01,02,03,04,05,06,07,08,09 00-09がtc_ptt値 ' 2 10,11,12,13,14,15,16,17,18,19 ' 3 20,21,22,23,24,25,26,27,28,29 Dim bit_1 As Byte 'tc_ptt用2進1桁目 Dim bit_2 As Byte 'tc_ptt用2進2桁目 Dim bit_3 As Byte 'tc_ptt用2進3桁目 Dim bit_4 As Byte 'tc_ptt用2進4桁目 Initlcd 'LCDイニシャライズ Serclear 'シリアル・バッファ・クリア High RD.Bit7 'RD.Bit7をHigh(PTT OFF)にする。PTTへ配線必要。 High RD.Bit6 'RD.Bit6をHigh(LED ON)にする。LEDへ配線必要。 Input RD.Bit3 'RD.Bit3を入力端子にする。端子はプルアップされている。 Input RD.Bit2 'RD.Bit2を入力端子にする。端子はプルアップされている。 Input RD.Bit1 'RD.Bit1を入力端子にする。端子はプルアップされている。 Input RD.Bit0 'RD.Bit0を入力端子にする。端子はプルアップされている。 tc_ptt=0 '!!!!ユニークなID扱い!!!! 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: 'メインルーチン '************************************************************************** 'tc_pttの設定をデジタルスイッチから読み込み、tc_ttpへセットする。 '毎処理ごと読み直すので、常時変更可能。 'ソフトで固定する場合、tc_pttへ0-9を代入する。 If RD.Bit3=1 Then bit_1=0 Else bit_1=1 If RD.Bit2=1 Then bit_2=0 Else bit_2=2 If RD.Bit1=1 Then bit_3=0 Else bit_3=4 If RD.Bit0=1 Then bit_4=0 Else bit_4=8 tc_ptt=bit_1+bit_2+bit_3+bit_4 '固定の場合は実数を入れるようにする。 'tc_ptt=0 'tc_ptt=8 'MNEA行を読む。 'DVのシリアル実効速度は約950bpsなので、GGAを74byte読んだ場合、約80ms掛かる。 'したがって、2倍以上マージンとって、シリアルのWaitは200msとする。 wait_top: '行頭("$")を待つ。 Serin pb4800,200,nmea_s(1) If nmea_s(1)<>36 Then Goto wait_top '"$"が来るまで待つ 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(12)<48 Or nmea_s(15)>57 Then Goto error '数字か? GPS時間の10秒部分のチェック If nmea_s(13)<48 Or nmea_s(15)>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でなければエラー '以降高度をチェックする際は可変長になるので要注意。 '*************************************************************************** ' 60秒部分を読み取って、PTT処理を行う 'GGAの場合、nmea_s(12),nmea_s(13)は60秒時計であるのでタイムベースに使う。 '0は10進コードで"48"なので48を引いて使う。 '奇数秒は1秒足してから偶数秒で扱う。 tc_gps=(nmea_s(12)-48)*10+(nmea_s(13)-48)+((nmea_s(13)-48)-((nmea_s(13)-48)/2)*2) '60秒時計、パラメータとしては0-29。 tc_gps=tc_gps/2 '奇数秒は1秒足してから偶数秒で扱うと59秒は(59+1)/2で30になってしまうので、ロジックで0にする。 If tc_gps=30 Then tc_gps=0 'NMEAが1回/2秒のため、最小2秒間隔として、30PTT/分あたり管理が限界。 '3PTT*10局/分(1局あたり1PTT/20秒)の管理で設計する。 ' Setpos 0,0:Putlcd tc_gps 'デバッグ用のtc_gps表示。時計が動かないかチェックするため。 'PTTのため、tc_gpsとtc_gps+αのタイミングでPTTを送出する。 If tc_gps=tc_ptt+0 Then Gosub sub_time_ptt '所定のtc_gps+0になったらPTT動作。 If tc_gps=tc_ptt+10 Then Gosub sub_time_ptt '所定のtc_gps+10になったらPTT動作。 If tc_gps=tc_ptt+20 Then Gosub sub_time_ptt '所定のtc_gps+20になったらPTT動作。 '************************************************************************** Goto main 'サイクル終了、最初へ。 '************************************************************************** error: 'エラー処理 '現在、何も処理なし。 Serclear 'LCDコントロールのためのシリアル制御が残っているといけないので、一応シリアルをクリアしておく。 Goto wait_top '************************************************************************** '************************************************************************** 'サブルーチン群 '************************************************************************** 'tc_pttの値でPTTのための割り込み処理を行うサブルーチン '動作確認用にRD6もコントロールしている。 sub_time_ptt: '位置送出を自動で行う。PTTへ配線必要。 '秒が奇数なら1秒遅らせて処理する。 Sleep ((nmea_s(13)-48)-((nmea_s(13)-48)/2)*2)*1000 Low RD.Bit7 'RD.Bit7をLow(PTT ON)にする。 Low RD.Bit6 'RD.Bit6をLow(LED OFF)にする。 Sleep 50 'PTTを200msec維持。長いとNMEAを取りこぼす。 High RD.Bit7 'RD.Bit7をHigh(PTT OFF)にする。 High RD.Bit6 'RD.Bit6をHigh(LED ON)にする。 Return '元へ戻る '**************************************************************************