/*******************************************
** Input Impedance Calculation **
** **
** Maynard A. Wright, P. E. 1990 **
** **
*******************************************/
/* Stored as "zin.c." Algorithm used here
described in M. A. Wright, "Computation of
Input Impedance Using RPN Calculators," IEEE
1979 Region VI Conference Proceedings. This
version of the program uses functions from
the Microsoft graphics library and must
therefore 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_reat("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);
}