DECLARE SUB Help (a$)
DECLARE SUB PlotAvgA (a$, N!)
DECLARE SUB InitScrnA ()
DECLARE SUB InitScrn ()
DECLARE SUB DoPoint (N!, SIG!, PRN$, EL$, Az$)
DECLARE SUB PlotAvg (a$, N!)
DECLARE SUB Gfield (a!, a$, B$)
DECLARE SUB Save ()
DECLARE SUB Load ()
COMMON SHARED MX(), NO(), MI(), SS(), MA(), SSAZ(), SSZZ(), NOAZ(), NOZZ(), Az, SB(), NA()
DIM MX(2, 40)
DIM NO(2, 99), MI(2, 99), SS(2, 99), MA(2, 99)
DIM SSAZ(2, 361, 6), NOAZ(2, 361, 6), SB(2, 6), NA(2, 6)
CALL Help("X")
INPUT "Enter the COM# port for the 1st GPS unit (1 or 2), [1]"; a$
IF a$ = "" THEN Port$ = "COM1" ELSE Port$ = "COM" + a$
OPEN Port$ + ":4800,n,8,1,cs0,cd0,ds0" FOR RANDOM AS #1
INPUT "Enter the COM# port for the 2nd GPS unit (1, 2 or NONE), [N]"; a$
IF a$ = "1" OR a$ = "2" THEN
   OPEN "COM" + a$ + ":4800,n,8,1,cs0,cd0,ds0" FOR RANDOM AS #2
   Port2 = 2
END IF
ON ERROR GOTO errortrap
SCREEN 9
WIDTH 80, 43
CALL InitScrn
DO
 GOSUB More1
 LOCATE 5, 1: PRINT LEFT$("1: " + a$, 79)
 IF LEFT$(a$, 6) = "$GPGGA" THEN
    LOCATE 43, 1: PRINT LEFT$(a$, 79);
 ELSEIF LEFT$(a$, 6) = "$GPGSV" THEN
    a = 7
    CALL Gfield(a, a$, NSS$)
    CALL Gfield(a, a$, NCS$): LOCATE 1 + VAL(NCS$), 1: PRINT LEFT$(a$, 79)
    CALL Gfield(a, a$, NSA$)
    L = LEN(a$) - 4
    DO WHILE a > 2 AND a < L
       CALL Gfield(a, a$, PRN$)
       LOCATE 9 + VAL(PRN$), 1: PRINT PRN$;
       CALL Gfield(a, a$, EL$): PRINT RIGHT$("    " + EL$, 4);
       CALL Gfield(a, a$, Az$): PRINT RIGHT$("    " + Az$, 4);
       CALL Gfield(a, a$, SNR$)
       SIG = VAL(SNR$)
       IF SIG > 20 AND SIG < 60 THEN CALL DoPoint(1, SIG, PRN$, EL$, Az$)
    LOOP
 END IF
REM Now PORT TWO! * * * * * * * * * * * * * * * ** * * **** **
IF Port2 THEN
   GOSUB More2
   IF a2$ = "NoComms" THEN Port2 = 0
   LOCATE 6, 1: PRINT LEFT$("2: " + a2$, 79)
   IF LEFT$(a2$, 6) = "$GPGGA" THEN
   ELSEIF LEFT$(a2$, 6) = "$GPGSV" THEN
      a = 7
      CALL Gfield(a, a2$, NSS$)
      CALL Gfield(a, a2$, NCS$)
      CALL Gfield(a, a2$, NSA$)
      L = LEN(a2$) - 4
      DO WHILE a > 2 AND a < L
         CALL Gfield(a, a2$, PRN$)
         LOCATE 9 + VAL(PRN$), 20
         CALL Gfield(a, a2$, EL$)
         CALL Gfield(a, a2$, Az$)
         CALL Gfield(a, a2$, SNR$)
         SIG = VAL(SNR$)
         IF SIG > 20 AND SIG < 60 THEN CALL DoPoint(2, SIG, PRN$, EL$, Az$)
      LOOP
   END IF
