'Automated Test Software for SCM5Bxx-xx Voltage,
'Current, TC and RTD input models.
'** MAIN PROGRAM SET 2 OF 2 **

'AUTHOR:        John Lehman

'******** Declare some useful constants *******
CONST MAXSTATUSINDEX = 21   'Maximum index of the Status array

DECLARE SUB CALDAC (TE$)
DECLARE SUB CALSEQ (CAL%)                       'Determine & perform calibration sequence
DECLARE SUB COMPTEST (STATUS$(), CAL%, GENAMPL!, TSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), TOTLRESPEC!)    'Complete set of tests
DECLARE SUB CONTINUE ()
DECLARE SUB ENABLE (ONOFF%)                     'Module output switch control
DECLARE SUB FOOTER (STATUS$())                  'Sends footer to printer if all tests passed
DECLARE SUB FUNCTEST (CAL%)                     'Routines for functional test
DECLARE SUB GENSET (GENAMPL!)                   'Displays message to set signal generator
DECLARE SUB GETADD (FILENAME$)                  'Gets parallel port/Mux/Testhead address
DECLARE SUB GETSN (SN$)                         'Gets serial number
DECLARE SUB GETSPECS ()                         'Gets module type and specifications
DECLARE SUB HEADERA (SN$)                       'Prints test sheet header
DECLARE SUB HEADERB (TESTTITLE$)                'Prints test screen header
DECLARE SUB INIT488 (DVMADDR%)
DECLARE SUB INDIVID (SEL%, CAL%)                'Performs the tests individually
DECLARE SUB LOADMUX (CH%, CHON%)
DECLARE SUB LOGIT (STATUS$(), SN$, TSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), TOTLRESPEC!)               'Logs test results to disk
DECLARE SUB MODULEOUTLINE ()
DECLARE SUB NOTES ()                            'Notes on ATE operation
DECLARE SUB OHMSET (OHM!)
DECLARE SUB ONESHOTTEST ()                      'Tests one-shot pulse width
DECLARE SUB PASSTHRUTEST (STATUS$(), TSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$())
DECLARE SUB PAUSE (TIME!)
DECLARE SUB POWERON (VOLTAGE!)                  'Sets module supply voltage
DECLARE SUB REPORT (STATUS$(), TSPEC$())        'Prints test data on screen
DECLARE SUB RESETTH ()                          'Reset test head to known condition
DECLARE SUB REMEXCPIN (PINSTAT%)
'DECLARE SUB SETDAC (VOLTAGE!, CH%, VSENATTEN!)
DECLARE SUB SETDAC (VOLTAGE!, CH%, VRANGE!, VSENATTEN!)
DECLARE SUB SETDACFAST (VOLTAGE!)
DECLARE SUB SETTEST (TEST%)
DECLARE SUB SETTH (DOUT%, CB%)
DECLARE SUB SETTHFAST (DOUT%, CB%)
DECLARE SUB SETLOAD (LOAD!)                     'Set excitation load
DECLARE SUB SORTDB (ENDFLAG%)
DECLARE SUB TSPECS (TSPEC$(), TOTLRESPEC!)      'Creates a string array of test specifications
DECLARE SUB WRITEDVM (FUNC$, VALUE!)
DECLARE SUB WRITEPS (ADDR%, CMD$)
DECLARE SUB FAILSTATUS (TESTVALUE$, YLOC%, XLOC%, TEXTVALUE$, SPACES%)
DECLARE SUB LOGMODFILES (STATUS$(), SN$, TSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), TSPEC$(), TOTLRESPEC!, TX%)
DECLARE SUB INTERLUDE () ' WAIT FOR USER
DECLARE SUB WORKORDERLINE (FAILSTATE%, SN$)
DECLARE SUB WORKORDERPRINT (SN$)
DECLARE SUB WORKORDERHEADER (SN$)
DECLARE SUB GETDSFNAME (SN$, DSSNAME$, DSFNAME$)    'Gets datasheet search and file names from serial number
DECLARE SUB DATASHEETWRITE (SN$, STATUS$(), TSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), TSPEC$(), TX%)
DECLARE SUB DATASHEETPRINT (SN$, STATUS$())
DECLARE SUB HARDCOPY ()
DECLARE SUB SNPARSE (SN$, WO$, DS$)

DECLARE FUNCTION GETWOSFNAME$ (SN$)         'Returns work order status file name from serial number

DECLARE FUNCTION BESTFIT! (SLOPE!, OFFSETS!, TSIM!(), NUMPTS%, ERRO!())
												'Library fn. Calculates bestfit line and max error
DECLARE FUNCTION CJCGAIN$ ()                    'Measure module CJC gain
DECLARE FUNCTION EXCCAL$ (CAL%)                 'Calibrate isolated excitation voltage
DECLARE FUNCTION EXCILIM$ ()                    'Test excitation current limit
DECLARE FUNCTION EXCREG$ ()                     'Tests excitation load regulation
DECLARE FUNCTION FAILS% (STATUS$())             'Tests for failed tests
DECLARE FUNCTION FREQRESP$ (GENAMPL!)           'Performs Frequency response Test
DECLARE FUNCTION GAINCAL$ (CAL%, CONTRES!, PFSMEAS!, INTERACT!, OSERR2!, DIRG%)  'Performs Gain Calibration
DECLARE FUNCTION GENATTENR! ()                  'Calculate fn gen attenuator
DECLARE FUNCTION GETTHID% ()                    'Get test head id #
DECLARE FUNCTION GETPSID% ()
DECLARE FUNCTION IEXC2$ (IEXCSENSE!)            'Measure excitation I source #2
DECLARE FUNCTION IEXC1$ (IEXCSENSE!)            'Measure excitation I source #1
DECLARE FUNCTION IMATCH$ (I1$, I2$)             'Check current source matching
DECLARE FUNCTION INPUTR$ ()                     'Performs Input Resistance Test
DECLARE FUNCTION KEYBDIN$ ()                    'Get keyboard input
DECLARE FUNCTION LEADREFF$ (TOTLRESPEC!)        'Measure lead resistance effects
DECLARE FUNCTION LINTEST$ (ACC$, CONTRES!, TSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$())      'Performs Accuracy and Linearity Tests
DECLARE FUNCTION MEASRES! (OHM!, RESNUM%, TE$)  'Measure loop current sense resistor
DECLARE FUNCTION MENU1% ()                      'Gets the Test Group selection
DECLARE FUNCTION MENU2% ()                      'Gets the individual test #
DECLARE FUNCTION MENU3% ()                      'Gets the module family
DECLARE FUNCTION UTILMENU% ()                   'Utility menu for Individual Test menu.
DECLARE FUNCTION OFFSETCAL$ (CAL%, CONTRES!, DIRO%) 'Performs Offset Calibration
DECLARE FUNCTION OPENIN$ ()                     'Measure open input response
DECLARE FUNCTION OUTNOISE$ ()                   'Performs Output Noise Test
DECLARE FUNCTION OUTSWITCH$ ()                  'Test output switch operation
DECLARE FUNCTION PARASITICTCV! (VCJC!)          'Measure VCJC and calculate PTC
DECLARE FUNCTION POWERIO$ (ADDR%, CMD$)       'Library fn. Kepco DPS power supply I/O
DECLARE FUNCTION READDVM! (TOL!)                'Library fn. Reads Fluke meter to TOL!
DECLARE FUNCTION READGPIB$ (ADDR%, CMD$)
DECLARE FUNCTION READPS$ (ADDR%, CMD$)
DECLARE FUNCTION REPEAT$ (N$)                   'Library fn. Ask if you would like to repeat test
DECLARE FUNCTION RTDOHMS! (TEMP!, SENTYPE$)     'Library fn. Convert RTD in temp to ohms
DECLARE FUNCTION RTDTEMP! (OHMS!, SENTYPE$)     'Library fn. Convert RTD ohms to temp
DECLARE FUNCTION SENSORNUM% ()                  'Assign a number to each sensor type
DECLARE FUNCTION SENSORIN! (MEASVIN!, PTCV!)    'Calculates sensor input
DECLARE FUNCTION SENSOROUT! (PVIN!, PTCV!)      'Calculates module input
DECLARE FUNCTION SETAC! (ONOFF%, GENAMPL!)      'Sets AC in Off or On
DECLARE FUNCTION SETATTEN% (VOLTAGE!)           'Library fn. Sets test head R/2R ladder
DECLARE FUNCTION SETPOWER$ (ADDR%, VSUPPLY!, FUNC$)    'Library fn. Set high voltage input power supply
DECLARE FUNCTION STEPRESP$ ()                   'Performs Step Response Test
DECLARE FUNCTION STRINGVAL% (a$)                'Library fn.
DECLARE FUNCTION SUPPLYI$ (EXCL%)               'Measure module supply current
DECLARE FUNCTION SUPPLYSEN$ ()                  'Performs Power Supply Sensitivity
DECLARE FUNCTION TCVOLTS! (TEMP!, TCTYPE$)      'Library fn. Convert TC in temp to V
DECLARE FUNCTION TCTEMP! (TCV!, TCTYPE$)        'Library fn. Convert TC in temp to V
DECLARE FUNCTION UPSN$ (SN$)                    'Library fn. Increments dash# of serial#
DECLARE FUNCTION VOREG$ ()                      'Tests delta Vo with Exc. load
DECLARE FUNCTION VOUT! (SENOUT!)                'Calculates module output for a given input
DECLARE FUNCTION LIBVERVAL$ ()              'Function to return the library source file version
DECLARE SUB WAITFORFINISH ()
DECLARE SUB FINISHSUB ()                    'Subroutine to run at "FINISH" label (after F10 keypress).
DECLARE FUNCTION LIBVERVAL$ ()              'Function to return the library source file version
DECLARE FUNCTION PROGVERVAL$ ()             'Function to return the program source file version
DECLARE FUNCTION PROGNAMEVAL$ ()            'Function to return the program executable file name
DECLARE FUNCTION MENUCODE% ()               'Function to return integer value of 0-35 for keypress of 0-9 or A-Z.
DECLARE SUB CHECKRESOURCES (SN$)    'Checks whether the datasheet and work order status files can be written.
DECLARE FUNCTION CHECKFILECREATE% (FOLDERNAME$, FILENAME$, KEYTOPRESS$) 'Checks whether the file can be written to the folder.
DECLARE FUNCTION CHECKPRINTER% (PrinterMessage$)    'Checks to see of the printer can print.
DECLARE FUNCTION WAITFORKEY$ (KEY$, TABPOS%, FORECOL%, BACKCOL%)

'Database Record definition for the specifications
	TYPE DBASE
		MODNAME         AS STRING * 15  'SCM5B47X-XXXXT
		SENTYPE         AS STRING * 7   'mV, V, mA, xTC, xxRTDxW, FBRIDGE, 2WTX, HBRIDGE
		ISMAXNEXCL      AS SINGLE
		ISMAXFEXCL      AS SINGLE
		OUTRES          AS SINGLE
		MININ           AS SINGLE
		MAXIN           AS SINGLE
		IEXC            AS SINGLE
		RCONV           AS SINGLE
		MINOUT          AS SINGLE
		MAXOUT          AS SINGLE
		OSCALPT         AS SINGLE
		GNCALPT         AS SINGLE
		CALTOL          AS SINGLE
		VEXC            AS SINGLE
		VEXCACC         AS SINGLE
		EXCLOAD         AS SINGLE
		EXCLOADREG      AS SINGLE
		EXCIMAX         AS SINGLE
		LINEAR          AS SINGLE
		ACCURACY        AS SINGLE
		TESTFREQ        AS SINGLE
		ATTEN           AS SINGLE
		ATTENTOL        AS SINGLE
		STEPRMIN        AS SINGLE
		STEPRMAX        AS SINGLE
		PSS             AS SINGLE
		OUTNOISE        AS SINGLE
		INPUTRES        AS SINGLE
		VOPENINMIN      AS SINGLE
		VOPENINMAX      AS SINGLE
		LEADRERR        AS SINGLE
		LINEARIZED      AS INTEGER  '1 = linearized, 0 = non-linearized
		OSCALIN         AS SINGLE   'input for offset calibration
		GNCALIN         AS SINGLE   'input for gain calibration
		BANDWIDTH       AS SINGLE   'filter -3dB point
		IMATCHTOL       AS SINGLE   'current source matching tolerance
	END TYPE
			  
	TYPE DBASE2
		RECNUM          AS INTEGER
		MODNAME         AS STRING * 15
	END TYPE

'$INCLUDE: 'QB.BI2'

'define common variables
COMMON SHARED /SAMPLE/ SPECS AS DBASE, SORTDATA1 AS DBASE2, SORTDATA2 AS DBASE2
COMMON SHARED /SAMPLE/ PON%, TX%, SN$, LOGDAT%, TE$, PCBNO$
COMMON SHARED CB0VAL%, CB1VAL%, CB2VAL%, CB3VAL%
COMMON SHARED MAINMAX!, MAINMIN!, VERNMAX!, VERNMIN!
COMMON SHARED BADDRS%, LPTADDR%, MUXADDR%, THADDR%, PSADDR%, VINADDR%
COMMON SHARED PSPORT%, DVMADDR%, GENADDR%
COMMON SHARED DPSPSADDR%, DPSVINADDR%, ABCPSADDR%, ABCVINADDR%
COMMON SHARED PSMODEL$, VINMODEL$
COMMON SHARED /PRTSCR/ inreg AS RegType, outreg AS RegType
COMMON SHARED TTYPE%, MAXINVAR!
COMMON SHARED FORCEACCLINFAIL%, FORCEVCJCFAIL%, TESTPAUSE%

CONST OHM4$ = "F4", OHM2$ = "F3", VODC$ = "F1", VOAC$ = "F2", MADC$ = "F5"

										'assign constants to test head variables
CONST CB0% = 0, CB1% = 1, CB2% = 2, CB3% = 3  'control bank addresses
CONST CON% = 1, COFF% = 0               'channel 'on' defined as '1'
										'off' defined as '0'
'CONST DVMADDR% = 1                      'GPIB address of Fluke 8842A meter

CONST LOOPOFF$ = "SOP=OFF", LOOPON$ = "SOP=ON", LOCAL$ = "LOC"

'CONST DPSVINADDR% = 2                      'Power supply for high voltage signal input
'CONST ABCVINADDR% = 6
'assign specifications which are constant for all modules
CONST IEXCSEN! = 714                    'Iexc sense resistor, 2.5Kohm
CONST RSERIES! = 5100000!               '5.1M ohm, test head series input R
CONST RFNGN! = 6800                     'Function generator attenuator series R, 6.8Kohm

KEY(10) ON                              'Activates F10 key
ON KEY(10) GOSUB FINISH                 'Traps for F10 key Exits if pressed

FINISH:
	'Exit program from F10 keypress
	CALL FINISHSUB
	END 'End of program
	
'******************* Test Titles and Units *****************************************
LINES:  DATA "Supply Current, Nom","mA","Supply Current, Max","mA"
		DATA "Exc. Current #1","uA","Exc. Current #2","uA"
		DATA "Exc. Current Match","uA","Output Resistance","ohms", "CJC Gain", "uV/C"
		DATA "Exc. Voltage","V","Exc. Load Reg.","ppm/mA"
		DATA "Vout Reg. w/ Load","%","Exc. Current Limit","mA"
		DATA "Linearity","%","Accuracy","%","Lead R Effect","C/ohm"
		DATA "Supply Sensitivity","uV/%","Input Resistance","Mohms"
		DATA "Open Input Response","V","Frequency Response","dB"
		DATA "Step Response","%","Output Noise","uVrms"
		DATA "Over-range Response","V"


'END SUB

FUNCTION CHECKFILECREATE% (FOLDERNAME$, FILENAME$, KEYTOPRESS$)
	'Function to check for the existence of the folder passed by
	'FOLDERNAME$ by creating the file passed by FILENAME$. At the
	'end, the function deletes the test file and waits for the
	'operator to press the key specified by KEYTOPRESS$ to ensure
	'that the messages about whether the file could be created (or
	'that the folder exists and can be written to) are acknowledged.
	'Since the addition of an error handler tends to cause the program
	'to run out of memory to compile, this function depends on messages
	'to the test operator about which files and folders are being
	'checked, so if the program crashes out (which it will if there is
	'an error without an error handler), the previously-displayed
	'message can point to the problem file or folder.
	'
	CHECKFILECREATE% = 1    'Initialize to "error" return for function
	PRINT TAB(10); "Attempting to open a temporary";
	PRINT TAB(10); "file in the following folder...";
	PRINT SPC(50);
	COLOR 15, 0 'Text color to bright white on black
	PRINT TAB(10); "Folder name: "; FOLDERNAME$
	PRINT SPC(50);
	COLOR 14, 0 'Text color to bright yellow on black
	PRINT TAB(10); "Record the folder name and notify engineering";
	PRINT TAB(10); "if the program crashes after this message!";
	PRINT SPC(50);
	COLOR 11, 0 'Text color back to light cyan (blue) on black
	OPEN FOLDERNAME$ + FILENAME$ FOR OUTPUT AS #9
	CLOSE #9
	'Delete the file
	KILL FOLDERNAME$ + FILENAME$
	'CLS
	'PRINT TAB(10); "Press any key to continue."
	'a$ = KEYBDIN$
	'DUMKEY$ = WAITFORKEY(KEYTOPRESS$, 10, 14, 0)   'Waits for specified key press (display bright yellow on black)

	CHECKFILECREATE% = 0    'Return of "no error" for function (if processing gets this far)

END FUNCTION

FUNCTION CHECKPRINTER% (PrinterMessage$)
	'Function to display a message to check that enough paper is loaded.
	'The program will crash if paper is not loaded when an attempt is made
	'to print. The function also checks that the printer can be written to
	'for automatic printing of the work order status file at the end of
	'testing or when a work order number is changed.
	'
	'NOTE:  Since the addition of an error handler tends to cause the
	'       program to run out of memory to compile, this function
	'       depends on messages to the test operator about the printer
	'       and the message that should be printed, so if the program
	'       crashes out (which it will if there is an error without
	'       an error handler), the already-displayed message can point
	'       to the problem.
	'
	CHECKPRINTER% = 1   'Initialize to "error" return for function
	CLS
	'LOCATE 10
	LOCATE 5
	COLOR 14, 0, 0  'Yellow on black
	PRINT TAB(10); "-----------------------------------------------------------------"
	COLOR 28, 0, 0  'Flashing light red
	PRINT TAB(10); "Verify that there is plenty of paper in the printer!"
	COLOR 14, 0, 0  'Yellow on black
	PRINT TAB(10); "-----------------------------------------------------------------"
	COLOR 11, 0, 0  'Cyan on black background
	PRINT SPC(50);
	PRINT TAB(10); "Enough paper should be loaded in the printer to print"
	PRINT TAB(10); "the W.O. Status Report in addition to any hardcopy or"
	PRINT TAB(10); "datasheet printouts that may be selected."
	PRINT SPC(50);
	COLOR 14, 0 'Text color to bright yellow on black
	PRINT TAB(10); "Notify engineering if the printer does not print the";
	PRINT TAB(10); "message listed below or if the program crashes      ";
	PRINT TAB(10); "before the question can be answered.... ";
	PRINT SPC(50);
	COLOR 11, 0, 0  'Cyan on black background
	PRINT TAB(10); "Now attempting to verify that the printer can print."
	PRINT SPC(50);
	COLOR 14, 0 'Text color to bright yellow on black
	PRINT TAB(10); "Did the printer eject a sheet of paper with         "
	PRINT TAB(10); "the following message printed on it?                "
	PRINT SPC(50);
	COLOR 15, 0 'Text color to bright white on black
	PRINT TAB(10); PrinterMessage$
	PRINT SPC(50);
	'Print to printer.
	OPEN "LPT1:" FOR RANDOM AS #14
	PRINT #14, PrinterMessage$
	PRINT #14, CHR$(12) 'Form feed
	CLOSE #14
	COLOR 14, 0 'Text color to bright yellow on black
	PRINT TAB(10); "Enter Y or y for YES, N or n for NO"
	DO
		KEYRTN$ = INKEY$
		KEYRTN$ = UCASE$(KEYRTN$)
	LOOP WHILE (KEYRTN$ <> "N") AND (KEYRTN$ <> "Y")
	IF (KEYRTN$ = "Y") THEN
		CHECKPRINTER% = 0   'Return of "no error" for function (if processing gets this far)
	ELSE
		CHECKPRINTER% = 1   'Return of "is error" for function (if processing gets this far)
	END IF
	COLOR 11, 0, 0  'Cyan on black background
	
