PROGRAM Autocon30; { Last Update 4/21/94 } {full 8087 emulation:} {$N+,E+} {********************** CHANGES MADE ***************************} {* 4/1/94 ver. 1.00 to be tested by Russ Cook *} {* 4/4/94 cosmetic changes, add turn off conditioning, *} {* excursion timeout instead of value reached, *} {* wait before start to overlook inital excursion. *} {* stepsize 8 on excursion. *} {* 4/21/94 put conditioning off before keypress to exit. *} {* exit program when 'no' to try again question. *} {***************************************************************} USES Crt,ListPlus,RCM; TYPE deltaray = ARRAY[0..3] OF Real; CONST { *** increments in HT for the various ranges *** } DeltakV : deltaray = (0.275,0.275,0.137,0.082); { *** Constants used by RCM software *** } StepSize = 8; Focus = 7; Ready = 7; { *** HT points that determine range limits *** } HTRNG : deltaray = (300,315,325,330); { *** % of old emission that triggers decr. HT by 30kV *** } EMISMULT : Real = 2.0; { 200% } { *** % increment in old emission value that you must drop back to *** } EMISINC : Real = 0.2; { 120% of old } { *** increment in old vac that will cause a hold in HT incr *** } PRESSHOLDINC : Integer = 2; { if press >= 2 + old value, hold up } { *** increment in old vac reading that you must drop back to *** } PRESSBKINC : Integer = 2; { drop back to <= 2 + old value } VAR igpnew,igpold,stepnbr,j : Integer; HT,emisold,emisnew,delta : Real; ch : Char; panic : Boolean; LABEL GetOut; { *** Used to exit program gracefully *** } {***************************************************************} PROCEDURE NoDriver; { writes a message on the screen if there is no driver } BEGIN Fill(1,1,80,25,Cyan+16*Blue,178); Fbox(5,3,75,23,white,blue,2); WriteCenter(5,Yellow,Cyan,' The device driver is not present. '); WriteCenter(7,black,Cyan,' In the root directory of the disk you boot '); WriteCenter(8,black,Cyan,' from is the file CONFIG.SYS. This normal '); WriteCenter(9,black,Cyan,' ASCII file must contain the following phrase : '); WriteCenter(11,White,Cyan,' Device = RCM.SYS '); WriteCenter(13,black,Cyan,'If you do not wish to place the file RCM.SYS '); WriteCenter(14,black,Cyan,' in the root directory, but for example in the '); WriteCenter(15,black,Cyan,' directory C:\RemoteCM, then this phrase must be : '); WriteCenter(17,White,Cyan,' Device = C:\RemoteCM\RCM.SYS '); WriteCenter(19,black,Cyan,' You can change the file config.sys with any '); WriteCenter(20,black,Cyan,' normal ASCII text editor. '); WriteCenter(21,Yellow,Cyan,' Please correct this, then boot again. '); END; { of procedure NoDriver } {***************************************************************} { This procedure will Display a comment on all the possible RCM results } PROCEDURE DisplayResult (Result: RCMResultType); VAR errmsg : string[32]; BEGIN IF Result <> Ok THEN BEGIN IF Result = DelayedExpected THEN BEGIN delay(2000); Exit; END; CASE Result of { The errors returned by the device driver } InvalidFunctionId : errmsg := 'Invalid Function Id'; EquipmentNotAvailable : errmsg := 'Equipment Not Available'; InvalidData : errmsg := 'Invalid Data'; InvalidMicroscopeStatus : errmsg := 'Invalid Microscope Status'; InvalidPCStatus : errmsg := 'Invalid PC Status'; DelayedError : errmsg := 'Delayed Error'; DelayedExpected : errmsg := 'Delay Expected'; IncorrectDeviceDriver : errmsg := 'Incorrect Device Driver'; NotAvailable : errmsg := 'Not Available'; PressOnly : errmsg := 'Press Only'; CannotPressButton : errmsg := 'Cannot Press Button'; DeviceDriverNotOpened : errmsg := 'Device Driver Not Opened'; DirectOperationImpossible : errmsg := 'Direct Operation Impossible'; NotCalibrated : errmsg := 'Relocation System Not Calibrated'; InvalidPos : errmsg := 'Invalid Location'; InvalidReg : errmsg := 'Invalid Register'; END; { Case } Uhuh; TempMsgBx(0,0,Yellow,Red,White,Red,32,3,'Error ! '+errmsg); END; { If Result } END; { of display RCM result } {***************************************************************} { Test to see if equipment is available } PROCEDURE Test_available; Label TestCM; BEGIN TestCM: Fill(1,1,80,25,44,176); MsgBx(0,4,White,Cyan,LightCyan,Blue,1,' Testing if equipment available .... '); IF NOT EquipmentAvailable then BEGIN Uhuh; Msg(0,0,White,Red,177, ' Microscope Not Available!~ Check Remote Control Function.'); IF ReadYN(0,21,white,blue,' Do you wish to try again (Y/N) ? ') THEN Goto TestCM; closeremoteCM; CursOn; { turn the cursor back on } TextAttr := 7; { gray on black } ClrScr; Halt; END; END; { of test available } {***************************************************************} { Read and display Vacuum } PROCEDURE vacuum; VAR p : PressureType; BEGIN PressureReadout(p); DisplayResult (RCMResult); IF RCMResult = OK THEN BEGIN igpnew := Trunc(p[4]); END; END; {***************************************************************} { Set the starting HT } FUNCTION SetkV : Integer; CONST kV1 = ' 50 † 100 † 150 † 200 † 250 † 300 † '; kV2 = ' §§§§§ §§§§§ §§§§§ §§§§§ §§§§§ §§§§§ '; XCORN = 17; YCORN = 10; volt : ARRAY[0..5] OF Integer = (50,100,150,200,250,300); VAR select : Word; ch : Char; BEGIN Fill(1,1,80,25,Blue + 16 * Cyan,178); Button(XCORN-4,YCORN-2,XCORN+48,YCORN+2,white,DarkGray,Lightgray); WriteAt(XCORN,YCORN,DarkGray,LightGray,kV1); WriteAt(XCORN,Succ(YCORN),DarkGray,LightGray,kV2); WriteCenter(YCORN+4,White,Blue, ' Select kV using arrow keys and Enter. '); FOR select := 0 TO 5 DO Attrib(XCORN+8*select,YCORN,5,Black+16*Cyan); select := 0; ESCAPED := FALSE; SetkV := 50; REPEAT Attrib(XCORN+8*select,YCORN,5,White+16*Blue); ch := GetKey; Attrib(XCORN+8*select,YCORN,5,Black+16*Cyan); CASE ch OF LARR,MLEFT : IF select > 0 THEN Dec(select) ELSE select := 5; RARR,MRIGHT : IF select < 5 THEN Inc(select) ELSE select := 0; ESC,MRIGHTB : BEGIN ESCAPED := TRUE; Exit; END; END; { Case } UNTIL ch IN [ENTER,MLEFTB]; SetkV := volt[select]; END; { SetkV } {***************************************************************} { Draw background on which HT increments are choosen. } PROCEDURE DeltaBkgd; CONST K1 = ' 0.275 † 0.275 † 0.137 † 0.082 † '; K2 = ' §§§§§§§ §§§§§§§ §§§§§§§ §§§§§§§ '; K3 = ' 0 † 300 † 315 † 325 † 330 † END † '; K4 = ' §§§§§ §§§§§ §§§§§ §§§§§ §§§§§ §§§§§ '; XCORN = 12; YCORN =10; VAR j : Integer; BEGIN Button(XCORN-4,YCORN-2,XCORN+60,YCORN+8,LightCyan,Cyan,Lightgray); DrawShadow(XCORN-4,YCORN-2,XCORN+60,YCORN+8); WriteAt(XCORN,YCORN+1,DarkGray,LightGray,K1); WriteAt(XCORN,YCORN+2,DarkGray,LightGray,K2); WriteAt(XCORN,YCORN+3,DarkGray,LightGray,K3); WriteAt(XCORN,YCORN+4,DarkGray,LightGray,K4); WriteCenter(YCORN-1,White,Blue, ' Select increment using arrow keys '); FOR j := 0 TO 3 DO WriteAt(XCORN+10*j+7,YCORN+2,Red,LightGray,#25); FOR j := 0 TO 3 DO Attrib(XCORN+10*j+3,YCORN+1,7,Black+16*Cyan); FOR j := 0 TO 5 DO Attrib(XCORN+10*j,YCORN+3,5,White+16*Cyan); Attrib(XCORN+3,YCORN+1,7,White+16*Blue); { Range Select Hilite } Attrib(XCORN,YCORN+3,5,White+16*Red); { 0 HT Hilite } END; { DeltaBkgd } {***************************************************************} { Set the individual HT increments } PROCEDURE SetDelta(ch : Char); CONST select : Word = 0; { selection } XCORN = 12; YCORN = 10; BEGIN Attrib(XCORN+10*select+3,YCORN+1,7,Black+16*Cyan); CASE ch OF LARR,MLEFT : IF select > 0 THEN Dec(select) ELSE select := 3; RARR,MRIGHT : IF select < 3 THEN Inc(select) ELSE select := 0; UARR,MUP : BEGIN IF DeltakV[select] < 0.1 THEN DeltakV[select] := 0.137 ELSE IF DeltakV[select] < 0.2 THEN DeltakV[select] := 0.275 ELSE UhUh; WriteAT(XCORN+10*select+4,YCORN+1,7,Black+16*Cyan, RealToStr(DeltakV[select],5,3)); END; DARR,MDOWN : BEGIN IF DeltakV[select] > 0.2 THEN DeltakV[select] := 0.137 ELSE IF DeltakV[select] > 0.1 THEN DeltakV[select] := 0.082 ELSE UhUh; WriteAT(XCORN+10*select+4,YCORN+1,7,Black+16*Cyan, RealToStr(DeltakV[select],5,3)); END; END; { Case } Attrib(XCORN+10*select+3,YCORN+1,7,White+16*Blue); END; { SetDelta } {***************************************************************} Procedure TitleBx; BEGIN Fill(20,2,60,5,16*Cyan,32); WriteCenter(3,White,Cyan,'AutoConditioning Program for CM30'); WriteCenter(4,Yellow,Cyan,'Press Esc key to stop program.'); DrawShadow(20,2,60,5); END; { TitleBx } {***************************************************************} Procedure Excursion; BEGIN { *** Signal that an excursion has taken place *** } Fill(20,2,60,5,16*Red,32); WriteCenter(3,White,Red,'An emission excursion has occurred!'); WriteCenter(4,Yellow,Red,'Reducing HT 27.5 kV and waiting....'); DrawShadow(20,2,60,5); { *** Decrease the HT by 30kV *** } HT := HT - 27.5; { *** turn the stepsize knob completely ccw *** } Turnknob(StepSize,-9); Displayresult(RCMresult); { *** turn the stepsize knob to position 8 *** } Turnknob(StepSize,8); Displayresult(RCMresult); { *** turn the focus knob ccw 1 unit of stepsize *** } { *** should be 27.5 kV down from previous *** } Turnknob(focus,-1); Displayresult(RCMresult); { *** Wait for 1 minute *** } SetWait(60); REPEAT emisnew := EmissionCurrent; TextBackground (Blue ); TextColor(White); GotoXY(59,17); Write(emisnew:8,' '); { *** check for keypress to exit program or change incr *** } IF KeyPressed THEN BEGIN ch := GetKey; IF ch IN [LARR,RARR,UARR,DARR,MLEFT,MRIGHT,MUP,MDOWN] THEN SetDelta(ch); { change increment if required } IF ch = #27 THEN { quit conditioning if desired } BEGIN panic := TRUE; Exit; END; END; { If } UNTIL WaitUP; emisold := emisnew; { reset the old } TitleBx; { restore the title } END; { Excursion } {***************************************************************} Procedure RiseBx; BEGIN { *** Signal that a rise has taken place *** } Fill(20,2,60,5,16*Blue,32); WriteCenter(3,White,Blue,'The Pressure rose suddenly!'); WriteCenter(4,Yellow,Blue,'Waiting for recovery ....'); DrawShadow(20,2,60,5); END; { RiseBx } {***************************************************************} Procedure PressRise; BEGIN { *** Signal that a rise has taken place *** } RiseBx; REPEAT { *** read the vacuum and display it *** } vacuum; WriteAT(12,17,White,Blue, ' Last IGP Reading: '+IntToStr(igpnew,2)+' '); { *** read and display emission *** } emisnew := EmissionCurrent; TextBackground (Blue ); TextColor(White); GotoXY(59,17); Write(emisnew:8,' '); { *** check for large increase in emission current *** } IF emisnew > (EMISMULT*emisold) THEN BEGIN Excursion; RiseBx; END; { *** check for keypress to exit program or change incr *** } IF KeyPressed THEN BEGIN ch := GetKey; IF ch IN [LARR,RARR,UARR,DARR,MLEFT,MRIGHT,MUP,MDOWN] THEN SetDelta(ch); { change increment if required } IF ch = #27 THEN { quit conditioning if desired } BEGIN panic := TRUE; Exit; END; END; { If } UNTIL igpnew <= (igpold + PRESSBKINC); igpold := igpnew; { reset base value } SetWait(5); { Start a new 5 second delay } TitleBx; { restore title } END; { PressRise } {***************************************************************} PROCEDURE WatchNWait(ShowWait:Boolean); BEGIN REPEAT { *** Show wait time if ShowWait is true *** } IF ShowWait THEN WriteCenter(4,Yellow,Green, IntToStr(((NewWait-Waittime) DIV 1080)+1,2)+' Minutes Remaining..'); { *** check for keypress to change increments or exit program *** } IF KeyPressed THEN BEGIN ch := GetKey; IF ch IN [LARR,RARR,UARR,DARR,MLEFT,MRIGHT,MUP,MDOWN] THEN SetDelta(ch); { change increment if required } IF ch = #27 THEN panic := TRUE; { quit conditioning if desired } END; { If } { *** read and display emission *** } emisnew := EmissionCurrent; TextBackground (Blue ); TextColor(White); GotoXY(59,17); Write(emisnew:8,' '); { *** if a drop in emission current, lower the reference current *** } IF emisnew < emisold THEN emisold := emisnew; { *** check for large increase in emission current *** } IF emisnew > (EMISMULT*emisold) THEN Excursion; IF panic THEN Exit; { ESC pressed in Excursion } { *** read the vacuum and display it *** } vacuum; WriteAT(12,17,White,Blue, ' Last IGP Reading: '+IntToStr(igpnew,2)+' '); { *** If it gets better then save new reference value *** } IF igpnew < igpold THEN igpold := igpnew; { *** Check for pressure rise and wait till it subsides *** } IF igpnew > 5 THEN { only if pressure > 5 } IF igpnew > (igpold + PRESSHOLDINC) THEN PressRise; IF panic THEN Exit; { Esc pressed in PressRise } UNTIL WaitUp; { *** repeat until the time is up *** } END; { WatchNWait } {***************************************************************} BEGIN { Main } panic := FALSE; { *** Flag to get out in emergency *** } CursOFF; { turn off cursor } moused := FALSE; { disable the mouse } ClrScr; { *** Check for remote driver *** } GotoXY(1,6); Write('Testing presence of RC driver .... '); IF NOT OpenRemoteCM THEN BEGIN NoDriver; Halt(0); END; { *** See if we have a controllable microscope *** } Test_Available; { Check if microscope is Remote Controllable } { *** Get inital values of vac and emmis current *** } vacuum; { first read of igp } igpold := igpnew; emisnew := EmissionCurrent; emisold := emisnew; { *** Ask what starting high voltage is *** } HT := SetkV; { *** turn the proper knobs to start conditioning *** } turnknob(StepSize,-9); displayresult(RCMresult); { StepSize CCW } pushbutton(Ready, Press); displayresult(RCMresult); { Push 'Ready' } softkey(9,1); displayresult(RCMresult); { Select 'Parameters' } softkey(3,1); displayresult(RCMresult); { Select 'Conditioning' } { *** delay to ignore initial emission excursion *** } Msg(0,13,White,Blue,32,' 15 sec delay before starting ... '); SetWait(15); WHILE NOT WaitUp DO; { *** display the main conditioning screen *** } Fill(1,1,80,25,white+16*blue,176); TitleBx; Msg(0,21,Yellow,Red,32, 'Do not touch the MICROCONTROLLER during execution of this program'); DeltaBkgd; { draw the background for changing increments } { *** Display emission current and vacuum *** } WriteAT(42,17,White,Blue,' Emission Current: '); TextBackground(Blue); GotoXY(60,17); Write(emisnew:8,' '); WriteAT(12,17,White,Blue,' Last IGP Reading: '+IntToStr(igpnew,2)+' '); { *** Now enter the conditioning loop *** } ch := #0; { just to make sure } WHILE HT < 330 DO { *** ramp up to 330 kV *** } BEGIN { *** determine range of HT and set appropriate delta *** } IF HT < HTRNG[0] THEN delta := deltakV[0] ELSE IF HT < HTRNG[1] THEN delta := deltakV[1] ELSE IF HT < HTRNG[2] THEN delta := deltakV[2] ELSE delta := deltakV[3]; { *** set new HT ... first determine size of focus control step *** } IF delta > 0.15 THEN stepnbr := 2 ELSE IF delta > 0.1 THEN stepnbr := 1 ELSE stepnbr := 0; { *** Update the HT value and turn knobs to change it *** } HT := HT + delta; { *** turn the stepsize knob completely ccw *** } Turnknob(StepSize,-9); Displayresult(RCMresult); { *** now go up zero, one or two clicks depending on stepsize *** } Turnknob(StepSize,stepnbr); Displayresult(RCMresult); { *** turn the focus knob one unit of stepsize *** } Turnknob(focus,1); Displayresult(RCMresult); { *** Display new setting of HT on screen. *** } WriteCenter(15,White,Blue, ' HT Set to: '+RealToStr(HT,6,3)+' KeV '); { *** Highlite HT buttons to this range *** } FOR j := 0 TO 3 DO IF HT > HTRNG[j] THEN Attrib(22+10*j,13,5,White+16*Red); { *** Initialize a waiting loop *** } SetWait(5); { 5 Seconds } { *** Now go into wait loop for this increment in HT *** } WatchNWait(False); IF panic THEN Goto GetOut; END; { While } { *** repeat until you reach 330 kV *** } { *** Now wait at 330 kV for 10 minutes *** } SetWait(600); { 600 seconds wait } { *** Display message *** } Fill(20,2,60,5,16*Green,32); WriteCenter(3,White,Green,'Now waiting at 330 kV for 10 minutes.'); DrawShadow(20,2,60,5); { *** Highlite END HT button *** } Attrib(62,13,5,White+16*Red); { *** Display time remaining and wait for time up *** } WatchNWait(TRUE); { *** Signal completion of the conditioning *** } Fill(20,2,60,5,16*Cyan,32); WriteCenter(3,White,Cyan,'Conditioning Complete.'); WriteCenter(4,Yellow,Cyan,'Press any key to exit program.'); DrawShadow(20,2,60,5); { turn off conditioning mode } softkey(3,1); displayresult(RCMresult); { Select 'Conditioning' } { *** Wait for keypress *** } ch := GetKey; { *** Exit the program gracefully *** } GetOut: CloseRemoteCM; { close the device handling the microscope } CursOn; { turn the cursor back on } TextAttr := 7; { gray on black } ClrScr; END. { Main }