END IF
a$ = UCASE$(INKEY$)
IF a$ = "H" THEN a$ = "": CALL Help(a$)
IF a$ = "R" THEN Port2 = 2: a2$ = ""
IF a$ = "A" THEN CALL InitScrnA
IF a$ = "E" THEN CALL InitScrn
IF a$ = "S" THEN CALL Save
IF a$ = "L" THEN CALL Load
IF a$ = "Q" THEN END
IF a$ = "D" OR a$ = "P" THEN
   IF Az = 0 THEN
      CALL InitScrn
      CALL PlotAvg(a$, 1)
      CALL PlotAvg(a$, 2)
   END IF
   IF Az = 1 THEN
      CALL InitScrnA
      CALL PlotAvgA(a$, 1)
      CALL PlotAvgA(a$, 1)
   END IF
END IF
LOOP
STOP



More1:   t = 1: j = 1: a = 0: strt = TIMER
    DO WHILE j > 0 AND a = 0
       IF ABS(TIMER - strt) >= t THEN j = 0: a$ = "NoComms": As$ = "": EXIT DO
       a = INSTR(As$, CHR$(13))
       IF a > 0 THEN a$ = LEFT$(As$, a - 1): As$ = MID$(As$, a + 1): EXIT DO
       IF LOC(1) > 0 THEN As$ = As$ + INPUT$(LOC(1), 1)
    LOOP
    DO WHILE LEFT$(a$, 1) < " " AND LEN(a$) > 0
       a$ = MID$(a$, 2)
    LOOP
    RETURN

More2:   t = 1: j = 1: a = 0: strt = TIMER
    DO WHILE j > 0 AND a = 0
       IF ABS(TIMER - strt) >= t THEN j = 0: a2$ = "NoComms": As2$ = "": EXIT DO
       a = INSTR(As2$, CHR$(13))
       IF a > 0 THEN a2$ = LEFT$(As2$, a - 1): As2$ = MID$(As2$, a + 1): EXIT DO
       IF LOC(2) > 0 THEN As2$ = As2$ + INPUT$(LOC(2), 2)
       LOOP
    DO WHILE LEFT$(a2$, 1) < " " AND LEN(a2$) > 0
       a2$ = MID$(a2$, 2)
    LOOP
    RETURN



errortrap: RESUME NEXT

SUB DoPoint (N, SIG, PRN$, EL$, Az$)
      
    AZd = VAL(Az$)
    ELd = VAL(EL$)
    SAT = VAL(PRN$): IF MX(N, SAT) < SIG THEN MX(N, SAT) = SIG
    ELr = ELd / 57.4
    AZr = (90 + AZd) / 57.4
    SS(N, ELd) = SS(N, ELd) + SIG
    NO(N, ELd) = NO(N, ELd) + 1
    IF ELd > 0 AND ELd <= 20 THEN
        ELz = 1
        Cz = 11
    END IF
    IF ELd > 20 AND ELd <= 40 THEN
        ELz = 2
        Cz = 12
    END IF
    IF ELd > 40 AND ELd <= 60 THEN
        ELz = 3
        Cz = 13
    END IF
    IF ELd > 60 THEN
        ELz = 4
        Cz = 14
    END IF
    SSAZ(N, AZd, ELz) = SSAZ(N, AZd, ELz) + SIG
    NOAZ(N, AZd, ELz) = NOAZ(N, AZd, ELz) + 1
    IF MI(N, ELd) = 0 THEN MI(N, ELd) = SIG
    IF SIG > MA(N, ELd) THEN MA(N, ELd) = SIG
    IF SIG < MI(N, ELd) THEN MI(N, ELd) = SIG
    COE = 7 * COS(ELr)
    SIE = 5 * SIN(ELr)
    COEZ = 7 * COS(AZr)
    SIEZ = 5 * SIN(AZr)
    PRINT "  "; SIG;
    PRINT RIGHT$("    " + STR$(MX(N, SAT)), 3)
    c = 14: IF N = 2 THEN c = 12
    IF Az = 0 THEN
        x = 240: y = 300: IF N = 2 THEN x = 238: y = 302 'was 198
        CIRCLE (x + SIG * COE, y - SIG * SIE), 1, c
    END IF
    IF Az = 1 THEN
        SIGZ = SIG / 2
        x = 417: y = 175: IF N = 2 THEN x = 418: y = 177
        CIRCLE (x + SIGZ * COEZ, y - SIGZ * SIEZ), 1, Cz
    END IF

