home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hacker Chronicles 2
/
HACKER2.BIN
/
138.DIGITIZE.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1988-10-18
|
21KB
|
503 lines
(****************************************************************************)
(*** ***)
(*** Digitizer is to read data directly from the digitizing pad, then ***)
(*** perform analysis on that data until it represents the "actual" ***)
(*** waveform in the photograph. The digitizer used is the Micro ***)
(*** Digi-Pad 6"x6" Electromagnetic Type 7 digitizer from GTCO Corp. ***)
(*** The input parameter DataToDigitize determines whether to digitize ***)
(*** time or frequency domain data. ***)
(*** ***)
(****************************************************************************)
UNIT DigitizeWaveform;
INTERFACE
USES
{$IFDEF DOSCrt}
DOSCrt,
{$ELSE}
Crt,
{$ENDIF}
Extended_Reals,
TextOps,
Async,
Graph,
DrawGraf,
Global,
GraphText;
PROCEDURE Digitizer ( DataToDigitize : CHAR);
PROCEDURE Digitize_Wave;
(****************************************************************************)
IMPLEMENTATION
CONST
Reset_Command = 'RS'; { Reset digitizer to power-up }
Point_Command = 'P1'; { Set digitizer to point input }
parity = 'N'; { Set digitizer to no parity }
baud_rate = 9600; { Set digitizer to 9600 Baud }
data_bits = 8; { Set digitizer to 8 bits per word }
stop_bits = 2; { Set digitizer to two stop bits }
PauseLength = 250; { Pause after sending commands }
ShortPauseLength = 100; { Delay between digitizer bytes }
MinX = 100; { Left edge of digitizer work area }
MaxX = 2000; { Right edge of digitizer work area }
MinY = 200; { Bottom edge of digitizer work area }
MaxY = 1800; { Top edge of digitizer work area }
NormSize : byte = 1; { Normal size of default font }
VAR
ch1,ch2,ch3,ch4,ch5 : CHAR; { input from digitizer }
in2,in3,in4,in5 : INTEGER; { INTEGER (ch) }
INCOMING : BOOLEAN; { valid data coming from digitizer? }
EMPTY : BOOLEAN; { is input buffer empty? }
VALID_PORT : BOOLEAN; { is a device connected to COM? }
quit : CHAR; { done viewing picture? }
min_time : REAL; { minimum time }
max_time : REAL; { maximum time }
min_amplitude : REAL; { minimum amplitude }
max_amplitude : REAL; { maximum amplitude }
horiz_units : string; { horizontal axis units }
vert_units : string; { vertical axis units }
leftx : INTEGER; { Left edge of window boundary }
rightx : INTEGER; { Right edge of window boundary }
topy : INTEGER; { Top edge of window boundary }
bottomy : INTEGER; { Bottom edge of window boundary }
FreqDATA : BOOLEAN; { DataToDigitize = 'F'? }
{----------------------------------------------------------------------------}
{- -}
{- Rotate_Waveform transforms each point (x',y') in oblique -}
{- coordinates to point (x,y) in rectangular coordinates. This is -}
{- done to ensure true horizontal and vertical axes. The specific -}
{- steps performed are -}
{- 1. Calculate true origin; set equal to (x1,y1). -}
{- 2. Determine scaling factors and units. -}
{- 3. Transform oblique coordinates to rectangular coordinates. -}
{- 4. Eliminate coordinate axes information. -}
{- 5. Eliminate non-sequential data points. -}
{- -}
{----------------------------------------------------------------------------}
PROCEDURE Rotate_Waveform;
CONST
epsilon = 1;
VAR
x0,y0 : REAL; { coordinates of true origin }
mr : REAL; { slope of radius axis }
mx : REAL; { slope of digitized x axis }
my : REAL; { slope of digitized y axis }
r : REAL; { magnitude of radius vector }
rx : REAL; { length of digitized x axis }
ry : REAL; { length of digitized y axis }
theta : REAL; { phase of radius vector }
phi : REAL;
omega : REAL;
i : INTEGER; { counter variable }
j : INTEGER; { counter variable }
k : INTEGER; { counter variable }
dummy : string; { time plus multiplier, units }
total_amplitude : REAL; { amp/div * number of div }
xfactor : REAL; { x scaling factor }
yfactor : REAL; { y scaling factor }
delta_x : REAL; { diff between x coor, origin }
delta_y : REAL; { diff between y coor, origin }
BEGIN {Rotate_Waveform}
ClrScr;
{- Calculate origin -}
mx:=(TempYPtr^[2]-TempYPtr^[1])/(TempXPtr^[2]-TempXPtr^[1]);
IF (ABS (TempXPtr^[4]-TempXPtr^[3]) < epsilon)
THEN x0:=0.5*(TempXPtr^[3]+TempXPtr^[4])
ELSE BEGIN
my:=(TempYPtr^[4]-TempYPtr^[3])/(TempXPtr^[4]-TempXPtr^[3]);
x0:=(TempYPtr^[2]-TempYPtr^[3]+my*TempXPtr^[3]
-mx*TempXPtr^[2])/(my-mx);
END; {ELSE}
y0:=TempYPtr^[2]+mx*(x0-TempXPtr^[2]);
TempXPtr^[0]:=x0;
TempYPtr^[0]:=y0;
{- Determine scaling factors -}
delta_x:=TempXPtr^[2]-x0;
delta_y:=TempYPtr^[2]-y0;
rx:=sqrt(sqr(delta_x)+sqr(delta_y));
delta_x:=TempXPtr^[4]-TempXPtr^[3];
delta_y:=TempYPtr^[4]-TempYPtr^[3];
ry:=sqrt(sqr(delta_x)+sqr(delta_y));
IF FreqDATA
THEN BEGIN
Write ('Minimum frequency: '); ReadLn (dummy);
String_To_Value (dummy,min_time,horiz_units);
Write ('Maximum frequency: '); ReadLn (dummy);
String_To_Value (dummy,max_time,horiz_units);
xfactor:=(max_time-min_time)/rx;
Write ('Minimum amplitude: '); ReadLn (dummy);
String_To_Value (dummy,min_amplitude,vert_units);
Write ('Maximum amplitude: '); ReadLn (dummy);
String_To_Value (dummy,max_amplitude,vert_units);
yfactor:=(max_amplitude-min_amplitude)/ry;
END {THEN}
ELSE BEGIN
min_time:=0;
Write ('Maximum time: '); ReadLn (dummy);
String_To_Value (dummy,max_time,horiz_units);
xfactor:=max_time/rx;
min_amplitude:=0;
Write ('Total amplitude: '); ReadLn (dummy);
String_To_Value (dummy,max_amplitude,vert_units);
yfactor:=max_amplitude/ry;
END; {ELSE}
{- Switch from input coordinates to rectangular coordinates -}
delta_x:=TempXPtr^[2]-x0;
delta_y:=TempYPtr^[2]-y0;
theta:=arctan (delta_y/delta_x);
delta_y:=TempYPtr^[3]-y0;
IF delta_y < epsilon
THEN BEGIN
delta_y:=TempYPtr^[4]-y0;
delta_x:=TempXPtr^[4]-x0;
IF delta_x < epsilon
THEN phi:=-0.5*PI
ELSE phi:=arctan (delta_y/delta_x);
END {THEN}
ELSE BEGIN
delta_x:=TempXPtr^[3]-x0;
IF delta_x < epsilon
THEN phi:=0.5*PI
ELSE phi:=arctan (delta_y/delta_x);
END; {ELSE}
omega:=phi-theta;
FOR i:=5 TO NumPoints + 4 DO BEGIN
delta_x:=(TempXPtr^[i]-x0)*cos(theta)+
(TempYPtr^[i]-y0)*cos(omega+theta);
delta_y:=(TempXPtr^[i]-x0)*sin(theta)+
(TempYPtr^[i]-y0)*sin(omega+theta);
TempXPtr^[i]:=(delta_x*xfactor + min_time);
TempYPtr^[i]:=(delta_y*yfactor + min_amplitude);
END; {FOR}
{- Eliminate coordinate axes, non-sequential information. -}
IF FreqDATA
THEN BEGIN
TempXPtr^[0]:=TempXPtr^[5];
TempYPtr^[0]:=TempYPtr^[5];
i:=1;
END {THEN}
ELSE BEGIN
TempXPtr^[0]:=0;
TempYPtr^[0]:=0;
TempXPtr^[1]:=TempXPtr^[5];
TempYPtr^[1]:=TempYPtr^[5];
i:=2;
INC (NumPoints,1);
END; {ELSE}
j:=6;
k:=0;
REPEAT
WHILE TempXPtr^[j] <= TempXPtr^[i-1] DO BEGIN
INC (j,1);
INC (k,1);
END; {WHILE}
TempXPtr^[i]:=TempXPtr^[j];
TempYPtr^[i]:=TempYPtr^[j];
INC (i,1);
INC (j,1);
UNTIL (i+k=NumPoints);
DEC (NumPoints,k);
END; {Rotate_Waveforms}
{----------------------------------------------------------------------------}
{- -}
{- Draw_waveform sets up a window for drawing the digitized waveform, -}
{- then draws it. -}
{- -}
{----------------------------------------------------------------------------}
PROCEDURE Draw_Waveform;
VAR
error : BYTE;
i : INTEGER;
xdelay : REAL;
ydelay : REAL;
BEGIN {Draw_Waveform}
ClearViewPort;
leftx:=SUCC(GetMaxX) div 8;
rightx:=7*leftx;
bottomy:=3*(SUCC(GetMaxY) div 8);
topy:=7*(GetMaxY div 8);
DrawGraph (TempXPtr,TempYPtr,NumPoints,Linear,leftx,topy,
rightx,bottomy,xdelay,ydelay,'','',error);
END; {Draw_Waveform}
{----------------------------------------------------------------------------}
{- -}
{- Initialize_Digitizer opens the COM port (port SerialPort, as -}
{- selected from the Advanced Options Menu; the default is COM1:) -}
{- then sends commands to the digitizer to reset it to power up -}
{- conditions, then set it to the point mode. The input buffer is -}
{- then emptied. -}
{- -}
{----------------------------------------------------------------------------}
PROCEDURE Initialize_Digitizer;
BEGIN {Initialize_Digitizer}
VALID_PORT:=TRUE;
Async_Init;
IF NOT Async_Open (SerialPort,baud_rate,parity,data_bits,stop_bits)
THEN BEGIN
Write ('Invalid port!');
VALID_PORT:=FALSE;
END {THEN}
ELSE BEGIN
Async_Send_String (Reset_Command);
Async_Send_String (Point_Command);
Delay (PauseLength);
REPEAT UNTIL NOT Async_Buffer_Check (ch1);
END; {ELSE}
END; {Initialize_Digitizer}
{----------------------------------------------------------------------------}
{- -}
{- Read_Digitizer tests if there is a character in the input buffer. -}
{- If yes, then the next four characters are read. (The Digi-Pad -}
{- digitizer uses five bytes per input point.) The input buffer is -}
{- then emptied. Note that a delay MUST occur between each buffer -}
{- check, or the computer will not recognize the information. -}
{- -}
{----------------------------------------------------------------------------}
PROCEDURE Read_Digitizer;
BEGIN {Read_Digitizer}
WRITEtext('here at 1',1,1);
IF ASYNC_BUFFER_CHECK (CH1) THEN WRITETEXT('ASYNC BUFFER CHECK = TRUE',1,15)
ELSE WRITETEXT('ASYNC BUFFER CHECK = FALSE',1,15);
IF Async_Buffer_Check (ch1) THEN BEGIN
writetext('here at 14',1,14);
Delay (PauseLength);
WRITEtext('here at 2',1,2);
IF Async_Buffer_Check (ch2) THEN in2:=INTEGER(ch2) AND $3F;
Delay (PauseLength);
IF Async_Buffer_Check (ch3) THEN in3:=INTEGER(ch3) AND $3F;
Delay (PauseLength);
IF Async_Buffer_Check (ch4) THEN in4:=INTEGER(ch4) AND $3F;
Delay (PauseLength);
IF Async_Buffer_Check (ch5) THEN in5:=INTEGER(ch5) AND $3F;
DELAY (PAUSELENGTH);
WRITEtext('here at 3',1,3);
INC (i,1);
WRITEtext('here at 4',1,4);
TempXPtr^[i]:=(in3 shl 6) OR in2;
TempYPtr^[i]:=(in5 shl 6) OR in4;
PutPixel (round(TempXPtr^[i]),round(TempYPtr^[i]),white);
WRITEtext('here at 5',1,5);
REPEAT UNTIL NOT Async_Buffer_Check (ch1);
WRITEtext('here at 6',1,6);
END; {IF}
delay(2000);
END; {Read_Digitizer}
{----------------------------------------------------------------------------}
{- -}
{- Read_Keyboard detects either an ENTER or ESCAPE key being pressed, -}
{- otherwise, keyboard input is ignored. -}
{- -}
{----------------------------------------------------------------------------}
PROCEDURE Read_Keyboard (VAR DONE : BOOLEAN);
BEGIN {Read_Keyboard}
DONE:=FALSE;
writetext('here at 7',1,7);
IF keypressed THEN BEGIN
writetext('here at 8',1,8);
ch1:=ReadKey;
IF ch1 = ENTER
THEN DONE:=TRUE
ELSE IF ch1 = ESC
THEN BEGIN
writetext('here at 9',1,9);
PutPixel (round(TempXPtr^[i]),round(TempYPtr^[i]),black);
DEC (i,1);
SetColor (DrawColor);
END; {ELSE-IF}
END; {IF}
END; {Read_Keyboard}
{----------------------------------------------------------------------------}
{- -}
{- Set_Up_Axes uses the first two points input as the left and right -}
{- enpoints of the x axis, and the next two points as the top and -}
{- bottom of the y axis. -}
{- -}
{----------------------------------------------------------------------------}
PROCEDURE Set_Up_Axes;
VAR
correct : CHAR;
dummy : BOOLEAN;
BEGIN {Set_Up_Axes}
delay(4000);
REPEAT
writetext ('here at 10',1,10);
WriteText ('Enter x axis coordinates: ',22,21);
writetext ('here at 11',1,11);
i:=0;
REPEAT
Read_Digitizer;
Read_Keyboard (dummy);
writetext('here at 12',1,12);
DELAY(3000);
CLEARVIEWPORT;
UNTIL i=2;
writetext('here at 13',1,13);
Line (round(TempXPtr^[1]),round(TempYPtr^[1]),
round(TempXPtr^[2]),round(TempYPtr^[2]));
WriteText ('Enter y axis coordinates: ',22,21);
REPEAT
Read_Digitizer;
Read_Keyboard (dummy);
UNTIL i=4;
Line (round(TempXPtr^[3]),round(TempYPtr^[3]),
round(TempXPtr^[4]),round(TempYPtr^[4]));
WriteText ('Are axes correct? ',22,21);
Buzzer;
correct:=UpCase(ReadKey);
IF (correct = 'Y') THEN Exit; { Quit when axes are correct. }
ClearViewport;
SetViewPort (MinX,MinY,MaxX,MaxY,ClipOn);
UNTIL FALSE;
END; {Set_Up_Axes}
{----------------------------------------------------------------------------}
{- -}
{- Add_Comments is used to store descriptive information with the data -}
{- as comments. These descriptors include -}
{- 1. Test Point. -}
{- 2. Test Type. -}
{- 3. Attenuation factor. -}
{- 4. Probe Number. -}
{- 5. x-axis units. -}
{- 6. y-axis units. -}
{- 7. Any additional comments. -}
{- -}
{----------------------------------------------------------------------------}
PROCEDURE Add_Comments;
VAR
i : INTEGER;
st : string[80];
BEGIN
ClrScr;
Write ('Test Point: '); ReadLn (st); info[1]:='Test Point: '+st;
Write ('Test Type: '); ReadLn (st); info[2]:='Test Type: '+st;
Write ('Attenuation: '); ReadLn (st); info[3]:='Attenuation: '+st;
Write ('Probe Number: '); ReadLn (st); info[4]:='Probe Number: '+st;
Write ('Comments: '); ReadLn (st); info[7]:='Comments: '+st;
info[5]:='X-Axis units: '+horiz_units;
info[6]:='Y-Axis units: '+vert_units;
FOR i:=8 TO MaxInfo DO info[i]:=blank;
END; {Add_Comments}
{----------------------------------------------------------------------------}
PROCEDURE Digitizer ( DataToDigitize : CHAR);
VAR
STOP : BOOLEAN; { done yet? }
i : INTEGER; { counter variable }
BEGIN {Digitizer}
FreqDATA:=(DataToDigitize = 'F');
SetGraphMode (GraphMode);
SetViewPort (MinX,MinY,MaxX,MaxY,ClipOn);
SetColor (DrawColor);
STOP:=FALSE;
Initialize_Digitizer;
IF VALID_PORT THEN BEGIN
REPEAT UNTIL NOT Async_Buffer_Check (ch1);
WHILE keypressed DO ch1:=ReadKey;
Set_Up_Axes;
WriteText ('Enter x,y coordinate pairs. ',22,21);
WriteText ('Press ESC to erase, or ENTER to finish.',22,23);
REPEAT
Read_Digitizer;
Read_Keyboard (STOP);
UNTIL STOP;
ClearLine (22,21,40);
ClearLine (22,23,40);
NumPoints:=i-4;
IF (NumPoints >= 5)
THEN BEGIN
RestoreCrtMode;
Rotate_Waveform;
Add_Comments;
SetGraphMode (GraphMode);
Draw_Waveform;
Async_Send_String (Reset_Command);
Async_Close;
WriteText ('Strike any key to return to Main Menu.',22,20);
ORIG:=TRUE;
TRANS:=FALSE;
ACCEPT:=FALSE;
time^:=TempXPtr^;
ampl^:=TempYPtr^;
END {THEN}
ELSE BEGIN
WriteText ('Too few points input. ',22,21);
WriteText ('Strike any key to continue ...',22,23);
ORIG:=FALSE;
TRANS:=FALSE;
ACCEPT:=FALSE;
END; {ELSE}
Quit:=ReadKey;
END; {IF VALID_PORT}
RestoreCRTMode;
TextColor (ForeColor);
TextBackground (BackColor);
ClrScr;
END; {Digitizer}
{----------------------------------------------------------------------------}
PROCEDURE Digitize_Wave;
VAR
ch : CHAR;
BEGIN {Digitize_Wave}
IF (SerialPort <> 0) THEN BEGIN
GotoXY (StartColumn,23);
Write ('Digitize time or frequency data (T/F)? ');
REPEAT
ch:=UpCase(ReadKey);
UNTIL (ch IN ['T','F',ENTER]);
IF (ch = ENTER)
THEN Digitizer ('T')
ELSE Digitizer (ch);
END; {IF}
END; {Digitize_Wave}
(****************************************************************************)
BEGIN {Initialization}
END. {Initialization}