

Listing 7:

/**************************************************
**                                               **
**          Input Impedance Calculation          **
**                                               **
**         Maynard A. Wright, P. E. 1990         **
**                                               **
**************************************************/

/* Stored as "zin.c."  Algorithm used here de-
   scribed in M. A. Wright, "Computation of In-
   put Impedance Using RPN Calculators," IEEE
   1979 Region VI Conference Proceedings. This
   version of the program uses functions from
   the Microsoft graphics library and must there-
   fore be compiled using Microsoft C or QuickC.
   The program also uses function prototypes and
   constant definitions from include file cmplx.h
   and must be linked to library cmplxlib.lib. */

#include <graph.h>
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <local\cmplx.h>

#define DBSCALE 8.68588963  /* convert dB to nepers */
#define PHASCALE 57.29577951 /* convert degrees to
                                radians */
#define MINVAL 1e-100  /* minimum value of double
                          input */
#define NW '\xC9' /* northwest graphics corner */
#define NE '\xBB' /* northeast graphics corner */
#define SW '\xC8' /* southwest graphics corner */
#define SE '\xBC' /* southeast graphics corner */
#define HZ '\xCD' /* horizontal graphics line */
#define VR '\xBA' /* vertical graphics line */

double get_real(char*, short, short);

void main(void)