END SUB

SUB Gfield (a, a$, B$)

 B = INSTR(a + 1, a$, ",")
 IF B >= a + 1 THEN B$ = MID$(a$, a + 1, B - (a + 1)) ELSE B = 1: B$ = ""
 a = B
END SUB

SUB Help (a$)
CLS : PRINT "SIGPLOT.bas Version 1.2  by  Bob Bruninga, WB4APR.  16 Jan 1997"
PRINT
PRINT "This APRS program monitors the NMEA $GPGSV sentence to extract AZ/EL and Signal"
PRINT "data from satellites in view and then plot an Antenna pattern.  It can monitor"
PRINT "TWO GPS units simultaneously so you can compare one antenna to a reference.  "
PRINT
PRINT "Each second's data is plotted as it comes in, but you may press either D for"
PRINT "Dots or L for a line plot.  After a few hours you should have enough data for"
PRINT "a good Elevation plot since you are taking data from ALL azimuths.  But the"
PRINT "AZIMUTH plot takes 12 hours to get enough data for all the possible Azimuths"
PRINT "Since you are only taking data from 1/4 of the elevations for each profile."
PRINT
PRINT "The AZIMUTH shows 4 colors, one for each elevation range.  This is because the"
PRINT "Elevation plot is not equal at all elevations.  Also to make the plot look"
PRINT "reasonable until enough data comes in, missing data are assumed to be the"
PRINT "average value, so you will see perfect circles until the data fills in."
PRINT
PRINT "REMEMBER THESE Three QUESTIONABLE ASSUMPTIONS:"
PRINT "  1) All satellites are transmitting equal output powers"
PRINT "  2) Your sky view is unobstructed in all directions."
PRINT "  3) For the ELEVATION plot, that your AZIMUTH pattern is OMNIdirectional"
PRINT "     Meaning a sat at 45ø to East is averaged with all other 45ø sats, etc"
PRINT
IF a$ = "" THEN
   PRINT
   PRINT
   PRINT
   PRINT "Hit E to return to the ELEVATION plot"
   PRINT
   PRINT "Hit A to return to the AZIMUTH plot"
   PRINT
   DO UNTIL a$ <> "": a$ = UCASE$(INKEY$): LOOP
END IF

END SUB

