
{ This code was written for the microwave lab at the University Of Central
  Florida by Robert Middelveen. March 11, 1986                             }

Program Double_Stub_Impedance_Matching;

Const Conv = 1.7453292e-2; { CONVERT FROM DEGREES TO RADIANS                }
      C    = 2.998e8;      { SPEED OF LIGHT IN FREE SPACE  (Meters/Sec)     }

VAR   Z0,                  { CHARACTERISTIC IMPEDANCE OF THE LINE           }
      ZST1,                {       ''           ''    ''  '' 1st STUB       }
      ZST2,                {       ''           ''    ''  '' 2nd STUB       }
      F,                   { FREQUENCY (Hz)                                 }
      D,DD,                { DISTANCE FROM THE LOAD D,   Wavelengths        }
                           {                       DD,   Degrees            }
      DBS,                 { DISTANCE BETWEEN THE STUBS, Wavelengths        }
      ZZR,                 { LOAD IMPEDANCE, REAL PART                      }
      ZZI,                 {  ''      ''   , IMAGINARY PART                 }
      ZLR,                 { NORMALIZED LOAD IMPEDANCE, REAL PART           }
      ZLI,                 {      ''     ''      ''    , IMAGINARY PART     }
      YLR, YLM, LAM_LM,    { Y's ARE NORMALIZED LOAD ADMITTANCES            }
                           { R's ARE REAL, I'S ARE IMAGINARY,               }
                           { M's ARE THE MAGNITUDES, P'S ARE THE PHASE.     }
      YLI, YLP, LAM_LP,    { LAM's ARE THE REFLECTION COEFFICIENT           }
                           { AT THIS POINT                                  }
      YD1R,                { THE NORMALIZED ADMITTANCE LOOKING AT THE LOAD  }
      YD1I,                { FROM DISTANCE D                                }
      A,B,                 { 2 PARAMETERS USED BY PROCEDURE CIRCLE          }

      Y11R_1, LAM_11_1R, LAM_11_1M,
      Y11I_1, LAM_11_1I, LAM_11_1P,
      Y11R_2, LAM_11_2R, LAM_11_2M,
      Y11I_2, LAM_11_2I, LAM_11_2P,

      { THE ABOVE: THE NORMALIZED ADMITTANCE AND THE REFLECTION COEFFICIENT }
      { LOOKING AT THE PARALLEL COMBINATION OF YD1 AND THE FIRST STUB.      }
      { THERE ARE 2 POSSIBLE SOLUTIONS AT THIS POINT.                       }
      { R, I, M, P: REAL, IMAGINARY, MAGNITUDE, PHASE                       }

      YS1_1, LAM_S1_1P,    { THE NORMALIZED ADMITTANCE OF THE FIRST STUB    }
      YS1_2, LAM_S1_2P,    { 2 SOLUTIONS. LAM's ARE REFLECTION              }
      DUMMY,               { DUMMY REAL VARIABLE                            }
      L1_1,                { LENGTH OF THE FIRST STUB IN WAVELENGTHS        }
      L1_2,                { THERE ARE 2 SOLUTIONS.                         }
      LGTH1_1,
      LGTH1_2,             { SAME LENGTHS BUT IN METERS.                    }

      Y22R_1, Y22I_1, LAM_22_1M, LAM_22_1P,
      Y22R_2, Y22I_2, LAM_22_2M, LAM_22_2P,

      { THE ABOVE: THE NORMALIZED ADMITTANCE AND THE REFLECTION COEFFICIENT }
      { LOCATED AT POINT 22 ON THE CHART. LOCATED DOWN THE LINE DISTANCE D  }
      { + THE DISTANCE BETWEEN  THE STUBS. REPRESENTS THE PARALLEL          }
      { COMBINATION OF THE LINE AT 22 AND THE SECOND STUB.                  }

      YS2_1, LAM_S2_1P,    { THE NORMALIZED ADMITTANCE OF THE SECOND STUB.  }
      YS2_2, LAM_S2_2P,    { THE LAM's ARE REFLECTION                       }
      L2_1,                { THE LENGTH OF THE SECOND STUB IN WAVELENGTHS   }
      L2_2,
      LGTH2_1,             { AND IN METERS.                                 }
      LGTH2_2,
      SWR_1, SWR_2: REAL;  { THE STANDING WAVE RATIO BETWEEN THE TWO        }
                           { SECTIONS OF STUBS. 2 SOLUTIONS.                }

      Q1,Q2:        CHAR;  { ANSWERS TO QUESTIONS.                          }

(*$I B:ATAN2.PAS *)
(* A TWO ARGUMENT ARCTANGENT FUNCTION NOT PRESENT IN STANDARD PASCAL *)
(* CALCULATES ANGLES IN DEGREES FOR ALL 4 QUADRENTS *)

PROCEDURE R_P(VAR MAG,PHASE:REAL; RE,IM:REAL);

{ RECTANGULAR TO POLAR CONVERSION                                           }

BEGIN
  MAG:=SQRT(SQR(RE)+SQR(IM));
  PHASE:=ATAN(RE,IM);
  IF PHASE<0.0 THEN PHASE:=PHASE+360.0
END;

PROCEDURE P_R(VAR RE,IM:REAL; MAG,PHASE:REAL);

{ POLAR TO RECTANGULAR CONVERSION                                           }

BEGIN
  RE:=MAG*COS(PHASE*CONV);
  IM:=MAG*SIN(PHASE*CONV)
END;

PROCEDURE ADM_REF(VAR LAMBDA_M,LAMBDA_P:REAL; Y_R,Y_I:REAL);

{ NORMALIZED ADMISSION TO REFLECTION CONVERSION                             }

VAR NR,NI,DR,DI,NM,NP,DM,DP:REAL;

BEGIN
  NR:=Y_R-1.0; NI:=Y_I; R_P(NM,NP,NR,NI);
  DR:=Y_R+1.0; DI:=Y_I; R_P(DM,DP,DR,DI);
  LAMBDA_M:=NM/DM; LAMBDA_P:=NP-DP;
  IF LAMBDA_P<0.0 THEN LAMBDA_P:=LAMBDA_P+360.0
END;

PROCEDURE REF_ADM(VAR Y_R,Y_I:REAL; LAMBDA_M,LAMBDA_P:REAL);

{ REFECTION TO NORMALIZED ADMISSION CONVERSION                              }

VAR LAMBDA_R,LAMBDA_I,Y_M,Y_P,NR,NI,NM,NP,DR,DI,DM,DP:REAL;

BEGIN
  P_R(LAMBDA_R,LAMBDA_I,LAMBDA_M,LAMBDA_P);
  NR:=1.0+LAMBDA_R; NI:=LAMBDA_I; R_P(NM,NP,NR,NI);
  DR:=1.0-LAMBDA_R; DI:=-LAMBDA_I; R_P(DM,DP,DR,DI);
  Y_M:=NM/DM; Y_P:=NP-DP;
  P_R(Y_R,Y_I,Y_M,Y_P)
END;

PROCEDURE CIRCLE(VAR X1,Y1,X2,Y2:REAL; A,B,C,D,E:REAL);

{ THIS PROCEDURE CALCULATES THE INTERSECTION OF THE SPACING CIRCLE AND A    }
{ CIRCLE OF CONSTANT CONDUCTANCE ON THE SMITH CHART. THE INPUTS ARE THE     }
{ PARAMETERS OF THE TWO CIRCLES AND THE OUTPUTS ARE THE X AND Y COORDINATES }
{ OF THE TWO SOLUTIONS. THESE TWO SOLUTIONS DENOTE THE REFLECTION           }
{ COEFFICIENT AT THE POINT Y11 ON THE CHART.                                }

CONST TOLERANCE=0.001;

VAR F,G,H,I,J,YSQ:REAL;

BEGIN
  F:=C*C-B*B+D*D-E*E-A*A;
  G:=2.0*A-2.0*D;
  H:=4.0*B*B*(E*E-D*D)-F*F;
  I:=8.0*B*B*D-2.0*G*F;
  J:=-(4.0*B*B+G*G);
  X1:=(-I+SQRT(I*I-4.0*J*H))/(2.0*J);
  X2:=(-I-SQRT(I*I-4.0*J*H))/(2.0*J);
  YSQ:=E*E-SQR(X1-D);
  IF ABS(SQR(X1-A)+SQR(SQRT(YSQ)-B)-C*C)>TOLERANCE THEN Y1:=-SQRT(YSQ)
                                                   ELSE Y1:=SQRT(YSQ);
  YSQ:=E*E-SQR(X2-D);
  IF ABS(SQR(X2-A)+SQR(SQRT(YSQ)-B)-C*C)>TOLERANCE THEN Y2:=-SQRT(YSQ)
                                                   ELSE Y2:=SQRT(YSQ);
END;


PROCEDURE GET_DATA;

{ THIS PROCEDURE PROMPTS THE USER AND INPUTS THE VARIABLES NEEDED TO SOLVE }
{ THE DOUBLE STUB PROBLEM.                                                 }

BEGIN
  ClrScr;
  WRITELN;
  WRITELN;
  WRITE('Z0=?   ');                          READLN(Z0);
  WRITE('ZST1=? ');                          READLN(ZST1);
  WRITE('ZST2=? ');                          READLN(ZST2);
  WRITELN;
  WRITELN('Will distances be in wavelengths or meters?');
  WRITELN('from the load and between the stubs ( 1=WAVELENGTHS 2=METERS ) ');
                                             READLN(Q1);
  WRITELN;
  WRITE('Distance from the load?     ');     READLN(D);
  WRITE('Distance between the stubs? ');     READLN(DBS);
  WRITELN;
  WRITE('ZLR=?     ');                       READLN(ZZR);
  WRITE('ZLI=?     ');                       READLN(ZZI);
  WRITELN;
  WRITE('F=? (GHz) ');                       READLN(F); F:=F*1E9;
END;

PROCEDURE CALCULATIONS;

{ THIS PROCEDURE SOLVES THE PROBLEM.                                        }

BEGIN
  ZLR:=ZZR/Z0; { NORMALIZE THE LOAD RESISTANCE                              }
  ZLI:=ZZI/Z0;

  R_P(YLM,YLP,ZLR,ZLI); { FIND THE NORMALIZED ADMITTANCE AT THE LOAD.       }
  YLM:=1.0/YLM; YLP:=-YLP;
  P_R(YLR,YLI,YLM,YLP);
  ADM_REF(LAM_LM,LAM_LP,YLR,YLI); { FIND THE REFLECTION COEFFICIENT         }
                                  { AT THE LOAD.                            }

  IF Q1='2' THEN { ADJUST DISTANCES TO WAVELENGTHS IF NEEDED.               }
  BEGIN
    D:=D*F/C;
    DBS:=DBS*F/C
  END;

DD:=D*720.0; LAM_LP:=LAM_LP-DD; { MOVE DISTANCE D AWAY FROM THE LOAD.       }

REF_ADM(YD1R,YD1I,LAM_LM,LAM_LP); { FIND THE NORMALIZED ADMITTANCE AT THIS  }
                                  { POINT.                                  }

P_R(A,B,0.5,720*DBS); { CALCULATE CIRCLE PARAMETERS A AND B.                }

CIRCLE(LAM_11_1R,LAM_11_1I,LAM_11_2R,LAM_11_2I,
       A,B,0.5,YD1R/(1.0+YD1R),1.0/(1.0+YD1R));

{ CIRCLE FINDS THE REFLECTION COEFFICIENT AT POINT 11 ON THE CHART. THERE   }
{ ARE 2 POSSIBLE SOLUTIONS. SOLUTIONS ARE IN RETANGULAR COORDINATES.        }

R_P(LAM_11_1M,LAM_11_1P,LAM_11_1R,LAM_11_1I);
R_P(LAM_11_2M,LAM_11_2P,LAM_11_2R,LAM_11_2I);

{ CONVERT THESE TO POLAR COORDINATES.                                       }

SWR_1:=(1.0+LAM_11_1M)/(1.0-LAM_11_1M);
SWR_2:=(1.0+LAM_11_2M)/(1.0-LAM_11_2M);

{ THE STANDING WAVE RATIO ON THE SECTION OF LINE BTWEEN THE STUBS CAN NOW   }
{ BE CALCULATED.                                                            }

REF_ADM(Y11R_1,Y11I_1,LAM_11_1M,LAM_11_1P);
REF_ADM(Y11R_2,Y11I_2,LAM_11_2M,LAM_11_2P);

{ FIND THE ADMITTANCE AT 11.                                                }

YS1_1:=(Y11I_1-YD1I)*ZST1/Z0;
YS1_2:=(Y11I_2-YD1I)*ZST1/Z0;

{ THE NORMALIZED SUSCEPTANCE OF THE FIRST STUB CAN NOW BE FOUND.            }

ADM_REF(DUMMY,LAM_S1_1P,0.0,YS1_1);
ADM_REF(DUMMY,LAM_S1_2P,0.0,YS1_2);

{ THE PHASE OF THE REFLECTION COEFFICIENT CORRESPONDING TO A CONDUCTANCE OF }
{ ZERO AND A SUCEPTANCE OF THE STUB IS CALCULATED.                          }

L1_1:=0.5-LAM_S1_1P/720.0;
L1_2:=0.5-LAM_S1_2P/720.0;

{ CALCULATE THE LENGTH OF THE FIRST STUB IN WAVELENGTHS.                    }

LGTH1_1:=C*L1_1/F;
LGTH1_2:=C*L1_2/F;

{ AND IN METERS.                                                            }

LAM_22_1M:=LAM_11_1M; LAM_22_1P:=LAM_11_1P-DBS*720.0;
REF_ADM(Y22R_1,Y22I_1,LAM_22_1M,LAM_22_1P);

LAM_22_2M:=LAM_11_2M; LAM_22_2P:=LAM_11_2P-DBS*720.0;
REF_ADM(Y22R_2,Y22I_2,LAM_22_2M,LAM_22_2P);

{ MOVE TO POSITION 22 ON THE CHART.                                         }

YS2_1:=-Y22I_1;
YS2_2:=-Y22I_2;

{ CALCULATE THE NORMALIZED SUSCEPTANCE OF THE SECOND STUB.                  }

ADM_REF(DUMMY,LAM_S2_1P,0.0,YS2_1);
ADM_REF(DUMMY,LAM_S2_2P,0.0,YS2_2);

{ SAME PROCEDURE USED WITH THE FIRST STUB.                                  }

L2_1:=0.50-LAM_S2_1P/720.0;
L2_2:=0.50-LAM_S2_2P/720.0;

{ CALCULATE THE LENGTH OF THE SECOND STUB IN WAVELENGTHS.                   }

LGTH2_1:=C*L2_1/F;
LGTH2_2:=C*L2_2/F;

{ AND IN METERS.                                                            }

END;


PROCEDURE ANSWER;

{ THIS PROCEDURE OUTPUTS THE LENGTHS OF THE STUBS NEEDED AND INFORMATION    }
{ CONCERNING THE PROBLEM.                                                   }

BEGIN
  ClrScr;
  WRITELN;
  WRITELN('Z0=     ',Z0:10:5);
  WRITELN('ZST1=   ',ZST1:10:5);
  WRITELN('ZST2=   ',ZST2:10:5);
  WRITELN('ZL=     ',ZZR:10:5,'  +j  ',ZZI:10:5);
  WRITELN('zl=     ',ZLR:10:5,'  +j  ',ZLI:10:5);
  WRITELN('yl=     ',YLR:10:5,'  +j  ',YLI:10:5);
  WRITELN('yd1=    ',YD1R:10:5,'  +j  ',YD1I:10:5);
  WRITELN('y11_1=  ',Y11R_1:10:5,'  +j  ',Y11I_1:10:5);
  WRITELN('y11_2=  ',Y11R_2:10:5,'  +j  ',Y11I_2:10:5);
  WRITELN('ys1_1=              +j  ',YS1_1:10:5);
  WRITELN('ys1_2=              +j  ',YS1_2:10:5);
  WRITELN('l1_1=   ',L1_1:10:5,'  Wavelengths');
  WRITELN('l1_2=   ',L1_2:10:5,'  Wavelengths');
  IF LGTH1_1>1.0
    THEN WRITELN('LGHT1_1=',LGTH1_1:10:5,' Meters')
    ELSE WRITELN('LGHT1_1=',(LGTH1_1*100):10:5,' Cm');
  IF LGTH1_2>1.0
    THEN WRITELN('LGTH1_2=',LGTH1_2:10:5,' Meters')
    ELSE WRITELN('LGHT1_2=',(LGTH1_2*100):10:2,' Cm');
  WRITELN;
  WRITELN('TYPE <RETURN> TO CONTINUE'); READLN(Q2);
  ClrScr;
  WRITELN;
  WRITELN('y22_1=  ',Y22R_1:10:5,'  +j  ',Y22I_1:10:5);
  WRITELN('y22_2=  ',Y22R_2:10:5,'  +j  ',Y22I_2:10:5);
  WRITELN('ys2_1=              +j  ',YS2_1:10:5);
  WRITELN('ys2_2=              +j  ',YS2_2:10:5);
  WRITELN('l2_1 =  ',L2_1:10:5,'  Wavelengths');
  WRITELN('l2_2 =  ',L2_2:10:5,'  Wavelengths');
  IF LGTH2_1>1.0
    THEN WRITELN('LGHT2_1=',LGTH2_1:10:5,' Meters')
    ELSE WRITELN('LGTH2_1=',(LGTH2_1*100):10:5,' Cm');
  IF LGTH2_2>1.0
    THEN WRITELN('LGTH2_2=',LGTH2_2:10:5,' Meters')
    ELSE WRITELN('LGHT2_2=',(LGTH2_2*100):10:5,' Cm');
  WRITELN('SWR_1=  ',SWR_1:10:5,' v/v');
  WRITELN('SWR_2=  ',SWR_2:10:5,' v/v');
  WRITELN('F=      ',(F/1E9):10:5,' GHz')
END;

{                             MAIN PROGRAM                                  }

BEGIN
  GET_DATA;
  CALCULATIONS;
  ANSWER;
END.