{
   /* declarations */

   char decision, counter;
   short linectr;
   double atten, phase, length;
   struct cmplx_nmbr calcz, termz, linez, inputz;

   /* screen header */

   _settextcolor(14);
   _clearscreen(_GCLEARSCREEN);
   _settextposition(3,20);
   printf("%c", NW);
   for(counter = 1; counter <= 37; ++counter)
      printf("%c", HZ);
   printf("%c", NE);
   _settextposition(4,20);
   printf("%c     INPUT IMPEDANCE CALCULATION     %c",
         VR, VR);
   _settextposition(5,20);
   printf("%c", SW);
   for(counter = 1; counter <= 37; ++counter)
      printf("%c", HZ);
   printf("%c", SE);

   /* input data from keyboard */

   termz.real = get_real("ENTER REAL PART OF
TERMINATING IMPEDANCE IN OHMS:", 8, 17);
   if(termz.real == 0.) /* make input nonzero to
                           avoid sub- */
      termz.real = MINVAL; /* sequent math errors */
   termz.imag = get_real("ENTER IMAGINARY PART OF
TERMINATING IMPEDANCE IN OHMS:", 9, 12);
   if(termz.imag == 0.)
      termz.imag = MINVAL;
   do

   {
      linez.real = get_real("ENTER REAL PART OF
CHARACTERISTIC IMPEDANCE OF LINE IN OHMS:", 10, 6);
      if(linez.real == 0.)
         linez.real = MINVAL;
      linez.imag = get_real("ENTER IMAGINARY PART OF
CHARACTERISTIC IMPEDANCE OF LINE IN OHMS:", 11, 1);
      if(linez.imag == 0.)
         linez.imag = MINVAL;
      atten = get_real("ENTER ATTENUATION PER UNIT
LENGTH OF LINE:", 12, 24);
      if(atten == 0.)
         atten = MINVAL;
      _settextposition(13,22);
      printf("ATTENUATION IN DECIBELS OR NEPERS? ");
      printf("(D OR N):");
      do

      {
         fflush(stdin);
         decision = getche();
         if(decision != 'D' && decision != 'd' &&
               decision != 'N' && decision != 'n')
         {
            _settextposition(14,22);
            printf("      !!! RESPONSE MUST BE D OR 
                   N !!!");
            printf("          ");
            _settextposition(13,66);
         }
      }

      while(decision != 'D' && decision != 'd' &&
            decision != 'N' && decision != 'n');
      if(decision == 'D' || decision == 'd')
         atten /= DBSCALE;
      phase = get_real("ENTER PHASE SHIFT PER UNIT 
LENGTH OF LINE:", 14, 24);
      if(phase == 0.)
         phase = MINVAL;
      _settextposition(15,22);
      printf("PHASE SHIFT IN DEGREES OR RADIANS? ");
      printf("(D OR R):");
      do

      {
         fflush(stdin);
         decision = getche();
         if(decision != 'D' && decision != 'd' &&
               decision != 'R' && decision != 'r')
         {
            _settextposition(16,22);
            printf("      !!! RESPONSE MUST BE D OR 
                   R !!!");
            printf("          ");
            _settextposition(15,66);
         }
      }

      while(decision != 'D' && decision != 'd' &&
            decision != 'R' && decision != 'r');
      if(decision == 'D' || decision == 'd')
         phase /= PHASCALE;
      length = get_real("                    ENTER 
LENGTH OF LINE:", 16, 25);
      _settextposition(17,22);
      printf("                                    
                  ");
      if(length == 0.)
         length = MINVAL;

      /* calculate attenuation and phase shift of line */

      atten *= length;
      phase *= length;

      /* calculate termz / linez */

      calcz = cmplxdiv(termz, linez);

      /* handle case of angle = 0 */

      if(calcz.imag == 0.)
         calcz.imag = 1e-100;

      /* calculate inverse complex hyperbolic tangent */

      calcz = catnh(calcz);

      /* add in line constants */

      calcz.real += atten;
      calcz.imag += phase;

      /* calculate complex hyperbolic tangent */

      calcz = ctanh(calcz);

      /* denormalize solution to obtain input impedance */

      inputz = cmplxmul(calcz, linez);

      /* print results */

      for(linectr = 19; linectr <= 20; ++linectr)

      {
         _settextposition(linectr, 51);
         printf("                              ");
      }

      _settextposition(19,20);
      printf("REAL PART OF INPUT ");
      printf("IMPEDANCE = %+lG OHMS",inputz.real);
      _settextposition(20,15);
      printf("IMAGINARY PART OF INPUT ");
      printf("IMPEDANCE = %+lG OHMS\n\n",inputz.imag);

      /* loop for another section or terminate execution */

      _settextposition(22,4);
      printf("USE INPUT IMPEDANCE AS TERMINAL IMPED");
      printf("ANCE FOR ANOTHER SECTION?  ");
      _settextposition(22,67);
      decision = 0;
      fflush(stdin);
      decision = getche();
      if(decision == 'Y' || decision == 'y')

      {
         termz.real = inputz.real;
         termz.imag = inputz.imag;

         /* set up screen for new input */

         for(linectr = 8; linectr <= 16; ++linectr)

         {
            _settextposition(linectr, 66);
            printf("               ");
         }

         _settextposition(19,20);
         printf("                         ");
         printf("                         ");
         _settextposition(20,15);
         printf("                              ");
         printf("                         ");
         _settextposition(8,66);
         printf("%+lG", inputz.real);
         _settextposition(9,66);
         printf("%+lG", inputz.imag);
      }
   }

   while(decision == 'Y' || decision == 'y');
   printf("\n");
}

double get_real(char *num_string, short x, short y)

{
   struct rccoord rcoord;
   double value;
   char *phlag = '\0', *remainder, string[20];
   short inrow, incol;

   do

   {
      if(phlag)

      {
         _settextposition((x + 1), 1);
         printf("                                  
                      ");
         printf("                                  
                     ");
         _settextposition((x + 1), 25);
         printf("!!! ERROR IN INPUT: PLEASE REENTER
                !!!");
      }

      _settextposition(x, y);
      printf("%s", num_string);
      printf("          ");
      rcoord = _gettextposition();
      inrow = rcoord.row;
      incol = rcoord.col + strlen(num_string);
      _settextposition(inrow, incol);
      ++phlag;
      fflush(stdin);
   }

   while((!(value = strtod((gets(string)),\
         &remainder)) && *remainder) || value ==
         HUGE_VAL);
   _settextposition(inrow, incol);
   printf("%G         ", value);
   if(phlag)

   {
      _settextposition((x+1), 25);
      printf("                                      ");
   }

   return(value);
}