SUB InitScrn
    Az = 0
    CLS
    LOCATE 8, 1: PRINT "SAT EL  AZ  SIG MAX  SG2 MX2"
    LOCATE 9, 1: PRINT "--- --  --  --- ---  --- ---"
    LINE (240, 300)-(594, 48), 14, B
    REM x*7 and y*5 is a square plot
    FOR i = 0 TO 90
        a = i / 57.4
        PSET (240 + 350 * COS(a), 300 - 250 * SIN(a)), 15
        PSET (240 + 280 * COS(a), 300 - 200 * SIN(a)), 15
        PSET (240 + 210 * COS(a), 300 - 150 * SIN(a)), 15
        IF INT(i / 10) = i / 10 THEN
           CIRCLE (240 + 350 * COS(a), 300 - 250 * SIN(a)), 1, 15
           CIRCLE (240 + 280 * COS(a), 300 - 200 * SIN(a)), 1, 15
           CIRCLE (240 + 210 * COS(a), 300 - 150 * SIN(a)), 1, 15
        END IF
    NEXT
    LOCATE 39, 32: PRINT "SIGNAL STRENGTH          30      40      50"
    LOCATE 38, 76: PRINT "0"
    LOCATE 32, 75: PRINT "10";
    LOCATE 27, 73: PRINT "20"
    LOCATE 22, 70: PRINT "30"
    LOCATE 18, 66: PRINT "40"
    LOCATE 14, 60: PRINT "50"
    LOCATE 8, 47: PRINT "70"
    LOCATE 7, 40: PRINT "80"
    LOCATE 6, 32: PRINT "90"
    FOR i = 1 TO 9
        LOCATE 7 + i, 32: PRINT MID$("ELEVATION", i, 1);
        LOCATE 7 + i, 34: PRINT MID$("  ANGLE  ", i, 1);
    NEXT
    LOCATE 25, 32: PRINT "WB4APR";
    LOCATE 26, 32: PRINT "APRS SIGPLOT1.3";
    LOCATE 28, 32: PRINT "A - AZIMUTH plot";
    LOCATE 29, 32: PRINT "D - DOTS min/max/avg";
    LOCATE 30, 32: PRINT "E - EL data (current)";
    LOCATE 31, 32: PRINT "H - HELP";
    LOCATE 32, 32: PRINT "L - LOAD Data";
    LOCATE 33, 32: PRINT "P - PLOT Line";
    LOCATE 34, 32: PRINT "Q - to QUIT.";
    LOCATE 35, 32: PRINT "R - RETRY comms";
    LOCATE 36, 32: PRINT "S - SAVE Data";

    LOCATE 8, 55: PRINT "Let program run for"
    LOCATE 9, 55: PRINT "At least an hour to"
    LOCATE 10, 55: PRINT "fill in all angles."
    LOCATE 12, 65: PRINT "de WB4APR"
END SUB

SUB InitScrnA
    Az = 1
    CLS
    LOCATE 8, 1: PRINT "SAT EL  AZ  SIG MAX  SG2 MX2"
    LOCATE 9, 1: PRINT "--- --  --  --- ---  --- ---"
    LINE (240, 300)-(594, 48), 14, B
    REM x*7 and y*5 is a square plot
    strt = TIMER

    FOR i = 0 TO 360 STEP 2
        a = i / 57.4
        COSa = COS(a)
        SINa = SIN(a)
        PSET (417 + 177 * COSa, 175 - 125 * SINa), 15
        PSET (417 + 137 * COSa, 175 - 100 * SINa), 15
        PSET (417 + 102 * COSa, 175 - 75 * SINa), 15
        IF INT(i / 10) = i / 10 THEN
           CIRCLE (417 + 177 * COSa, 175 - 125 * SINa), 1, 15
           CIRCLE (417 + 137 * COSa, 175 - 100 * SINa), 1, 15
           CIRCLE (417 + 102 * COSa, 175 - 75 * SINa), 1, 15
        END IF
    NEXT
    LOCATE 15, 50: PRINT "WB4APR"
    LOCATE 16, 45: PRINT "APRS SIGPLOT v1.2"
    LOCATE 18, 45: PRINT "ELEVATION ANGLES"
    LOCATE 20, 52: PRINT "00-20"
    LOCATE 22, 52: PRINT "20-40"
    LOCATE 24, 52: PRINT "40-60"
    LOCATE 26, 52: PRINT "60-80"
    LOCATE 28, 45: PRINT "For good plot, run"
    LOCATE 29, 45: PRINT "  for 12 hours"
    FOR i = 1 TO 4
        y = 136 + 16 * i
        LINE (370, y)-(400, y + 8), 10 + i, BF
    NEXT
    
