10 COLOUR_PAL 100 start_screen 110 init 120 setup_display_windows 130 GPS_data_init 140 data_for_sim 150 main_loop 160 STOP 1000 REMark *************************************************************************************************************** 1010 DEFine PROCedure start_screen 1020 WINDOW#0;SCR_XLIM,SCR_YLIM,0,0:BORDER#0;2,0,1:PAPER#0;0:INK#0;7:CLS#0 1030 WINDOW#1;SCR_XLIM,SCR_YLIM,0,0:BORDER#1;2,0,1:PAPER#1;12:INK#1;1:CLS#1 1040 WINDOW#2;SCR_XLIM,SCR_YLIM,0,0:BORDER#2;2,0,1:PAPER#2;12:INK#2;1:CLS#2 1050 BANNER 1,(SCR_XLIM/2)-100,50,4,1,4,"QLToday GPS" 1060 INBANNER 1,20,100,1,4,1,4,"Input from GPS (R)eceiver or (F)ile :" 1070 IF in$<>"R" AND in$<>"r" AND in$<>"F" AND in$<>"f" THEN GO TO 1060 1080 IF in$=="f" THEN sim=1:AT#1;7,57:BANNER 1,20,100,4,1,4,"Input from GPS (R)eceiver or (F)ile : Input from file" 1090 IF in$=="r" THEN sim=0:AT#1;7,57:BANNER 1,20,100,4,1,4,"Input from GPS (R)eceiver or (F)ile : Input from receiver" 1100 INBANNER 1,20,150,1,4,1,4,"Show (O)rbits or (T)rack :" 1110 IF in$<>"O" AND in$<>"o" AND in$<>"T" AND in$<>"t" THEN GO TO 1100 1120 IF in$=="t" THEN ShowTrack%=1:BANNER 1,20,150,4,1,4,"Show (O)rbits or (T)rack : Show Track" 1130 IF in$=="o" THEN ShowTrack%=0:BANNER 1,20,150,4,1,4,"Show (O)rbits or (T)rack : Orbits" 1140 IF ShowTrack%=0 THEN INBANNER 1,20,200,1,4,1,4,"Show Orbits as (B)lobs or (L)ines :":ELSE GO TO 1180 1150 IF in$<>"B" AND in$<>"b" AND in$<>"L" AND in$<>"l" THEN GO TO 1140 1160 IF in$=="B" THEN Blobs%=1:BANNER 1,20,200,4,1,4,"Show Orbits as (B)lobs or (L)ines : Show Orbits as Blobs" 1170 IF in$=="L" THEN Blobs%=0:BANNER 1,20,200,4,1,4,"Show Orbits as (B)lobs or (L)ines : Show Orbits as Lines" 1180 IF sim=0:AT#1;13,20:INBANNER 1,20,250,1,4,1,4,"Save raw data from recevier (Y/N) :":ELSE GO TO 1260 1190 IF in$<>"Y" AND in$<>"y" AND in$<>"N" AND in$<>"n" THEN GO TO 1140 1200 IF in$=="y" THEN dtof=1:BANNER 1,20,250,4,1,4,"Save raw data from recevier (Y/N) : Saves raw receiver data" 1210 IF in$=="n" THEN dtof=0:BANNER 1,20,250,3,1,4,"Save raw data from recevier (Y/N) : Does NOT save receiver data" 1220 IF dtof=1:AT#1;15,20:INBANNER 1,20,300,28,3,1,4,"Enter raw data file name (e.g. win5_gps_sats_dat) :":ELSE GO TO 1260 1230 raw1$=in$ 1240 BLOCK#1,970,25,20,300,12 1250 BANNER 1,20,300,4,1,4,"Data from receiver will be sent to file :":BANNER 1,680,300,4,7,4,raw1$ 1260 IF sim=0:AT#1;17,20:INBANNER 1,20,350,1,4,1,4,"Serial Port GPS Receiver connected to (1-6) :":ELSE GO TO 1310 1270 SerPort%=in$ 1280 IF SerPort%<1 AND SerPort%>6 THEN GO TO 1260 1290 BLOCK#1,800,25,20,350,12 1300 ser$=SerPort%:BANNER 1,20,350,4,1,4,"Receiver connected to serial port :": BANNER 1,593,350,4,1,4,ser$ 1310 IF sim=1:INBANNER 1,20,400,28,3,1,4,"Enter raw data file name (e.g. win5_gps_sats_dat) :":ELSE GO TO 1370 1320 raw2$=in$ 1330 BLOCK#1,970,25,20,400,12 1340 BANNER 1,20,400,4,1,4,"Data will come from file :":BANNER 1,450,400,4,7,4,raw2$ 1350 REMark Delay in seconds between readings 1360 REMark to avoid enormous sats_data file 1370 INBANNER 1,20,450,1,4,1,4,"Delay between reading receiver data in seconds " 1380 delay=in$ 1390 BANNER 1,773,450,4,1,4,delay 1400 INBANNER 1,20,500,1,4,1,4,"Confirm these settings are correct (Y/N)" 1410 IF in$<>"Y" AND in$<>"y" AND in$<>"N" AND in$<>"n" THEN GO TO 1400 1420 IF in$=="n" THEN GO TO 1020 1430 END DEFine start_screen 1440 REMark ******************************************************************************************************************** 1450 DEFine PROCedure BANNER(Ch%,Xx%,Yy%,Sz%,Ink%,Pap%,f$) 1460 LOCal l%,X%,Y%,W%,H% 1470 l%=LEN(f$) 1480 SELect ON Sz% 1490 =1:W%=7*(l%+1):H%=19 1500 =2:W%=8*(l%+1):H%=19 1510 =3:W%=12*(l%+1):H%=19 1520 =4:W%=16*(l%+1):H%=19 1530 =5:W%=7*(l%+1):H%=30 1540 =6:W%=8*(l%+1):H%=30 1550 =7:W%=12*(l%+1):H%=30 1560 =8:W%=16*(l%+1):H%=30 1570 END SELect 1580 IF Xx%<0 THEN X%=(512-W%)/2:ELSE X%=Xx%:END IF 1590 IF Yy%<0 THEN Y%=(256-H%)/2:ELSE Y%=Yy%:END IF 1600 BLOCK#Ch%;W%,H%,X%+6,Y%+4,0 1610 BLOCK#Ch%;W%,H%,X%,Y%,0 1620 BANNER_TXT Ch%,Xx%,Yy%,Sz%,Ink%,Pap%,f$ 1630 END DEFine BANNER 1640 REMark ********************************************************************************************************************** 1650 DEFine PROCedure BANNER_TXT(Ch%,Xx%,Yy%,Sz%,Ink%,Pap%,f$) 1660 LOCal l%,X%,Y%,W%,H% 1670 l%=LEN(f$) 1680 SELect ON Sz% 1690 =1:W%=7*(l%+1):H%=19:CSIZE#Ch%;0,0 1700 =2:W%=8*(l%+1):H%=19:CSIZE#Ch%;1,0 1710 =3:W%=12*(l%+1):H%=19:CSIZE#Ch%;2,0 1720 =4:W%=16*(l%+1):H%=19:CSIZE#Ch%;3,0 1730 =5:W%=7*(l%+1):H%=30:CSIZE#Ch%;0,1 1740 =6:W%=8*(l%+1):H%=30:CSIZE#Ch%;1,1 1750 =7:W%=12*(l%+1):H%=30:CSIZE#Ch%;2,1 1760 =8:W%=16*(l%+1):H%=30:CSIZE#Ch%;3,1 1770 END SELect 1780 IF Xx%<0 THEN X%=(512-W%)/2:ELSE X%=Xx%:END IF 1790 IF Yy%<0 THEN Y%=(256-H%)/2:ELSE Y%=Yy%:END IF 1800 BLOCK#Ch%;W%-4,H%-2,X%+2,Y%+1,Pap% 1810 OVER#Ch%;1:INK#Ch%;0 1820 CURSOR#Ch%;X%+5,Y%+4:PRINT#Ch%;f$; 1830 CURSOR#Ch%;X%+7,Y%+4:PRINT#Ch%;f$; 1840 CURSOR#Ch%;X%+5,Y%+6:PRINT#Ch%;f$; 1850 CURSOR#Ch%;X%+7,Y%+6:PRINT#Ch%;f$; 1860 INK#Ch%;Ink% 1870 CURSOR#Ch%;X%+6,Y%+5:PRINT#Ch%;f$; 1880 END DEFine BANNER_TXT 1890 REMark ************************************************************************************************************************* 1900 DEFine PROCedure INBANNER(Ch%,Xx%,Yy%,Ex%,Sz%,Ink%,Pap%,f$) 1910 LOCal l%,X%,Y%,W%,H% 1920 l%=LEN(f$) 1930 SELect ON Sz% 1940 =1:W%=7*(l%+1+Ex%):H%=19 1950 =2:W%=8*(l%+1+Ex%):H%=19 1960 =3:W%=12*(l%+1+Ex%):H%=19 1970 =4:W%=16*(l%+1+Ex%):H%=19 1980 =5:W%=7*(l%+1+Ex%):H%=30 1990 =6:W%=8*(l%+1+Ex%):H%=30 2000 =7:W%=12*(l%+1+Ex%):H%=30 2010 =8:W%=16*(l%+1+Ex%):H%=30 2020 END SELect 2030 IF Xx%<0 THEN X%=(512-W%)/2:ELSE X%=Xx%:END IF 2040 IF Yy%<0 THEN Y%=(256-H%)/2:ELSE Y%=Yy%:END IF 2050 BLOCK#Ch%;W%,H%,X%+6,Y%+4,0 2060 BLOCK#Ch%;W%,H%,X%,Y%,0 2070 INBANNER_TXT Ch%,Xx%,Yy%,Ex%,Sz%,Ink%,Pap%,f$ 2080 END DEFine INBANNER 2090 REMark **************************************************************************************************************************** 2100 DEFine PROCedure INBANNER_TXT(Ch%,Xx%,Yy%,Ex%,Sz%,Ink%,Pap%,f$) 2110 LOCal l%,X%,Y%,W%,H% 2120 l%=LEN(f$) 2130 SELect ON Sz% 2140 =1:W%=7*(l%+1+Ex%):H%=19:CSIZE#Ch%;0,0 2150 =2:W%=8*(l%+1+Ex%):H%=19:CSIZE#Ch%;1,0 2160 =3:W%=12*(l%+1+Ex%):H%=19:CSIZE#Ch%;2,0 2170 =4:W%=16*(l%+1+Ex%):H%=19:CSIZE#Ch%;3,0 2180 =5:W%=7*(l%+1+Ex%):H%=30:CSIZE#Ch%;0,1 2190 =6:W%=8*(l%+1+Ex%):H%=30:CSIZE#Ch%;1,1 2200 =7:W%=12*(l%+1+Ex%):H%=30:CSIZE#Ch%;2,1 2210 =8:W%=16*(l%+1+Ex%):H%=30:CSIZE#Ch%;3,1 2220 END SELect 2230 IF Xx%<0 THEN X%=(512-W%)/2:ELSE X%=Xx%:END IF 2240 IF Yy%<0 THEN Y%=(256-H%)/2:ELSE Y%=Yy%:END IF 2250 BLOCK#Ch%;W%-4,H%-2,X%+2,Y%+1,Pap% 2260 OVER#Ch%;1:INK#Ch%;0 2270 CURSOR#Ch%;X%+5,Y%+4:PRINT#Ch%;f$; 2280 CURSOR#Ch%;X%+7,Y%+4:PRINT#Ch%;f$; 2290 CURSOR#Ch%;X%+5,Y%+6:PRINT#Ch%;f$; 2300 CURSOR#Ch%;X%+7,Y%+6:PRINT#Ch%;f$; 2310 INK#Ch%;Ink% 2320 CURSOR#Ch%;X%+6,Y%+5:PRINT#Ch%;f$; 2330 SELect ON Sz% 2340 =1:=5:CURSOR#Ch%;X%+6+(l%*6),Y%+4 2350 =2:=6:CURSOR#Ch%;X%+6+(l%*8),Y%+4 2360 =3:=7:CURSOR#Ch%;X%+6+(l%*12),Y%+4 2370 =4:=8:CURSOR#Ch%;X%+6+(l%*16),Y%+4 2380 END SELect 2390 INK#Ch%;1:INPUT#Ch%;in$ 2400 END DEFine INBANNER_TXT 2410 REMark ******************************************************************************************************************************** 2420 DEFine PROCedure init 2430 maxid=30:REMark highest permitted satellite id no. 2440 : 2450 IF ShowTrack%>0 THEN 2460 Minlon=0:Minlet=0:Maxlon=0:Maxlat=0 2470 REMark PRINT "Minlon:";Minlon;" Minlat:";Minlat;" Maxlon:";Maxlon;" Maxlat:";Maxlat 2480 REMark For Displaying track, must set min and max 2490 REMark lat and lon or call a procedure to do so ... 2500 ChiCityMap: REMark May need user input here for required area to be covered. 2510 REMark PfdMap 2520 : 2530 REMark See Jan Jones page 39,40 2540 IF (1+Minlon+Minlat+Maxlon+Maxlat)=1 THEN 2550 CLS 2560 PRINT \\\" ** Map limits not set ***":STOP 2570 END IF 2580 END IF 2590 : 2600 REMark For orbit display 2610 REMark Colours used for spot showing first observed 2620 REMark position and use of satellite 2630 seentint%=194:usdtint%=96 2640 : 2650 CLS#0:CLS#1 2660 CSIZE#1;0,0 2670 : 2680 set_serial_port 2690 END DEFine init 2700 REMark ********************************************************************************************************************************** 2710 REMark Follow a series of definitions of charts for tracks 2720 REMark Maxlon necessary for lat, lon grid 2730 DEFine PROCedure ChiCityMap 2740 Minlat=50+49/60 2750 Maxlat=50+51/60 2760 Minlon=-47/60 2770 Maxlon=-43/60 2780 END DEFine ChiCityMap 2790 REMark *************************************************************************************************************************************** 2800 DEFine PROCedure PfdMap 2810 Minlat=50.7667 2820 Maxlat=51.05 2830 Minlon=-1-3/60 2840 Maxlon=-.6 2850 END DEFine PfdMap 2860 REMark ***************************************************************************************************************************************** 2870 DEFine PROCedure set_serial_port 2880 REMark Set up the Serial Port if needed 2890 IF sim THEN 2900 REMark If sim=1(true) 2910 REMark Serial Port simulated by data file 2920 cs%=FOP_IN(raw2$) 2930 : 2940 ELSE 2950 REMark Otherwise real time data from receiver 2960 REMark SerPort% set to 1 to 6 as selected by the user in the Start_Screen procedure 2970 BAUD SerPort%,4800 2980 SerPort$=SerPort% 2990 cs%=FOPEN("srx"&SerPort$&"IA"): REMark I=Ignore flow control, A=is end of line, is end of page. 3000 END IF 3010 END DEFine set_serial_port 3020 REMark ******************************************************************************************************************************************* 3030 DEFine PROCedure setup_display_windows 3040 REMark Window to display raw data 3050 dd%=FOPEN("con") 3060 CURSOR 0,350 3070 PRINT "Raw incoming data" 3080 WINDOW#dd%,550,75,0,365 3090 BORDER#dd,1,9,1 3100 PAPER#dd%,36:INK#dd%,0:CLS#dd% 3110 : 3120 REMark Windowto display error and other messages 3130 REMark in particular, corrupted data 3140 de%=FOPEN("con") 3150 CURSOR 0,440 3160 PRINT "Error and Other messages" 3170 WINDOW#de%,400,75,0,455 3180 BORDER#de%,1,9,1 3190 PAPER#de%,39:INK#de%,0:CLS#de%:REMark paper was 36 3200 : 3210 REMark Window for main display of orbits or track 3220 asprat=.8:REMark aspect ratio: width/height 3230 size=3.5:REMark for early fiddling with windows 3240 dc%=FOPEN("con") 3250 Mctr=COS(RAD((Minlat+Maxlat)/2)) 3260 High=100*size 3270 wide=137*size*asprat 3280 WINDOW#dc%,wide,High,0,0 3290 BORDER#dc%,1,9,1 3300 INK#dc%,0 3310 PAPER#dc%,37:CLS#dc% 3320 : 3330 REMark Set up for track display 3340 IF ShowTrack%<>0 THEN 3350 difflon=Maxlon-Minlon 3360 difflat=Maxlat-Minlat 3370 SCALE#dc%,difflat,Minlat*asprat*Mctr,Minlat 3380 : 3390 REMark Lat and Lon grid 3400 LatLonGrid 3410 : 3420 REMark Window to show instantaneous track and speed 3430 dt%=FOPEN("scr") 3440 Topdc%=3 3450 WINDOW#dt%,137/4*size*asprat,100/4*size,280,Topdc% 3460 BORDER#dt%,1,9,1 3470 SCALE#dt%,200,-100*asprat,-100 3480 PAPER#dt%,36:CLS#dt% 3490 ELSE 3500 REMark For orbit display 3510 SCALE#dc%,2.2,-1.1*asprat,-1.1 3520 REMark set up alternative for orbits 3530 SatSky 3540 END IF 3550 : 3560 REMark Window to show speed, bearing, validity etc. 3570 ds%=FOPEN("con") 3580 WINDOW#ds%,305,350,388,0 3590 BORDER#ds%,1,9,1 3600 PAPER#ds%,36:CLS#ds% 3610 : 3620 REMark Window to show satellite signal data 3630 dn%=FOPEN("scr") 3640 WINDOW#dn%,320,350,697,0 3650 BORDER#dn%;1,9,1 3660 PAPER#dn%,36:CLS#dn% 3670 INK#dn%;0 3680 AT#dn%;2,2:PRINT#dn%;"Signal Strength" 3690 AT#dn%;4,2:PRINT#dn%;"50" 3700 AT#dn%;9,2:PRINT#dn%;"40" 3710 AT#dn%;14,2:PRINT#dn%;"30" 3720 AT#dn%;19,2:PRINT#dn%;"20" 3730 AT#dn%;24,2:PRINT#dn%;"10" 3740 AT#dn%;29,2:PRINT#dn%;"00" 3750 AT#dn%;31,2:PRINT#dn%;"ID" 3760 BLOCK#dn%;3,40,17,50,2 3770 BLOCK#dn%;3,40,17,100,4 3780 BLOCK#dn%;3,40,17,150,3 3790 BLOCK#dn%;3,40,17,200,6 3800 BLOCK#dn%;3,40,17,250,0 3810 BLOCK#dn%;290,3,17,303,0 3820 DIM peak%(12):REMark area to store peak signal strength. 3830 DIM pht%(12):REMark area to store loop count before reseting peak hold to current level 3840 END DEFine setup_display_windows 3850 REMark ******************************************************************************************************************************************** 3860 : 3870 DEFine PROCedure LatLonGrid 3880 REMark For track, prints a grid of lats and longs 3890 REMark .. each at one minute of acr intervals 3900 REMark parameters set in main program 3910 REMark No need for precise match to window as SB 3920 REMark just doesn't draw outside it 3930 LOCal Glat, Glon, Gld,Glm 3940 INK#dc%,13:REMark nice pale gray 3950 : 3960 REMark Start with latitudes 3970 Gl=Minlat 3980 REMark need to convert to decimal degrees 3990 Gl=INT(Gl)+(INT((Gl-INT(Gl))*60))/60 4000 Gminl=Minlon*asprat*Mctr:Gmaxl=Maxlon*asprat*Mctr 4010 REPeat LatLines 4020 IF Minlat<=Gl AND Maxlat>Gl THEN 4030 LINE#dc%,Gminl,Gl TO Gmaxl,Gl 4040 END IF 4050 Gl=Gl+1/60 4060 IF Gl>Maxlat THEN EXIT LatLines 4070 END REPeat 4080 : 4090 REMark next meridians 4100 Gl=Minlon 4110 Gl=INT(Gl)+(INT((Gl-INT(Gl))*60))/60 4120 Gminl=Minlon:Gmaxl=Maxlon 4130 REPeat LonLines 4140 IF Minlon<=Gl AND Maxlon>Gl THEN 4150 Gp=Gl*asprat*Mctr 4160 LINE#dc%,Gp,Minlat TO Gp,Maxlat 4170 END IF 4180 Gl=Gl+1/60 4190 IF Gl>Maxlon THEN EXIT LonLines 4200 END REPeat 4210 END DEFine LatLonGrid 4220 REMark ***************************************************************************************************************************************** 4230 DEFine PROCedure SatSky 4240 REMark Sky disk 4250 FILL#dc%,1 4260 INK#dc%,29 4270 ELLIPSE#dc%,0,0,1,1*asprat,0 4280 FILL#dc%,0 4290 : 4300 REMark Draw polar plot grid lines 4310 INK#dc%,12 4320 radials:REMark draw the bearings 4330 REMark Now draw the elevations 4340 FOR i=1 TO 3 4350 ELLIPSE#dc%,0,0,1/3,1*asprat,0 4360 END FOR 4370 LINE#dc%,-1.02*asprat,0 TO 1.02*asprat,0 4380 LINE#dc%,0,-1.02 TO 0,1.02 4390 : 4400 REMark Mark point of compass 4410 INK#dc%,9 4420 CURSOR#dc%,1.03*asprat,0,0,-4 4430 PRINT#dc%,"E" 4440 CURSOR#dc%,-1.03*asprat,0,-6,-4 4450 PRINT#dc%,"W" 4460 CURSOR#dc%,0,1.04,-3,-8 4470 PRINT#dc%,"N" 4480 CURSOR#dc%,0,-1.03,-3,2 4490 PRINT#dc%,"S" 4500 : 4510 REMark Mark azimuth scale 4520 FOR i=30 TO 330 STEP 30 4530 IF (i MOD 90)=0 THEN NEXT i 4540 j=i+90 4550 CURSOR#dc%,1.03*COS(j*PI/180)*asprat,1.03*SIN(j*PI/180),-6,-5 4560 PRINT#dc%,360-i 4570 END FOR i 4580 : 4590 REMark mark elevation scale 4600 FOR i=0 TO 3 4610 CURSOR#dc%,0,i/3,-6,-5 4620 PRINT#dc%,90-30*i 4630 END FOR i 4640 END DEFine SatSky 4650 REMark **************************************************************************************************************************************** 4660 DEFine PROCedure radials 4670 REMark Draws the celestial meridians at 30 deg intervals 4680 REMark as a series od dots to avoid to dark a line 4690 LOCal i,j,interval 4700 interval=2E-2 4710 FOR i=0 TO 350 STEP 10 4720 FOR j=2 TO 100 4730 REMark uses j*interval as a radial distance .. 4740 REMark .. which must be converted to x,y for plot 4750 IF j*interval>1 THEN EXIT j 4760 POINT#dc%,j*interval*COS(i*PI/180)*asprat,j*interval*SIN(i*PI/180) 4770 END FOR j 4780 END FOR i 4790 END DEFine radials 4800 REMark ******************************************************************************************************************************************* 4810 DEFine PROCedure GPS_data_init 4820 : 4830 REMark Display now set up, now get ready for GPS data: 4840 : 4850 REMark Array to store the raw data lines from the reciever 4860 DIM rawdata$(6,128):REMark some receivers may issue more lines, so increase this array as required 4870 REMark Array to store satellite data.. 4880 REMark with: IdNo, Bearing, Elevation, Usage 4890 REMark where: usage is 0 for not used, 1 for used 4900 DIM satvis(12,3):REMark Allow for 12 satellites 4910 : 4920 DIM satsusd(12):REMark List of Ids for satellites used: 4930 : 4940 REMark I use copies of the raw data... 4950 DIM satlist$(6,128):REMark Satellite data from $GPSGV input 4960 REMark Allowed for 7 $GPSGV lines (OTT - never more than 2 !), Not quiet true, is dependant on receiver, some issue 3 $GPSGSV lines. 4970 : 4980 DIM rmcdata$(128):REMark Lat,Long,Time 4990 : 5000 REMark Posns for orbits plotted as lines 5010 REMark to draw a blob for first point, then a line 5020 REMark Store: Old x,y;New x,y:5th item, )=new orbit... 5030 REMark .. so draw blob, 1=orbit started so draw line 5040 DIM posns(maxid,5):REMark need enough for each satellite, maxid set in line 2410, default maxid=30 5050 REMark set all to zero for a start 5060 FOR i%=0 TO maxid-1 5070 FOR j%=0 TO 4 5080 posns(i%,j%)=0 5090 END FOR j% 5100 END FOR i% 5110 : 5120 REMark For plotting trach, need a point to start 5130 REMark then continue with lines. 5140 REMark Don't bother not defining this if orbits 5150 FirstPt%=0 5160 : 5170 Lines=0:REMark A count of input lines 5180 GoodLines=0:REMark Another count of input lines 5190 CLS#dd%:REMark I needed this for raw data display 5200 END DEFine GPS_data_init 5210 REMark ******************************************************************************************************************************************* 5220 DEFine PROCedure data_for_sim 5230 REMark Open a file to collect the data from the receiver for simulation 5240 IF dtof<>0 THEN 5250 fc%=FOP_NEW(raw1$) 5260 END IF 5270 END DEFine data_for_sim 5280 REMark ****************************************************************************************************************************************** 5290 DEFine PROCedure main_loop 5300 REMark Setting up complete, now for ... 5310 REMark ... data reading and display 5320 : 5330 REMark Repeat loop for continous display 5340 REMark delay at end 5350 REMark Each run through loop deals with a single set 5360 REMark of data sentences, 5 to 7 depending on incoming data stream, starting 5370 REMark with a $GPGGA. Sent each second, but read 5380 REMark at a rate determined by missing some with the delay 5390 REMark Test for $GPVTG sentence present or not, WD-G-ZX4120 module has this sentence, but the RF Solutions development card does not. 5400 test_receiver_sentences 5410 : 5420 REPeat orbits 5430 AT#dd%;6,0:PRINT#dd%;" " 5440 AT#dd%,0,0:AT#ds%;0,0:REMark To keep the display tidy 5450 REMark I read all the sentences at one go so that I 5460 REMark don't end up with some from a later second's lot. 5470 rawdata$(0)=gpsdata$("$GPGGA"):REMark wait for a first, GPS fix data 5480 rawdata$(1)=gpsdata$("$GPGSA"):REMark read the rest, GNSS DOP and active satellites 5490 rawdata$(2)=gpsdata$("$GPGSV"):REMark Satellites in view 5500 nummes=rawdata$(2,8) 5510 rawdata$(3)=gpsdata$("$GPGSV"):REMark Satellites in view 5520 rawdata$(4)="$GPGSV,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*" 5530 IF nummes=3 THEN rawdata$(4)=gpsdata$("$GPGSV"):REMark Satellites in view 5540 rawdata$(5)=gpsdata$("$GPRMC"):REMark Recommended minimum specific GNSS data 5550 IF VTG%=1:rawdata$(6)=gpsdata$("$GPVTG"):REMark Velocity and track over ground 5560 IF VTG%=1 THEN Lines=Lines+6:ELSE Lines=Lines+5:REMark lines, Goodlines bit messy ... 5570 REMark ... intended it to help look at corrupted data 5580 REMark Check lines for not corrupted data 5590 IF VTG%=1 THEN t=6:ELSE t=5 5600 FOR i=0 TO t 5610 IF i=4 AND nummes<>3 THEN NEXT i 5620 REMark Go through data to look for corrupted lines 5630 REMark This became a long winded process so that is 5640 REMark why I read all the sentences in one go. 5650 REMark Ignoring all the set of data. If there is one 5660 REMark corrupted item, is a bit OTT, but safe. 5670 : 5680 REMark Sometimes get lines much longer than spec.. 5690 REMark .. 'Long' lines seem to be a normal line but.. 5700 REMark .. no and followed by more,.. 5710 REMark .. badly formed, data, so ignore them : 5720 ChkFld%='*' INSTR rawdata$(i) 5730 REMark IF LEN(rawdata$(i))>ChkFld%+3 THEN NEXT orbits 5740 : 5750 IF dtof<>0 THEN 5760 PRINT#fc%,rawdata$(i):REMark Save in file if needed 5770 END IF 5780 : 5790 REMark Check 'Checksum' field 5800 Check%=CheckSum(rawdata$(i)) 5810 IF Check%<>0 THEN 5820 NEXT orbits 5830 END IF 5840 GoodLines=GoodLines+1 5850 DisLine dd%,GoodLines&" "&rawdata$(i),80 5860 END FOR i 5870 : 5880 REMark Get ready for GPS fix data 5890 REMark from GPGGA data line, not used in Hugh's orginal program, some data duplicated in GPRMC data line. 5900 gpsfix$=rawdata$(0) 5910 Extract_gpgga_data 5920 : 5930 REMark Get ready for list of sateliites used 5940 REMark from $GPGSA data line 5950 gpgsa$=rawdata$(1):REMark cautiously us copies 5960 Extract_GPGSA_data 5970 : 5980 REMark Get ready for list of satellite data 5990 REMark First $GPGSV lines gives no of $GPSV lines 6000 satlist$(1)=rawdata$(2) 6010 Extract_GPGSV1_data 6020 REMark Extract number of $GPGSV lines 6030 novrecs%=numsatview1$ 6040 : 6050 REMark Extracting the data from the second $GPGSV sentence 6060 satlist$(2)=rawdata$(3) 6070 Extract_GPGSV2_data: 6080 : 6090 REMark Extracting the data from the third $GPGSV which a dummy setence when not present in the data stream. 6100 satlist$(3)=rawdata$(4) 6110 Extract_GPGSV3_data 6120 : 6130 REMark Copy RMC data 6140 gpsrmc$=rawdata$(5) 6150 Extract_GPSRMC_data 6160 : 6170 REMark Copy VTG data, if present 6180 gpvtg$=rawdata$(6) 6190 REMark if VTG%=1 then Extract_GPVTG_data 6200 : 6210 display_data 6220 END REPeat orbits 6230 END DEFine main_loop 6240 REMark ************************************************************************************************************************************************ 6250 DEFine PROCedure test_receiver_sentences 6260 VTG%=0:rawdata$(5)=" " 6270 FOR ii=0 TO 7 6280 IF EOF(#cs%) THEN 6290 PRINT "End of File" 6300 CLS#1:CLS#0:CLS#2:CLOSE:STOP 6310 END IF 6320 INPUT#cs%;t$ 6330 IF t$(1 TO 6)="$GPVTG" THEN VTG%=1 6340 END FOR ii 6350 END DEFine test_receiver_sentences 6360 REMark ************************************************************************************************************************************************ 6370 DEFine FuNction gpsdata$(id$) 6380 REMark Waits for and reads a sentence of data starting 6390 REMark with the string id$ (not sat id this time) 6400 REMark Give up if there's no data to serial port 6410 FOR i=1 TO 50 6420 IF EOF(#cs%) THEN 6430 AT#ds%;30,3:PRINT#ds%;"Lines: ";Lines!; 6440 PRINT#ds%;" Good Lines: ";GoodLines 6450 INPUT#ds%;" Press to finish: ";t$ 6460 CLS#1:CLS#0:CLS#2:CLOSE:STOP 6470 END IF 6480 INPUT#cs%,t$ 6490 REMark More check for dodgy data 6500 IF LEN(t$)=0 THEN NEXT i 6510 IF t$(1)<>"$" THEN NEXT i 6520 IF t$(1 TO 6)=id$ THEN RETurn t$: 6530 END FOR 6540 IF i>10 THEN PRINT#ds%;" No GPS data":STOP 6550 END DEFine gpsdata$ 6560 REMark *********************************************************************************************************************************************** 6570 DEFine FuNction CheckSum(a$) 6580 LOCal i,aa$,ChkSum,ChkCode$ 6590 IF LEN(a$)=0 THEN RETurn -2 6600 FOR i=1 TO 256:REMark Allow for sentence.. 6610 REMark .. not terminated properly, i.e. no '*' 6620 aa$=a$(i) 6630 SELect ON CODE(aa$) 6640 REMark set ChkSum to zros at start of sentence 6650 =CODE('$'):ChkSum=0 6660 =CODE('*'): 6670 ChkCode$=a$((i+1) TO (i+2)) 6680 EXIT i 6690 =REMAINDER : 6700 REMark ^^ is 'bit-wise exclusive OR' Jan Jones p 40 6710 ChkSum=CODE(aa$)^^ChkSum 6720 END SELect 6730 END FOR i 6740 REMark Checksum is data is two hex chars (8 bits) 6750 IF HEX$(ChkSum,8)=ChkCode$ THEN 6760 RETurn 0: REMark Good result 6770 ELSE 6780 REMark Bad result 6790 PRINT#de%,a$;" ChkSum: ";HEX$(ChkSum,8);" Check code: ";ChkCode$ 6800 RETurn -1 6810 END IF 6820 END DEFine CheckSum 6830 REMark ******************************************************************************************************************************************** 6840 DEFine PROCedure DisLine(c%,t$,l%) 6850 REMark Displays line padded to l% chars with spaces .. 6860 REMark .. in channel #c%, raw data window, the spaces are needed 6870 REMark when short lines follow long 6880 REMark Had no success with cls so far 6890 PRINT#c%;t$; 6900 tl%=LEN(t$) 6910 IF tl%"" THEN satsusd(1)=SU1$:ELSE satsusd(1)=-1 9580 IF SU2$<>"" THEN satsusd(2)=SU2$:ELSE satsusd(2)=-1 9590 IF SU3$<>"" THEN satsusd(3)=SU3$:ELSE satsusd(3)=-1 9600 IF SU4$<>"" THEN satsusd(4)=SU4$:ELSE satsusd(4)=-1 9610 IF SU5$<>"" THEN satsusd(5)=SU5$:ELSE satsusd(5)=-1 9620 IF SU6$<>"" THEN satsusd(6)=SU6$:ELSE satsusd(6)=-1 9630 IF SU7$<>"" THEN satsusd(7)=SU7$:ELSE satsusd(7)=-1 9640 IF SU8$<>"" THEN satsusd(8)=SU8$:ELSE satsusd(8)=-1 9650 IF SU9$<>"" THEN satsusd(9)=SU9$:ELSE satsusd(9)=-1 9660 IF SU10$<>"" THEN satsusd(10)=SU10$:ELSE satsusd(10)=-1 9670 IF SU11$<>"" THEN satsusd(11)=SU11$:ELSE satsusd(11)=-1 9680 IF SU12$<>"" THEN satsusd(12)=SU12$:ELSE satsusd(12)=-1 9690 FOR i=1 TO 12 9700 IF satsusd(i)=-1 THEN EXIT i 9710 IF satsusd(i)<10 THEN PRINT#ds%;"0"; 9720 PRINT#ds%; satsusd(i);" "; 9730 END FOR i 9740 : 9750 REMark Spaces at end of 'used' line for shorter overwrite 9760 PRINT#ds%;" " 9770 : 9780 PRINT#ds%;" Sats in View: "; 9790 : 9800 REMark display sat signal data 9810 AT#dn%;31,5 9820 REMark reformat signal data for bargraph routine 9830 v$=" ,"&snr1$&","&snr2$&","&snr3$&","&snr4$&","&snr5$&","&snr6$&","&snr7$&","&snr8$&","&snr9$&","&snr10$&","&snr11$&","&snr12$ 9840 FOR i=1 TO 12 9850 v$=chop$(v$,1) 9860 sn$=field$(v$) 9870 IF LEN(sn$)=0 THEN sn$="0" 9880 IF i=1 THEN AT#dn%;3,5 9890 IF i>1 THEN AT#dn%;3,(4*i)+1 9900 IF sn$<10 THEN PRINT#dn%;"0"; 9910 PRINT#dn%;sn$!; 9920 sn%=sn$*(255/50):REMark bargraph scaling 9930 holdtime%=3:REMark adjust to lengthen or shorten the bargraph peek hold bar time 9940 IF sn%>peak%(i) THEN peak%(i)=sn%:pht%(i)=holdtime% 9950 IF sn%1 THEN AT#dn%;31,(4*i)+1 10110 IF id$<10 THEN PRINT#ds%;"0"; 10120 IF id$<10 THEN PRINT#dn%;"0"; 10130 PRINT#ds%;id%!; 10140 PRINT#dn%;id%; 10150 v$=chop$(v$,1):REMark Satellite elevation 10160 el$=field$(v$) 10170 IF LEN(el$)=0 THEN el$="0" 10180 el%=el$ 10190 v$=chop$(v$,1):REMark Satellite azimuth 10200 az$=field$(v$) 10210 IF LEN(az$)=0 THEN az$="0" 10220 az%=az$ 10230 v$=chop$(v$,1):REMark Signal from Satellite 10240 sn$=field$(v$) 10250 IF az$="0" OR el$="0" THEN NEXT i 10260 j=0:tint%=seentint% 10270 REPeat chkid 10280 IF satsusd(j)=-1 THEN EXIT chkid 10290 IF satsusd(j)=id% THEN 10300 tint%=usdtint% 10310 END IF 10320 j=j+1 10330 END REPeat chkid 10340 : 10350 IF ShowTrack%=0 THEN 10360 REMark At last can plot satellite in position 10370 REMark Plot only valid data and sat ID's over 0 10380 IF Inv%=0 AND id%>0 THEN :spot el%,az%,id%,tint% 10390 END IF 10400 END FOR i 10410 : 10420 REMark Spaces as end of 'ids' line for shorter overwrite 10430 PRINT#ds%;" " 10440 : 10450 REMark Print validity 10460 PRINT#ds%;\" "; 10470 IF Inv%=1:PRINT#ds%;"Inv";: ELSE PRINT#ds%;"V"; 10480 PRINT#ds%;"alid Postion "; 10490 IF Mode3$=1 THEN PRINT#ds%;"Fix not available " 10500 IF Mode3$=2 THEN PRINT#ds%;"2D postion fix " 10510 IF Mode3$=3 THEN PRINT#ds%;"3D postion fix " 10520 REMark Spaces to overwrite longer 'Invaid' and postion fix messages 10530 : 10540 REMark uses extracted Lat and Long 10550 REMark Chopped gpsrmc$ also used by Track code 10560 CSIZE#ds%;3,1 10570 AT#ds%;3,0 10580 : 10590 REMark Display Latitude 10600 LatDeg$=Latitude2$(1 TO 2) 10610 LatMin$=Latitude2$(3 TO (LEN(Latitude2$))) 10620 PRINT#ds%;" ";LatDeg$;CHR$(186); 10630 PRINT#ds%;" ";LatMin$;"'"!NSindicator2$; 10640 REMark Latitude 10650 lat=DecDeg(LatDeg$,LatMin$) 10660 IF NSindicator2$=="S" THEN lat=-lat 10670 : 10680 REMark Display Longitude 10690 LonDeg$=Longitude2$(1 TO 2) 10700 LonMin$=Longitude2$(3 TO (LEN(Longitude2$))) 10710 PRINT#ds%;" ";LonDeg$;CHR$(186); 10720 PRINT#ds%;" ";LonMin$;"'"!EWIndicator2$ 10730 Lon=DecDeg(LonDeg$,LonMin$) 10740 IF EWIndicator2$=="W" THEN Lon=-Lon 10750 : 10760 REMark Display Altitude 10770 AT#ds%;5,1:CSIZE#ds%;0,0:PRINT#ds%;"Altitude" 10780 AT#ds%;11,3:CSIZE#ds%;3,1:PRINT#ds%;Altitude$;" ";Meter1$;"etres" 10790 PRINT_USING#ds%;"#####.#",Altitude$/.3048:PRINT#ds%;" Feet" 10800 : 10810 REMark display UTC, processed way back 10820 AT#ds%;8,2 10830 PRINT#ds%;UTC$ 10840 : 10850 REMark display date, processed way back 10860 AT#ds%;9,4 10870 PRINT#ds%;SatDate$(1 TO 2);"/";SatDate$(3 TO 4);"/";SatDate$(5 TO 6) 10880 : 10890 REMark Display Track data, 10900 AT#ds%;10,2 10910 trak$=COG$ 10920 speed$=SOG$ 10930 IF NumChk(speed$)<>0 THEN CSIZE#ds%;0,0:NEXT orbits 10940 Speed=speed$*1.150779:REMark Convert Knots to m.p.h. 10950 PRINT#ds%;"Track"!trak$;CHR$(186):REMark Bearing 10960 PRINT_USING#ds%;" at ##.# m.p.h",Speed 10970 PRINT_USING#ds%;" at ##.# k.p.h",speed$ 10980 Brg=trak$ 10990 : 11000 CSIZE#ds%;0,0 11010 : 11020 IF ShowTrack% THEN 11030 REMark Show track as a line: colour shows speed 11040 INK#dc%,Spink%(Speed) 11050 IF FirstPt%==0 THEN 11060 POINT#dc%,Lon*asprat*Mctr,lat 11070 FirstPt%=1 11080 ELSE 11090 LINE#dc% TO Lon*asprat*Mctr,lat 11100 END IF 11110 : 11120 REMark Show Speed and bearing as a line 11130 REMark .. Length and colour for speed 11140 REMark .. bearing as direction of line. 11150 CLS#dt%:INK#dt%,Spink%(Speed) 11160 POINT#dt%,0,0 11170 PENDOWN#dt% 11180 TURNTO#dt%,90-Brg:MOVE#dt%,Speed 11190 PENUP#dt% 11200 END IF 11210 : 11220 REMark Pause to slow down rate of refreshment 11230 PAUSE 50*delay 11240 : 11250 REMark End of repeat loop for continous of display 11260 END REPeat orbits 11270 CLOSE#cs%:IF dtof<>0 THEN CLOSE#dc% 11280 END DEFine display_data 11290 REMark **************************************************************************************************************************************** 11300 DEFine FuNction chop$(str$,skip) 11310 REMark Chps off skip firlds from the start of str$ 11320 REMark Haven't had to chop as far as the '*' yet 11330 LOCal i,j 11340 IF (skip < 1) THEN RETurn str$ 11350 FOR i=1 TO skip 11360 j="," INSTR str$ 11370 str$=str$(j+1 TO) 11380 END FOR 11390 RETurn str$ 11400 END DEFine chop$ 11410 REMark ******************************************************************************************************************************************** 11420 DEFine FuNction NumChk(a$) 11430 REMark Check if a$ contains a decimal number fixed point 11440 REMark Return: 0=ok; 1=empty; 2=>1 d.ps;3=non-numeric 11450 LOCal i%,a%,NoDecPts%:NoDecPts%=0 11460 REMark NoDecPts% hold the numer of dec pts found 11470 IF LEN(a$)=0 THEN RETurn 1 11480 FOR i%=1 TO LEN(a$) 11490 a%=CODE(a$(i%)) 11500 REMark 48 and 57 are codes for '0' and '9' 11510 REMark .. I just like < more than <= 11520 IF a%>47 AND a%<58 THEN 11530 NEXT i% 11540 ELSE 11550 REMark Check for dec pt 11560 IF a%=46 THEN 11570 NoDecPts%=NoDecPts%+1:REMark Allow one dec. pt. 11580 IF NoDecPts%>1 THEN RETurn 2:ELSE NEXT i% 11590 END IF 11600 RETurn 3 11610 END IF 11620 END FOR i% 11630 RETurn 0 11640 END DEFine NumChk 11650 REMark ************************************************************************************************************************************************* 11660 DEFine FuNction GPSTime$(t$) 11670 REMark Extracts time from t$ -- copy of RMC input 11680 REMark Should have used chop$ ect, but by this time the 11690 REMark data format seemed stable enough and CBB took over. 11700 t$=chop$(t$,1):REMark Remove '$GPRMC' 11710 RETurn '@ '&t$(1 TO 2)&':'&t$(3 TO 4)&':'&t$(5 TO 6)&'UTC' 11720 END DEFine GPSTime$ 11730 REMark *************************************************************************************************************************************************** 11740 DEFine FuNction DecDeg(D$,M$) 11750 IF LEN(D$)==0 OR LEN(M$)==0 THEN RETurn 361 11760 IF ',' INSTR(D$&M$) THEN RETurn 362 11770 RETurn D$+(M$/60) 11780 IF LEN(D$)==0 OR LEN(M$)==0 THEN RETurn 361 11790 END DEFine DecDeg 11800 REMark ********************************************************************************************************************************************* 11810 DEFine FuNction field$(str$) 11820 REMark Extracts the first field from the NMEA message data 11830 REMark after it has been chopped to the start of the 11840 REMark field, with comma separated fields so making 11850 REMark no assumption about the field lenght 11860 LOCal k% 11870 REMark last field terminated by* at start of checksum 11880 REMark so need to check for ',' -- if none then '*' 11890 k%="," INSTR str$ 11900 IF k%=0 THEN k%="*" INSTR str$ 11910 RETurn str$(TO(k%-1)) 11920 REMark NOTE error such as empty string must be 11930 REMark dealt with on return from call 11940 END DEFine field$ 11950 REMark *********************************************************************************************************************************************** 11960 DEFine PROCedure spot(elvn,azm,id,tint) 11970 REMark Draw a blob in tint at elvnm azm and show id 11980 REMark For a polar plot need to convert to x,y coords 11990 REMark Code for line plot added later 12000 LOCal x,y,srad 12010 REMark ignore data if id outside possiable range .. 12020 REMark .. it has happened, usually during start up of RX 12030 IF id>maxid THEN RETurn 12040 srad=(90-elvn)/90:REMark zero to one on plot 12050 x=srad*SIN(azm*PI/180)*asprat 12060 y=srad*COS(azm*PI/180) 12070 REMark Copy previous posn as 'old' 12080 posns(id,0)=posns(id,2) 12090 posns(id,1)=posns(id,3) 12100 REMark Save new posn for 'old' next time 12110 posns(id,2)=x 12120 posns(id,3)=y 12130 INK#dc%,tint:STRIP#dc%,tint 12140 REMark Draw sat as blob if first time plotted 12150 IF posns(id,4)<1 OR Blobs%=1 THEN 12160 posns(id,4)=1:REMark Remember as blobbed 12170 REMark Draw a blob 12180 FILL#dc%,1 12190 ELLIPSE#dc%,x,y,6E-2,asprat,0 12200 FILL#dc%,0 12210 REMark Show sat id in contrasting ink 12220 IF tint=seetint% THEN INK#dc%,0:ELSE INK#dc%,7 12230 CURSOR#dc%,x,y,-6,-5 12240 IF id<10 THEN PRINT#dc%,0;:REMark Add leading zero? 12250 PRINT#dc%,id:REMark At last, print sat id 12260 ELSE 12270 REMark ... otherwise draw line 12280 INK#dc%,tint:LINE#dc%,posns(id,0),posns(id,1) TO posns(id,2),posns(id,3):INK#dc%,0 12290 END IF 12300 END DEFine spot 12310 REMark ********************************************************************************************************************************************** 12320 DEFine FuNction Spink%(S) 12330 REMark Returns a colour according to the Speed S 12340 SELect ON S 12350 ON S=0 TO 9.999:RETurn 0: REMark Black 12360 ON S=10 TO 19.999:RETurn 59: REMark Brown 12370 ON S=20 TO 29.999:RETurn 2: REMark Red 12380 ON S=30 TO 39.999:RETurn 236: REMark Yellow 12390 ON S=40 TO 49.999:RETurn 22: REMark Orange 12400 ON S=50 TO 59.999:RETurn 3: REMark Green 12410 ON S=60 TO 69.999:RETurn 25: REMark Blue 12420 ON S=70 TO 79.999:RETurn 26: REMark Violet 12430 REMark Shocking pink for over 80m.p.h. 12440 ON S=REMAINDER :RETurn 112 12450 END SELect 12460 END DEFine Spink% 12470 REMark ************************************************************************************************************************************************* 12480 DEFine PROCedure bargraph (bc%,bw%,bh%,bx%,by%,col1%,col2%,col3%,col4%,bd%,th1%,th2%,bg%,pk%) 12490 REMark bargraph parameters 12500 REMark bc%=Screen channel number 12510 REMark bw%=Bar width 12520 REMark bh%=Bar height 12530 REMark bx%=Bar position x 12540 REMark by%=Bar position y 12550 REMark col1%=First/lowest bar colour 12560 REMark col2%=Second/mid bar colour 12570 REMark col3%=Third/top bar colour 12580 REMark col4%=Peak Hold colour 12590 REMark bd%=Bargraph level data 12600 REMark th1%=Threshold from first to second bar colour 12610 REMark th2%=Threshold from second to third bar colour 12620 REMark bg%=Bar background colour 12630 REMark pk%=Peak value 12640 BLOCK#bc%;bw%,bh%-bd%,bx%,by%,bg%:REMark background bar 12650 bd2%=bd% 12660 IF bd2%>th1% THEN bd2%=th1% 12670 BLOCK#bc%;bw%,bd2%,bx%,by%+(bh%-bd2%),col1%:REMark First bar level 12680 bd3%=bd%-th1% 12690 IF bd%>th2% THEN bd3%=th2%-th1% 12700 IF bd%>th1% THEN BLOCK#bc%;bw%,bd3%,bx%,by%+(bh%-th1%-bd3%),col2%:REMark second bar level 12710 bd4%=bd%-th2% 12720 IF bd%>th2% THEN BLOCK#bc%;bw%,bd4%,bx%,by%+(bh%-bd%),col3%:REMark second bar level 12730 BLOCK#bc%;bw%,2,bx%,(by%+(bh%-pk%))-2,col4%:REMark peek hold bar 12740 END DEFine bargraph 32000 DEFine PROCedure update 32010 SAVE win5_gps_QLToday_GPSProg6 32020 PRINT "Update complete" 32030 END DEFine