END FUNCTION

SUB CHECKRESOURCES (SN$)
	'Sub to check for the datasheet and work order status file directories and
	'the presence of the printer. Error messages will be posted if there is a
	'a problem with these, before the program exits. This sub should not be
	'called unless a module serial number has been obtained.
	'
	'NOTE:  the sub, as is, does not need a serial number and does not currently
	'       check for the printer.
	'

	'ON ERROR GOTO ERRHANDLER ' Prepares the error handler
	'IF (SN$ = "") THEN 'Serial number not yet set
	'   COLOR 30, 0 'Text color to bright yellow on black
	'   CLS
	'   LOCATE 10, 10
	'   PRINT TAB(10); "No valid module serial number entered!"
	'   PRINT
	'   COLOR 11, 0 'Text color back to light cyan (blue) on black
	'   PRINT TAB(10); "Press any key to enter valid work order and"
	'   PRINT TAB(10); "dash numbers."
	'   a$ = KEYBDIN$
	'   CALL GETSN(SN$)                     'Gets module serial #
	'END IF

	ISERROR% = 0    'Initialize to "no error"

	'-------------------------------------------
	'Check for ability to create a file in the
	'STAGE directory (datasheet file directory)
	'-------------------------------------------
	CLS
	LOCATE 10
	PRINT TAB(10); "Checking for the ability to create a datasheet file."
	PRINT TAB(10); "----------------------------------------------------"
	PRINT SPC(50);
	IF (CHECKFILECREATE%("C:\STAGE\", "temp.fil", "S") = 1) THEN
		ISERROR% = 1    'Error flag set
	END IF
	'DUMKEY$ = WAITFORKEY("F", 10, 14, 0)   'Waits for "F" key press (display bright yellow on black)
	
	'------------------------------------------------
	'Check for ability to create a file in the REPORT
	'directory (work order status file directory)
	'------------------------------------------------
	CLS
	LOCATE 10
	PRINT TAB(10); "Checking for the ability to create a work order status file."
	PRINT TAB(10); "------------------------------------------------------------"
	PRINT SPC(50);
	IF (CHECKFILECREATE%("C:\REPORTS\", "temp.fil", "R") = 1) THEN
		ISERROR% = 1    'Error flag set
	END IF
	
	'------------------------------------------------
	'Check for ability to write to the printer
	'------------------------------------------------
	PrinterMessage$ = "Printer OK"  'Message to be printed by the printer
	CLS
	LOCATE 10
	PRINT TAB(10); "Checking for the ability to write to the printer."
	PRINT TAB(10); "-------------------------------------------------"
	PRINT SPC(50);
	IF (CHECKPRINTER%(PrinterMessage$) = 1) THEN
		'Error when printing
		ISERROR% = 1    'Error flag set
	ELSE
		CLS
	END IF
	
	'Exit program if there is an error
	IF (ISERROR% = 1) THEN
		CLS
		COLOR 12, 0 'Red on black background for fails
		LOCATE 10
		PRINT TAB(10); "Error encountered! Notify engineering!";
		COLOR 11, 0     'Back to light cyan (blue) on black background               
		PRINT SPC(50);
		PRINT TAB(10); "Program will end now. Press any key.";
		'a$ = KEYBDIN$
		PRINT TAB(10); "Program will end now. Press the specified key.";
		a$ = WAITFORKEY("A", 10, 14, 0) 'Waits for "A" key press (display bright yellow on black)
		END 'End program
	END IF
END SUB

SUB DATASHEETPRINT (SN$, STATUS$())
	'Sub to ask to print that specified datasheet file (and print if "yes" is selected).
	'NOTE:  the sub only attempts to print the datasheet file if the datasheet file
	'       should have been created (the module passed and the "write datasheet" flag
	'       was "on").
	'
	'-----------------------------------------------------------
	'Skip trying to print the datasheet if it was not created:
	' 1:    If the "write datasheet" flag ("TX%") is not a "1".
	' 2:    If the module failed.
	'-----------------------------------------------------------
	IF ((TX% <> 1) OR (FAILS%(STATUS$()) <> 0)) THEN EXIT SUB
	
	COLOR 15, 0, 0  'Clear screen to bright white on black background
	CLS
	CALL GETDSFNAME(SN$, DSSNAME$, DSFNAME$)    'Gets datasheet search and file names from serial number

	LOCATE 8, 10: PRINT "Do you want to print the "; DSFNAME$ + " datasheet file?"
	LOCATE 9, 10: PRINT "Either the 'Y' or 'N' must be pressed."
	
	DO  'Loop until the "Y" or "N" key is pressed
		a$ = INKEY$
		a$ = UCASE$(a$) 'Set key value to uppercase
	LOOP WHILE (a$ <> "N") AND (a$ <> "Y")

	IF a$ <> "N" THEN
		PRINT   'Blank line
		PRINT TAB(10); "Printing: " + DSFNAME$ + ", wait until printing is complete."
		SHELL "COPY C:\STAGE\" + DSFNAME$ + " LPT1 > NUL"       'Print datasheet file
		LPRINT CHR$(12) 'Form feed
		PRINT
		PRINT TAB(10); "Has the " + DSFNAME$ + " file finished printing?"
		DUMKEY$ = WAITFORKEY("F", 10, 14, 0)    'Waits for "F" key press (display bright yellow on black)
	END IF
	COLOR 11, 0, 0  'Cyan on black background
	
END SUB

SUB DATASHEETWRITE (SN$, STATUS$(), TSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), TSPEC$(), TX%)
	'Sub to write the datasheet file (to be archived to the network and website)
	'
	IF TX% <> 1 THEN EXIT SUB   'Skip writing datasheet file if write to datasheet flag is not "1"

	CALL GETDSFNAME(SN$, DSSNAME$, DSFNAME$)    'Gets datasheet search and file names from serial number
	
	'Check for module pass or fail
	'IF 0 THEN              'For debug (PWR)
	IF FAILS%(STATUS$()) <> 0 THEN
		'Failing module
		'NOTE:  Currently not creating a file with "Invalid Serial Number" in it, since this type
		'       of "failing" file could overwrite a "passing" datasheet file from later testing
		'       on another tester, depending on the order that the testers are rebooted (and
		'       subsequently when their test files are transferred to the network). Therefore the
		'       the following four lines have been commented out.
'       'OPEN "C:\STAGE\" + SN$ + ".TXT" FOR OUTPUT AS #9
'       OPEN "C:\STAGE\" + DSFNAME$ FOR OUTPUT AS #9
'       PRINT #9, "Invalid Serial Number"
'       CLOSE #9
	ELSE
		'Passing module
		PRINT
		PRINT TAB(10); "Writing datasheet file."
		'OPEN "C:\STAGE\" + SN$ + ".TXT" FOR OUTPUT AS #9
		OPEN "C:\STAGE\" + DSFNAME$ FOR OUTPUT AS #9
		
		'Get and calculate values.
		SENSOR$ = SPECS.SENTYPE
		MININ! = SPECS.MININ
		MAXIN! = SPECS.MAXIN
		MINOUT! = SPECS.MINOUT
		MAXOUT! = SPECS.MAXOUT
		MAXLINERR! = SPECS.LINEAR                               '%
		MAXACCERR! = SPECS.ACCURACY                             '%
		BANDWIDTH! = SPECS.BANDWIDTH
		LIN% = SPECS.LINEARIZED
		CALOS! = SPECS.OSCALPT / 100             '%
		INRANGE! = SENSOROUT!(SPECS.MAXIN!, 0) - SENSOROUT!(SPECS.MININ!, 0)
		ORANGE! = MAXOUT! - MINOUT!              'Output range (V)

		SNM% = SENSORNUM%
		
		'------------
		'Write header
		'------------
		PRINT #9, TAB(5); "DATAFORTH CORPORATION"; TAB(51); "Phone: (520) 741-1404"
		PRINT #9, TAB(5); "3331 E. Hemisphere Loop"; TAB(51); "Fax:   (520) 741-0762"
		PRINT #9, TAB(5); "Tucson, AZ  85706  USA"; TAB(51); "email: info@dataforth.com"
		PRINT #9,
		PRINT #9, TAB(33); "TEST DATA SHEET"
		PRINT #9, TAB(5);
		FOR X = 5 TO 75
			PRINT #9, "~";
		NEXT
		LOCATE 8
		PRINT #9, TAB(5); "Date: "; DATE$
		PRINT #9, TAB(5); "Model: "; SPECS.MODNAME
		PRINT #9, TAB(5); "SN: "; TAB(12); SN$
		PRINT #9,
	
		'-----------------------
		'Write accuracy results 
		'-----------------------
		'Output format
		'1        10        20        30        40        50        60        70        80
		'         |         |         |         |         |         |         |         |
			'Rin (ohms)
			' Temp. (C)
			' Iin (mA)       Calculated       Measured
			'  Vin (V)        Vout (V)        Vout (V)       Error (%)       Status
			'==========      ==========      ==========      =========      ========
			' #####.##        +##.###         +##.###        +###.###
			' +####.##        +##.###         +##.###        +###.###
			' +###.###        +##.###         +##.###        +###.###         PASS
		'
		PRINT #9, TAB(34); "ACCURACY TEST"
		PRINT #9,
		PRINT #9, TAB(21); "Calculated"; TAB(38); "Measured"
		IF SNM% >= 3 AND SNM% <= 6 THEN     'Temperature input modules
			PRINT #9, TAB(6); "Temp. (C)";
		ELSEIF SNM% = 2 OR SNM% = 9 THEN    'Current input modules
			INSCALE! = 1
			PRINT #9, TAB(6); "Iin (mA)";
		ELSEIF SNM% = 7 THEN                'Resistance input modules
			PRINT #9, TAB(5); "Rin (ohms)";
		ELSE
			IF MAXIN! >= 1 THEN
				INSCALE! = 1
				PRINT #9, TAB(7); "Vin (V)";
			ELSE
				INSCALE! = 1000
				PRINT #9, TAB(6); "Vin (mV)";
			END IF
		END IF
		PRINT #9, TAB(22); "Vout (V)"; TAB(38); "Vout (V)*";
		PRINT #9, TAB(53); "Error (%)"; TAB(69); "Status"
		PRINT #9, TAB(5); "=========="; TAB(21); "=========="; TAB(37); "==========";
		PRINT #9, TAB(53); "========="; TAB(68); "========"
			
		NUMPTS% = 5                                     'Number of points in test
		FOR INC% = 1 TO NUMPTS% STEP 1
			IF SNM% >= 3 AND SNM% <= 6 THEN     'Temperature input modules
				PRINT #9, TAB(6); USING "+####.##        +##.###         +##.###        +###.###"; TSIM!(INC%); OUTCALC!(INC%); OUTMEAS!(INC%); ERROROUT!(INC%);
			ELSEIF SNM% = 7 THEN                'Resistance input modules
				PRINT #9, TAB(6); USING "#####.##        +##.###         +##.###        +###.###"; TSIM!(INC%); OUTCALC!(INC%); OUTMEAS!(INC%); ERROROUT!(INC%);
			ELSE                                'Voltage or current input modules
				PRINT #9, TAB(6); USING "+###.###        +##.###         +##.###        +###.###"; TSIM!(INC%) * INSCALE!; OUTCALC!(INC%); OUTMEAS!(INC%); ERROROUT!(INC%);
			END IF
			PRINT #9, TAB(70); ACCSTAT$(INC%)
		NEXT    'Next accuracy/linearity measurement step (PWR)

		'-------------------------------------------
		'Write tests results (except accuracy steps)
		'-------------------------------------------
		'Output format
		'1        10        20        30        40        50        60        70        80
		'         |         |         |         |         |         |         |         |
		'           Parameter         Measured Value*      Specification      Status
		'    =======================  ===============  =====================  ======
		'                               ###### uVrms   ##### to ##### uVrms    PASS
		'
		RESTORE LINES   'Get test names and units from data listing
		'Write all-tests header
		PRINT #9,
		PRINT #9, TAB(31); "FINAL TEST RESULTS"
		PRINT #9,
		PRINT #9, TAB(12); "Parameter"; TAB(30); "Measured Value"; TAB(51); "Specification ";
		PRINT #9, TAB(70); "Status"
		PRINT #9, TAB(5); "======================="; TAB(30); "===============";
		PRINT #9, TAB(47); "====================="; TAB(70); "======"

		'FOR X = 1 TO 21
		FOR X = 1 TO MAXSTATUSINDEX
			'Write all-tests results
			READ a$, B$ 'Read test names and units from data listing
			'STATUS$(X) format = <pass/fail>+<measured data>+<# decimal places>
			'                     4 char.     ? char          1 char.
			'
			IF LEN(STATUS$(X)) > 4 THEN         'Check for test data
				PRINT #9, TAB(5); a$;
				DATALEN% = LEN(STATUS$(X))
				NUMDATA! = VAL(MID$(STATUS$(X), 5, DATALEN% - 5))
									'print using requested # of decimal places
				IF X = 14 AND SNM% = 7 THEN
					B$ = "ohm/ohm"          'Set proper units
				ELSEIF X = 15 AND (SNM% = 5 OR SNM% = 6) THEN
					B$ = "C/V"
				END IF
				IF RIGHT$(STATUS$(X), 1) = "0" THEN
					PRINT #9, TAB(31); USING "###### &"; NUMDATA!; B$;
				ELSEIF RIGHT$(STATUS$(X), 1) = "1" THEN
					PRINT #9, TAB(31); USING "####.# &"; NUMDATA!; B$;
				ELSEIF RIGHT$(STATUS$(X), 1) = "2" THEN
					PRINT #9, TAB(31); USING "####.# &"; NUMDATA!; B$;
				ELSEIF RIGHT$(STATUS$(X), 1) = "3" THEN
					PRINT #9, TAB(31); USING "##.### &"; NUMDATA!; B$;
				ELSEIF RIGHT$(STATUS$(X), 1) = "4" THEN
					PRINT #9, TAB(31); USING "#.#### &"; NUMDATA!; B$;
				END IF
				 
				SPECLEN% = LEN(TSPEC$(X))
				PRINT #9, TAB(60 - SPECLEN%); TSPEC$(X);
				PRINT #9, TAB(61); B$;
				PRINT #9, TAB(71); LEFT$(STATUS$(X), 4)
			END IF  'End if length of status greater than 4 (test performed)
		NEXT    'Next test in status string array
		
		'------------
		'Write footer
		'------------
		IF LEFT$(SPECS.MODNAME, 7) <> "SCM5BPT" AND LEFT$(SPECS.MODNAME, 10) <> "SCM5B-1369" THEN
			PRINT #9, TAB(5); "240 VAC Withstand"; TAB(71); "PASS"
			PRINT #9, TAB(5); "Hi-Pot "; TAB(71); "PASS"
		END IF
	 
		PRINT #9, TAB(5);
		FOR X = 5 TO 75
			PRINT #9, "_";
		NEXT X
		PRINT #9, TAB(35); "Check List"
		PRINT #9,
		PRINT #9, TAB(5); "Module Appearance:      __X__"; TAB(45); "Mounting Screw:           __X__"
		PRINT #9,
		PRINT #9, TAB(5); "Pins Straight:          __X__"; TAB(45); "Module Header:            __X__"
'                        PRINT #9,
'                        PRINT #9, TAB(5); "Tested by:      _____________"; TAB(45); "QC:             _______________"
		PRINT #9,
		PRINT #9, TAB(5); "It is hereby certified that the above product is in conformance with"
		PRINT #9, TAB(5); "all requirements to the extent specified.  This product is not"
		PRINT #9, TAB(5); "authorized or warranted for use in life support devices and/or systems."
		PRINT #9,
		PRINT #9, TAB(5); "* NIST traceable calibration certificates support Measured Value data."
		PRINT #9, TAB(5); "  Calibration services are available through ANSI/NCSL Z540-1 and"
		PRINT #9, TAB(5); "  ISO Guide 25 Certified Metrology Labs."
		
		'Close datasheet file
		CLOSE #9
	END IF  'End else (passing module)
END SUB

SUB FAILSTATUS (TESTVALUE$, YLOC%, XLOC%, TEXTVALUE$, SPACES%)
	'Sub to format and print the test value to the screen. First, it locates
	'and prints the "TEXTVALUE$" string to the location specified by "XLOC%"
	'and "YLOC%" and then it prints the "TESTVALUE$" string, first formatting
	'it in red text if the leftmost 4 characters are "FAIL". In the special
	'case of "XLOC%" = "-1", "YLOC%" contains the number of spaces to tab
	'over before printing "TEXTVALUE$".
	'
	IF (LEFT$(TESTVALUE$, 4) = "FAIL") THEN
		COLOR 12, 0 'Test value text color to light red
	ELSE
		COLOR 10, 0 'Test value text color to light green
	END IF
	
	IF (XLOC% = -1) THEN
		'Tab over and print status text
		PRINT TAB(YLOC%); TEXTVALUE$; TESTVALUE$; SPC(SPACES%);
	ELSE
		'Locate and print status text
		LOCATE YLOC%, XLOC%: PRINT TEXTVALUE$; TESTVALUE$; SPC(SPACES%);
	END IF

	IF (LEFT$(TESTVALUE$, 4) = "FAIL") THEN
		CALL CONTINUE
	ELSE
		IF (TESTPAUSE% = 1) THEN
			EATTHIS$ = INKEY$
			CALL CONTINUE
			'"Eat" the unnecessary yet possible "any" keystroke
			'press (likely the spacebar) after the status display.
		ELSE
			'If the test passed, "eat" the unnecessary yet possible "any" keystroke
			'press (likely the spacebar) after the status display.
			EATTHIS$ = INKEY$
		END IF
	END IF
	
	'Text color back to light cyan (blue)
	COLOR 11, 0
		
END SUB

SUB FOOTER (STATUS$())
	'Sub to create footer (if there are no fails). Removed code to print footer to file
	'since that is now accomplished by the "DATASHEETWRITE" sub. The datasheet can still
	'be sent to two places (screen and printer), so when updating remember to make any
	'changes to both the "PRINT" and "LPRINT" sections.
	'
	'NOTE:  Currently, the footer is only printed to the printer, not the screen.
	'
	IF FAILS%(STATUS$()) = 0 THEN

'       'Send to screen
'       IF LEFT$(SPECS.MODNAME, 7) <> "SCM5BPT" AND LEFT$(SPECS.MODNAME, 10) <> "SCM5B-1369" THEN
'           PRINT TAB(5); "240 VAC Withstand"; TAB(71); "PASS"
'           PRINT TAB(5); "Hi-Pot "; TAB(71); "PASS"
'       END IF
'       
'       PRINT TAB(5);
'       FOR X = 5 TO 75
'           PRINT "_";
'       NEXT X
'       PRINT TAB(35); "Check List"
'       PRINT
'       PRINT TAB(5); "Module Appearance:      _____"; TAB(45); "Mounting Screw:           _____"
'       PRINT
'       PRINT TAB(5); "Pins Straight:          _____"; TAB(45); "Module Header:            _____"
'       PRINT
'       PRINT TAB(5); "Tested by:      _____________"; TAB(45); "QC:             _______________"
'       PRINT
'       PRINT TAB(5); "It is hereby certified that the above product is in conformance with"
'       PRINT TAB(5); "all requirements to the extent specified.  This product is not"
'       PRINT TAB(5); "authorized or warranted for use in life support devices and/or systems."
'       PRINT
'       PRINT TAB(5); "* NIST traceable calibration certificates support Measured Value data."
'       PRINT TAB(5); "  Calibration services are available through ANSI/NCSL Z540-1 and"
'       PRINT TAB(5); "  ISO Guide 25 Certified Metrology Labs."
		 
		'Send to printer
		IF PON% = 1 THEN
	 
			IF LEFT$(SPECS.MODNAME, 7) <> "SCM5BPT" AND LEFT$(SPECS.MODNAME, 10) <> "SCM5B-1369" THEN
				LPRINT TAB(5); "240 VAC Withstand"; TAB(71); "PASS"
				LPRINT TAB(5); "Hi-Pot "; TAB(71); "PASS"
			END IF

			LPRINT TAB(5);
			FOR X = 5 TO 75
				LPRINT "_";
			NEXT X
			LPRINT TAB(35); "Check List"
			LPRINT
			LPRINT TAB(5); "Module Appearance:      _____"; TAB(45); "Mounting Screw:           _____"
			LPRINT
			LPRINT TAB(5); "Pins Straight:          _____"; TAB(45); "Module Header:            _____"
			LPRINT
			LPRINT TAB(5); "Tested by:      _____________"; TAB(45); "QC:             _______________"
			LPRINT
			LPRINT TAB(5); "It is hereby certified that the above product is in conformance with"
			LPRINT TAB(5); "all requirements to the extent specified.  This product is not"
			LPRINT TAB(5); "authorized or warranted for use in life support devices and/or systems."
			LPRINT
			LPRINT TAB(5); "* NIST traceable calibration certificates support Measured Value data."
			LPRINT TAB(5); "  Calibration services are available through ANSI/NCSL Z540-1 and"
			LPRINT TAB(5); "  ISO Guide 25 Certified Metrology Labs."
		END IF
	END IF
 
	IF PON% = 1 THEN LPRINT CHR$(12)   'Send form feed to printer (whether a passing or failing module)

END SUB

SUB HARDCOPY
	'Sub to ask if hardcopy printout is desired

	   COLOR 15, 0, 0  'Clear screen to black background
	   CLS
		COLOR 20, 0, 0
		LOCATE 8, 15: PRINT "                   --  NOTE  --                   "
		COLOR 8, 0, 0
		LOCATE 9, 15: PRINT "**************************************************"
		COLOR 14, 0, 0      'yellow txt on black
'       PRINT TAB(15); "ENSURE THAT THE PRINTER PAPER IS ALIGNED CORRECTLY"
		LOCATE 11, 15: PRINT "      DO YOU WANT A HARD COPY PAPER PRINTOUT?     "
		LOCATE 12, 15: PRINT "           Y or y for YES, N or n for NO"
		COLOR 8, 0, 0
		LOCATE 14, 15: PRINT "**************************************************"
		SOUND 400, 1
		PON% = 0
		COLOR 14, 0, 0
'       LOCATE , 15: INPUT " ";     HRDCPY$                     'print to hardcopy
	DO
		HRDCPY$ = INKEY$
		HRDCPY$ = UCASE$(HRDCPY$)
	LOOP WHILE (HRDCPY$ <> "N") AND (HRDCPY$ <> "Y")

	IF HRDCPY$ = "Y" THEN
		
			PON% = 1
			CLS
			COLOR 15, 0, 0  ' white txt on black
			LOCATE 8, 15: PRINT "**************************************************"
			COLOR 14, 0, 0      'yellow txt on black
			LOCATE 10, 15: PRINT "ENSURE THAT THE PRINTER PAPER IS ALIGNED CORRECTLY"
			COLOR 15, 0, 0
			LOCATE 12, 15: PRINT "**************************************************"
			CALL CONTINUE
		END IF
	COLOR 11, 0 'Back to cyan with a black background
	CLS
END SUB

SUB HEADERA (SN$)
	'Sub to printer header section datasheet if print flag is "on"
	'
	IF PON% = 1 THEN
		LPRINT TAB(5); "DATAFORTH CORPORATION"; TAB(51); "Phone: (520) 741-1404"
		LPRINT TAB(5); "3331 E. Hemisphere Loop"; TAB(51); "Fax:   (520) 741-0762"
		LPRINT TAB(5); "Tucson, AZ  85706  USA"; TAB(51); "email: info@dataforth.com"
		LPRINT
		LPRINT TAB(33); "TEST DATA SHEET"
		LPRINT TAB(5);
		FOR X = 5 TO 75
			LPRINT "~";
		NEXT
		LOCATE 8
		LPRINT TAB(5); "Date: "; DATE$
		LPRINT TAB(5); "Model: "; SPECS.MODNAME
		LPRINT TAB(5); "SN: "; TAB(12); SN$
		LPRINT
	END IF
END SUB

SUB HEADERB (TESTTITLE$)
		'print test title, model under test, and SN at top of screen
	  
		TITLEN = LEN(TESTTITLE$) + LEN(SPECS.MODNAME)
		PRINT TAB(40 - TITLEN / 2); SPECS.MODNAME; " "; TESTTITLE$;
		IF SN$ <> "" THEN
				PRINT TAB(66); "SN: "; SN$      'print SN if available
		ELSE
				PRINT
		END IF
		LOCATE , 40 - TITLEN / 2
		FOR L = 1 TO TITLEN + 1                 'underline test title
				PRINT "-";
		NEXT
		PRINT

END SUB

SUB INTERLUDE
	'Wait for user input. Prints message based on current cursor row, unlike
	'the library "CONTINUE" which prints on a fixed row
	COLOR 15, 0     'Bright white, black background
	'Y% = CSRLIN + 1
	'LOCATE Y%, 10: Print "Press any key to continue"
	PRINT ""
	PRINT TAB(10); "Press any key to continue"
	DO
		KB$ = INKEY$
	LOOP WHILE KB$ = ""
	COLOR 11, 0 'Cyan, black background
END SUB

FUNCTION MEASRES! (OHM!, RESNUM%, TE$)
	'Measure specified resistance
	'Legend:
	'RESNUM%        Resistor
	'-------        --------
	'   1           On board supply current sense resistor,
	'               24 or 100 ohm for Rev B PCB, 0.5 ohm, not measured, for Rev A PCB.
	'   2           Iexc sense resistor, RTD or pot input, 2.5Kohm
	'   3           Simulated sensor input, RTD or pot, 8-20Mohm
	'   4           Contact resistance, RTD or pot input, milliOhm
	'   5           Jumper between -IN and -EXC on SCM5B42-xx
	'   6           Simulated sensor input, RDAC test
	'   7           Pass-through module continuity test
	'
	SELECT CASE RESNUM%                     'Branches to the specific measurement
		CASE 1
			CALL WRITEDVM(OHM2$, OHM! / 1000)       'Sets meter
			CALL LOADMUX(3, CON%)                   'Sets mux channel
			MEASTOL! = .001                         '0.1% measurement tolerance
			INITTOL! = .2                           '20% initial tolerance
		CASE 2
			CALL WRITEDVM(OHM2$, OHM! / 1000)       'Sets meter
			CALL LOADMUX(4, CON%)                   'Sets mux channel
			MEASTOL! = .001                         '0.1% measurement tolerance
			INITTOL! = .05                          '5% initial tolerance
		CASE 3
			IF LEFT$(SPECS.SENTYPE, 2) = "C1" OR LEFT$(SPECS.SENTYPE, 2) = "C2" THEN
				LOWOHM% = 1                         'Enable 10 ohm input
				CB1VAL% = CB1VAL% AND &HFB          '1 1 1 1  1 0 1 1
				CALL SETTH(CB1VAL%, CB1%)
			END IF
			CALL SETTEST(7)                         'Open series relay
			IF OHM! = 0 THEN OHM! = 8               'RDAC min setting.
			CALL WRITEDVM(OHM4$, OHM! / 1000)       'Sets meter
			CALL LOADMUX(1, CON%)                   'Sets mux channel
			CALL LOADMUX(8, CON%)                   'set sense channel
			MEASTOL! = .00005                       '0.005% measurement tolerance
			INITTOL! = .15                          '15% initial tolerance
		CASE 4
			CALL OHMSET(1E+10)                      'Open all relays
			CALL SETTEST(3)                         'Measure contact resistance
			CALL WRITEDVM(OHM4$, OHM! / 1000)       'Sets meter
			CALL LOADMUX(1, CON%)                   'Sets mux channel
			CALL LOADMUX(6, CON%)                   'set sense channel
			MEASTOL! = .0001                        '0.01% measurement tolerance
			INITTOL! = .15                          '15% initial tolerance
			CLS : LOCATE 10
			PRINT TAB(10); "Measuring resistance.  Please wait..."
		CASE 5
			CALL WRITEDVM(OHM2$, OHM! / 1000)       'Sets meter
			CALL LOADMUX(6, CON%)                   'Sets mux channel
			MEASTOL! = 0!                           '1% measurement tolerance
			INITTOL! = .2                           '20% initial tolerance
		CASE 6
			CALL SETTEST(7)                         'Open series relay
			IF OHM! < 1000 THEN
				CALL WRITEDVM(OHM4$, OHM! / 1000)   'Sets meter
				CALL LOADMUX(1, CON%)               'Sets mux channel
				CALL LOADMUX(8, CON%)               'set sense channel
			ELSE
				CALL WRITEDVM(OHM2$, OHM! / 1000)   'Sets meter
				CALL LOADMUX(1, CON%)               'Sets mux channel
			END IF

			IF OHM! > 1000000! THEN
				INITTOL! = .15                      '15% initial tolerance
				MEASTOL! = .005                     '0.5% measurement tolerance
			ELSE
				INITTOL! = .05                      '5% initial tolerance
				MEASTOL! = .0005                    '0.05% measurement tolerance
			END IF
	   
		CASE 7
			CALL WRITEDVM(OHM2$, OHM! / 1000)       'Sets meter
			CALL LOADMUX(2, CON%)                   'Sets mux channel
			MEASTOL! = .005                         '0.5% measurement tolerance
			INITTOL! = .2                           '20% initial tolerance

	END SELECT

	TEMP! = READDVM!(MEASTOL! * OHM!)   'Measure resistor value to tolerance
   
	IF OHM! > 1! AND ABS(TEMP! - OHM!) > (OHM! * INITTOL!) THEN   'Test for 15% deviation
		CLS
		LOCATE 10, 10
		PRINT "Measured resistance = "; TEMP!; " ohms."
		PRINT TAB(10); USING "Required resistance = #######.## ohms to #######.## ohms"; OHM! * (1 - INITTOL!); OHM! * (1 + INITTOL!)
		PRINT TAB(10); "Check all cables and try again."
		PRINT TAB(10); "If the failure continues, notify engineering."
		END
	END IF
	IF RESNUM% <> 6 THEN CALL WRITEDVM(VODC$, 1!)   'Resets meter
	CALL LOADMUX(0, CON%)                           'Clears mux
	  
	IF RESNUM% = 3 THEN
		CALL SETTEST(2)                         'Reset to standard operation
		IF LOWOHM% = 1 THEN
			CB1VAL% = CB1VAL% OR &H4            '0 0 0 0  0 1 0 0
			CALL SETTH(CB1VAL%, CB1%)
		END IF
	ELSEIF RESNUM% = 4 THEN
		CALL SETTEST(2)
		IF LEFT$(SPECS.SENTYPE, 2) = "C1" OR LEFT$(SPECS.SENTYPE, 2) = "C2" THEN
			CB1VAL% = CB1VAL% AND &HFB          '1 1 1 1  1 0 1 1
			CALL SETTH(CB1VAL%, CB1%)
		END IF
		IF TEMP! > .5 THEN                     'Contact res. out of spec
			PRINT
			PRINT TAB(10); "Contact resistance = "; TEMP!; "ohms."
			PRINT TAB(10); "This test head requires repair."
			PRINT TAB(10); "Please notify engineering."
			CALL CONTINUE
			END
		END IF
	END IF

	MEASRES! = TEMP!                                'Passes resistor value back

END FUNCTION

FUNCTION MENU1%
	' ***** PROGRAM CONTROL MENU 1 *****
	'
	CLS
	COLOR 14, 0, 0
	LOCATE 5, 23: PRINT "SCM5Bxx-xx AUTOMATED TEST EQUIPMENT"
	PRINT TAB(23); "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
	LOCATE 8
	COLOR 11, 0, 0
	PRINT TAB(14); "1.) Offset/Gain and Excitation Calibration"
	PRINT TAB(14); "2.) Pre-Encapsulation Complete Test"
	'PRINT TAB(14); "3.) Post Encapsulation Complete Test (Print Results)"
	PRINT TAB(14); "3.) Post Encapsulation Complete Test"
	PRINT TAB(14); "    (Optional Printout)"
	'PRINT TAB(14); "4.) Sealed Module Retest (Print Results)"
	PRINT TAB(14); "4.) Sealed Module Retest"
	PRINT TAB(14); "    (Optional Printout)"
	PRINT TAB(14); "5.) Individual Test Menu"
	PRINT TAB(14); "6.) SCM5BPT, SCM5BPT-1367, SCM5BPT-1516, SCM5B-1369 Test"
	PRINT TAB(14); "7.) Return to the FAMILY TYPE menu"
	PRINT
	PRINT TAB(14); "Press the F9 key at any time to return to this menu."
	PRINT TAB(14); "Press the F10 key at any time to exit the program."

	DO
			I$ = INKEY$
	LOOP WHILE VAL(I$) < 1 OR VAL(I$) > 7

	MENU1% = VAL(I$)
	CLS

END FUNCTION

FUNCTION MENU2%
	'Individual Test menu.
	'
	CLS
	LOCATE , 23
	COLOR 14, 0, 0
	PRINT "SCM5Bxx-xx AUTOMATED TEST EQUIPMENT"
	COLOR 11, 0, 0
	PRINT TAB(9); "1.) Supply Current Test, No Excitation Load"
	PRINT TAB(9); "2.) Supply Current Test, Full Excitation Load (SCM5B38, 42 ONLY)"
	PRINT TAB(9); "3.) Current Source Operation & Matching (SCM5B34, 35, 36 ONLY)"
	PRINT TAB(9); "4.) Output Switch Test"
	PRINT TAB(9); "5.) Cold Junction Compensation Gain (SCM5B37, 47 ONLY)"
	PRINT TAB(9); "6.) Offset & Gain Calibration"
	PRINT TAB(9); "7.) Excitation Calibration (SCM5B38, 42 ONLY)"
	PRINT TAB(9); "8.) Excitation Load Regulation Test (SCM5B38, 42 ONLY)"
	PRINT TAB(9); "9.) Excitation Current Limit Test (SCM5B38, 42 ONLY)"
	PRINT TAB(9); "A.) Linearity / Accuracy Test"
	PRINT TAB(9); "B.) Lead Resistance Effects Test (SCM5B34, 36 ONLY)"
	PRINT TAB(9); "C.) Power Supply Sensitivity Test"
	PRINT TAB(9); "D.) Input Resistance & Bias Current (SCM5B30, 31, 40, 41 ONLY)"
	PRINT TAB(9); "E.) Open Input Response Test"
	PRINT TAB(9); "F.) Frequency Response Test"
	PRINT TAB(9); "G.) Step Response Test"
	PRINT TAB(9); "H.) Output Noise Test"
	PRINT TAB(9); "I.) Notes On ATE Operation"
	PRINT TAB(9); "J.) Eject paper from printer";
	PRINT TAB(9); "K.) Utility Menu: Printer, Log, Pause On/Off"
	PRINT TAB(9); "L.) Exit to the 5B Main Menu"
	PRINT TAB(9); "Enter your selection.  "
	'
	'NOTE1: The entry for character M is not shown in the displayed
	'       menu items above. It is a "hidden" selection to debug
	'       and calibrate the "one-shot" in the testhead that is
	'       used for the Step Response test.
	'
	'NOTE2: The entry for character N is not shown in the displayed
	'       menu items above. It is a "hidden" toggle for a debug
	'       mode that forces the input measurements in the LINTEST$
	'       steps into a failure to verify the failure formatting.
	'
	'NOTE3: The entry for character O is not shown in the displayed
	'       menu items above. It is a "hidden" toggle for a debug
	'       mode that forces Vcjc failures to verify the failure code.
	'
	MENU2% = MENUCODE%  'Get value from menu keypress.
	CLS
END FUNCTION

FUNCTION MENU3%
	'Module Family Selection Menu.
	'
	CLS
	LOCATE 3, 26
	COLOR 14, 0, 0
	PRINT "Module Family Selection Menu"
	PRINT TAB(26); "----------------------------"
	PRINT
	COLOR 11, 0, 0
	PRINT TAB(24); "1.)  SCM5B30-xx"
	PRINT TAB(24); "2.)  SCM5B31-xx"
	PRINT TAB(24); "3.)  SCM5B32-xx"
	PRINT TAB(24); "4.)  SCM5B34-xx"
	PRINT TAB(24); "5.)  SCM5B35-xx"
	PRINT TAB(24); "6.)  SCM5B36-xx"
	PRINT TAB(24); "7.)  SCM5B37-xx"
	PRINT TAB(24); "8.)  SCM5B38-xx"
	PRINT TAB(24); "9.)  SCM5B392-xx"
	PRINT TAB(24); "A.)  SCM5B40-xx"
	PRINT TAB(24); "B.)  SCM5B41-xx"
	PRINT TAB(24); "C.)  SCM5B42-xx"
	PRINT TAB(24); "D.)  SCM5B43-xx"
	PRINT TAB(24); "E.)  SCM5B47x-xx"
	PRINT TAB(24); "F.)  SCM5BPT, -1367, -1516, SCM5B-1369"
	PRINT TAB(24); "G.)  Exit"

	DO
		DO
			I$ = UCASE$(INKEY$)
		LOOP WHILE I$ = ""
		C% = ASC(I$)
	LOOP WHILE (C% < 49 OR C% > 57) AND (C% < 65 OR C% > 71)
	  
	IF C% > 57 THEN
		M3% = C% - 55
	ELSE
		M3% = C% - 48
	END IF

	IF M3% >= 4 AND M3% <= 6 THEN           'Parallel port, mux & test head addresses
		TE$ = "TE1012"                      'Resistance input test head
		FILENAME$ = "ABC5BRIN.ADR"
	ELSE
		TE$ = "TE1005"                      'Voltage/current input test head
		FILENAME$ = "ABC5BVIN.ADR"          'Parallel port, mux & test head addresses
	END IF

	CALL GETADD(FILENAME$)                  'Gets the Parallel port, Mux and Testhead address
	MENU3% = M3%
	CLS
END FUNCTION

FUNCTION MENUCODE%
	'Function to return numeric code (for CASE statements, etc.) from
	'0-9 or A-Z single-key menu choices.
	'
	'0-9 returns 0-9, while A-Z returns 10 through 35.
	'
	I$ = "" 'Initialize.
	DO      'Loop through allowed keys (0-9 or A-Z).
		DO  'Loop waiting for a key (any key) to be pressed.
			I$ = UCASE$(INKEY$)
		LOOP WHILE I$ = ""
		C% = ASC(I$)    'Get ASCII value of key pressed.
		'Loop while screen entry is 1 to 9 (ASCII codes 49 to 57) or
		'A through Z (ASCII codes 65 to 90).
		'
	LOOP WHILE (C% < 49 OR C% > 57) AND (C% < 65 OR C% > 90)

	IF C% > 57 THEN
		'Really, this should be ">= 65" since the values between 57 ("9") and
		'64 ("@") are not valid.
		'
		'Translate character (ASCII) values of A to Z (65 to 90) to integer values of 10 through 35
		MENUCODE% = C% - 55
	ELSE
		'Translate character (ASCII) values of 1 to 9 to integer values of 1 through 9
		MENUCODE% = C% - 48
	END IF
	
END FUNCTION

SUB NOTES
	  
		'Notes on ATE operation

		CLS
		LOCATE 5, 25
		PRINT "AUTOMATED TEST EQUIPMENT NOTES"
		PRINT
		PRINT TAB(10); "1.) During the calibration subroutines the following keystrokes"
		PRINT TAB(14); "can be used:"
		PRINT
		PRINT TAB(14); "(C)alibrate will exit the routine and continue"
		PRINT TAB(14); "program execution."
		PRINT
		PRINT TAB(14); "(T)roubleshoot will pause the program.  The DVM will continuously"
		PRINT TAB(14); "display the calibration reading."
		PRINT
		PRINT TAB(10); "2.) Press (F10) at any time to break out of the program and"
		PRINT TAB(14); "return to DOS."
		CALL CONTINUE

END SUB

FUNCTION OFFSETCAL$ (CAL%, CONTRES!, DIRO%)
	'Calibrate module offset
	'Inputs;        calibration flag
	'               measured contact resistance (used for resistance in only)
	'
	SENSOR$ = SPECS.SENTYPE
	MINUSFSIN! = SPECS.MININ
	MAXIN! = SENSOROUT!(SPECS.MAXIN!, 0)    'Use to check for high voltage input
	MINOUT! = SPECS.MINOUT
	MAXOUT! = SPECS.MAXOUT
	CALOS! = SPECS.OSCALPT / 100            '%
	INITTOL! = 8                            'Uncalibrated offset tolerance (%)
	CALTOL! = SPECS.CALTOL                  'Calibration tolerance (% span)
	OSCALIN! = SPECS.OSCALIN                'Module input for offset calibration
	GNCALIN! = SPECS.GNCALIN                'Module input for offset calibration
	BANDWIDTH! = SPECS.BANDWIDTH
	LIN% = SPECS.LINEARIZED
	SNM% = SENSORNUM%

	CLS
	TESTTITLE$ = "Offset Calibration"
	CALL HEADERB(TESTTITLE$)

	CALL MODULEOUTLINE
	
	IF (SNM% >= 3 AND SNM% <= 6) AND LIN% = 0 THEN
		CALSPAN! = VOUT!(SENSOROUT!(GNCALIN!, 0)) - VOUT!(SENSOROUT!(OSCALIN!, 0)) 'Adjustment range is +/- x% of +f.s.
						'Output not linear with input
	ELSEIF OSCALIN! = -2 * MAXIN! THEN
		CALSPAN! = MAXOUT! - MINOUT!                   'For bipolar input, unipolar output modules
	ELSE
		CALSPAN! = VOUT!(GNCALIN!) - VOUT!(OSCALIN!)   'Adjustment range is +/- x% of +f.s.
	END IF

	IF OSCALIN! > GNCALIN! THEN
		CALSPAN! = ABS(CALSPAN!)
	END IF

	INRANGE! = MAXIN! - SENSOROUT!(SPECS.MININ!, 0)
	ORANGE! = MAXOUT! - MINOUT!             'Output range (V)
  
	MN$ = MID$(SPECS.MODNAME, 6, 2)

	IF (MN$ = "30" OR MN$ = "31" OR MN$ = "32" OR MN$ = "34" OR MN$ = "35" OR MN$ = "36" OR MN$ = "37" OR MN$ = "47" OR MID$(SPECS.MODNAME, 6, 7) = "41-1794") AND (MID$(SPECS.MODNAME, 6, 7) <> "32-1476") THEN
'            IF MID$(SPECS.MODNAME, 6, 7) = "41-1794" THEN POT1% = 0
			POT1% = 34
			POT2% = 40
'            IF SNM% = 8 OR SNM% = 9 OR SNM% = 11 THEN
'                POT3% = 53
'                ADJ% = 53
'            ELSE
				ADJ% = 34
'            END IF
			TXT% = ADJ% - 11
		'ELSE
		'    POT1% = 34
		'    POT2% = 53
		'    IF SNM% = 8 OR SNM% = 9 OR SNM% = 11 THEN
		'        POT3% = 40
		'        ADJ% = 40
		'    ELSE
		'        ADJ% = 34
		'    END IF
		'    TXT% = ADJ% - 11
		'END IF
	'ELSEIF PCBNO$ = "1211.1212.1214" THEN    'Assume pcb1212
	ELSE
		POT1% = 34
		POT2% = 40
'        IF MID$(SPECS.MODNAME, 6, 2) <> "30" AND MID$(SPECS.MODNAME, 6, 2) <> "31" AND MID$(SPECS.MODNAME, 6, 2) <> "32" AND MID$(SPECS.MODNAME, 6, 2) <> "39" AND MID$(SPECS.MODNAME, 6, 7) <> "32-1476" THEN
'            POT3% = 53
'            ADJ% = 53
'        ELSE
'            ADJ% = 34
'        END IF
'        TXT% = ADJ% - 11
		   
			IF MN$ = "40" OR MN$ = "41" OR SNM% = 8 OR SNM% = 9 OR SNM% = 10 OR SNM% = 11 OR MID$(SPECS.MODNAME, 6, 7) = "32-1476" AND MID$(SPECS.MODNAME, 6, 7) <> "41-1794" THEN
				IF MID$(SPECS.MODNAME, 6, 7) = "32-1476" THEN POT1% = 0
				POT3% = 53
				ADJ% = 53
			ELSE
				ADJ% = 34
			END IF
			TXT% = ADJ% - 11
   
	'ELSE                                'Assume pcb1121, pcb1173
	'    POT1% = 34
	'    POT2% = 53
	'    IF SNM% <> 2 THEN
	'        POT3% = 40
	'        ADJ% = 40
	'    ELSE
	'        ADJ% = 34
	'    END IF
	'    TXT% = ADJ% - 11
	END IF
	  
	IF MN$ = "40" OR MN$ = "41" AND MID$(SPECS.MODNAME, 6, 7) <> "41-1794" THEN POT1% = 0

	IF POT1% <> 0 THEN
		LOCATE 5, POT1%
		PRINT CHR$(233)
	END IF
   
	LOCATE 5, POT2%
	PRINT CHR$(233)
	IF POT3% <> 0 THEN
		LOCATE 5, POT3%
		PRINT CHR$(233)
	END IF
	LOCATE 7
	PRINT TAB(ADJ%); CHR$(24); : PRINT SPC(20);
	PRINT TAB(TXT%); "OFFSET POTENTIOMETER";
   
	LOCATE 12, 10
	PRINT "Please wait..."

	IF CAL% = 2 THEN
		ZERROR! = INITTOL!                  'Offset tolerance for func. test (%)
		TOL! = .0001 * ORANGE!              'Measurement tolerance, 1 pass test
	ELSE
		ZERROR! = CALTOL!                   'Offset calibration tolerance (%)
		TOL! = 0!                           'Measurement tolerance, continuous test
	END IF

	IF SNM% >= 5 AND SNM% <= 7 THEN             'Check if RTD in
		'CALL SETTEST(7)
		MININ! = SENSOROUT!(OSCALIN!, 0)        'Calc. +f.s. ohms
		CALL OHMSET(MININ! - CONTRES!)          'Set -f.s. input
	END IF

	'CALL POWERON(5!)
	  
	DO
		TIME1! = TIMER                          'Start timer
		L% = 0
		  
		IF CAL% = 3 THEN
			LOCATE 11, 10
			PRINT "Measuring module offset error, no adjustment is required."
		ELSE
			LOCATE 12, 10
			PRINT TAB(10); "Measuring input.  Please wait..."
		END IF
		IF SNM% >= 5 AND SNM% <= 7 THEN         'Check if RTD in
			IF CAL% = 0 THEN CALL WRITEDVM("S0", 0)     'Slow reading rate for max accuracy
			MININMEAS! = MEASRES!(MININ!, 3, "") + CONTRES! 'Measure simulated resistor
			'PAUSE (.5)
			CALL POWERON(5)
			CALL PAUSE(2)
		ELSE
			IF L% = 0 THEN CALL POWERON(5)
			IF SNM% = 3 THEN
				PTCV! = PARASITICTCV!(VCJC!)
				IF VCJC! = 99! THEN
					PRINT TAB(10); "Error in OFFSETCAL$ test:"
					PRINT TAB(10); "Vcjc = 99 (error value)!"
					OFF$ = "FAIL"       'Set FAIL status.
					SOUND 1000, .5      'Beep to alert to failure.
					OFFSETCAL$ = OFF$ + "V" 'Set function output to FAIL status with trailing "V" for special formatting.
					CALL FAILSTATUS(OFF$, 15, 10, "Status: ", 30)       'Print test status to screen
					EXIT FUNCTION
				END IF
			ELSE
				PTCV! = 0
			END IF
		   
			MININ! = SENSOROUT!(OSCALIN!, PTCV!) 'Calc. minin volts, meas. Vcjc
'-------------------------------------------------------
		   
			CALL SETDAC(MININ!, 1, MAXINVAR!, 0)                   'Sets DAC
			IF CAL% = 0 OR ABS(MININ!) > 10! THEN      'Always measure high voltage
														'input to get exact reading
				CALL WRITEDVM("S0", 0)                  'Slow reading rate for max accuracy
				CALL WRITEDVM(VODC$, ABS(MININ!))            'Sets meter to read
				CALL LOADMUX(1, CON%)
				CALL LOADMUX(0, CON%)
				CALL LOADMUX(1, CON%)
			   
				MININMEAS! = READDVM!(INRANGE! * .0001) '0.01% tolerance
				WHILE ABS(MININ!) > 10! AND ABS(MININ!) - ABS(MININMEAS!) > 1
														'Power supply current limit tripped
					SL$ = SETPOWER(VINADDR%, ABS(MININ!), FUNC$) 'Set Vin
					MININMEAS! = READDVM!(INRANGE! * .0001)   '0.01% tolerance
				WEND
				CALL LOADMUX(1, COFF%)
			ELSE
				MININMEAS! = MININ!
			END IF
		END IF
		   
		CALL WRITEDVM("S1", 0)       'Medium reading rate
			   
		IF (SNM% >= 3 AND SNM% <= 6) AND LIN% = 0 THEN
			OUTCALC! = VOUT!(MININMEAS! + PTCV!) + CALOS! * ORANGE!
												'Output not linear with input
		ELSE                                'temperature.
			OUTCALC! = VOUT!(SENSORIN!(MININMEAS!, PTCV!)) + CALOS! * ORANGE!
		END IF
		  
		CALL LOADMUX(2, CON%)                'Measure Vout
		CALL LOADMUX(0, CON%)                'Mux erroneously set on Station 3.
											 'Sometimes CH4, sometimes CH8
		CALL LOADMUX(2, CON%)                'Measure Vout
	   
		CALL WRITEDVM(VODC$, OUTCALC! + CALSPAN! * INITTOL! / 100!)
		  
		IF BANDWIDTH! < 1 THEN
			P! = 5 '9
		'ELSEIF BANDWIDTH! < 10 OR MAXACCERR! <= .035 THEN
		'    P! = 2
		ELSE
			P! = 0
		END IF
		CALL PAUSE(P!)                      'Pause for filter settling
	   
		LOCATE 12, 10
		PRINT "Offset Error =";
		PRINT SPC(20);

		DO
			L% = L% + 1
			ERROROUT! = (READDVM!(TOL!) - OUTCALC!) / CALSPAN! * 100!   'Error (%)
			LOCATE 12, 24
			PRINT USING "+###.### %"; ERROROUT!
			   
			LOCATE 15, 10

			IF CAL% > 1 THEN
				CONREADS% = 5
			ELSEIF ABS(ERROROUT!) < ZERROR! THEN
				SOUND 200, .5
				PRINT "Stop turning offset potentiometer          "
				CONREADS% = CONREADS% + 1
			ELSEIF ERROROUT! < 0 THEN
				IF DIRO% = 1 THEN
					DIREC$ = "CLOCKWISE        "
				ELSE
					DIREC$ = "COUNTER-CLOCKWISE"
				END IF

				PRINT "Turn offset potentiometer "; DIREC$
				CONREADS% = 0
			ELSE
				IF DIRO% = 1 THEN
					DIREC$ = "COUNTER-CLOCKWISE"
				ELSE
					DIREC$ = "CLOCKWISE        "
				END IF

				PRINT "Turn offset potentiometer "; DIREC$
				CONREADS% = 0
			END IF

			LOCATE 20, 10
			a$ = INKEY$
			IF UCASE$(a$) = "T" THEN
				PRINT TAB(10); "Trouble Shooting Mode"
				CALL WRITEDVM("*", OUTCALC!)
				CALL CONTINUE
				CALL WRITEDVM("*T2S1", 0)          'Initialize Fluke meter
				LOCATE 20, 10
				PRINT SPC(22);
			ELSEIF UCASE$(a$) = "C" THEN
				CONREADS% = 5
			END IF
												   're-measure input
												   'once every 200 cycles
			CALL PAUSE(.1)                         'Slow down loop
		LOOP WHILE CONREADS% < 5 AND (L% < 200 OR CONREADS% < 5)
		CALL LOADMUX(2, COFF%)
		IF SNM% >= 5 AND SNM% <= 7 AND CONREADS% < 5 THEN CALL POWERON(0)
	LOOP WHILE CONREADS% < 5

	IF CAL% <> 3 THEN
		IF ABS(ERROROUT!) <= ZERROR! THEN
			OFF$ = "PASS"
		ELSE
			OFF$ = "FAIL"
			SOUND 1000, .5
		END IF

		'LOCATE 15, 10
		'PRINT "Status: "; OFF$;
		'CALL FAILSTATUS (OFF$, 15, 10, "Status: ")     'Print test status to screen
		
		LOCATE 15, 10
		PRINT SPC(31);
		PRINT TAB(10); "Offset calibration error is";
		PRINT TAB(50); USING " +###.### %"; ERROROUT!
		PRINT TAB(10); "Max. offset calibration error is";
		PRINT TAB(50); USING "+/-##.### %"; ZERROR!

		CALL FAILSTATUS(OFF$, 15, 10, "Status: ", 30)       'Print test status to screen
	  
	ELSE
		OFF$ = "PASS"
	END IF
	 
	OFFSETCAL$ = OFF$ + STR$(ERROROUT!) + "2"
   
	CALL RESETTH                                    'Reset the test head
	CALL PAUSE(.2)

END FUNCTION

SUB ONESHOTTEST
	  
		'Provide a continuous strobe to test one-shot pulse width
		'Trigger line (E07) is on '123 pin 1, S/H pulse is on pin 13 for TE1005.
		'Trigger line (E06) is on '123 pin 1, S/H pulse is on pin 13 for TE1012.

		CALL GETSPECS

		SNM% = SENSORNUM%

		CLS
		LOCATE 10, 10
	  
		IF TE$ = "TE1005" THEN
			PRINT TE$
			PRINT "Trigger line (E07) is on '123 pin 1, S/H pulse is on pin 13."
		ELSE                'TE1012
			PRINT TE$
			PRINT "Trigger line (E06) is on '123 pin 1, S/H pulse is on pin 13."
		END IF
		PRINT "Required pulse width is 220ms."

		PRINT
		PRINT "Press any key to exit test"

  DO
		IF SNM% >= 5 AND SNM% <= 7 THEN         'Check if resistance in
				CB0VAL% = CB0VAL% AND &HBF      '1 0 1 1  1 1 1 1
		ELSE
				CB0VAL% = CB0VAL% AND &H7F      '0 1 1 1  1 1 1 1
		END IF
		CALL SETTH(CB0VAL%, CB0%)               'set step relay, k7
												'start one-shot 220ms pulse
	
		CALL PAUSE(.5)                          'wait for pulse
	  
		IF SNM% >= 5 AND SNM% <= 7 THEN         'Check if resistance in
				CB0VAL% = CB0VAL% OR &H40       '0 1 0 0  0 0 0 0
		ELSE
				CB0VAL% = CB0VAL% OR &H80       '1 0 0 0  0 0 0 0
		END IF
		CALL SETTH(CB0VAL%, CB0%)               'reset test
	 
		I$ = INKEY$
  LOOP WHILE I$ = ""

END SUB

FUNCTION OPENIN$
	  
	MINOUT! = SPECS.MINOUT                  'Output voltage (V)
	MAXOUT! = SPECS.MAXOUT
	MININ! = SENSOROUT!(SPECS.MININ!, 0)    'Approximate -f.s. in, not including
											'parasitic TC
	RCONV! = SPECS.RCONV
	TESTSPECMIN! = SPECS.VOPENINMIN!
	TESTSPECMAX! = SPECS.VOPENINMAX!
	ORANGE! = MAXOUT! - MINOUT!
	SNM% = SENSORNUM%

	CLS
	TESTTITLE$ = "Open Input Response Test"
	CALL HEADERB(TESTTITLE$)
	LOCATE 10, 10
	 
	IF TESTSPECMIN! = 0 THEN
		PRINT "This test is not performed on model "; SPECS.MODNAME
		EXIT FUNCTION
	ELSE
		PRINT "Testing, please wait."
	END IF

	IF LEFT$(SPECS.MODNAME, 12) = "SCM5BPT-1516" THEN
		CALL SETDAC(10!, 1, MAXINVAR!, 0)                      'Over-range input
	ELSEIF RCONV! <> 0 THEN
		CALL SETDAC(0!, 1, MAXINVAR!, 0)                       'Short inputs, simulating
													'loss of input current.
	ELSEIF SNM% >= 5 AND SNM% <= 7 THEN             'Check if RTD in
		CALL OHMSET(1E+10)                          'Open all relays
		CALL SETTEST(3)                             'Measure contact resistance
	ELSE
		CALL SETDAC(MININ!, 1, MAXINVAR!, 0)                   'Set -f.s. input, zero
													'input underranges some modules

		CALL PAUSE(.2)
													'Remove short on inputs
		CALL SETTH(CB0VAL% OR &H8, CB0%)            '0 0 0 0  1 0 0 0
		CALL SETTH((CB1VAL% OR &HC0), CB1%)         'Clear R/2R ladder
		CALL SETTH((CB2VAL% OR &HFF), CB2%)
	END IF

	CALL PAUSE(2.5)                                 'Wait 2.5s (spec is 10s)
	CALL LOADMUX(2, CON%)                           'Measure Vout
	CALL WRITEDVM(VODC$, MAXOUT!)
	VO! = READDVM!(.001)                            'Output voltage (V)
													'Use 1mV tolerance in case
													'output is still changing.
	CALL LOADMUX(2, COFF%)

	IF VO! >= TESTSPECMIN! AND VO! <= TESTSPECMAX! THEN
		OTC$ = "PASS"
	ELSE
		OTC$ = "FAIL"
		SOUND 1000, .5
	END IF

	LOCATE 10, 10
	PRINT SPC(20);
	PRINT TAB(10); "Open input response is";
	PRINT TAB(50); USING "  ##.## V"; VO!
	PRINT TAB(10); "Required response is";
	PRINT TAB(50); USING "+##.## V to +##.## V"; TESTSPECMIN!; TESTSPECMAX!

	CALL FAILSTATUS(OTC$, 10, 10, "Status: ", 30)       'Print test status to screen

	OPENIN$ = OTC$ + STR$(VO!) + "1"
	 
	CALL RESETTH                                    'Reset the test head
	CALL PAUSE(.2)

END FUNCTION

FUNCTION OUTNOISE$
	'8842A displays a non-zero reading of < 300 digits in the 200mVAC range.
	'This equates to 300uVrms.  Typical readings are 150uVrms, but testing of
	'several meters shows readings from 90uVrms to 900uVrms.  Readings are not
	'always consistent between the front panel and rear panel input terminals.
	'As long as the voltage being measured is 1000 counts or more (>=1mVrms), the
	'reading will be within rated accuracy.  However, this is not the case for the
	'narrow bandwidth signal conditioners and transmitters.
	'The displayed reading is the sum of the squares of the signal, the RMS converter
	'error and the internally generated noise.
	'i.e.  Vn,RMS = sqr(signal(mVrms)^2 + 0.300^2)
	'or signal(mVrms) = SQR(Vn,RMS^2 - 0.300^2)
	'Assume the typical non-zero error is 200 digits
	'This error should also be taken into account when using low value Vrms readings
	'to determine filter performance (frequency response test).
	'Some 8842A meters read 0 digits of noise on the 2VAC scale (80 digits max).
	'In these cases, measured signal conditioner output noise matches that made
	'with other test equipment.
	'The -3dB bandwidth for AC measurements is 300KHz.  Accuracy is specified for
	'signals with frequency components up to 100KHz.
	'A 100KHz pole has been added to the input leads at the 8842A to eliminate
	'high frequency pick-up and switching spike amplification from the computers
	'and long signal lines.
	'Crest factors beyond 3.0 can exceed the 8842A's dynamic range limitations and
	'cause large errors.  Large crest factors are typical of waveforms with spikes.
	'Use caution when measuring waveforms with significant spikes in bandwidths
	'less than 300KHz.
	'
	MININ! = SENSOROUT!(SPECS.MININ, 0)         'Determine min in
	MAXIN! = SENSOROUT!(SPECS.MAXIN, 0)         'Determine max in
	IEXC! = SPECS.IEXC / 1000000!               'Convert to A
	OSCALIN! = SPECS.OSCALIN                    'Module input for offset calibration
	SPEC! = SPECS.OUTNOISE                      'uVrms
   
	INRANGE! = MAXIN! - MININ!
	ORANGE! = SPECS.MAXOUT - SPECS.MINOUT

	CLS
	TESTTITLE$ = "Output Noise Test"
	CALL HEADERB(TESTTITLE$)
	LOCATE 10, 10
	PRINT "Testing, please wait."

	SNM% = SENSORNUM%

	IF SNM% >= 5 AND SNM% <= 7 THEN             'Check if resistance in
		CALL OHMSET(SENSOROUT!(OSCALIN!, 0))    'Set -f.s. input
		VGAIN! = ORANGE! / (INRANGE! * IEXC!)   'Gain in V/V
	ELSE
		IF SNM% = 3 THEN
			PTCV! = PARASITICTCV!(VCJC!)
			IF VCJC! = 99! THEN
				PRINT TAB(10); "Error in OUTNOISE$ test:"
				PRINT TAB(10); "Vcjc = 99 (error value)!"
				VNOISE$ = "FAIL"        'Set FAIL status.
				SOUND 1000, .5      'Beep to alert to failure.
				OUTNOISE$ = VNOISE$ + "V"   'Set function output to FAIL status with trailing "V" for special formatting.
				CALL FAILSTATUS(VNOISE$, 10, 10, "Status: ", 30)        'Print test status to screen
				EXIT FUNCTION
			END IF
		END IF
		IF (SNM% = 1 OR SNM% = 10) AND OSCALIN! > 10 THEN
			CALL SETDAC(10, 1, MAXINVAR!, 0) 'Set to +10 input
		ELSEIF (SNM% = 1 OR SNM% = 10) AND OSCALIN! < -10 THEN
			CALL SETDAC(-10, 1, MAXINVAR!, 0) 'Set to -10 input
		ELSE
			CALL SETDAC(SENSOROUT!(OSCALIN!, PTCV!), 1, MAXINVAR!, 0) 'Set -f.s. input
		END IF
		VGAIN! = ORANGE! / INRANGE!             'Gain in V/V
	END IF

	CALL LOADMUX(2, CON%)                       'Measure Vout
	CALL WRITEDVM(VOAC$, SPEC! / 1000000!)      'Sets Fluke

	IF VGAIN! > 600 THEN NUMMEAS% = 3 ELSE NUMMEAS% = 1
	VRMS! = 0

	FOR L% = 1 TO NUMMEAS%
		VRMS! = VRMS! + READDVM!(.04 * SPEC! / 1000000!)    'Output noise (Vrms)
	NEXT

	VRMS! = VRMS! / NUMMEAS%

	IF VRMS! > .0002 THEN
		VRMS! = SQR(VRMS! ^ 2 - .0002 ^ 2)  'Account for meter zero-input error
	END IF
	   
	CALL LOADMUX(2, COFF%)
	   
	VRMS! = VRMS! * 1000000!                    'Convert to uV
	IF VRMS! <= SPEC! THEN
		VNOISE$ = "PASS"
	ELSE
		VNOISE$ = "FAIL"
		SOUND 1000, .5
	END IF

	'LOCATE 10, 10
	'PRINT "Status: "; VNOISE$;
	'CALL FAILSTATUS (VNOISE$, 10, 10, "Status: ")      'Print test status to screen
	
	LOCATE 10, 10
	PRINT SPC(20);
	PRINT TAB(10); "Measured output noise is";
	PRINT TAB(50); USING "##### uV RMS"; VRMS!
	PRINT TAB(10); "Maximum output noise is";
	PRINT TAB(50); USING "##### uV RMS"; SPEC!

	CALL FAILSTATUS(VNOISE$, 10, 10, "Status: ", 30)        'Print test status to screen

	OUTNOISE$ = VNOISE$ + STR$(VRMS!) + "0"
	  
	CALL RESETTH                                    'Reset the test head
	CALL PAUSE(.2)
	   
END FUNCTION

FUNCTION OUTSWITCH$
	'This routine tests the operation of the module output switch and
	'verifies that the switch resistance is within specification.
	'** 03/03/06 - Leakage current test for TOSHIBA models has been removed
	'** This test was required when '4053 o/p switch was used.
	'** The new o/p switch DG417 has the max leakage current spec of 5nA @85C, 0.25nA typ. @25C.
	'** Additionally, the test was causing false failure because open input would peg the signal to the rail and would not settle during LIN test.
	'
	LIN% = SPECS.LINEARIZED
	MININ! = SPECS.MININ
	MAXIN! = SPECS.MAXIN
	MINOUT! = SPECS.MINOUT
	MAXOUT! = SPECS.MAXOUT
	RES! = SPECS.OUTRES                     'Switch resistance in ohms
	RLOAD! = 2000                           '2Kohm load resistor
	RSWITCH! = 1000!                        'Dummy value, indicates failure
	TOL! = .15                              '15% reading tolerance allows
											'for o.s. & gain not calibrated.
	CONTRES! = .1       'PWR 2015-05-29: Hardcoded value added for Cu RTD input module.
'    VOPENINMAX! = SPECS.VOPENINMAX
'    ILEAKMAX! = 1E-08                       '10nA max output leakage current
											'with open input.  SCM5B34,35,36
	ORANGE! = MAXOUT! - MINOUT!             'Output range (V)
	INRANGE! = MAXIN! - MININ!              'Input range
	SNM% = SENSORNUM%

	CLS
	TESTTITLE$ = "Output Switch Test"
	CALL HEADERB(TESTTITLE$)
	LOCATE 10, 10
	PRINT "Testing, please wait."
	
	IF SNM% = 3 THEN
		PTCV! = PARASITICTCV!(VCJC!)
		IF VCJC! = 99! THEN
			PRINT TAB(10); "Error in OUTSWITCH$ test:"
			PRINT TAB(10); "Vcjc = 99 (error value)!"
			OUTSW$ = "FAIL"     'Set FAIL status.
			SOUND 1000, .5      'Beep to alert to failure.
			OUTSWITCH$ = OUTSW$ + "V"   'Set function output to FAIL status with trailing "V" for special formatting.
			CALL FAILSTATUS(OUTSW$, 10, 10, "Status: ", 30)         'Print test status to screen
			EXIT FUNCTION
		END IF
	END IF
 
	IF MAXOUT! > 5 THEN                     '2K ohm load puts module in current limit
		XFERFN! = ORANGE! / INRANGE!
		YINT! = MINOUT! - MININ! * XFERFN!      'Y-intercept
		MAXOUT! = 5!
		X5OUT! = (MAXOUT! - YINT!) / XFERFN!
		MAXIN! = SENSOROUT!(X5OUT!, PTCV!)      'Test at 1/2 f.s.
		  
		IF SNM% = 3 AND LIN% = 0 THEN            'Output not linear with input temperature
			MAXOUT! = VOUT!(MAXIN!)
		END IF
		   
	ELSEIF MAXOUT! > 4.5 THEN                       '06/01/06  MR
			XFERFN! = ORANGE! / INRANGE!
			YINT! = MINOUT! - MININ! * XFERFN!      'Y-intercept
			MAXOUT! = 4.5
			X4OUT! = (MAXOUT! - YINT!) / XFERFN!
			MAXIN! = SENSOROUT!(X4OUT!, PTCV!)      'Test at 90% f.s.
  
	ELSE
		MAXIN! = SENSOROUT!(SPECS.MAXIN, PTCV!)
		IF ABS(VOPENINMAX! - MAXOUT!) < 1 THEN     'Output clamp is close to
			MAXIN! = .9 * MAXIN!                'max. output.  For uncalibrated
			MAXOUT! = MAXOUT! * .9              'module, test at 90% span.
		END IF
	END IF

	VLCALC! = MAXOUT! * RLOAD! / (RLOAD! + RES!)


	IF SNM% >= 5 AND SNM% <= 7 THEN             'Check if resistance in
		'CALL OHMSET(MAXIN!)                     'Set +f.s. input
		CALL OHMSET(MAXIN! - CONTRES!)          'Set +f.s. input (updated PWR 2015-05-29).
	ELSE
		CALL SETDAC(MAXIN!, 1, MAXINVAR!, 0)               'Sets DAC
	END IF
   
	CALL WRITEDVM(VODC$, MAXOUT!)
	CALL LOADMUX(2, CON%)                       'Vout
	DO
		L% = L% + 1                             'Make sure module is out of saturation
												'34, 35-xx may saturate during IEXC test.
		VOUTNL! = READDVM!(.0001)               'Measure Vout
	LOOP WHILE ABS(VOUTNL! - MAXOUT!) > ORANGE! * .2 AND L% < 10
	 
	VOUTREQ! = MAXOUT!
	OUTMEAS! = VOUTNL!
	OUTSW$ = "PASS"

	IF ABS(VOUTNL! - MAXOUT!) > MAXOUT! * TOL! THEN
		OUTSW$ = "FAIL"
	ELSE                                        'Enable output load
		IF TE$ = "TE1012" THEN                  'TE1012
			CB0VAL% = CB0VAL% AND &H7F          '0 1 1 1  1 1 1 1
		ELSE                                    'TE1005
			CB0VAL% = CB0VAL% AND &HBF          '1 0 1 1  1 1 1 1
		END IF
		CALL SETTH(CB0VAL%, CB0%)               '**RESETS MUX
		CALL LOADMUX(2, CON%)                   'Vout
		VOUTL! = READDVM!(.001)                 'Measure Vout
		IF ABS(VOUTL! - VLCALC!) > VLCALC! * TOL! THEN
			OUTSW$ = "FAIL"
			VOUTREQ! = VLCALC!
			OUTMEAS! = VOUTL!
		ELSE
			RSWITCH! = (VOUTNL! - VOUTL!) * RLOAD! / VOUTL!
			IF RSWITCH! > RES! THEN
				RSTAT$ = "FAIL"
			ELSE
				RSTAT$ = "PASS"
				CALL ENABLE(COFF%)              'Disable output switch
				CALL LOADMUX(2, CON%)           'Vout
				VOUTDIS! = READDVM!(.001)
				IF ABS(VOUTDIS!) > MAXOUT! * TOL! THEN
					OUTSW$ = "FAIL"
					VOUTREQ! = 0!
					OUTMEAS! = VOUTDIS!
				END IF
			END IF
		END IF
	END IF
	 
	'LOCATE 10, 10
	'PRINT "Switch Operation Status: "; OUTSW$
	'CALL FAILSTATUS (OUTSW$, 12, 10, "Status: ")       'Print test status to screen
	
	LOCATE 11, 10
	PRINT TAB(10); "Measured output voltage is";
	PRINT TAB(50); USING "+##.## V"; OUTMEAS!
	PRINT TAB(10); "Required output voltage is";
	PRINT TAB(50); USING "+##.## +/- #.## V"; VOUTREQ!; MAXOUT! * TOL!

	CALL FAILSTATUS(OUTSW$, 10, 10, "Status: ", 30)         'Print test status to screen

	IF OUTSW$ = "FAIL" THEN
		SOUND 1000, .5
		PRINT
		PRINT TAB(10); "Check for correct signals on output switch."
	END IF
   
	N% = 15
	DO
		LASTCHAR$ = MID$(SPECS.MODNAME, N%, 1)
		N% = N% - 1
	LOOP WHILE LASTCHAR$ = " "
   
'    IF SNM% >= 5 AND SNM% <= 7 AND UCASE$(LASTCHAR$) = "T" AND MID$(SPECS.MODNAME, 9, 4) <> "1502" THEN 'Check if TOSHIBA resistance in
'        PRINT SPECS.MODNAME
'        PRINT "INSIDE LOOP"
'        PAUSE (10)
'        CALL OHMSET(1E+10)                      'open input
'        IOUTLEAK$ = "PASS"
'        CB0VAL% = CB0VAL% OR &H80               '1 0 0 0  0 0 0 0
'        CALL SETTH(CB0VAL%, CB0%)               'Disable output load
'        CALL ENABLE(COFF%)                      'Disable output switch
'        CALL LOADMUX(2, CON%)                   'Vout
'        IOUT! = READDVM!(.001) / 4700000!
'        IF ABS(IOUT!) > ILEAKMAX! THEN
'            OUTSW$ = "FAIL"
'            RSWITCH! = 1000!
'            SOUND 1000, .5
'            PRINT
'            PRINT TAB(10); "Measured switch leakage current is";
'            PRINT TAB(50); USING " #### nA"; IOUT! * 1E+09
'            PRINT TAB(10); "Required switch resistance is";
'            PRINT TAB(50); USING "< ### nA"; ILEAKMAX! * 1E+09
'            PRINT
'            PRINT TAB(10); "Replace the output switch."
'            CALL CONTINUE
'        END IF
'    END IF
   
	IF RSWITCH! <> 1000! THEN                   'Switch resistance was measured

		'PRINT TAB(10); "Switch Resistance Status: "; RSTAT$
		'CALL FAILSTATUS (RSTAT$, 10, -1, "Switch Resistance Status: ")     'Print test status to screen
		
		LOCATE 15, 10
		PRINT TAB(10); "Measured switch resistance is";
		PRINT TAB(50); USING " #### ohms"; RSWITCH!
		PRINT TAB(10); "Required switch resistance is";
		PRINT TAB(50); USING "< ### ohms"; RES!

		CALL FAILSTATUS(RSTAT$, 14, 10, "Switch Resistance Status: ", 30)       'Print test status to screen

		IF RSTAT$ = "FAIL" THEN
			OUTSW$ = "FAIL"                 'Set overall test status
			SOUND 1000, .5
			PRINT
			PRINT TAB(10); "Replace the output switch."
		END IF
	END IF
   
	IF TE$ = "TE1012" THEN                          'TE1012
		CB0VAL% = CB0VAL% OR &H80                   '1 0 0 0  0 0 0 0
	ELSE                                            'TE1005
		CB0VAL% = CB0VAL% OR &H40                   '0 1 0 0  0 0 0 0
	END IF
	CALL SETTH(CB0VAL%, CB0%)                       'Disable output load
	CALL LOADMUX(2, COFF%)
	CALL ENABLE(CON%)                               'Enable output switch
	OUTSWITCH$ = OUTSW$ + STR$(RSWITCH!) + "0"      'append # decimal places

	CALL RESETTH                                    'Reset the test head
	CALL PAUSE(.2)

END FUNCTION

FUNCTION PARASITICTCV! (VCJC!)
	'Measures CJC input to module and calculates compensation voltage to
	'be added to module input.
	'
	SENSOR$ = SPECS.SENTYPE
	TCTYPE$ = LEFT$(SENSOR$, 1)
  
	SEEBECK! = (TCVOLTS!(50!, TCTYPE$) - TCVOLTS!(0!, TCTYPE$)) / 50!
	VTC25C! = TCVOLTS!(25!, TCTYPE$)        'Calculate TC voltage @ 25C
	CALL LOADMUX(4, CON%)                   'Measure test head CJC output
	CALL WRITEDVM(VODC$, .5)                'Vcjc(25C) = 0.5100V
	VCJC! = READDVM(.0001)
	CALL LOADMUX(4, COFF%)
	IF ABS(VCJC! - .51) > .0125 THEN        '+/- 3C error for malfunction
		SOUND 1000, .5
		PRINT
		PRINT TAB(10); "Error in PARASITICTCV! function:"
		PRINT TAB(10); "Test head temperature sensor malfunction"
		PRINT TAB(10); "or module not installed."
		PRINT TAB(10); "Vcjc = "; VCJC!; "V"
		PRINT
		PRINT TAB(10); "Press any key to continue."
		IF UCASE$(KEYBDIN$) = "C" THEN
			CLS
			LOCATE 5, 20
			PRINT "TEST HEAD TEMPERATURE SENSOR CALIBRATION"
			CALL LOADMUX(4, CON%)           'Measure test head CJC output
			CALL WRITEDVM(VODC$, .5)        'Vcjc(25C) = 0.5100V
			DO
				VCJCERR! = READDVM(.0001) - .51
				LOCATE 10, 20
				PRINT USING "Vcjc error = ###.# mV"; VCJCERR! * 1000
				IF VCJCERR! < 0 THEN
					LOCATE 12, 20
					PRINT "Turn potentiometer on XEV board COUNTER-CLOCKWISE."
				ELSE
					PRINT "Turn potentiometer on XEV board CLOCKWISE."
				END IF
			LOOP UNTIL ABS(VCJC! - .51) < .0025
			PRINT
			PRINT TAB(10); "Test head temperature sensor is now calibrated."
			CALL CONTINUE
			CALL LOADMUX(4, COFF%)
		ELSE
			VCJC! = 99!
			PARASITICTCV! = 0!
			EXIT FUNCTION
		END IF
	END IF
   
	IF LEFT$(SPECS.MODNAME, 13) = "SCM5B47K-1820" OR LEFT$(SPECS.MODNAME, 13) = "SCM5B47K-1781" OR LEFT$(SPECS.MODNAME, 13) = "SCM5B47K-1782" THEN    'Models used with SCMX1508 custom CJC
		AMBTEMPDIFF! = ((VCJC! - .51) / -.0025) + .4   'CJC Compensation for SCMX1508 at 0 deg C
	ELSE
		AMBTEMPDIFF! = (VCJC! - .51) / -.0025  'Temp. difference from 25C for standard CJC.
	END IF

	'PARASITICTCV! = TCVOLTS!(25 + AMBTEMPDIFF!, TCTYPE$)
	PARASITICTCV! = VTC25C! + AMBTEMPDIFF! * SEEBECK!  'Parasitic TC voltage
	
	'Force error value for debug (PWR 2014-11-12).
	IF FORCEVCJCFAIL% = 1 THEN
		PARASITICTCV! = 99!
	END IF
	
END FUNCTION

SUB POWERON (VOLTAGE!)
	
		IF TE$ = "TE1012" THEN
		  
			IF VOLTAGE! = 5.25 THEN
				MASK% = 0               '0 0 0 0  0 0 0 0
			ELSEIF VOLTAGE! = 0 THEN
				MASK% = &H8             '0 0 0 0  1 0 0 0
			ELSEIF VOLTAGE! = 4.75 THEN
				MASK% = &H10            '0 0 0 1  0 0 0 0
			ELSE                            'Voltage = +5.0V
				MASK% = &H18            '0 0 0 1  1 0 0 0
			END IF

			CB0VAL% = (CB0VAL% AND &HE7) OR MASK%    '1 1 1 0  0 1 1 1
			CALL SETTH(CB0VAL%, CB0%)
	  
		ELSE                            'TE1005
		  
			IF VOLTAGE! = 5.25 THEN
				MASK% = 0               '0 0 0 0  0 0 0 0
			ELSEIF VOLTAGE! = 0 THEN
				MASK% = 1               '0 0 0 0  0 0 0 1
			ELSEIF VOLTAGE! = 4.75 THEN
				MASK% = 2               '0 0 0 0  0 0 1 0
			ELSE                            'Voltage = +5.0V
				MASK% = 3               '0 0 0 0  0 0 1 1
			END IF

			CB1VAL% = (CB1VAL% AND &HFC) OR MASK%    '1 1 1 1  1 1 0 0
			CALL SETTH(CB1VAL%, CB1%)
   
		END IF
	  
		CALL WRITEDVM(VODC$, 5!)
		CALL LOADMUX(7, CON%)   'Select module supply voltage channel
		REPS% = 0

		IF VOLTAGE! = 0 THEN
			VSTOL! = 2
		ELSE
			VSTOL! = .05
		END IF

		DO
			REPS% = REPS% + 1
			ERRORV! = READDVM!(0!) - VOLTAGE!
		LOOP WHILE ABS(ERRORV!) > VSTOL! AND REPS% < 10

		IF REPS% = 10 THEN
			CLS
			LOCATE 10, 10
			PRINT USING "Measured power supply voltage is +#.## V."; VOLTAGE! + ERRORV!
			PRINT TAB(10); USING "Required power supply voltage is +#.## V."; VOLTAGE!
			PRINT TAB(10); "Please check the test head connections."
			PRINT TAB(10); "If the problem continues, notify engineering."
			SOUND 1000, .5
			'CALL RESETTH
			CALL CONTINUE
		END IF
	  
		CALL LOADMUX(7, COFF%)

		VOLTAGE! = VOLTAGE! + ERRORV!           'Pass actual Vs back

		'IF VOLTAGE! = 5! THEN CALL PAUSE(2!)    'Allow module output to settle.
		'                                        'Usually power was previously off.

END SUB

SUB REMEXCPIN (PINSTAT%)

'PINSTAT%=0, PIN IS NOT INSTALLED. RECONNECT TO TEST HEAD
'PINSTAT%=1, PIN IS INSTALLED. DISCONNECT FROM TEST HEAD

	IF PINSTAT% = 0 THEN
		CLS
		LOCATE 5, 5
		COLOR 14, 0, 0
		PRINT "CONNECT THE +EXC WIRE TO THE TEST HEAD"
		COLOR 15, 0, 0
		PRINT
		PRINT "Test heads with PCB1261, reconnect the +EXC wire to the P1 pin 6 location."
		PRINT
		PRINT "Test heads with the XEV board, remove the Kapton tape from the +EXC pin."
		PRINT "Reinstall the pin to the XEV board before exiting."
		CALL CONTINUE
		COLOR 11, 0, 0
	END IF
  
	IF PINSTAT% = 1 THEN
		CLS
		LOCATE 5, 5
		COLOR 14, 0, 0
		PRINT "THIS MODULE REQUIRES THAT THE +EXC PIN IS DISCONNECTED FROM THE TEST HEAD"
		COLOR 15, 0, 0
		PRINT
		PRINT "Test heads with PCB1261, remove the +EXC wire from the P1 pin 6 location."
		PRINT
		PRINT "Test heads with the XEV board, find the +EXC pin and cover with Kapton tape."
		PRINT "Reinstall the pin to the XEV board and begin testing the units."
		CALL CONTINUE
		COLOR 11, 0, 0
	END IF

END SUB

SUB REPORT (STATUS$(), TSPEC$())
	'Sub to create main test results section of datasheet. Removed code to print to file
	'since that is now accomplished by the "DATASHEETWRITE" sub. The datasheet can still be
	'sent to two places (screen and printer), so when updating remember to make any
	'changes to both the "PRINT" and "LPRINT" sections.
	'
	'Output format
	'1        10        20        30        40        50        60        70        80
	'         |         |         |         |         |         |         |         |
	'           Parameter         Measured Value*      Specification      Status
	'    =======================  ===============  =====================  ======
	'                               ###### uVrms   ##### to ##### uVrms    PASS
	'
	SNM% = SENSORNUM%
	RESTORE LINES
	  
	CLS
	PRINT TAB(31); "FINAL TEST RESULTS"
	PRINT
	PRINT TAB(12); "Parameter"; TAB(30); "Measured Value"; TAB(51); "Specification ";
	PRINT TAB(70); "Status"
	PRINT TAB(5); "======================="; TAB(30); "===============";
	PRINT TAB(47); "====================="; TAB(70); "======"
   
	IF PON% = 1 THEN
		LPRINT
		LPRINT TAB(31); "FINAL TEST RESULTS"
		LPRINT
		LPRINT TAB(12); "Parameter"; TAB(30); "Measured Value"; TAB(51); "Specification ";
		LPRINT TAB(70); "Status"
		LPRINT TAB(5); "======================="; TAB(30); "===============";
		LPRINT TAB(47); "====================="; TAB(70); "======"
	END IF
	  
	'FOR X = 1 TO 21
	FOR X = 1 TO MAXSTATUSINDEX
		READ a$, B$
		IF LEN(STATUS$(X)) > 4 THEN         'Check for test data
			PRINT TAB(5); a$;
			IF PON% = 1 THEN LPRINT TAB(5); a$;
			   
			'                      4 char.      ? char          1 char.
			DATALEN% = LEN(STATUS$(X))
			NUMDATA! = VAL(MID$(STATUS$(X), 5, DATALEN% - 5))
								'print using requested # of decimal places
			IF X = 14 AND SNM% = 7 THEN
				B$ = "ohm/ohm"          'Set proper units
			ELSEIF X = 15 AND (SNM% = 5 OR SNM% = 6) THEN
				B$ = "C/V"
			END IF
			IF RIGHT$(STATUS$(X), 1) = "0" THEN
				PRINT TAB(31); USING "###### &"; NUMDATA!; B$;
				IF PON% = 1 THEN LPRINT TAB(31); USING "###### &"; NUMDATA!; B$;
			ELSEIF RIGHT$(STATUS$(X), 1) = "1" THEN
				PRINT TAB(31); USING "####.# &"; NUMDATA!; B$;
				IF PON% = 1 THEN LPRINT TAB(31); USING "####.# &"; NUMDATA!; B$;
			ELSEIF RIGHT$(STATUS$(X), 1) = "2" THEN
				PRINT TAB(31); USING "###.## &"; NUMDATA!; B$;
				IF PON% = 1 THEN LPRINT TAB(31); USING "####.# &"; NUMDATA!; B$;
			ELSEIF RIGHT$(STATUS$(X), 1) = "3" THEN
				PRINT TAB(31); USING "##.### &"; NUMDATA!; B$;
				IF PON% = 1 THEN LPRINT TAB(31); USING "##.### &"; NUMDATA!; B$;
			ELSEIF RIGHT$(STATUS$(X), 1) = "4" THEN
				PRINT TAB(31); USING "#.#### &"; NUMDATA!; B$;
				IF PON% = 1 THEN LPRINT TAB(31); USING "#.#### &"; NUMDATA!; B$;
			ELSEIF RIGHT$(STATUS$(X), 1) = "V" THEN     'PWR 2014-10-19: Added for Vcjc failures.
				PRINT TAB(31); LEFT$(STATUS$(X), 4); " Vcjc";
				IF PON% = 1 THEN LPRINT TAB(31); LEFT$(STATUS$(X), 4); " Vcjc";
			END IF
			 
			SPECLEN% = LEN(TSPEC$(X))
			PRINT TAB(60 - SPECLEN%); TSPEC$(X);
			PRINT TAB(61); B$;
			'PRINT TAB(71); LEFT$(STATUS$(X), 4)
			'IF LEFT$(STATUS$(X), 4) = "FAIL" THEN
			'   COLOR 12, 0 'Red on black background for fails
			'END IF
			IF LEFT$(STATUS$(X), 4) = "FAIL" THEN
				COLOR 12, 0 'Test value text color to light red
			ELSE
				COLOR 10, 0 'Test value text color to light green
			END IF
			PRINT TAB(71); LEFT$(STATUS$(X), 4)
			COLOR 11, 0     'Light cyan (blue) on black background
			
			IF PON% = 1 THEN
				LPRINT TAB(60 - SPECLEN%); TSPEC$(X);
				LPRINT TAB(61); B$;
				LPRINT TAB(71); LEFT$(STATUS$(X), 4)
			END IF

			'IF TOG% = 1 THEN PON% = 1               'Reset printer on
		END IF
	NEXT

END SUB

SUB RESETTH
	  
'****** reset the voltage or RTD test head to a known, desired condition.
	  
	SNM% = SENSORNUM%
	OSCALIN! = SPECS.OSCALIN                 'Module input for offset calibration
	  
	IF SNM% >= 5 AND SNM% <= 7 THEN 'Check if resistance in
		CALL OHMSET(SENSOROUT!(OSCALIN!, 0))    'Set -f.s. input
		CALL SETTEST(2)                  'Standard operation
	ELSE
		IF SENSOROUT!(SPECS.MAXIN, 0) > 10! THEN
'****** Remove high voltage from +/-IN
			SL$ = SETPOWER(VINADDR%, 999!, LOOPOFF$)
			CB3VAL% = CB3VAL% OR &HC0       '1 1 0 0  0 0 0 0
			CALL SETTH(CB3VAL%, CB3%)
		END IF
		CALL SETDAC(0!, 1, MAXINVAR!, 0)                   'Clear attenuator, short module inputs
	END IF

END SUB

FUNCTION SENSORIN! (MEASIN!, PTCV!)

		'Calculates simulated sensor input based on the measured ATE module input
		'Inputs;    MEASIN! = process variable input to sensor, i.e. temperature, voltage, current
		'           PTCV! = measured value of parasitic TC voltage

		SENSOR$ = SPECS.SENTYPE
		SNM% = SENSORNUM%
							 
								'Voltage, Potentiometer, Full Bridge, DC LVDT or Half Bridge in
		IF SNM% = 1 OR SNM% = 7 OR SNM% = 8 OR SNM% = 10 OR SNM% = 11 THEN
			SENSORIN! = MEASIN!
		ELSEIF SNM% = 2 OR SNM% = 9 THEN                'mA in
			RCONV! = SPECS.RCONV
			SENSORIN! = MEASIN! / RCONV! * 1000         'Convert to mA
		ELSEIF SNM% = 3 OR SNM% = 4 THEN                'TC in
			TCTYPE$ = LEFT$(SENSOR$, 1)
			TCT! = TCTEMP!(MEASIN! + PTCV!, TCTYPE$)
			SENSORIN! = TCT!
		ELSEIF SNM% = 5 OR SNM% = 6 THEN                'RTD in
			RTDTYPE$ = LEFT$(SENSOR$, 2)
			RTDI! = RTDTEMP!(MEASIN!, RTDTYPE$)         'Calculate actual simulated temp.
			SENSORIN! = RTDI!
		ELSE
			UNKNOWN% = 1
		END IF

		IF TCT! = 99! OR RTDI! = 99! OR UNKNOWN% = 1 THEN
			SOUND 1000, .5
			PRINT
			PRINT TAB(10); "Sensor type unknown.  Check database."
			SENSORIN! = 99!                             'Value indicates error
			CALL CONTINUE
		ELSEIF TCT! = 98! OR RTDI! = 98! THEN
			SOUND 1000, .5
			PRINT
			PRINT TAB(10); "Sensor polynomial limits have been exceeded."
			SENSORIN! = 99!                             'Value indicates error
			CALL CONTINUE
		END IF

END FUNCTION

FUNCTION SENSORNUM%

	'Assign a number to each sensor type for ease of handling
	'Sensor types;
	'1 = millivolt, volt
	'2 = milliamp
	'3 = thermocouple, except type B
	'4 = type B thermocouple (no CJC)
	'5 = 3-wire RTD
	'6 = 4-wire RTD
	'7 = potentiometer
	'8 = fbridge (full bridge strain gage, load cell)
	'9 = two-wire transmitter
	'10 = DC LVDT
	'11 = hbridge (half strain gage, load cell)

	SENSOR$ = SPECS.SENTYPE
	TCTYPE$ = LEFT$(SENSOR$, 1)

	IF UCASE$(LEFT$(SENSOR$, 1)) = "V" THEN
		SENSORNUM% = 1
	ELSEIF UCASE$(LEFT$(SENSOR$, 2)) = "MA" THEN
		SENSORNUM% = 2
	ELSEIF UCASE$(MID$(SENSOR$, 2, 2)) = "TC" THEN
		IF UCASE$(TCTYPE$) = "B" THEN
			SENSORNUM% = 4
		ELSE
			SENSORNUM% = 3
		END IF
	ELSEIF UCASE$(MID$(SENSOR$, 3, 5)) = "RTD3W" THEN
		SENSORNUM% = 5
	ELSEIF UCASE$(MID$(SENSOR$, 3, 5)) = "RTD4W" THEN
		SENSORNUM% = 6
	ELSEIF UCASE$(LEFT$(SENSOR$, 3)) = "POT" THEN
		SENSORNUM% = 7
	ELSEIF UCASE$(LEFT$(SENSOR$, 7)) = "FBRIDGE" THEN
		SENSORNUM% = 8
	ELSEIF UCASE$(LEFT$(SENSOR$, 4)) = "2WTX" THEN
		SENSORNUM% = 9
	ELSEIF UCASE$(LEFT$(SENSOR$, 6)) = "DCLVDT" THEN
		SENSORNUM% = 10
	ELSEIF UCASE$(LEFT$(SENSOR$, 7)) = "HBRIDGE" THEN
		SENSORNUM% = 11
	END IF

END FUNCTION

FUNCTION SENSOROUT! (PVIN!, PTCV!)
	  
		'Calculates sensor output based on the sensor type and input
		'Inputs;    PVIN! = process variable input to sensor, i.e. temperature, voltage, current
		'           PTCV! = measured value of parasitic TC voltage

		SENSOR$ = SPECS.SENTYPE
		SNM% = SENSORNUM%
							  
								'Voltage, Potentiometer, Full Bridge, DC LVDT, or Half Bridge in
		IF SNM% = 1 OR SNM% = 7 OR SNM% = 8 OR SNM% = 10 OR SNM% = 11 THEN
			SENSOROUT! = PVIN!
		ELSEIF SNM% = 2 OR SNM% = 9 THEN                'mA in
			RCONV! = SPECS.RCONV
			SENSOROUT! = PVIN! / 1000! * RCONV!
		ELSEIF SNM% = 3 OR SNM% = 4 THEN                'TC in
			TCTYPE$ = LEFT$(SENSOR$, 1)
			TCV! = TCVOLTS!(PVIN!, TCTYPE$)
			SENSOROUT! = TCV! - PTCV!
		ELSEIF SNM% = 5 OR SNM% = 6 THEN                'RTD in
			RTDTYPE$ = LEFT$(SENSOR$, 2)
			RTDO! = RTDOHMS!(PVIN!, RTDTYPE$)
			SENSOROUT! = RTDO!
		ELSE
			UNKNOWN% = 1
		END IF

		IF TCV! = 99! OR RTDO! = 99! OR UNKNOWN% = 1 THEN
			SOUND 1000, .5
			PRINT
			PRINT TAB(10); "Sensor type unknown.  Check database."
			SENSOROUT! = 99!
			CALL CONTINUE
		ELSEIF TCV! = 98! OR RTDO! = 98! THEN
			SOUND 1000, .5
			PRINT
			PRINT TAB(10); "Sensor polynomial limits have been exceeded."
			SENSOROUT! = 99!                          'Value indicates error
			CALL CONTINUE
		END IF
	  
END FUNCTION

FUNCTION SETAC! (ONOFF%, GENAMPL!)

	 SNM% = SENSORNUM%
	  
	 IF ONOFF% = 1 THEN
	  IF SNM% >= 5 AND SNM% <= 7 THEN             'Check if resistance in
		   CALL SETTEST(6)                         'Connect function generator
		   CB1VAL% = CB1VAL% AND &HF7              '1 1 1 1  0 1 1 1
		   CALL SETTH(CB1VAL%, CB1%)               'CH1- to AC input
		   CALL LOADMUX(1, CON%)                   'Attenuator input
	  ELSE
		   CB0VAL% = (CB0VAL% AND &HFD) OR (&H8)   '1 1 1 1  1 1 0 1
		   CALL SETTH(CB0VAL%, CB0%)               'Select function gen., input
		   CALL LOADMUX(8, CON%)                   'Attenuator input
	  END IF

	 CALL WRITEDVM(VOAC$, GENAMPL!)              'set meter range
		  
	  DO
		   VIN! = READDVM!(.001)
		   IF VIN! < GENAMPL! / 2! / SQR(2) * .75 THEN   'Check for adequate amplitude
			LOCATE 20, 15
			PRINT "WARNING!  Increase function generator amplitude."
		   END IF
		   
		   LOOP WHILE VIN! < GENAMPL! / 2! / SQR(2) * .75
			LOCATE 20, 15
			PRINT SPC(48);
		   ELSE
			IF SNM% >= 5 AND SNM% <= 7 THEN             'Check if resistance in
			  CALL RESETTH                            'Reset the test head
			ELSE
			  CB0VAL% = CB0VAL% OR &H2                '0 0 0 0  0 0 1 0
			  CALL SETTH(CB0VAL%, CB0%)               'De-select function gen., input
			  CALL SETDAC(0!, 1, MAXINVAR!, 0)   'Clear attenuator, short module inputs
			END IF
		END IF

		IF SNM% >= 5 AND SNM% <= 7 THEN             'Check if resistance in
			  CB1VAL% = CB1VAL% OR &H8                '0 0 0 0  1 0 0 0
			  CALL SETTH(CB1VAL%, CB1%)               'CH1- to -IN
			  CALL LOADMUX(1, COFF%)                  'Attenuator input
		ELSE
			  CALL LOADMUX(8, COFF%)                  'Attenuator input
		END IF
	  
		SETAC! = VIN!
END FUNCTION

SUB SETLOAD (LOAD!)
	  
		'Set the specified isolated excitation load.
		'Used only on SCM5B38 and SCM5B42
	 
		IF LOAD! >= 10000 THEN                          'load = 10K ohm
				MASK% = &HFF                            '
		ELSEIF LOAD! > 990 THEN                         'load = 1K ohm
				MASK% = &HDF                            '1 1 0 1  1 1 1 1
		ELSEIF LOAD! > 295 THEN                         'load = 330 ohm
				MASK% = &HEF                            '1 1 1 0  1 1 1 1
		ELSEIF LOAD! > 95 THEN                          'load = 120 ohm
				MASK% = &HF7                            '1 1 1 1  0 1 1 1
		ELSEIF LOAD! > 85 THEN                          'load = 88 ohm
				MASK% = &HE7                            '1 1 1 0  0 1 1 1
		ELSE                                            'load = 80 ohm
				MASK% = &HC7                            '1 1 0 0  0 1 1 1
		END IF

		CB1VAL% = (CB1VAL% OR &H38) AND MASK%           '0 0 1 1  1 0 0 0
		CALL SETTH(CB1VAL%, CB1%)

END SUB

SUB SORTDB (ENDFLAG%)
	'Create a file containing just the model numbers of all of the
	'records in the database for the model family selected
	'
	OPEN "C:\ATE\5BDATA\DBSORT2.DAT" FOR RANDOM AS #2 LEN = LEN(SORTDATA1)
	OPEN "C:\ATE\5BDATA\5BMAIN.DAT" FOR RANDOM AS #1 LEN = LEN(SPECS)
	NUMRECORD% = LOF(1) / LEN(SPECS)

	SELFAM% = MENU3%
	IF SELFAM% = 16 THEN
		ENDFLAG% = 1
		CLOSE #1
		CLOSE #2
		EXIT SUB        'exit selected from MENU3%
	END IF

	N% = 0

	FOR I% = 1 TO NUMRECORD%
		GET #1, I%, SPECS
		SORTDATA1.MODNAME = SPECS.MODNAME
		SORTDATA1.RECNUM = I%
		
		SELECT CASE SELFAM%    'Pick models in selected family

			CASE 1
				'SPECS.MODNAME = "SCM5B30-xxxx  "
				IF MID$(SPECS.MODNAME, 6, 2) = "30" THEN
					PUT #2, , SORTDATA1        'write record # and model number
					N% = N% + 1                'found a record
				END IF
			CASE 2
				'SPECS.MODNAME = "SCM5B31-xxxx  "
				IF MID$(SPECS.MODNAME, 6, 2) = "31" THEN
					PUT #2, , SORTDATA1        'write record # and model number
					N% = N% + 1                'found a record
				END IF
			CASE 3
				'SPECS.MODNAME = "SCM5B32-xxxx  "
				IF MID$(SPECS.MODNAME, 6, 2) = "32" THEN
					PUT #2, , SORTDATA1        'write record # and model number
					N% = N% + 1                'found a record
				END IF
			CASE 4
				'SPECS.MODNAME = "SCM5B34-xxxx  "
				IF MID$(SPECS.MODNAME, 6, 2) = "34" THEN
					PUT #2, , SORTDATA1        'write record # and model number
					N% = N% + 1                'found a record
				END IF
			CASE 5
				'SPECS.MODNAME = "SCM5B35-xxxx  "
				IF MID$(SPECS.MODNAME, 6, 2) = "35" THEN
					PUT #2, , SORTDATA1        'write record # and model number
					N% = N% + 1                'found a record
				END IF
			CASE 6
				'SPECS.MODNAME = "SCM5B36X-xxxx "
				IF MID$(SPECS.MODNAME, 6, 2) = "36" THEN
					PUT #2, , SORTDATA1        'write record # and model number
					N% = N% + 1                'found a record
				END IF
			CASE 7
				'SPECS.MODNAME = "SCM5B37-xxxx  "
				IF MID$(SPECS.MODNAME, 6, 2) = "37" THEN
					PUT #2, , SORTDATA1        'write record # and model number
					N% = N% + 1                'found a record
				END IF
			CASE 8
				'SPECS.MODNAME = "SCM5B38-xxxx  "
				IF MID$(SPECS.MODNAME, 6, 2) = "38" THEN
					PUT #2, , SORTDATA1        'write record # and model number
					N% = N% + 1                'found a record
				END IF
			CASE 9
				'SPECS.MODNAME = "SCM5B392-xxxx  "
				IF MID$(SPECS.MODNAME, 6, 3) = "392" THEN
					PUT #2, , SORTDATA1        'write record # and model number
					N% = N% + 1                'found a record
				END IF
			CASE 10
				'SPECS.MODNAME = "SCM5B40-xxxx  "
				IF MID$(SPECS.MODNAME, 6, 2) = "40" THEN
					PUT #2, , SORTDATA1        'write record # and model number
					N% = N% + 1                'found a record
				END IF
			CASE 11
				'SPECS.MODNAME = "SCM5B41-xxxx  "
				IF MID$(SPECS.MODNAME, 6, 2) = "41" THEN
					PUT #2, , SORTDATA1        'write record # and model number
					N% = N% + 1                'found a record
				END IF
			CASE 12
				'SPECS.MODNAME = "SCM5B42-xxxx  "
				IF MID$(SPECS.MODNAME, 6, 2) = "42" THEN
					PUT #2, , SORTDATA1        'write record # and model number
					N% = N% + 1                'found a record
				END IF
			CASE 13
				'SPECS.MODNAME = "SCM5B43-xxxx "
				IF MID$(SPECS.MODNAME, 6, 2) = "43" THEN
					PUT #2, , SORTDATA1        'write record # and model number
					N% = N% + 1                'found a record
				END IF
			CASE 14
				'SPECS.MODNAME = "SCM5B47x-xxxx "
				IF MID$(SPECS.MODNAME, 6, 2) = "47" THEN
					PUT #2, , SORTDATA1        'write record # and model number
					N% = N% + 1                'found a record
				END IF
			CASE 15
				'SPECS.MODNAME = "SCM5BPT-XXXX  ", "SCM5B-1369"
				IF MID$(SPECS.MODNAME, 6, 2) = "PT" OR MID$(SPECS.MODNAME, 7, 4) = "1369" THEN
					PUT #2, , SORTDATA1        'write record # and model number
					N% = N% + 1                'found a record
				END IF

		END SELECT
	NEXT

	SORTDATA1.MODNAME = "9999999999-9999"       'always sorted to last value.
	SORTDATA1.RECNUM = -1        'flag indicating end of new data (over writes old)
	PUT #2, , SORTDATA1

	CLOSE #1
	'Sort according to string value
	'DO
	'    Swaps% = FALSE
	'    FOR I% = 1 TO N%
	'        GET #2, I%, SORTDATA1
	'        A% = STRINGVAL%(SORTDATA1.MODNAME)
	'        GET #2, I% + 1, SORTDATA2
	'        B% = STRINGVAL%(SORTDATA2.MODNAME)
	'        'Do sort...
	'        IF A% > B% THEN
	'            PUT #2, I%, SORTDATA2
	'            PUT #2, (I% + 1), SORTDATA1
	'            Swaps% = I%
	'        END IF
	'    NEXT I%
	'LOOP WHILE Swaps%

	CLOSE #2

END SUB

FUNCTION STEPRESP$

		MINOUT! = SPECS.MINOUT                          'Output voltage (V)
		MAXOUT! = SPECS.MAXOUT
		STEPLOWLIM! = SPECS.STEPRMIN                    '%
		STEPHIGHLIM! = SPECS.STEPRMAX
		STEPMAXIN! = SENSOROUT!(SPECS.MAXIN, 0)         'Use for checking if test is run

		CLS
		TESTTITLE$ = "Step Response Test"
		CALL HEADERB(TESTTITLE$)
		LOCATE 10, 10
														'Output sample is at 0.2s
		IF LOWLIM! > .97 OR STEPMAXIN! > 10! THEN       'Check for BW > approx 10Hz
														'or high voltage input
				PRINT "This test is not performed on model "; SPECS.MODNAME
				EXIT FUNCTION
		ELSE
				PRINT "Testing, please wait..."
		END IF

		SNM% = SENSORNUM%

		IF SNM% = 3 THEN
			PTCV! = PARASITICTCV!(VCJC!)
			IF VCJC! = 99! THEN
				PRINT TAB(10); "Error in STEPRESP$ test:"
				PRINT TAB(10); "Vcjc = 99 (error value)!"
				ST$ = "FAIL"        'Set FAIL status.
				SOUND 1000, .5      'Beep to alert to failure.
				STEPRESP$ = ST$ + "V"   'Set function output to FAIL status with trailing "V" for special formatting.
				CALL FAILSTATUS(ST$, 10, 10, "Status: ", 30)        'Print test status to screen
				EXIT FUNCTION
			END IF
		END IF

		IF SPECS.OSCALIN = SPECS.MAXIN THEN
			MININ! = 0                                  'Unipolar input, bipolar output
														'modules have OSCALIN = MAXIN
														'for cal non-interaction
		ELSE
			MININ! = SPECS.OSCALIN
		END IF

		STEPMININ! = SENSOROUT!(MININ!, PTCV!)          'Calculate module input
		STEPMAXIN! = SENSOROUT!(SPECS.MAXIN, PTCV!)     'Re-calculate with known PTCV!

		IF SNM% >= 5 AND SNM% <= 7 THEN                 'Check if resistance in
				CALL OHMSET(STEPMININ!)
		ELSE
				THATTEN! = SETATTEN%(STEPMAXIN!)        'Set test head attenuator
														'This setting will be used
														'for minin and maxin for speed.
				CB0VAL% = (CB0VAL% AND &HEB) OR &H8     '1 1 1 0  1 0 1 1
				CALL SETTH(CB0VAL%, CB0%)               'ground inputs, short series R
														'remove short on inputs
				CALL SETDACFAST(STEPMININ! * THATTEN!)  'Set -f.s. input
		END IF
	  
		CALL LOADMUX(2, CON%)                           'Measure Vout
		CALL WRITEDVM(VODC$, VOUT!(MININ!))
		OUTLO! = READDVM(.001)                          'Read -f.s. output (V)
		CALL LOADMUX(2, COFF%)

		IF SNM% >= 5 AND SNM% <= 7 THEN                 'Check if resistance in
			'TIME1! = TIMER
			CB0VAL% = CB0VAL% AND &HBF                  '1 0 1 1  1 1 1 1
			CALL SETTHFAST(CB0VAL%, CB0%)               'Set step relay, K18
														'Start one-shot timer
			'PRINT TIMER - TIME1!
								'** elapsed time = 0 using SETTHFAST in OHMSET
			CALL OHMSET(STEPMAXIN!)
			'PRINT TIMER - TIME1!
								'** elapsed time = 0 using SETTHFAST in OHMSET
			'Measured delay between one-shot pulse start and input voltage step
			'is 20ms, therefore, set timer pulse to 220ms.

			CALL PAUSE(.3)                              'Wait for 200ms pulse
			CB0VAL% = CB0VAL% OR &H40                   '0 1 0 0  0 0 0 0
			CALL SETTH(CB0VAL%, CB0%)                   'reset test
		ELSE
			'TIME1! = TIMER
			CB0VAL% = CB0VAL% AND &H7F                  '0 1 1 1  1 1 1 1
			CALL SETTHFAST(CB0VAL%, CB0%)               'Set step relay, k7
														'Start one-shot timer
			'PRINT TIMER - TIME1!
								'** elapsed time = 0 using SETTHFAST
								'** elapsed time = 50ms using SETTH, regardless
								'   of pause time in SETTH.  Pause is required.
			CALL SETDACFAST(STEPMAXIN! * THATTEN!)      'Set +f.s input
			'PRINT TIMER - TIME1!
								'** elapsed time = 0 using SETDACFAST
								'** elapsed time = 50ms using SETDAC
			'Measured delay between one-shot pulse start and input voltage step
			'is 1ms.
	 
			CALL PAUSE(.3)                              'Wait for 200ms pulse
			CB0VAL% = CB0VAL% OR &H80                   '1 0 0 0  0 0 0 0
			CALL SETTH(CB0VAL%, CB0%)                   'reset test
		END IF

		CALL LOADMUX(5, CON%)                           'S/H Output
		CALL WRITEDVM(VODC$, MAXOUT!)
		OUTHI! = READDVM(.001)                          'Read sampled output (V)
		CALL LOADMUX(5, COFF%)

		CALL PAUSE(.5)                                  'Allow output to settle
														'to final value
		CALL LOADMUX(2, CON%)                           'Measure Vout
		OUTFINAL! = READDVM(.001)                       'Read final +f.s. output (V)
		CALL LOADMUX(2, COFF%)
	  
		SPAN! = OUTFINAL! - OUTLO!                      'Measured span
		OUTHIPERC! = (OUTHI! - OUTLO!) / SPAN! * 100!
		IF OUTHIPERC! >= STEPLOWLIM! AND OUTHI! <= STEPHIGHLIM! THEN
			ST$ = "PASS"
		ELSE
			ST$ = "FAIL"
			SOUND 1000, .5
		END IF

		'LOCATE 10, 10
		'PRINT "Status: "; ST$;
		'CALL FAILSTATUS (ST$, 10, 10, "Status: ")      'Print test status to screen
		
		LOCATE 10, 10
		PRINT SPC(20);
		PRINT TAB(10); "Output after 200ms is";
		PRINT TAB(50); USING "+###.# %"; OUTHIPERC!
		PRINT TAB(10); "Required output after 200ms is";
		PRINT TAB(50); USING "+###.# % to +###.# %"; STEPLOWLIM!; STEPHIGHLIM!

		CALL FAILSTATUS(ST$, 10, 10, "Status: ", 30)        'Print test status to screen

		STEPRESP$ = ST$ + STR$(OUTHIPERC!) + "1"

		CALL RESETTH                                    'Reset the test head
		CALL PAUSE(.2)

END FUNCTION

FUNCTION SUPPLYI$ (EXCL%)
	'Supply current tests.
	'
	MAXOUT! = SPECS.MAXOUT
	  
	IF EXCL% = 0 THEN
		LOAD$ = ""
	ELSE
		LOAD$ = ", Exc. Loaded"
	END IF

	CLS
	TESTTITLE$ = "Supply Current Test" + LOAD$
	CALL HEADERB(TESTTITLE$)
	LOCATE 10, 10
	  
	SNM% = SENSORNUM%
	
	IF EXCL% = 0 THEN
		'No excitation load.
		PRINT "Testing, please wait."
	ELSE
		'Excitation load.
		IF ((SNM% >= 8) AND (SNM% <= 11)) THEN
			'Full bridge, 2-wire transmitter, DCLVDT (General Purpose) or half bridge input module.
			PRINT "Testing, please wait...."
		ELSE
			'Not a full bridge, 2-wire transmitter, DCLVDT (General Purpose) or half bridge input module.
			PRINT "This test is not performed on model "; SPECS.MODNAME
			EXIT FUNCTION
		END IF
	END IF
	
	'IF (SNM% < 8 AND SNM% > 11) AND EXCL% <> 0 THEN
	'   PRINT "This test is not performed on model "; SPECS.MODNAME
	'   EXIT FUNCTION
	'ELSE
	'   PRINT "Testing, please wait."
	'END IF
	  
	IF EXCL% = 0 THEN
		ISMAX! = SPECS.ISMAXNEXCL               'Isupply with no exc load
	ELSE
		ISMAX! = SPECS.ISMAXFEXCL               'Isupply with full exc load
		VEXC! = SPECS.VEXC                      'Excitation voltage
		EXCLOAD! = SPECS.EXCLOAD / 1000!        'Max. exc. load (mA)
		CALL SETLOAD(VEXC! / EXCLOAD!)          'Set excitation load (ohms)
	END IF
	ISMIN! = ISMAX! * .25               'Determine if module is functional

	IF TE$ = "TE1005" THEN
		ISSEN! = 24                     'Isupply sense resistor,
										'PCB1044, 24 ohm for Rev B PCB, 0.5 ohm for Rev A PCB
	ELSE                                'TE1012
		ISSEN! = 100                    'PCB1128, 100 ohm
	END IF
	   
	RSENSE! = MEASRES!(ISSEN!, 1, "")   'Measure supply current sense resistor
										'Rev B PCB only (check test head conn.)
	CALL POWERON(5!)                            'Set Vsupply to 5.0V

	IF SNM% = 3 THEN
		PTCV! = PARASITICTCV!(VCJC!)
		IF VCJC! = 99! THEN
			PRINT TAB(10); "Error in SUPPLYI$ test:"
			PRINT TAB(10); "Vcjc = 99 (error value)!"
			SUPI$ = "FAIL"      'Set FAIL status.
			SOUND 1000, .5      'Beep to alert to failure.
			SUPPLYI$ = SUPI$ + "V"  'Set function output to FAIL status with trailing "V" for special formatting.
			CALL FAILSTATUS(SUPI$, 10, 10, "Status: ", 30)      'Print test status to screen
			EXIT FUNCTION
		END IF
	END IF
	MAXIN! = SENSOROUT!(SPECS.MAXIN, PTCV!)     'Calculate +f.s. in

	IF SNM% >= 5 AND SNM% <= 7 THEN             'Check if resistance in
		CALL OHMSET(MAXIN!)                     'Set +f.s. input
	ELSE
		CALL SETDAC(MAXIN!, 1, MAXINVAR!, 0)               'Sets DAC
	END IF
	   
	CALL ENABLE(COFF%)                          'Disables module output switch
												'Isupply is highest in this config.

	CALL WRITEDVM(VODC$, ISMAX! * RSENSE!)
	CALL LOADMUX(3, CON%)                       'Vout
	ISUP! = (READDVM!(.001) / RSENSE!) * 1000   'Reads voltage across sense resistor
	CALL LOADMUX(3, COFF%)

	IF ISUP! < ISMAX! AND ISUP! > ISMIN! THEN
		SUPI$ = "PASS"
	ELSE
		SUPI$ = "FAIL"
		CALL POWERON(0!)
		SOUND 1000, .5
	END IF
   
	'LOCATE 10, 10
	'PRINT "Status: "; SUPI$;
	'CALL FAILSTATUS (SUPI$, 10, 10, "Status: ")        'Print test status to screen
	
	LOCATE 10, 10
	PRINT SPC(10);
	PRINT TAB(10); "Measured supply current is";
	PRINT TAB(50); USING "####.# mA"; ISUP!
	PRINT TAB(10); "Required supply current is";
	PRINT TAB(50); USING " ###.# mA to ###.# mA"; ISMIN!; ISMAX!

	CALL FAILSTATUS(SUPI$, 10, 10, "Status: ", 30)      'Print test status to screen
   
	SUPPLYI$ = SUPI$ + STR$(ISUP!) + "1"    'append # decimal places

	IF EXCL% = 1 THEN
		CALL SETLOAD(10000!)            'Set excitation load to 10K ohms
	END IF
	CALL ENABLE(CON%)                       'Enable output switch

	CALL RESETTH                            'Reset the test head
	CALL PAUSE(.2)

END FUNCTION

FUNCTION SUPPLYSEN$
	  
	MINOUT! = SPECS.MINOUT                 'Module output voltage (V)
	MAXOUT! = SPECS.MAXOUT
	PSS! = SPECS.PSS                        'Spec (uV / % RTI or C/V)
	VS1! = 4.75                             'Power supply voltage #1
	VS2! = 5.25                             'Power supply voltage #2

	ORANGE! = MAXOUT! - MINOUT!             'Output range (V)
	INRANGE! = SPECS.MAXIN - SPECS.MININ

	SNM% = SENSORNUM%

	CLS
	TESTTITLE$ = "Power Supply Sensitivity Test"
	CALL HEADERB(TESTTITLE$)
	
	IF SNM% = 3 THEN
		PTCV! = PARASITICTCV!(VCJC!)
		IF VCJC! = 99! THEN
			PRINT TAB(10); "Error in SUPPLYSEN$ test:"
			PRINT TAB(10); "Vcjc = 99 (error value)!"
			PSSSTAT$ = "FAIL"       'Set FAIL status.
			SOUND 1000, .5          'Beep to alert to failure.
			SUPPLYSEN$ = PSSSTAT$ + "V" 'Set function output to FAIL status with trailing "V" for special formatting.
			CALL FAILSTATUS(PSSSTAT$, 10, 10, "Status: ", 30)       'Print test status to screen
			EXIT FUNCTION
		END IF
	END IF
	MAXIN! = SENSOROUT!(SPECS.MAXIN, PTCV!) 'Calc. maxin
	MININ! = SENSOROUT!(SPECS.MININ, PTCV!) 'Calc. minin
	  
	IF SNM% = 5 OR SNM% = 6 THEN            'Calculate gain in V/deg C
		GAIN! = ORANGE! / INRANGE!
		PSS! = PSS! * 5! / 100!             'Convert to C / %
	ELSEIF SNM% = 7 THEN                    'Calculate gain in V/V
		GAIN! = ORANGE! / (INRANGE! * SPECS.IEXC / 1000000!)
		PSS! = PSS! / 1000000!              'Convert to uV / %
	ELSE                                    'Calculate gain in V/V
		GAIN! = ORANGE! / (MAXIN! - MININ!)
		PSS! = PSS! / 1000000!              'Convert to uV / %
	END IF

	LOCATE 10, 10
	PRINT "Testing, please wait."
	IF SNM% >= 5 AND SNM% <= 7 THEN         'Check if resistance in
		CALL OHMSET(MAXIN!)                 'Set Rin for +f.s input
	ELSE
		   
		CALL SETDAC(MAXIN!, 1, MAXINVAR!, 0)           'Set DAC input
	END IF

'    CALL PAUSE(2.5)

	CALL POWERON(VS1!)                      'Set Vs = 4.75V
	VS1MEAS! = VS1!

	CALL LOADMUX(2, CON%)                   'Measure Vout
	CALL WRITEDVM("S0", MAXOUT!)            'Slow reading rate for max accuracy
	CALL WRITEDVM(VODC$, MAXOUT!)
	VOUT1! = READDVM(.0002)                 'Output voltage (V)
	CALL WRITEDVM("S1", MAXOUT!)            'Medium reading rate
	CALL LOADMUX(2, COFF%)                  'Turn off CH#2

	CALL POWERON(VS2!)                      'Set Vs = 5.25V
	VS2MEAS! = VS2!
	
	CALL LOADMUX(2, CON%)                   'Measure Vout
	CALL WRITEDVM("S0", MAXOUT!)            'Slow reading rate for max accuracy
	VOUT2! = READDVM(.0002)                 'Output voltage (V)
	CALL WRITEDVM("S1", MAXOUT!)            'Medium reading rate
	CALL LOADMUX(2, COFF%)                  'Turn off CH#2
	DELTAVO! = (VOUT2! - VOUT1!) * 1000!    'Change in output (mV)
	MAXCHG! = PSS! * GAIN! * (VS2MEAS! - VS1MEAS!) / 5! * 100! * 1000! 'Max delta Vo (mV)

	IF ABS(DELTAVO!) <= MAXCHG! THEN
		PSSSTAT$ = "PASS"
	ELSE
		PSSSTAT$ = "FAIL"
		SOUND 1000, .5
	END IF

	IF SNM% = 5 OR SNM% = 6 THEN                    'Express meas. in C/V
		MEASPSS! = DELTAVO! / 1000! / GAIN! / (VS2MEAS! - VS1MEAS!)
		UNIT$ = "C/V"
		N$ = "2"                                    'Display digits
	ELSE                                            'Express meas. in uV/%
		MEASPSS! = DELTAVO! / (MAXCHG! / PSS!) * 1000000!
		UNIT$ = "uV/%"
		IF ABS(MEASPSS!) < 100 THEN
			N$ = "1"                                'Display digits
		ELSE
			N$ = "0"
		END IF
	END IF

	'LOCATE 10, 10
	'PRINT "Status: "; PSSSTAT$;
	'CALL FAILSTATUS (PSSSTAT$, 10, 10, "Status: ")     'Print test status to screen
	
	LOCATE 10, 10
	PRINT SPC(20);
	PRINT TAB(10); "Measured change in output voltage is";
	IF N$ = "2" THEN
		PRINT TAB(47); USING " +####.## "; MEASPSS!;
	ELSEIF N$ = "1" THEN
		PRINT TAB(47); USING "  +####.# "; MEASPSS!;
	ELSE
		PRINT TAB(47); USING "  +###### "; MEASPSS!;
	END IF
	PRINT UNIT$
	PRINT TAB(10); "Max. change in output voltage is";
	IF N$ = "2" THEN
		PRINT TAB(47); USING "+/-###.## "; SPECS.PSS;
	ELSEIF N$ = "1" THEN
		PRINT TAB(47); USING "+/- ###.# "; SPECS.PSS;
	ELSE
		PRINT TAB(47); USING "+/- ##### "; SPECS.PSS;
	END IF
	PRINT UNIT$

	CALL FAILSTATUS(PSSSTAT$, 10, 10, "Status: ", 30)       'Print test status to screen

	SUPPLYSEN$ = PSSSTAT$ + STR$(MEASPSS!) + N$
   
	CALL POWERON(5!)                                'Reset Vsupply
	CALL RESETTH                                    'Reset the test head
	CALL PAUSE(.2)

END FUNCTION

SUB TSPECS (TSPEC$(), TOTLRESPEC!)

		IMATCHTOL! = SPECS.IMATCHTOL! / 100             'Convert to %

		ORANGE! = SPECS.MAXOUT - SPECS.MINOUT
		TCTYPE$ = LEFT$(SPECS.SENTYPE, 1)               'Determine TC type
		SEEBECK! = (TCVOLTS!(50!, TCTYPE$) - TCVOLTS!(0!, TCTYPE$)) / 50! * 1000000!

		TSPEC$(1) = " < " + STR$(SPECS.ISMAXNEXCL)      'Isupply spec, no exc. load
		TSPEC$(2) = " < " + STR$(SPECS.ISMAXFEXCL)      'Isupply spec, full exc. load
		TSPEC$(3) = "   " + STR$(SPECS.IEXC)            'Excitation current #1
		TSPEC$(4) = "   " + STR$(SPECS.IEXC)            'Excitation current #2
		TSPEC$(5) = "+/-" + LEFT$(STR$(SPECS.IEXC * IMATCHTOL!), 4) 'Current source matching
		TSPEC$(6) = " < " + STR$(SPECS.OUTRES)          'Output switch resistance
		TSPEC$(7) = "   " + LEFT$(STR$(SEEBECK!), 6)    'CJC gain
		TSPEC$(8) = MID$(STR$(SPECS.VEXC), 2, 5) + "+/-" + MID$(STR$(CINT(SPECS.VEXCACC / 100! * SPECS.VEXC * 1000) / 1000), 2, 4)
														'Excitation spec
		TSPEC$(9) = "+/-" + STR$(SPECS.EXCLOADREG)      'Excitation load regulation
	   
		IF SPECS.MODNAME = "SCM5B38-1345   " THEN
			ACC! = .05
		ELSE
			ACC! = SPECS.ACCURACY * 1.25
		END IF

		TSPEC$(10) = "+/-" + LEFT$(STR$(CINT(ACC! * 100) / 100), 4) 'Vo reg. with exc. load
		TSPEC$(11) = " < " + STR$(SPECS.EXCIMAX)        'Excitation current limit
		TSPEC$(12) = "+/-" + STR$(SPECS.LINEAR)         'Linearity/conformity spec
		TSPEC$(13) = "+/-" + STR$(SPECS.ACCURACY)       'Accuracy spec
		TSPEC$(14) = "+/-" + LEFT$(STR$(TOTLRESPEC), 4) 'Lead resistance effects
		TSPEC$(15) = "+/-" + LEFT$(STR$(SPECS.PSS), 5)  'Power supply sensitivity
		TSPEC$(16) = " >=" + STR$(SPECS.INPUTRES!)      'Input R, bias I effects
		'IF SPECS.VOPENINMIN > SPECS.MAXOUT THEN
		'        COND$ = " > "
		'ELSE
		'        COND$ = " < "
		'END IF
		'TSPEC$(17) = COND$ + STR$(SPECS.VOPENINMIN)     'Open Tc detect
		TSPEC$(17) = LEFT$(STR$(CINT(SPECS.VOPENINMIN! * 100) / 100), 5) + " to " + LEFT$(STR$(CINT(SPECS.VOPENINMAX! * 100) / 100), 5)
			
		IF MID$(SPECS.MODNAME, 6, 7) = "41-1794" THEN
			TSPEC$(18) = RIGHT$(STR$(SPECS.ATTEN), 2) + "+/-" + RIGHT$(STR$(SPECS.ATTENTOL), 6)
		ELSE
			TSPEC$(18) = RIGHT$(STR$(SPECS.ATTEN), 2) + "+/-" + RIGHT$(STR$(SPECS.ATTENTOL), 2)
		END IF
														'Frequency response
		TSPEC$(19) = LEFT$(STR$(SPECS.STEPRMIN), 3) + " to " + LEFT$(STR$(SPECS.STEPRMAX), 4)
							'Step response
		TSPEC$(20) = " < " + STR$(SPECS.OUTNOISE)       'Output noise
		TSPEC$(21) = LEFT$(STR$(CINT(SPECS.VOPENINMIN! * 100) / 100), 5) + " to " + LEFT$(STR$(CINT(SPECS.VOPENINMAX! * 100) / 100), 5)
	  
END SUB

FUNCTION UTILMENU%
	'Utility menu under the Individual Test menu.
	'
	CLS
	LOCATE , 23
	COLOR 14, 0, 0
	PRINT "SCM5Bxx-xx AUTOMATED TEST EQUIPMENT"
	COLOR 11, 0, 0
	PRINT TAB(9); "1.) Printer Output = ";
	IF PON% = 1 THEN
		PRINT "ON"
	ELSE
		PRINT "OFF"
	END IF
	PRINT TAB(9); "2.) Log Linearity Test Data = ";
	IF LOGDAT% > 0 THEN
		PRINT "ON"
	ELSE
		PRINT "OFF"
	END IF
	PRINT TAB(9); "3.) Pause after each test  = ";
	IF TESTPAUSE% = 1 THEN
		PRINT "ON"
	ELSE
		PRINT "OFF"
	END IF
	PRINT TAB(9); "4.) Exit to the Individual Test Menu"
	PRINT TAB(9); "Enter your selection."

	UTILMENU% = MENUCODE%   'Get value from menu keypress.
	CLS
END FUNCTION

FUNCTION VOREG$

	'Test the change in the module output with the change in the
	'isolated excitation voltage load.  SCM5B38 and SCM5B42 only.
	  
	MININ! = SENSOROUT!(SPECS.MININ!, 0)    'Calculate +f.s. input
	MAXIN! = SENSOROUT!(SPECS.MAXIN!, 0)    'Calculate +f.s. input
	MINOUT! = SPECS.MINOUT
	MAXOUT! = SPECS.MAXOUT
	SNM% = SENSORNUM%
	VEXC! = SPECS.VEXC                      'Excitation voltage
	EXCLOAD! = SPECS.EXCLOAD / 1000!        'Max. exc. load (mA)

	IF SPECS.MODNAME = "SCM5B38-1345   " THEN
		ACC! = .05
	ELSEIF SNM% = 11 THEN
		ACC! = SPECS.ACCURACY * 3.75        'MR 5/9/07, Increased VOREG for half-bridge

	ELSE
		ACC! = SPECS.ACCURACY * 1.25
	END IF

	ORANGE! = MAXOUT! - MINOUT!             'Output range (V)
	GAIN! = ORANGE! / (MAXIN! - MININ!)
	 
	CLS
	TESTTITLE$ = "Module Output Reg. with Exc. Load Test"
	CALL HEADERB(TESTTITLE$)
	LOCATE 10, 10

	IF SNM% < 8 OR SNM% > 11 THEN
		PRINT "This test is not performed on model "; SPECS.MODNAME
		EXIT FUNCTION
	ELSE
		PRINT "Testing, please wait."
	END IF
	 
	CALL SETDAC(MAXIN!, 1, MAXINVAR!, 0)                       'Sets DAC for +f.s. in
   
	CALL WRITEDVM("S0", 0)                          'Slow reading rate for max accuracy
	CALL LOADMUX(1, CON%)
	CALL WRITEDVM(VODC$, MAXIN!)                    'Sets meter to read
	'CALL PAUSE(2!)
	MAXINMEAS1! = READDVM!(MAXIN! * .0001)          '0.01% tolerance
	CALL LOADMUX(1, COFF%)
	CALL WRITEDVM("S1", 0)                          'Medium reading rate
	'MAXINMEAS1! = MAXIN!                            'Passed back from SETDAC
	  
	CALL LOADMUX(2, CON%)                           'Measure Vout
	CALL WRITEDVM(VODC$, MAXOUT!)
	VOEXCNL! = READDVM(.0001)                       'Vout, no excitation load
	CALL LOADMUX(2, COFF%)

	CALL SETLOAD(VEXC! / EXCLOAD!)                  'Set excitation load (ohms)
													'RESETS MUX
	CALL WRITEDVM("S0", 0)                          'Slow reading rate for max accuracy
	CALL LOADMUX(1, CON%)
	CALL WRITEDVM(VODC$, MAXIN!)                    'Sets meter to read
	'CALL PAUSE(1!)
	MAXINMEAS2! = READDVM!(MAXIN! * .0001)          '0.01% tolerance
	CALL LOADMUX(1, COFF%)
	CALL WRITEDVM("S1", 0)                          'Medium reading rate
   
	CALL LOADMUX(2, CON%)                           'Measure Vout
	CALL WRITEDVM(VODC$, MAXOUT!)
	VOEXCL! = READDVM(.0001)                        'Vout, full excitation load
	  
	CALL LOADMUX(2, COFF%)
	 
	DELTAVO! = (VOEXCL! - VOEXCNL! - (MAXINMEAS2! - MAXINMEAS1!) * GAIN!) / ORANGE! * 100!'Change in Vout (mV)
	 
	IF ABS(DELTAVO!) <= ACC! THEN
		VOR$ = "PASS"
	ELSE
		VOR$ = "FAIL"
		SOUND 1000, .5
		'Trouble shooting notes
		LOCATE 15, 10
		PRINT "Check the signals on the power transformer."
	END IF

	'LOCATE 10, 10
	'PRINT "Status: "; VOR$;
	'CALL FAILSTATUS (VOR$, 10, 10, "Status: ")     'Print test status to screen
	
	LOCATE 10, 10
	PRINT SPC(10);
	PRINT TAB(10); "Module output change with excitation load is";
	PRINT TAB(55); USING "  +###.### %"; DELTAVO!
	PRINT TAB(10); "Max. change with excitation load is";
	PRINT TAB(55); USING " +/-##.### %"; ACC!

	CALL FAILSTATUS(VOR$, 10, 10, "Status: ", 30)       'Print test status to screen
														
	VOREG$ = VOR$ + STR$(DELTAVO!) + "2"            '% span
   
	CALL SETLOAD(10000!)                            'Set excitation load to 10K ohms
	CALL RESETTH                                    'Reset the test head
	CALL PAUSE(.2)
	 
END FUNCTION

FUNCTION VOUT! (SENOUT!)

	'Calculates the module output for a given input (sensor output)

	MAXOUT! = SPECS.MAXOUT
	MINOUT! = SPECS.MINOUT
	SENSOR$ = SPECS.SENTYPE
	LIN% = SPECS.LINEARIZED

	SNM% = SENSORNUM%
												'Check for TC or RTD input.
	IF (SNM% >= 3 AND SNM% <= 6) AND LIN% = 0 THEN
		MININ! = SENSOROUT!(SPECS.MININ, 0) 'Output not linear with
		MAXIN! = SENSOROUT!(SPECS.MAXIN, 0) 'input temperature.
	ELSE
		MININ! = SPECS.MININ
		MAXIN! = SPECS.MAXIN
	END IF
	  
	ORANGE! = MAXOUT! - MINOUT!             'Output range (V)
	INRANGE! = MAXIN! - MININ!              'Input range
	
	XFERFN! = ORANGE! / INRANGE!
	YINT! = MINOUT! - MININ! * XFERFN!      'Y-intercept
	VOUT! = XFERFN! * SENOUT! + YINT!       'Output voltage (V)

END FUNCTION

SUB WAITFORFINISH
	'Wait for the user to press the "F" key (upper or lower case). Prints message based on row after
	'current cursor row. Used in situations where a specific key should be pressed, rather than "any"
	'key, such as after the final test status is displayed on the screen (so that the operator is sure
	'to see the "PASS" or "FAIL" status).
	COLOR 15, 0     'Bright white, black background
	COLOR 14, 0     'Bright yellow, black background 
	PRINT ""
	PRINT TAB(10); "Press the 'F' key to continue..."
	DO
		KB$ = INKEY$
		KB$ = UCASE$(KB$)
	LOOP WHILE (KB$ <> "F")
	COLOR 11, 0 'Cyan, black background
END SUB

FUNCTION WAITFORKEY$ (KEY$, TABPOS%, FORECOL%, BACKCOL%)
	'Wait for the user to press the key specified by the "KEY$" parameter (upper or lower case).
	'A message is displayed on row after the current row of the screen cursor row, tabbed over
	'the number of spaces specified by the "TABPOS%" parameter. This sub is used in situations
	'where a specific key should be pressed, rather than "any" key, such as after the final test
	'status is displayed on the screen (so that the operator is sure to see the "PASS" or "FAIL"
	'status) or in any situation when previous keystrokes need to be ignored. For distinction,
	'the message is displayed in the passed foreground and background colors.
	COLOR FORECOL%, BACKCOL%    'Set to passed foreground and background colors
	EATTHIS$ = INKEY$   '"Eat" any keystrokes in the buffer. 
	KEYUC$ = UCASE$(KEY$)
	KEYLC$ = LCASE$(KEY$)
	PRINT ""
	'PRINT TAB(10); "Press the '"; KEY$ ;"'key to continue..."
	PRINT TAB(TABPOS%); "Either '"; KEYUC$; "' or '"; KEYLC$; "' must be pressed."
	DO
		KB$ = INKEY$
		KB$ = UCASE$(KB$)
	LOOP WHILE (KB$ <> KEY$)
	COLOR 11, 0 'Cyan, black background
	
	WAITFORKEY$ = KB$   'Set function return.
	
END FUNCTION

SUB WORKORDERHEADER (SN$)
	'Sub to print the header for the work order status file.
	'
	'Column numbers (for reference) below:
	'         1         2    2    3   3     4       4 5         6         7         8 
	'1        0         0    5    0   4     0       8 0         0         0         0
	'
	'Example header format (example not necessarily for this test program):
	'
	'
	'===================================================================
	'WO#: 103456
	'
	'Date:  06-03-2014
	'
	'Work order status file for work order #: 103456
	'
	'Program:   TEST8B1Z.EXE
	'Version:   B.1 2014.04.24 PWR
	'Lib. Ver.: B.4 2014.04.10 PWR
	'
	'-------------------------------------------------------------------
	'Status   Serial#   DS File Name  Model         Date        Time
	'-------- --------- ------------  ------------- ----------  --------
	'
	KEY(10) OFF 'Deactivates F10 key

	PRINT TAB(10); "Writing header to work order status file."
	
	WOSFNAME$ = GETWOSFNAME$(SN$)  'Get work order status file name
	CALL SNPARSE(SN$, WO$, DS$) 'Get current work order and dash numbers from module serial number
	OPEN "C:\REPORTS\" + WOSFNAME$ FOR APPEND AS #10
	'OPEN "C:\REPORTS\" + WOSFNAME$ FOR OUTPUT AS #10
	'PRINT #10, 'Blank line
	PRINT #10,  'Blank line
	PRINT #10, "==================================================================="
	PRINT #10, "WO#: "; WO$
	PRINT #10,  'Blank line
	PRINT #10, "Date:  "; DATE$
	PRINT #10,  'Blank line
	PRINT #10, "Work order status file for work order #: "; WO$
	PRINT #10,  'Blank line
	'Program name and version and library version.
	PRINT #10, "Program:   "; PROGNAMEVAL$
	PRINT #10, "Version:   "; PROGVERVAL$
	PRINT #10, "Lib. Ver.: "; LIBVERVAL$
	PRINT #10,  'Blank line
	PRINT #10, "-------------------------------------------------------------------"
	'PRINT #10, "Status"; TAB(10); "Serial#"; TAB(20); "DS File Name"; TAB(34); "Model"; TAB(48); "Date"; TAB(60); "Time"
	'PRINT #10, "--------"; TAB(10); "---------"; TAB(20); "------------"; TAB(34); "-------------"; TAB(48); "----------"; TAB(60); "--------"
	PRINT #10, "Status"; TAB(10); "Serial#"; TAB(20); "DS File Name"; TAB(33); "DIR File Name"; TAB(47); "Model"; TAB(60); "Time"
	PRINT #10, "--------"; TAB(10); "---------"; TAB(20); "------------"; TAB(33); "-------------"; TAB(47); "------------"; TAB(60); "--------"
CLOSE #10

	KEY(10) ON  'Reactivates F10 key
	
END SUB

SUB WORKORDERLINE (FAILSTATE%, SN$)
	'Sub to write status lines for tested module in work order status file.
	'
	'Example line formats (below column numbers):
	'         1         2    2    3   3     4       4 5         6         7         8 
	'1        0         0    5    0   4     0       8 0         0         0         0
	'FAIL<<<< 103456-49 A3456-49.TXT  SCM5B48-01    02-19-2014  17:23:04
	'PASS     103456-50 A3456-50.TXT  SCM5B48-01    02-19-2014  22:28:31
	'
	KEY(10) OFF 'Deactivates F10 key

	CALL GETDSFNAME(SN$, DSSNAME$, DSFNAME$)    'Gets datasheet search and file names from serial number
	
	IF FAILSTATE% = 1 THEN
		STATE$ = "FAIL<<<<"     'Failure value for module STATUS string.
		FL$ = ""                'Failure value for datasheet file name from DIR command (null string).
		DSFNAME$ = ""   'Set datasheet file name blank for failing modules (since file is not generated).
	ELSE
		STATE$ = "PASS"
		
		'Check for created datasheet file. Write the name of the datasheet file (if found)
		'to a temporary file using a DOS shell DIR command, then read the name from the
		'temporary file to a variable to be used to write it to the module test-status line.
		'Then delete the temporary file.
		'
		TEMPFILEFOLDER$ = "C:\REPORTS\dstemp.fil"   'Set temporary file name (including folder location).

		'Open and closet the temporary file. This will create a zero-length file
		'that can be deleted (without the program crashing) later if there is no
		'appropriate datasheet file found by the "DIR" command.
		OPEN TEMPFILEFOLDER$ FOR OUTPUT AS #16
		CLOSE #16
		
		'Set shell command line to use a DOS directory command to write the datasheet file
		'name (if the file exists in the "C:\STAGE\" directory) to the temporary file.
		LINESHELL$ = "DIR C:\STAGE\" + RTRIM$(DSFNAME$) + " /B >> " + TEMPFILEFOLDER$
		SHELL LINESHELL$    'Run the shell command to write the datasheet file name to the temporary file.

		'Check for the length of the temporary file. If equal to or more than 4, it likely contains the
		'datasheet file name (the ".txt" portion would count for four characters), so open the file for
		'input and read the line into a string, then delete the temp. file.
		OPEN TEMPFILEFOLDER$ FOR BINARY AS #1
		FILELEN& = LOF(1)
		CLOSE #1
		IF FILELEN& >= 4 THEN
			'File length four characters or more. Read datasheet file name from file.
			OPEN TEMPFILEFOLDER$ FOR INPUT AS #16   'Open temp. file for input.
			LINE INPUT #16, FL$                     'Get one line from the temp. file.   
			CLOSE #16                               'Close the temp. file.
		END IF
		KILL TEMPFILEFOLDER$                    'Delete the temp. file.
	END IF

	'Set up and write the module test-status line to the WO Status Report file.
	WOSFNAME$ = GETWOSFNAME$(SN$)  'Get work order status file name
	OPEN "C:\REPORTS\" + WOSFNAME$ FOR APPEND AS #10
	'PRINT #10, STATE$; TAB(10); RTRIM$(SN$); TAB(20); RTRIM$(DSFNAME$); TAB(34); RTRIM$(SPECS.MODNAME$); TAB(48); DATE$; TAB(60); TIME$
	PRINT #10, STATE$; TAB(10); RTRIM$(SN$); TAB(20); RTRIM$(DSFNAME$); TAB(33); RTRIM$(FL$); TAB(47); RTRIM$(SPECS.MODNAME$); TAB(60); TIME$
	CLOSE #10
	
	KEY(10) ON  'Reactivates F10 key
	
END SUB

SUB WORKORDERPRINT (SN$)
	'Sub to print work order status file

	KEY(10) OFF 'Deactivates F10 key
	
	COLOR 15, 0, 0  'Clear screen to bright white on black background
	CLS
	LOCATE 5, 5: PRINT "PLEASE WAIT WHILE PRINTER PRINTS YOUR TEST RESULTS"

	WOSFNAME$ = GETWOSFNAME$(SN$)  'Get work order status file name
	CALL GETDSFNAME(SN$, DSSNAME$, DSFNAME$)    'Gets datasheet search and file names from serial number

	'Print file
	SHELL "COPY C:\REPORTS\" + WOSFNAME$ + " LPT1 > NUL"'Print work order status file
	LPRINT CHR$(12) 'Form feed

	COLOR 11, 0, 0  'Cyan on black background
	PRINT
	PRINT TAB(10); "Has the " + WOSFNAME$ + " file finished printing?"
	DUMKEY$ = WAITFORKEY("F", 10, 14, 0)    'Waits for "F" key press (display bright yellow on black)
	CLS

	KEY(10) ON  'Reactivates F10 key
	
END SUB