REM    LOCATE 39, 32: PRINT "SIGNAL STRENGTH          30      40      50"
    LOCATE 22, 76: PRINT "270"
    LOCATE 12, 70: PRINT "315";
    LOCATE 12, 34: PRINT "45"
    LOCATE 22, 28: PRINT "90"
    LOCATE 33, 34: PRINT "135"
    LOCATE 38, 52: PRINT "180"
    LOCATE 33, 70: PRINT "225"
    LOCATE 6, 53: PRINT "0"
REM    FOR i = 1 TO 15
REM        LOCATE 7 + i, 32: PRINT MID$("ELEVATION ANGLE", i, 1)
REM    NEXT
    
    LOCATE 39, 32: PRINT "A - AZ data (current)";
    LOCATE 40, 32: PRINT "D - DATA collected";
    LOCATE 41, 32: PRINT "E - ELEVATION plot";
    LOCATE 42, 32: PRINT "L - LOAD Data";
    LOCATE 39, 55: PRINT "P - PLOT Line";
    LOCATE 40, 55: PRINT "Q - QUIT.";
    LOCATE 41, 55: PRINT "R - RETRY comms";
    LOCATE 42, 55: PRINT "S - SAVE Data";


REM    LOCATE 8, 55: PRINT "Let program run for"
REM    LOCATE 9, 55: PRINT "At least an hour to"
REM    LOCATE 10, 55: PRINT "fill in all angles."
REM    LOCATE 12, 65: PRINT "de WB4APR"
END SUB

SUB Load
Name2:
LOCATE 40, 1: PRINT "                                               "
LOCATE 40, 2: PRINT "                                               "
F$ = "GPSANT.DAT"
LINE (0, 310)-(620, 325), 14, B
LOCATE 40, 2: PRINT "Name of File ("; F$; ")";
INPUT a$
IF a$ <> "" THEN
   IF INSTR(a$, ".") = 0 THEN a$ = a$ + ".dat"
   F$ = a$
END IF
IF LEN(F$) > 12 THEN GOTO Name2
OPEN F$ FOR INPUT AS #3
FOR N = 1 TO 2
        FOR L = 1 TO 36
                INPUT #3, MX(N, L)
        NEXT L
        FOR L = 1 TO 91
                INPUT #3, NO(N, L)
                INPUT #3, MI(N, L)
                INPUT #3, SS(N, L)
                INPUT #3, MA(N, L)
        NEXT L
        FOR L = 1 TO 361
                FOR M = 1 TO 6
                        INPUT #3, SSAZ(N, L, M)
                        INPUT #3, NOAZ(N, L, M)
                NEXT M
        NEXT L
        FOR L = 1 TO 6
                INPUT #3, SB(N, L)
                INPUT #3, NA(N, L)
        NEXT L
NEXT N
IF Az = 0 THEN CALL InitScrn
IF Az = 1 THEN CALL InitScrnA
END SUB

SUB PlotAvg (a$, N)
 First = -1
 FOR i = 1 TO 90
     a = i / 57.4
     COE = 7 * COS(a)
     SIE = 5 * SIN(a)
     SA = 0: IF NO(N, i) > 0 THEN SA = SS(N, i) / NO(N, i)
     IF SA > 20 AND SA < 60 THEN
        x = 240: y = 300: c = 10
        IF N = 2 THEN x = 238: y = 302: c = 12 'was 198
        IF a$ = "P" THEN
           IF First THEN
                X0 = x + SA * COE: Y0 = y - SA * SIE
                First = 0
           ELSE X1 = x + SA * COE: Y1 = y - SA * SIE
                LINE (X0, Y0)-(X1, Y1), c
                X0 = X1: Y0 = Y1
           END IF
        ELSE
           CIRCLE (x + SA * COE, y - SA * SIE), 3, c
        END IF
        CIRCLE (x + MI(N, i) * COE, y - MI(N, i) * SIE), 1, c
        CIRCLE (x + MA(N, i) * COE, y - MA(N, i) * SIE), 1, c
     END IF
   NEXT i

END SUB

SUB PlotAvgA (a$, N)
 First = -1
 NA = 0: SB = 0: SC = 0
 FOR ELz = 1 TO 4 'Compute average value for each of the 4 elevation ranges
     FOR i = 0 TO 360
        IF NOAZ(N, i, ELz) > 0 THEN
                SB(N, ELz) = SSAZ(N, i, ELz) / NOAZ(N, i, ELz) + SB(N, ELz)
                NA(N, ELz) = NA(N, ELz) + 1
        END IF
     NEXT i
 NEXT ELz
 FOR ELz = 1 TO 4  'Now draw the rings
     FOR i = 0 TO 360
        a = (90 + i) / 57.4
        COE = 7 * COS(a)
        SIE = 5 * SIN(a)
        SA = 0: SC = 1
        IF INT(i / 10) = i / 10 THEN  'At least every 10 deg, use the avg
                SA = SB(N, ELz) / NA(N, ELz): SC = 0
        END IF
        REM If there is a data point, then use it for SA
        IF NOAZ(N, i, ELz) > 0 THEN SA = SSAZ(N, i, ELz) / NOAZ(N, i, ELz)
        IF SA > 20 AND SA < 60 THEN
                SA = SA / 2
                x = 417: y = 175
                IF ELz = 1 THEN c = 11
                IF ELz = 2 THEN c = 12
                IF ELz = 3 THEN c = 13
                IF ELz = 4 THEN c = 14
                IF N = 2 THEN
                        x = 418
                        y = 177
                        IF ELz = 1 THEN c = 11
                        IF ELz = 2 THEN c = 12
                        IF ELz = 3 THEN c = 13
                        IF ELz = 4 THEN c = 14
                END IF
                IF a$ = "P" THEN
                   IF First THEN
                      X0 = x + SA * COE: Y0 = y - SA * SIE
                      First = 0
                   ELSE X1 = x + SA * COE: Y1 = y - SA * SIE
                        LINE (X0, Y0)-(X1, Y1), c
                        X0 = X1: Y0 = Y1
                   END IF
                ELSE
                   IF SC = 1 THEN
                      CIRCLE (x + SA * COE, y - SA * SIE), 3, c
                   END IF
                END IF
        END IF
     NEXT i
     SB(N, ELz) = 0: NA(N, ELz) = 0
 NEXT ELz
END SUB

SUB Save
Names:
LOCATE 40, 1: PRINT "                                               "
LOCATE 40, 2: PRINT "                                               "
F$ = "GPSANT.DAT"
LINE (0, 310)-(620, 325), 14, B
LOCATE 40, 2: PRINT "Name of File ("; F$; ")";
INPUT a$
IF a$ <> "" THEN
   IF INSTR(a$, ".") = 0 THEN a$ = a$ + ".dat"
   F$ = a$
END IF
IF LEN(F$) > 12 THEN GOTO Names
OPEN F$ FOR OUTPUT AS #3
FOR N = 1 TO 2
        FOR L = 1 TO 36
                PRINT #3, MX(N, L)
        NEXT L
        FOR L = 1 TO 91
                PRINT #3, NO(N, L)
                PRINT #3, MI(N, L)
                PRINT #3, SS(N, L)
                PRINT #3, MA(N, L)
        NEXT L
        FOR L = 1 TO 361
                FOR M = 1 TO 6
                        PRINT #3, SSAZ(N, L, M)
                        PRINT #3, NOAZ(N, L, M)
                NEXT M
        NEXT L
        FOR L = 1 TO 6
                PRINT #3, SB(N, L)
                PRINT #3, NA(N, L)
        NEXT L
NEXT N
IF Az = 0 THEN CALL InitScrn
IF Az = 1 THEN CALL InitScrnA
END SUB

