'Automated Test Software for DSCTx-xx Voltage,
'Current, TC and RTD input models.

'AUTHOR:        John Lehman
'DATE:          4/9/98
'USES LIBRARY = LIBATED.BAS

'       REVISION RECORD

'DATE     APPR    DESCRIPTION
'----     ----    -----------
'4/9/98    JL     Converted from TESTDIN1.BAS
'8/25/98   JL     Fix printing of high voltage message.
'8/27/98   JL     Fix MINLOOPV setting of Vin for MAXIN! >= 10V.
'09/17/98  JL     Add enough logged data to disk to fully reconstruct a data sheet.
'11/11/98  JL     Added GAINCALINT subroutine for transmitters with interactive adjustments.
'03/05/99  JL     Added system configuration notes on screen.
'04/07/99  JL     Test step response from OSCALIN to +f.s. instead of -f.s. to +f.s.
'08/03/99  JL     Added RDAC performance check upon startup.  Changed input
'                 display in LINTEST for mV input transmitters.
'09/16/99  JL     Increased IEXC tolerance from 1.6% to 2.0%.
'11/02/99  JL     Use TE10302 for input to calibrate on-board CJC.
'03/05/00  JL     Voltage input for underrange = 50% span (increased from 25%)
'05/12/00  JL     Correct step reponse limits in report.
'06/29/00  JL     Remove underrange for current input models.
'01/23/01  JL     Add note for DSCT CJC connection.
'02/27/01  CG     Updated for usage of all the DSCT models. Converted from TST2SCT1.BAS
'04/30/01  CG     Updated for better user interface. Converted from TST3SCT1.BAS
'06/08/01  CG     Added the CHAIN command as the software exits to link the program to the FAMILY MENU (menu7b.exe) program.
'06/14/01  CG     Add option menu when running finals. Add CHANGEDN and REPEAT2
'08/09/01  CG     Fixed excitation current test for the -34 and -36 units. SCT1P units
'                 where being test as DSCT units and viceversa.
'08/14/01  CG     For the resistance input units, added a command to turn off the power to the module
'                 before the input resistor is set and added an additional one to set the power
'                 to 24V afterwards. The commands where added to the GAINCAL, OFFSETCAL, OFFSETERR
'                 and LINTEST subroutines.
'08/22/01  CG     Changed the under range input resistance for the RTD test to be fixed at the
'                 minimum possible value of 8ohm.
'08/27/01  JL     Disable KEPCO power supply for |OSCALIN| > 10V.
'09/10/01  CG     Exchanged the definitions of the TE1037 mux channels to match the 5b and DSCA software.
'                 Now channel 6 is used for the sense lines of the contact resistance and
'                 channel 7 is used for the sense lines of the output current sense resistor.
'09/14/01  CG     Added an IF statement in the MEASRES routine to change the sense mux channel depending on what test
'                 test head is being used (resistance input or voltage input).
'                 Additionally enabled the F9 key such that when pushed it returns the user to the
'                 test select menu.
'09/18/01  CG     Updated the SENSORIEXC routine to turn on the supply voltage to the module
'                 in order to measure the excitation current
'10/17/01  CG     Swapped the excitation current test order (#2 and then #1) on the SCT34, 36 individual test
'01/15/02  CG     Added a the condition to calibrate the CJC when running finals on the DSCT units
'                 Changed the linearizer data file location to the E: drive and changed its format to only
'                 contain the error on mV for the DSCT units.
'01/30/02  CG     Added a 2 second pause after measuring the input resistance to the module to prevent
'                 the modules input to be open if power is applied. On measure resistance routine, changed the
'                 DMM setup from resistance to voltage to prevent voltage excitation on the input terminals
'                 while reset the test head to normal setup.
'02/05/02  CG     On the test report, corrected the exc current units (uA). Also displayed the test limit
'                 (5% for DSCT's and 2% for SCT's) for the excitation current. Corrected the parameter name
'                 such that the DSCT display minus and plus fs of the exc current and the SCT display source #1 and #2.
'03/01/02  JL     Re-init DVM after 'T' in cal.
'04/18/02  CG     Corrected the range setting on the step response routine when measuring the first point on bipolar
'                 input units. Added the ONESHOTTEST call (comented) on the main code to calibrate the S/H.
'07/09/02  CG     Corrected frequency generator settings for resistance input units. Limited the offset calibration
'                 verification to two loops only.
'07/12/02  CG     Corrected the max amplitude setting limit for resistance input modules.
'08/01/02  CG     Created a condition not to exceed the input current limit from 31.5mA. the limit was based from the
'                 250ohm resistor inside the test head, 50ohms sense resistors inside the module and the 16ohms max resistance
'                 from the polyswitch.
'04/28/03  CG     Changed the HEADERA, FOOTER, REPORT and LINTEST routines to make datasheet format more
'                 consistent through all the test codes.
'05/05/03  CG     Added a set of wires to channel 4 such that a more precise measurement can be done when
'                 calibrating the SCMVAS modules. Changed the adapter plate (TE1094) to accomodate the new connector.
'05/15/03  CG     In the MEASRES routine opened the mux channels before changing from test 3 to test 2. Before the excitation
'                 voltage from the DMM was being inputed to the module causing a drift error. Changed the location of the
'                 pauses for the resistance input units to after the 24V are applied.Changed was made in the
'                 OFFSETCAL, OFFSETERR, GAINCAL and LINTEST routines. Added selection menu after caibration.
'07/19/03  CG     Correct SCMVAS-MPT testing such that potentiometer calibration is done.
'01/29/04  CG     Removed the SCT1P items in the test code. VAS specific test head was added to the code (TE1120). This
'                 test head was modified to provide a means to test 8B units. The changed required the DAC output channel
'                 to be moved from channel 3 to channel 8. After this change the test head requires the TE1004 mux to test
'                 VAS modules. Also a separate address file (VAS.ADR) had to be created.
'02/06/04  CG     Replaced TE1036 and TE1035 references for TE1088 and TE1089 respectively. Conditionals where made for old
'                 SCT1P test head references.
'07/12/04  CG     Corrected MENU3 condition to reload the correct test equipment addressing depending on the module to be
'                 tested (i.e. resistance or voltage models).
'09/22/04  CG     Changed SCMVAS test section of the code to work with the TE1164 test head.
'                 On the GAINCAL routine added conditional to check for the expected input voltage for
'                 modules with an input voltage bigger than 10V. Correct the DSCT log file names so that the complete model
'                 number is used for storing the data (DSCT32-01 data was being logged under 2-01 and not 32-01). Added another
'                 conditional in the LOGIT routine to log in a separate directory the SCMVAS data.
'09/23/04  CG     Added a loop in the VAS test to remeasure the output until it is within the accuracy specification
'                 before taking the final measurment. NOticed that the output of the Kepco drifts over time.
'01/26/05  CG     On the INITTH changed the test head verification from a fixed value to the one read from the address file.
'03/08/05  CG     Changed the INITTH conditions to fix the TE1088 and TE1164 to an ID of "0" and the TE1089 to "1".
'06/02/05  CG     On the LOOPSENS routine, added a command to turn off the power supply after measuring the output at max Vloop.
'                 When changing the loop voltage from the max limit to 24V, the meter would occasionally trip.
'07/10/06  JL     Reinstate functional test.
'12/07/06  JL     Replaced LIBATE with LIBATEB.  See LIBATEB for details.
'07/11/07  JL     Added ONESHOTTEST as hidden option in Individual Test menu.
'                 Restructured INITTH to eliminate failure message for V or RTD test head not connected.
'08/13/07  MR     Changed VERR from 0.5V to 1.0V, in GAINCAL and GAINERR subroutines.
'11/09/07  TSO    Changed max loop supply test voltage from 100V to 60V, per catalog spec
'11/30/07  TSO    Updated code to work with new KEPCO ABC125 Power Supply
'03/18/08  TSO    Added the function call GETPSID in GETSPECS after the user is instructed to connect a
'                 high-Voltage Power Supply.  This enables the user to connect a power supply if it asks for one.
'04/02/08  TSO    Added conditional inside GAINCAL and GAINERR functions that will turn off the high-voltage
'                 Supply if TE$ = "TE1164" and turn off 24V Power Supply in all other cases.
'09/23/09  TSO    Reinstated the LED observation keypress verification in GAINCAL
'12/11/09  TSO    Added a second storage location to log files on Server T: drive
'03/28/11  TSO    Added a High Voltage Power Supply check algorithm in SCMVAS block
'                 Created a conditional that bypasses LED observation test for
'                 SCMVAS modules inside GAINCAL
'11/19/11   MR    Changed INITOL for OS and GN in functional test to 12%.
'                 Replaced CALSPAN with ORANGE for ERRORPERC calculation.
'06/18/12   MR    Added TCDUTCONNECT and TCDUTDISCONNECT Subroutines
'06/22/12   TSO   Changed offsetcal point to +0.02% and gaincal point to -0.02% on DSCT30-03
'                 Removed ERRFACT! = 2 in OFFSETERR! by commenting it out
'07/10/12   TSO   Changed ERRFACT! to 1 in TST5SCT1 and TST5SCT2 declarations
'                 and reinstated it in OFFSETERR!
'6/13/19     MF   modified display on VAS modules to show Kepco communication.
'7/24/24    BF    Made the test print out SCMHVAS instead of SCMVAS
'08/21/24   BF    Converted the test to say SCMHVAS and use SCMHVAS entries from the database.
DECLARE SUB CALDAC (TE$)
DECLARE SUB CALTEST (CAL%)
DECLARE SUB CHANGEDN (SN$)                      'Allow user to change dash number
DECLARE SUB COMPTEST (STATUS$(), ITERATION%, CAL%, GENAMPL!, TSIM!(), IOUTCALC!(), IOUTMEAS!(), ERRORPERC!(), ACCSTAT$(), LOWMA!, HIGHMA!, TOTLRESPEC!) 'Complete set of tests
DECLARE SUB CONTINUE ()
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 transmitter type and specifications
DECLARE SUB GETSPECS2 ()                        'Gets SCMVAS module data
DECLARE SUB HEADERA (SN$)                       'Prints test sheet header
DECLARE SUB HEADERB (TESTTITLE$)                'Prints test screen header
DECLARE SUB INDIVID (SEL%)                      'Performs the tests individually
DECLARE SUB INIT488 (DEVADDR%)
DECLARE SUB INITTH (TH1$, TH2$)                 'Initializes the Test Heads
DECLARE SUB INITPS (ADDR%, OVERI!, OVERV!)
DECLARE SUB LOADMUX (CH%, CHON%)
DECLARE SUB LOGIT (STATUS$(), SN$, TSIM!(), IOUTCALC!(), IOUTMEAS!(), ERRORPERC!(), ACCSTAT$(), LOWMA!, HIGHMA!, TOTLRESPEC!)              'Logs test results to disk
DECLARE SUB MODOUTLINE ()
DECLARE SUB NOTES ()                            'Notes on ATE operation
DECLARE SUB OHMSET (OHM!)
DECLARE SUB ONESHOTTEST ()                      'Tests one-shot pulse width
DECLARE SUB PAUSE (TIME!)
DECLARE SUB REPORT (STATUS$(), TSPEC$())        'Prints test data on screen
DECLARE SUB RESETTH ()                          'Reset test head to known condition
DECLARE SUB RTDTHCAL ()                         'Check test head operation
DECLARE SUB SETDAC (VOLTAGE!, CH%, VSENATTEN!)
DECLARE SUB SETDACFAST (VOLTAGE!)
DECLARE SUB SETTEST (TEST%)
DECLARE SUB SETTH (DOUT%, CB%)
DECLARE SUB SETTHFAST (DOUT%, CB%)
DECLARE SUB TSPECS (TSPEC$(), LOWMA!, HIGHMA!, TOTLRESPEC!) 'Creates a string array of test specifications
DECLARE SUB SORTDB (ENDFLAG%)
DECLARE SUB WRITEDVM (FUNC$, VALUE!)
DECLARE SUB TCDUTCONNECT ()
DECLARE SUB TCDUTDISCONNECT ()

DECLARE FUNCTION BESTFIT! (SLOPE!, OFFSETS!, TSIM!(), NUMPTS%, ERRO!())
                        'Library fn. Calculates besfit line and max error
DECLARE FUNCTION CALMENU% ()
DECLARE FUNCTION CJCCAL$ ()                     'Calibrate ambient temp sensor
DECLARE FUNCTION FAILS% (STATUS$())             'Tests for failed tests
DECLARE FUNCTION FREQRESP$ (GENAMPL!)           'Performs Frequency response Test
DECLARE FUNCTION GAINCAL$ (CAL%, CONTRES!, PFSMEAS!, INTERACT!, DELTAOS!)  'Performs Gain Calibration
DECLARE FUNCTION GAINCALINT$ (CAL%)
DECLARE FUNCTION GAINERR! (CAL%, CONTRES!, PFSMEAS!, INTERACT!, OSERR2!)
DECLARE FUNCTION GENATTENR! ()                  'Calculate fn gen attenuator
DECLARE FUNCTION GETTHID% ()                    'Library fn. Get test head id #
DECLARE FUNCTION GETPSID% ()
DECLARE FUNCTION IEXC1$ (IEXCSENSE!)            'Measure excitation I source #1
DECLARE FUNCTION IEXC2$ (IEXCSENSE!)            'Measure excitation I source #2
DECLARE FUNCTION IMATCH$ (I1$, I2$)             'Check current source matching
DECLARE FUNCTION INPUTR$ ()                     'Performs Input Resistance Test
DECLARE FUNCTION Iout! (SENOUT!)                'Calculates transmitter output for a given input
DECLARE FUNCTION KEYBDIN$ ()                    'Library fn. Get keyboard input
DECLARE FUNCTION LEADREFF$ (TOTLRESPEC!)        'Measure lead resistance effects
DECLARE FUNCTION LINTEST$ (ACC$, CONTRES!, TSIM!(), IOUTCALC!(), IOUTMEAS!(), ERRORPERC!(), ACCSTAT$())      'Performs Accuracy and Linearity Tests
DECLARE FUNCTION LOOPVSEN$ ()                   'Performs Power Supply Sensitivity
DECLARE FUNCTION MEASRES! (OHM!, RESNUM%, TE$)  'Measure loop current sense resistor
DECLARE FUNCTION MENU0% ()                      'Choose model family to test
DECLARE FUNCTION MENU1% ()                      'Gets the Test Group selection
DECLARE FUNCTION MENU2% ()                      'Gets the individual test #
DECLARE FUNCTION MENU3% ()                      'Gets the transmitter family
DECLARE FUNCTION MINLOOPV$ ()                   'check operation at min loop V
DECLARE FUNCTION MAXLOOPV$ ()                   'check operation at max loop V
DECLARE FUNCTION OFFSETCAL$ (CAL%, CONTRES!)    'Performs Offset Calibration
DECLARE FUNCTION OFFSETERR! (CAL%, CONTRES!)
DECLARE FUNCTION OPENTC$ ()                     'Measure open thermocouple response
DECLARE FUNCTION OUTNOISE$ ()                   'Performs Output Noise Test
DECLARE FUNCTION OVERRANGE$ ()                  'Measure over-range current
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 REPEAT$ (N$)                   'Ask if you would like to repeat test
DECLARE FUNCTION REPEAT2$ (N$, SN$)             'Menu function runned during finals only
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 SENSORIEXC$ (PERCFS%)          'Measures the resistor input exc. current
DECLARE FUNCTION SENSORIN! (PVIN!, PTCV!)       'Calculates sensor input
DECLARE FUNCTION SENSORNUM% ()                  'Assign a number to each sensor type
DECLARE FUNCTION SENSOROUT! (PVIN!, PTCV!)      'Calculates transmitter 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 SETCURRENTIN! (MODIN!)         'Set input current source
DECLARE FUNCTION SETPOWER$ (ADDR%, VSUPPLY!, FUNC$)    'Library fn. Sets supply voltage
DECLARE FUNCTION STEPRESP$ ()                   'Performs Step Response Test
DECLARE FUNCTION STRINGVAL% (A$)                'Library fn.
DECLARE FUNCTION SUPPLYI$ (EXCL%)               'Measure transmitter supply current
DECLARE FUNCTION TCTEMP! (TCV!, SENTYPE$)       'Library fn. Convert TC volts to deg. C
DECLARE FUNCTION TCVOLTS! (TEMP!, TCTYPE$)      'Library fn. Convert TC in temp to V
DECLARE FUNCTION UNDERRANGE$ ()                 'Measure under-range current
DECLARE FUNCTION UPSN$ (SN$)                    'Increments dash# of serial#

'Database Record defintion for the specifications
    TYPE DBASE
    MODNAME         AS STRING * 14  'SCT1P47X-XXXX, DSCT47X-XXXX
    SENTYPE         AS STRING * 7   'mV, V, mA, xTC, xxRTDxW
    MININ           AS SINGLE
    MAXIN           AS SINGLE
    IEXCMFS         AS SINGLE
    IEXCPFS         AS SINGLE
    RCONV           AS SINGLE
    MINOUT          AS SINGLE
    MAXOUT          AS SINGLE
    OSCALPT         AS SINGLE
    GNCALPT         AS SINGLE
    LINEAR          AS SINGLE
    ACCURACY        AS SINGLE
    TESTFREQ        AS INTEGER
    ATTEN           AS INTEGER
    ATTENTOL        AS INTEGER
    STEPRMIN        AS SINGLE
    STEPRMAX        AS SINGLE
    OUTNOISE        AS SINGLE
    INPUTRES        AS SINGLE
    IOPENTC         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
    CALTOL          AS SINGLE   'Calibration tolerance
    VSEN            AS SINGLE   'Loop voltage sensitivity
    END TYPE
           
    TYPE DBASE2
    RECNUM          AS INTEGER
    MODNAME         AS STRING * 14
    END TYPE

'$INCLUDE: 'QB.BI2'

'define common variables
COMMON SHARED /SAMPLE/ SPECS AS DBASE, SORTDATA1 AS DBASE2, SORTDATA2 AS DBASE2
COMMON SHARED /SAMPLE/ PON%, RSENSE!, SN$, LOGDAT%, IINSEN.MEAS!
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 TH$


COMMON SHARED /PRTSCR/ inreg AS RegType, outreg AS RegType

                    'assign constants to Fluke meter commands
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'

                    'assign constants to Kepco DPS power
                    'supply commands
CONST VOLT$ = "STV=", LOOPON$ = "SOP=ON", LOOPOFF$ = "SOP=OFF"
CONST CURRENT$ = "RTC", ISTAT$ = "RCS"
CONST OVERV! = 115                      'Power supply over voltage limit
CONST PSILIMIT! = 500                        'Power supply current limit
CONST VINOVERV! = 125
CONST VINILIMIT! = 32                   'High voltage input current limit
                    'assign constants to Kepco DPS power
                    'supply commands
         
'assign specifications which are constant for all transmitters
CONST IINSEN! = 250                     'Input current source sense resistor, 250ohm
CONST ICL! = .05                        'Max. loop current (over current limit)
CONST LPSEN! = 250                      'Loop current sense resistor, 250 ohm
CONST IEXCSEN! = 2500                   'Iexc sense resistor, 2.5Kohm
CONST IUR1! = .0015                     'Min under-range current (A)
CONST IUR2! = .0038                     'Max under-range current (A)
CONST RSERIES! = 5100000!               '5.1M ohm, test head series input R
CONST RFNGN! = 6800                     'Function generator attenuator series R, 6.8Kohm
CONST ERRFACT! = 1'2 changed 7/10/12 TSO      'Max error in offset allowed (factor)


DIM STATUS(17) AS STRING, TSPEC(17) AS STRING
DIM TSIM!(102), IOUTCALC!(102), IOUTMEAS!(102), ERRORPERC!(102), ACCSTAT$(102)

' Variable intialization
BADDRS% = &H250                         'Base address of PC4311 '488 controller
CB0VAL% = &HFF                          'Set all lines off
CB1VAL% = &HFF
CB2VAL% = &HFF
CB3VAL% = &HFF

'PSPORT% = 1                              'initialize port address

'TE1088 configuration:
'(all control lines are active low)
'Use Relay/Mux TE1013 (see below)
'
'Control Bank    Line      Assignment
'------------   ------     ----------
'     0          7 MSB     0 = Connect Vo to S/H, Start timer
'                6         0 = Connect 2Kohm || 220pF load
'                5         1 = CJC 25C simulation, 0 = CJC 50C simulation
'                4         0 = Tie transmitter inputs to analog ground
'                3         0 = Short transmitter inputs
'                2         0 = Short out 5.1Mohm series input R
'                1         1 = DAC input to transmitter, 0 = Freq. Gen. input
'                0 LSB     0 = Enable output switch
'
'     1          7 MSB     0 = R/2R ladder
'                6         0 = R/2R ladder LSB
'                5         0 = 1Kohm excitation load
'                4         0 = 330ohm excitation load
'                3         0 = 120ohm excitation load
'                2         0 = D.U.T CJC Sensor, 1 = Reference CJC Sensor  (LED #2 on Rev A pcb)
'                1         Vsupply control MSB
'                0 LSB     Vsupply control LSB
'
'     2          7 MSB     0 = R/2R ladder MSB
'                6         0 = R/2R ladder
'                5         0 = R/2R ladder
'                4         0 = R/2R ladder
'                3         0 = R/2R ladder
'                2         0 = R/2R ladder
'                1         0 = R/2R ladder
'                0 LSB     0 = R/2R ladder
'
'     3          7 MSB     High Voltage Input; 0 = V- to +IN, V+ to -IN, 1 = NC
'                6         High Voltage Input; 0 = V+ to +IN, V- to -IN, 1 = NC
'                5         D.U.T. input; 0 = current source, 1 = R/2R ladder
'                4         Input current sourced from; 0 = +EXC, 1 = +15V
'                3         0 = LED4 ON, Disconnect Rsense from loop, 1 = Rsense connected to loop
'                2         0 = LED3
'                1         0 = LED2
'                0 LSB     0 = LED1

'TE1013 Relay/Mux channel assignments (for TE1088 only)

'Mux Channel   Assignment
'-----------   ----------
'     1        Vin (R/2R ladder output)
'     2        Iout sense resistor
'     3        DAC output
'     4        Test head CJC sensor / DUT CJC sensor, multiplexed through relay Kxx
'     5        Sample/Hold output
'     6        Sense lines for Iout sense resistor, 4-wire ohms
'     7        Input current source conversion resistor, source lines
'     8        Input current source conversion resistor, sense lines


'TE1035 & TE1089 (pcb1128 Rev A + pcb1129 Rev A daughter card)
'(all control lines are active low)
'Use Relay/Mux TE1037 (see below)
'
'Control Bank    Line      Assignment
'------------   ------     ----------
'     0          7 MSB     0 = Connect 2Kohm || 220pF load
'                6         0 = Connect Vo to S/H, Start timer
'                5         0 = Enable output switch
'                4         Vsupply control MSB
'                3         Vsupply control LSB
'                2         Test Select MSB (See legend below)
'                1         Test Select
'                0 LSB     Test Select LSB
'
'     1          7 MSB     0 = R DAC MSB, line 20 of 20
'                6         0 = R DAC, line 19
'                5         0 = R DAC, line 18
'                4         0 = R DAC, line 17
'                3         0 = LED4
'                2         0 = LED3
'                1         0 = LED2
'                0 LSB     0 = LED1
'
'     2          7 MSB     0 = R DAC, line 16
'                6         0 = R DAC, line 15
'                5         0 = R DAC, line 14
'                4         0 = R DAC, line 13
'                3         0 = R DAC, line 12
'                2         0 = R DAC, line 11
'                1         0 = R DAC, line 10
'                0 LSB     0 = R DAC, line 9
'
'     3          7 MSB     0 = R DAC, line 8
'                6         0 = R DAC, line 7
'                5         0 = R DAC, line 6
'                4         0 = R DAC, line 5
'                3         0 = R DAC, line 4
'                2         0 = R DAC, line 3
'                1         0 = R DAC, line 2
'                0 LSB     0 = R DAC LSB, line 1

'TE1037 Relay/Mux channel assignments (for TE1089 only)
'Address = 3

'Mux Channel   Assignment
'-----------   ----------
'     1        DUT +/-IN terminals
'     2        Iout sense resistor
'     3        Function Generator input to test head
'     4        Iexc sense resistor
'     5        Sample/Hold output
'     6        Contact resistance sense lines, 4-wire ohms
'     7        Sense lines for Iout sense resistor, 4-wire ohms
'     8        DUT Rin sense lines, 4-wire ohms


'TE1164 (pcb1044 Rev B.) configuration:
'(no control lines are used)
'Use Relay/Mux TE1004 (see below)
'
'
'TE1004 Relay/Mux channel assignments (for TE1164 only)
'Address = 1

'Mux Channel   Assignment
'-----------   ----------
'     1        Vin (Kepco output)
'     2        Vout (VAS output)
'     3        not used
'     4        not used
'     5        not used
'     6        not used
'     7        not used
'     8        not used


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

DO
    SEL0% = MENU0%
    SELECT CASE SEL0%


       
    '*************************** DSCT Test Block *********************************
    CASE 1
        TH1$ = "TE1088"                          'Assign test head #, defines channel
                            'used for DAC input.
        MU1$ = "TE1013"                          'Assign test head #, defines channel
                            'used for DAC input.
        TH2$ = "TE1089"                          'Assign test head #, defines channel
                            'used for DAC input.
        MU2$ = "TE1037"                          'Assign test head #, defines channel
                            'used for DAC input.
        CLS
        LOCATE 3, 25
        COLOR 14, 0, 0
        PRINT "DSCT TEST SYSTEM CONFIGURATION"
        LOCATE 5
        COLOR 15, 0, 0
        PRINT TAB(10); "To test DSCT30-xx, 31-xx, 32-xx, 37x-xx, 47x-xx use"
        PRINT
        PRINT TAB(10); "Test Head   "; TH1$; ""
        PRINT TAB(10); "Relay Mux   "; MU1$; ""
        PRINT TAB(10); "Multimeter  FLUKE 8842A"
        LOCATE 13
        PRINT TAB(10); "To test DSCT34-xx, 36-xx, use"
        PRINT
        PRINT TAB(10); "Test Head    "; TH2$; ""
        PRINT TAB(10); "Relay Mux    "; MU2$; ""
        PRINT TAB(10); "Multimeter  FLUKE 8842A"
     
        CALL CONTINUE
        CALL INITTH(TH1$, TH2$)

        'CALL ONESHOTTEST
        LOGDAT% = -1                    'Log linearity test data OFF

START:
        KEY(9) ON                       'Activates F9 key
        ON KEY(9) GOSUB START           'Traps for F9 key returns to the main menu if pressed


'TSO - During development of the ABC KEPCO integration, I noticed that LOOPOFF$
'was already commanded from INITTH (and GETPSID).  The DPS KEPCO locked-up if
'sent LOOPOFF$ command string more than once in succession
        'SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)               'Turn off loop power

        CALL WRITEDVM("*T2S1", 0)               'Initialize Fluke meter
           
        IF SENSORNUM% = 1 AND (SPECS.MAXIN > 10 OR SPECS.MININ < -10) THEN
            SL$ = SETPOWER$(VINADDR%, 999!, LOOPOFF$)          'Turn off loop power
        END IF

        DO                                      'Main program loop
        SN$ = ""                            'Reset serial number
        SEL1% = MENU1%                      'Gets the # of the sub program
        SELECT CASE SEL1%                   'Branches to the specific Tests

        '**************** Functional Test  ***********************************

            CASE 1
            PON% = 0                                'Sets printer flag ON
            CAL% = 2                                'don't calibrate o.s & gain
     
            CALL GETSPECS                           'Gets transmitter test specs

            IF LEFT$(SPECS.MODNAME, 4) <> "EXIT" THEN
                CALL FUNCTEST(CAL%)
            END IF
      
    
        '*********************** Pre-Burn In Complete Test (NO printout) ******************************
    
            CASE 2
            PON% = -1                               'Print Flag <0 Printer OFF
            CAL% = 0                                'Calibrate o.s. & gain.
                
            CALL GETSPECS                           'Gets transmitter test specs
            IF LEFT$(SPECS.MODNAME, 4) <> "EXIT" THEN
        
                CALL GENSET(GENAMPL!)               'Displays message to set signal gen.
                DO                                  'Complete test loop start
                    ITERATION% = 1                  'Sets # of times to repeat offset/gain cal
                    CALL COMPTEST(STATUS$(), ITERATION%, CAL%, GENAMPL!, TSIM!(), IOUTCALC!(), IOUTMEAS!(), ERRORPERC!(), ACCSTAT$(), LOWMA!, HIGHMA!, TOTLRESPEC!) 'Performs complete set of tests
                    CALL TSPECS(TSPEC$(), LOWMA!, HIGHMA!, TOTLRESPEC!) 'Sets up a string with the test specifications
                    CALL REPORT(STATUS$(), TSPEC$())  'Prints data to screen
                    CALL CONTINUE                   'Waits for a key press
                LOOP WHILE REPEAT$(SPECS.MODNAME) <> "N" 'End of Complete Test loop
                IF SENSORNUM% = 1 AND (SPECS.MAXIN > 10 OR SPECS.MININ < -10) THEN
                    PRINT
                    PRINT TAB(5); "Insert the yellow connector into the meter +/-SENSE terminals."
                    CALL CONTINUE
                END IF
            END IF

        '**************** Post-Burn In Complete Test (with printout)  ***********************************

            CASE 3
            PON% = 1                                'Sets printer flag ON
            CAL% = 0                                'calibrate o.s & gain
        
            CALL GETSPECS                           'Gets transmitter test specs

            IF LEFT$(SPECS.MODNAME, 4) <> "EXIT" THEN
       
                CALL GENSET(GENAMPL!)               'Displays message to set signal generator
                CALL GETSN(SN$)                     'Gets transmitter serial #
                DO                                  'Start of Test loop
                    ITERATION% = 1                  'Sets # of times to repeat offset/gain cal
                    CALL HEADERA(SN$)               'Prints data sheet header on printer
                    CALL COMPTEST(STATUS$(), ITERATION%, CAL%, GENAMPL!, TSIM!(), IOUTCALC!(), IOUTMEAS!(), ERRORPERC!(), ACCSTAT$(), LOWMA!, HIGHMA!, TOTLRESPEC!) 'Performs complete set of tests
                    CALL TSPECS(TSPEC$(), LOWMA!, HIGHMA!, TOTLRESPEC!) 'Creates a string of test parameters
                    WIDTH , 43                      'Change screen lines to 43
                    CALL REPORT(STATUS$(), TSPEC$())  'Displays test results
                    CALL FOOTER(STATUS$())                'Prints footer if no fails
                    'CALL INTERRUPT(5, inreg, outreg)  'Prints test data
                    LPRINT CHR$(12)                 'Send form feed to printer
                    CALL LOGIT(STATUS$(), SN$, TSIM!(), IOUTCALC!(), IOUTMEAS!(), ERRORPERC!(), ACCSTAT$(), LOWMA!, HIGHMA!, TOTLRESPEC!)      'Logs test data to disk
                    CALL CONTINUE                   'Waits for key press
                    WIDTH , 25                      'Change screen lines to 25
                LOOP WHILE REPEAT2$(SPECS.MODNAME, SN$) <> "N" 'End of test loop
                IF SENSORNUM% = 1 AND (SPECS.MAXIN > 10 OR SPECS.MININ < -10) THEN
                    PRINT
                    PRINT TAB(5); "Insert the yellow connector into the meter +/-SENSE terminals."
                    CALL CONTINUE
                END IF
            END IF
      
        '**************** Sealed Module Retest (Print Results, No Adjustments)  ***********************************

            CASE 4
            PON% = 1                                'Sets printer flag ON
            CAL% = 1                                'don't calibrate o.s & gain
       
            CALL GETSPECS                           'Gets transmitter test specs

            IF LEFT$(SPECS.MODNAME, 4) <> "EXIT" THEN
      
                CALL GENSET(GENAMPL!)               'Displays message to set signal generator
                CALL GETSN(SN$)                     'Gets transmitter serial #
                DO                                  'Start of Test loop
                    ITERATION% = 1                  'Sets # of times to repeat offset/gain cal
                    CALL HEADERA(SN$)               'Prints data sheet header on printer
                    CALL COMPTEST(STATUS$(), ITERATION%, CAL%, GENAMPL!, TSIM!(), IOUTCALC!(), IOUTMEAS!(), ERRORPERC!(), ACCSTAT$(), LOWMA!, HIGHMA!, TOTLRESPEC!) 'Performs complete set of tests
                    CALL TSPECS(TSPEC$(), LOWMA!, HIGHMA!, TOTLRESPEC!) 'Creates a string of test parameters
                    WIDTH , 43                      'Change screen lines to 43
                    CALL REPORT(STATUS$(), TSPEC$())  'Displays test results
                    CALL FOOTER(STATUS$())            'Prints footer if no fails
                    'CALL INTERRUPT(5, inreg, outreg)  'Prints test data
                    LPRINT CHR$(12)                 'Send form feed to printer
                    CALL LOGIT(STATUS$(), SN$, TSIM!(), IOUTCALC!(), IOUTMEAS!(), ERRORPERC!(), ACCSTAT$(), LOWMA!, HIGHMA!, TOTLRESPEC!)      'Logs test data to disk
                    CALL CONTINUE                   'Waits for key press
                    WIDTH , 25                      'Change screen lines to 25
                LOOP WHILE REPEAT2$(SPECS.MODNAME, SN$) <> "N" 'End of test loop
                IF SENSORNUM% = 1 AND (SPECS.MAXIN > 10 OR SPECS.MININ < -10) THEN
                    PRINT
                    PRINT TAB(5); "Insert the yellow connector into the meter +/-SENSE terminals."
                    CALL CONTINUE
                END IF
            END IF

        '***********************Individual Test Routines******************************

            CASE 5

            PON% = -1                               'Print Flag <0 Printer OFF
    
            DO                                      'Start of loop
                SEL% = MENU2%                       'Gets # of test
                IF SEL% <> 19 THEN                  'Checks for exit
                    IF SEL% = 16 THEN
                        CALL NOTES                  'Print ATE notes
                    ELSEIF SEL% = 17 THEN           'Checks for printer toggle
                        PON% = -PON%                'Toggles printer status
                    ELSEIF SEL% = 18 THEN
                        LOGDAT% = -LOGDAT%
                    ELSEIF SEL% = 20 THEN
                        CALL ONESHOTTEST
                    ELSE
                        CALL GETSPECS                'Gets transmitter specs
                        IF LEFT$(SPECS.MODNAME, 4) <> "EXIT" THEN
                            CALL INDIVID(SEL%)       'Performs individual test
                        END IF
                    END IF
                END IF
            LOOP UNTIL SEL% = 19                    'End of loop

        '******************* Offset/Gain Excitation Calibration  ***************************
   
            CASE 6
            PON% = -1                               'Print Flag <0 Printer OFF
            CAL% = 0                                'calibrate module
         
            CALL GETSPECS                           'Gets transmitter test specs
            IF LEFT$(SPECS.MODNAME, 4) <> "EXIT" THEN
                IF SNM% = 3 THEN CALL TCDUTCONNECT
                CALL CALTEST(CAL%)
                IF SNM% = 3 THEN CALL TCDUTDISCONNECT
            END IF
       
        '*************************** End Program Selection *********************************
           
            CASE 7
            ENDPROG% = 1                            'Sets end program flag
        END SELECT
        LOOP WHILE ENDPROG% <> 1                            'Loops until end program flag set

      
    '*************************** SCMVAS Test Block *********************************
    CASE 2
        TH1$ = "TE1164"                          'Assign test head #, defines channel
                            'used for DAC input.
        MU1$ = "TE1004"                          'Assign test head #, defines channel
                            'used for DAC input.
        CLS
        LOCATE 3, 25
        COLOR 14, 0, 0
        PRINT "SCMHVAS TEST SYSTEM CONFIGURATION"
        LOCATE 5
        COLOR 15, 0, 0
        PRINT TAB(10); "To test SCMHVAS-Mxxx use"
        PRINT
        PRINT TAB(10); "Test Head   "; TH1$; ""
        PRINT TAB(10); "Relay Mux   "; MU1$; ""
        PRINT TAB(10); "Multimeter  FLUKE 8842A"
        CALL CONTINUE
       
        CALL INITTH(TH1$, "")
        VINADDR% = 0
        COUNT = 0
        WHILE COUNT <> 1!' THEN
            PSID% = GETPSID%
            
           
            'IF VINADDR% <> 2 AND VINADDR% <> 6 THEN
                LOCATE 10, 12: PRINT "A High Voltage Power Supply must be connected"
               
                LOCATE 12, 10: PRINT "Attach either a KEPCO DPS-125 Power Supply as address 2"
                LOCATE 13, 25: PRINT "or"
                LOCATE 14, 7: PRINT "If system is KEPCO ABC-125 Compliant, attach this supply"
                LOCATE 15, 7: PRINT "and set to Power Supply's GPIB address to 6 from the front"
                PRINT TAB(5); "panel by pressing: Menu, Menu, 06, ENTER, RESET."
                LOCATE 19, 7: PRINT "Connect test cables from power supply to test head"
             

            'END IF
            COUNT = COUNT + 1
            CALL CONTINUE
        WEND
             IF VINADDR% <> 2 AND VINADDR% <> 6 THEN
               LOCATE 20, 7: PRINT "Fail to Communicate to Kepco"
               END
             END IF



       
        'CALL ONESHOTTEST
        LOGDAT% = -1                            'Log linearity test data OFF
      
        SN$ = ""                                'Reset serial number
     
   
        CALL GETSPECS                          'Gets attenuator module test specs
     
        IF LEFT$(SPECS.MODNAME, 4) <> "EXIT" THEN
            CALL GETSN(SN$)                         'Get serial #
            DO
                FOR X = 1 TO 16                     'Clear test result array
                    STATUS$(X) = ""
                NEXT X
             
                CLS
                TESTTITLE$ = "Module Installation"
                CALL HEADERB(TESTTITLE$)
                LOCATE 10, 10
                PRINT ; "Install the module on the test head adapter TE1094."
                PRINT
                PRINT TAB(10); "Plug the assembly into the test head input connector."
                CALL CONTINUE

                IF LEFT$(SPECS.MODNAME, 10) <> "SCMHVAS-MPT" THEN
                    CAL% = 0                            'Calibrate attenuation
                ELSE
                    CAL% = 1                            'Pass-thru. Do not calibrate attenuation
                END IF
               
                ITER% = 0
                DO
                    ITER% = ITER% + 1
                    A$ = GAINCAL$(CAL%, 0, 0, 1, 0)
                    IF CAL% = 0 THEN
                        CALERR! = GAINERR!(1, 0, 0, 1, 0)
                    ELSE
                        CALERR! = 0
                    END IF
                    IF ABS(CALERR!) >= SPECS.CALTOL AND ITER% < 3 THEN
                        RECAL$ = "Y"
                        PRINT TAB(10); ""
                        PRINT TAB(10); "Calibration error is bigger than allowed."
                        PRINT TAB(10); "Software will loop back for recalibration.";
                        PAUSE (1)
                    ELSEIF ABS(CALERR!) >= SPECS.CALTOL AND ITER% >= 3 THEN
                        RECAL$ = "N"
                        PRINT TAB(10); ""
                        PRINT TAB(10); "Maximum limit of iterations reached."
                        PRINT TAB(10); "Continuing with final test.";
                        PAUSE (1)
                    ELSE
                        RECAL$ = "N"
                    END IF
                LOOP WHILE RECAL$ = "Y"
               
                IF LEFT$(A$, 4) <> "FAIL" THEN      'Module passed, now test in case
                    CLS
                    TESTTITLE$ = "Module Installation"
                    CALL HEADERB(TESTTITLE$)
                    LOCATE 10, 10
                    PRINT "Remove the module under test from the test head."
                    PRINT
                    PRINT TAB(10); "Install the module in its plastic case and snap on the header."
                    PRINT
                    PRINT TAB(10); "Re-install the module on the test head adapter (TE1094)."
                    PRINT
                    PRINT TAB(10); "Plug the assembly back into the test head input connector."
                    CALL CONTINUE
                 
                    CAL% = 1                        'Measure attenuation, don't calibrate
                    PON% = 1                                'Sets printer flag ON
                    STATUS$(9) = GAINCAL$(CAL%, 0, 0, 1, 0)
                    CALL HEADERA(SN$)               'Prints data sheet header on printer
                    CALL TSPECS(TSPEC$(), LOWMA!, HIGHMA!, TOTLRESPEC!) 'Creates a string of test parameters
                    CALL REPORT(STATUS$(), TSPEC$())  'Displays test results
                    CALL FOOTER(STATUS$())            'Prints footer if no fails
                    'CALL INTERRUPT(5, inreg, outreg)  'Prints test data
                    LPRINT CHR$(12)                 'Send form feed to printer
                    CALL LOGIT(STATUS$(), SN$, TSIM!(), IOUTCALC!(), IOUTMEAS!(), ERRORPERC!(), ACCSTAT$(), LOWMA!, HIGHMA!, TOTLRESPEC!)      'Logs test data to disk
                    CALL CONTINUE                   'Waits for key press
                END IF
            LOOP WHILE REPEAT2$(SPECS.MODNAME, SN$) <> "N" 'End of test loop
        END IF
      
    '*************************** Exit Program *********************************
    CASE 3        'PROGRAM END
       GOTO START
    END SELECT
LOOP
    
FINISH:
    IF SEL0% <> 0 THEN
        SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)               'Turn off loop power
        SL$ = SETPOWER$(PSADDR%, 999!, "LOC")                  'Return to local mode
        SL$ = SETPOWER$(PSADDR%, 999!, "ZER")             'Clear the error queue
           
        IF SENSORNUM% = 1 AND (SPECS.MAXIN > 10 OR SPECS.MININ < -10) AND TH$ <> "TE1164" THEN
            SL$ = SETPOWER$(VINADDR%, 999!, LOOPOFF$)          'Turn off loop power
            SL$ = SETPOWER$(VINADDR%, 999!, "LOC")             'Return to local mode
            SL$ = SETPOWER$(VINADDR%, 999!, "ZER")             'Clear the error queue
           
        END IF
    END IF
   
    CHAIN "C:\ATE\MENUX"
    END                                             'End of program

MAINMENU:
    CHAIN "C:\ATE\MENUX"
END
'SUB HEADERA (SN$)

'    LPRINT TAB(32); "TEST DATA SHEET"
'    FOR X = 1 TO 80
'    LPRINT "~";
'    NEXT
'    LPRINT
'    IF LEFT$(SPECS.MODNAME, 6) = "SCMVAS" THEN
'    LPRINT TAB(5); "Module Type: "; SPECS.MODNAME
'    ELSE
'    LPRINT TAB(5); "Transmitter Type: "; SPECS.MODNAME
'    END IF
'    LPRINT
'    LPRINT TAB(5); "Serial Number: "; SN$
'    LPRINT

FUNCTION CALMENU%

    TESTTITLE$ = "Post Calibration Test Options"
 
    CLS
    COLOR 14, 0, 0
    LOCATE 2, 23:
    TESTTITLE$ = "Post Calibration Test Options"
    CALL HEADERB(TESTTITLE$)
    COLOR 15, 0, 0
    LOCATE 6
    PRINT TAB(14); "Please select the desired option for the next test:"
    LOCATE 8
    COLOR 11, 0, 0
    PRINT TAB(22); "1.) Repeat OFFSET/GAIN calibration"
    PRINT TAB(22); "2.) Perform LINEARITY/ACCURACY test"
    PRINT TAB(22); "3.) EXIT to individual test menu"
    PRINT
    PRINT

    DO
        I$ = INKEY$
    LOOP WHILE VAL(I$) < 1 OR VAL(I$) > 3
   
    SEL2% = VAL(I$)

    CALMENU% = SEL2%

END FUNCTION

SUB CALTEST (CAL%)
  
    IF SETPOWER$(PSADDR%, 24!, FUNC$) = "FAIL" THEN        'Set loop V to 24V
        EXIT SUB                                    'Do not proceed if over-
                                                    'current is detected
    END IF
  
    SNM% = SENSORNUM%
    IF SENSOROUT!(SPECS.MININ, 0) = 99! THEN        'Check for valid sensor type
        EXIT SUB
    ELSEIF SNM% = 2 THEN                            'Check if current input
        IINSEN.MEAS! = MEASRES!(IINSEN!, 5, "")     'Measure current source sense R
    END IF
   
    DO
        IF SNM% = 3 AND LEFT$(SPECS.MODNAME, 4) = "DSCT" THEN
            A$ = CJCCAL$                                'Ambient temp sensor cal.
        ELSEIF SNM% = 3 AND PON% < 0 AND LEFT$(SPECS.MODNAME, 4) = "SCT1" THEN
            A$ = CJCCAL$                                'Ambient temp sensor cal.
        END IF                                          'Pre-encap only.
       
        ITERATION% = 0
      
        DO
            IF SNM% >= 5 AND SNM% <= 7 THEN             'Check if resistance in
                SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)       'Disable power supply
                CONTRES! = MEASRES!(1!, 4, "")          'Measure contact resistance
            END IF
          
            A$ = OFFSETCAL$(CAL%, CONTRES!)             'Offset calibration
              
            A$ = GAINCAL$(CAL%, CONTRES!, PFSMEAS!, INTERACT!, DELTAOS!)  'Gain calibration
          
            OFFERR! = OFFSETERR!(CAL%, CONTRES!)
            ITERATION% = ITERATION% + 1
        LOOP WHILE ABS(OFFERR!) >= ERRFACT * SPECS.CALTOL AND ITERATION% < 2
      
        SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)               'Disable power supply
        CALL RESETTH                                    'Reset test head
   
    LOOP WHILE REPEAT$(SPECS.MODNAME) <> "N"

END SUB

FUNCTION CJCCAL$
       
    'Calibrate the D.U.T. ambient temperature sensor.
    'This test can be performed only on unencapsulated units.

    MODNAME$ = SPECS.MODNAME
    TERROR! = .1                            'Temp sensor error (mV)
                        '+/-0.1mV = +/-0.04 deg. C

    CLS
    TESTTITLE$ = "Ambient Temperature Sensor Calibration"
    CALL HEADERB(TESTTITLE$)
    LOCATE 10, 10

    IF SENSORNUM% <> 3 THEN
    PRINT "This test is performed on un-encapsulated, thermocouple"
    PRINT TAB(10); "input transmitters only (except Type B)."
    CALL CONTINUE
    EXIT FUNCTION
    ELSE
        CALL MODOUTLINE
        LOCATE 4, 30
        PRINT "x x"
        LOCATE 7, 31
        PRINT CHR$(24); "  "; CHR$(24)
        PRINT TAB(30); "P1  CJC POTENTIOMETER"
    END IF
       
    PRINT TAB(10); "Make sure that test box TE10302 is connected and is turned on."
    PRINT
    PRINT TAB(10); "The adjustment potentiometer is located on the left side of the"
    PRINT TAB(10); "module under test above the brass terminal blocks."
    CALL CONTINUE
   
    CLS
    TESTTITLE$ = "Ambient Temperature Sensor Calibration"
    CALL HEADERB(TESTTITLE$)
    LOCATE 10, 10
    PRINT "Testing, please wait...";
    PRINT SPC(40); : PRINT
    PRINT SPC(66); : PRINT
    PRINT SPC(30); : PRINT
    PRINT SPC(70);

    DO
    TIME1! = TIMER                          'Start timer

    CALL LOADMUX(4, CON%)                   'Measure TE10302 CJC sensor output
    CALL WRITEDVM(VODC$, .5)                'Vcjc(25C) = 0.5100V
    THVCJC! = READDVM(.001)
    CALL LOADMUX(4, COFF%)
    IF ABS(THVCJC! - .51) > .05 THEN        '+/- 25C error for malfunction
        SOUND 1000, .5                      'This means 0C <= Ta <= 50C
        PRINT
        PRINT TAB(10); "TE10302 temperature sensor malfunction."
        PRINT TAB(10); USING "Vcjc = #.### V"; THVCJC!
        CALL CONTINUE
        CALL LOADMUX(4, COFF%)
        EXIT FUNCTION
    END IF
           
    CB1VAL% = CB1VAL% AND &HFB              '1 1 1 1  1 0 1 1
    CALL SETTH(CB1VAL%, CB1%)               'Measure DUT CJC sensor output
    CALL LOADMUX(4, CON%)
                        'Reset when SETTH executed
   
    LOCATE 10, 10
    PRINT "Temperature Sensor Error ="
      
    DO
        DUTVCJC! = READDVM(.001)
        IF ABS(DUTVCJC! - .51) > .05 THEN   '+/- 25C error for malfunction
        SOUND 1000, .5                  'This means 0C <= Ta <= 50C
        PRINT
        PRINT TAB(10); "Transmitter temperature sensor malfunction."
        PRINT TAB(10); USING "Vcjc = #.### V"; DUTVCJC!
        CB1VAL% = CB1VAL% OR &H4                '0 0 0 0  0 1 0 0
        CALL SETTH(CB1VAL%, CB1%)               'Reset to TE10302 CJC sensor output
        CALL LOADMUX(4, COFF%)
        CJCCAL$ = "FAIL"
        EXIT FUNCTION
        ELSE
        CJCCAL$ = "PASS"
        END IF
      
        ERRORV! = (DUTVCJC! - THVCJC!) * 1000       'Error in mV
                            'Error in C = ERRORV!/-2.5
        LOCATE 10, 37
       
        PRINT USING "+###.# mV"; ERRORV!
        PRINT TAB(37); USING "+##.# C"; ERRORV! / -2.5
       
        LOCATE 15, 10
        IF ABS(ERRORV!) < TERROR! THEN
        SOUND 600, .5
        PRINT "Stop turning temp. sensor potentiometer          "
        CONREADS% = CONREADS% + 1
        ELSEIF ERRORV! < 0 THEN
        PRINT "Turn temp. sensor potentiometer clockwise        "
        CONREADS% = 0
        ELSE
        PRINT "Turn temp. sensor potentiometer counter-clockwise"
        CONREADS% = 0
        END IF
       
        LOCATE 20, 10
        A$ = INKEY$
      
        IF UCASE$(A$) = "T" THEN
        PRINT TAB(10); "Trouble Shooting Mode"
        CALL WRITEDVM("*", MINOUT!)
        CALL CONTINUE
        LOCATE 20, 10
        PRINT SPC(22);
        ELSEIF UCASE$(A$) = "C" THEN
        CONREADS% = 5
        END IF
      
        TOTTIME! = TIMER - TIME1!               're-measure cjc voltage
                            'once every 20s
        CALL PAUSE(.2)                          'Slow loop down
    LOOP WHILE CONREADS% < 5 AND TOTTIME! < 20!
        
    CB1VAL% = CB1VAL% OR &H4                '0 0 0 0  0 1 0 0
    CALL SETTH(CB1VAL%, CB1%)               'Measure TE10302 CJC sensor output
    CALL LOADMUX(4, COFF%)
   
    LOOP WHILE CONREADS% < 5

    PRINT TAB(10); "Remove the CJC connector from the transmitter."
    CALL CONTINUE
    'CALL PAUSE(1!)

END FUNCTION

SUB COMPTEST (STATUS$(), ITERATION%, CAL%, GENAMPL!, TSIM!(), IOUTCALC!(), IOUTMEAS!(), ERRORPERC!(), ACCSTAT$(), LOWMA!, HIGHMA!, TOTLRESPEC!)

    SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)                'Set loop V to 24V
   
    SNM% = SENSORNUM%
    IF SENSOROUT!(SPECS.MININ, 0) = 99! THEN        'Check for valid sensor type
        EXIT SUB
    ELSEIF SNM% = 2 THEN                            'Check if current input
        IINSEN.MEAS! = MEASRES!(IINSEN!, 5, "")     'Measure current source sense R
    ELSEIF SNM% = 3 THEN
        CALL TCDUTCONNECT
    END IF
      
    FOR X = 1 TO 16                                 'Clear test result array
        STATUS$(X) = ""
    NEXT X

    IF SNM% <> 2 AND SNM% <> 7 THEN
        STATUS$(1) = UNDERRANGE$                    'Under-range test
    ELSE
        STATUS$(1) = "PASS"                         'Pot in can't be under-ranged
    END IF

    STATUS$(2) = OVERRANGE$                         'Over-range test
    STATUS$(3) = MINLOOPV$                          'Minimum loop voltage test
    STATUS$(4) = MAXLOOPV$                          'Maximum loop voltage test
     
    IF SNM% = 3 AND LEFT$(SPECS.MODNAME, 4) = "DSCT" THEN
        A$ = CJCCAL$                                'Ambient temp sensor cal.
    ELSEIF SNM% = 3 AND PON% < 0 AND LEFT$(SPECS.MODNAME, 4) = "SCT1" THEN
        A$ = CJCCAL$                                'Ambient temp sensor cal.
    END IF                                          'Pre-encap only.
       
    IF SNM% >= 5 AND SNM% <= 7 THEN                 'Check if resistance in
        SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)           'Disable power supply
       
    IF (SNM% = 5 AND LEFT$(SPECS.MODNAME, 4) <> "DSCT") OR (SNM% = 7 AND LEFT$(SPECS.MODNAME, 4) <> "DSCT") THEN
        STATUS$(6) = IEXC2$(IEXCSENSE!)
        STATUS$(5) = IEXC1$(IEXCSENSE!)
        STATUS$(7) = IMATCH$(STATUS$(5), STATUS$(6))
    ELSEIF (SNM% = 5 AND LEFT$(SPECS.MODNAME, 4) <> "SCT1") OR (SNM% = 7 AND LEFT$(SPECS.MODNAME, 4) <> "SCT1") THEN
        STATUS$(5) = SENSORIEXC$(0)             'min f.s. exc current
        STATUS$(6) = SENSORIEXC$(1)             'max f.s. exc current
        STATUS$(7) = "PASS"
    ELSE
        STATUS$(5) = IEXC1$(IEXCSENSE!)
        STATUS$(6) = "PASS"
        STATUS$(7) = "PASS"
    END IF
    ELSE
    STATUS$(5) = "PASS"
    STATUS$(6) = "PASS"
    STATUS$(7) = "PASS"
    END IF
       
    ITERATION% = 0
   
    DO
        IF SNM% >= 5 AND SNM% <= 7 THEN             'Check if resistance in
            SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)       'Disable power supply
            CONTRES! = MEASRES!(1!, 4, "")          'Measure contact resistance
        END IF
       
        A$ = OFFSETCAL$(CAL%, CONTRES!)             'Offset calibration
           
        A$ = GAINCAL$(CAL%, CONTRES!, PFSMEAS!, INTERACT!, DELTAOS!)  'Gain calibration
       
        IF CAL% = 0 THEN
            OFFERR! = OFFSETERR!(CAL%, CONTRES!)
        ELSE
            OFFERR! = 0
        END IF
        ITERATION% = ITERATION% + 1
    LOOP WHILE ABS(OFFERR!) >= ERRFACT * SPECS.CALTOL AND ITERATION% < 2

    IF SNM% >= 5 AND SNM% <= 7 THEN                 'Check if resistance in
    SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)           'Disable power supply
    CONTRES! = MEASRES!(1!, 4, "")              'Measure contact resistance
    END IF
   
    STATUS$(8) = LINTEST$(ACC$, CONTRES!, TSIM!(), IOUTCALC!(), IOUTMEAS!(), ERRORPERC!(), ACCSTAT$())          'Performs linearity and
                            'accuracy tests
    STATUS$(9) = ACC$                               'Assigns results of accuracy test
                   
    'IF SNM% = 5 OR SNM% = 7 THEN                    'Check if 3-wire resistance in
    '    STATUS$(10) = LEADREFF$(TOTLRESPEC!)
    'ELSE
    '    STATUS$(10) = "PASS"
    'END IF
     
    STATUS$(11) = LOOPVSEN$                         'Loop supply sensitivity
       
'    IF SNM% = 1  AND SPECS.MAXIN < 10! THEN         'Check for V in
'                                                    'and Vmax <= 10V
'        STATUS$(12) = INPUTR$                       'Input resistance / bias
'    ELSE
    STATUS$(12) = "PASS"
'    END IF
       
    IF SNM% = 3 OR SNM% = 4 THEN                    'Check for TC in
    STATUS$(13) = OPENTC$                       'Open thermocouple response
    ELSE
    STATUS$(13) = "PASS"
    END IF
           
    STATUS$(14) = FREQRESP$(GENAMPL!)               'Tests Frequency Response
       
    IF SPECS.STEPRMIN < 97 AND SENSOROUT!(SPECS.MAXIN, 0) < 25! AND (SNM% < 5 OR SNM% > 7) AND SNM% <> 2 THEN
                            'Resistance input test head has too much delay
                            'Current source not set up for SETTHFAST
                            'Check for b.w. > approx 10Hz
    STATUS$(15) = STEPRESP$                     'Tests Step Response
    ELSE
    STATUS$(15) = "PASS"
    END IF
       
    STATUS$(16) = OUTNOISE$                         'Test Output Noise
     
    SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)               'Disable power supply
    IF SNM% = 3 THEN CALL TCDUTDISCONNECT

END SUB

FUNCTION FAILS% (STATUS$())

    FAILS% = 0

    FOR X = 1 TO 16
    IF LEFT$(STATUS$(X), 1) = "F" THEN        'Tests for failed tests
        FAILS% = 1
    END IF
    NEXT

END FUNCTION

SUB FOOTER (STATUS$())
       
    'NEED TO REVISE IN ORDER TO CHAGE CHECKLIST FOR VAS MODULES
   
    IF FAILS%(STATUS$()) <> 1 THEN
        IF LEFT$(SPECS.MODNAME, 7) = "SCMHVAS" THEN
            PRINT
            PRINT
        ELSE
            PRINT TAB(5); "240VAC Withstand"; TAB(71); "PASS"
            PRINT TAB(5); "Hi-Pot"; TAB(71); "PASS"
        END IF
     
        PRINT TAB(5);
        FOR X = 5 TO 75
            PRINT "_";
        NEXT
        PRINT
        PRINT TAB(35); "Check List"
        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) = "SCMHVAS" THEN
                LPRINT
                LPRINT
            ELSE
                LPRINT TAB(5); "240VAC Withstand"; TAB(71); "PASS"
                LPRINT TAB(5); "Hi-Pot"; TAB(71); "PASS"
            END IF
    
            LPRINT TAB(5);
            FOR X = 5 TO 75
                LPRINT "_";
            NEXT
            LPRINT
            LPRINT TAB(35); "Check List"
            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
END SUB

FUNCTION FREQRESP$ (GENAMPL!)

    MININ! = SENSOROUT!(SPECS.MININ, 0)         'Determine min in
    MAXIN! = SENSOROUT!(SPECS.MAXIN, 0)         'Determine max in
    IEXCMFS! = SPECS.IEXCMFS / 1000000!               'Convert to A

    INRANGE! = MAXIN! - MININ!
    ORANGE! = (SPECS.MAXOUT - SPECS.MINOUT) / 1000! 'Convert to A

    SPEC! = SPECS.ATTEN
    SPECTOL! = SPECS.ATTENTOL
    SNM% = SENSORNUM%
       
    CLS
    TESTTITLE$ = "Frequency Response Test"
    CALL HEADERB(TESTTITLE$)
    LOCATE 10, 10
    PRINT "Testing, please wait."
       
    IF SNM% >= 5 AND SNM% <= 7 THEN             'Check if resistance in
    'Simulated RTD input is the bottom leg in a voltage divider
    'from the function generator.  The series resistor is 6.8Kohms.
    R! = GENATTENR!                         'Find attenuator shunt R
    CALL OHMSET(R!)
    THATTEN! = (6800! + R!) / R!
    XFERFN! = ORANGE! / (INRANGE! * IEXCMFS!)  'Gain in V/V
    ELSEIF SNM% = 2 THEN                        'mA in
    THATTEN! = IINSEN.MEAS!
    XFERFN! = ORANGE! / (INRANGE! / 1000!)  'V/mA
    ELSE
        IF ABS(MAXIN!) > 10 THEN MAXIN! = 10
    THATTEN! = SETATTEN%(MAXIN!)            'Set test head attenuator
    XFERFN! = ORANGE! / INRANGE!             'Gain in V/V
    END IF
     
    VOUTMEAS! = READDVM!(.001)              'Reads Meter

    VAC! = SETAC!(CON%, GENAMPL!)           'Turns on AC input
    
    CALL LOADMUX(2, CON%)                   'Turns on mux
    CALL WRITEDVM(VOAC$, 2000!)             'Sets up Meter (Autorange)
       
     
    VOUTMEAS! = READDVM!(.0001)             'Reads Meter
    IF VOUTMEAS! > .0002 THEN
    VOUTMEAS! = SQR(VOUTMEAS! ^ 2 - .0002 ^ 2)  'Account for meter zero-input error
    END IF                                          'See output noise test for details
    IOUTMEAS! = VOUTMEAS! / RSENSE!         'Reads Meter
       
    CALL LOADMUX(2, COFF%)                  'Turns off mux
    
                        'Calculate attenuation
                        'max 2% error from R/2R ladder
                        'ideal assumption results in
                        '0.3% error in 60dB measurement.
    ATTEN! = -20 * (LOG(IOUTMEAS! / (VAC! / THATTEN! * XFERFN!)) / LOG(10))
       
    IF ABS(ATTEN! - SPEC!) <= SPECTOL! THEN
    ATTEN$ = "PASS"
    ELSE
    ATTEN$ = "FAIL"
    SOUND 1000, .5
    END IF

    LOCATE 10, 10
    PRINT "Status: "; ATTEN$;
    PRINT SPC(20);
    PRINT TAB(10); USING "Attenuation at ##### Hz is"; SPECS.TESTFREQ%;
    PRINT TAB(50); USING "###.# dB"; ATTEN!
    PRINT TAB(10); "Required attenuation is";
    PRINT TAB(50); USING "###.# +/- ##.# dB"; SPEC!; SPECTOL!
       
    FREQRESP$ = ATTEN$ + STR$(ATTEN!) + "1"

    VAC! = SETAC(COFF%, GENAMPL!)                   'Turns off AC input
       
    CALL PAUSE(1!)

END FUNCTION

SUB FUNCTEST (CAL%)
       
    'Sequence of tests to determine if main transmitter circuits are functional
     
    MAXOUT! = SPECS.MAXOUT
       
    IF SETPOWER$(PSADDR%, 24!, FUNC$) = "FAIL" THEN        'Set loop V to 24V
    EXIT SUB                                    'Do not proceed if over-
                            'current is detected
    END IF
  
    SNM% = SENSORNUM%
    IF SENSOROUT!(SPECS.MININ, 0) = 99! THEN        'Check for valid sensor type
    EXIT SUB
    ELSEIF SNM% = 2 THEN                            'Check if current input
    IINSEN.MEAS! = IINSEN!                      'Assign current source sense R
    ELSEIF SNM% = 3 THEN
        CALL TCDUTCONNECT
    END IF

    DO
    SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)                       'Set Vsupply to 24.0V
    CONFLAG% = 0
    FOR FTEST% = 1 TO 3
        SELECT CASE FTEST%
        CASE 1
            IF SNM% <> 2 AND SNM% <> 7 THEN
            IF LEFT$(UNDERRANGE$, 4) = "FAIL" THEN  'Under-range check
                CALL CONTINUE
                CONFLAG% = 1                'Sets exit flag
            END IF
            END IF
                
            IF LEFT$(OVERRANGE$, 4) = "FAIL" THEN  'Over-range check
            CALL CONTINUE
            CONFLAG% = 1                    'Sets exit flag
            END IF
        CASE 2
            IF LEFT$(MINLOOPV$, 4) = "FAIL" THEN    'Operation @ min loop V
            CALL CONTINUE
            CONFLAG% = 1
            END IF
                
            IF LEFT$(MAXLOOPV$, 4) = "FAIL" THEN    'Operation @ max loop V
            CALL CONTINUE
            CONFLAG% = 1
            END IF
        CASE 3
            CONTRES! = 0
            IF LEFT$(OFFSETCAL$(CAL%, CONTRES!), 4) = "FAIL" THEN
'            CALL CONTINUE           'Checks for offset error < 12% span
            CONFLAG% = 1
            END IF
                
            IF LEFT$(GAINCAL$(CAL%, CONTRES!, PFSMEAS!, INTERACT!, OSERR2!), 4) = "FAIL" THEN
'            CALL CONTINUE           'Checks for Gain error < 12% span
            CONFLAG% = 1
            END IF
        END SELECT
        IF CONFLAG% <> 0 THEN EXIT FOR
    NEXT
       
    SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)           'Disable power supply
                         
    IF SNM% = 3 THEN CALL TCDUTDISCONNECT
    LOOP WHILE REPEAT$(SPECS.MODNAME) <> "N"        'Repeat for another transmitter
       
    CALL RESETTH                                    'Reset the test head

END SUB

FUNCTION GAINCAL$ (CAL%, CONTRES!, PFSMEAS!, INTERACT!, OSERR2!)
       
    'Calibrate module gain
    'Inputs;        calibration flag
    '       CAL%    0 = calibrate module; high accuracy input, loop until calibrated,
    '                   narrow error tolerance, AMPL! = 0, use SPECS.GNCALIN for DUT input
    '               1 = measure once and exit, high accuracy input,
    '                   narrow error tolerance, use AMPL! for DUT input.
    '               2 = functional test; coarse input setting, wide error tolerance,
    '                   measure once and exit, AMPL! = 0, use SPECS.GNCALIN for DUT input
    '
    '               measured contact resistance (used for resistance in only)
     
    SENSOR$ = SPECS.SENTYPE
    MINOUT! = SPECS.MINOUT
    MAXOUT! = SPECS.MAXOUT
    INITTOL! = 12                           'Uncalibrated offset tolerance
    ACCTOL! = SPECS.ACCURACY                'Final calibration tolerance
    CALTOL! = SPECS.CALTOL                  'Calibration tolerance (% span)
    OSCALIN! = SPECS.OSCALIN                'transmitter input for offset calibration
    GNCALIN! = SPECS.GNCALIN                'transmitter input for gain calibration
    BANDWIDTH! = SPECS.BANDWIDTH
    LIN% = SPECS.LINEARIZED
    CALGN! = SPECS.GNCALPT / 100!           'Convert from %
   
    ORANGE! = (MAXOUT! - MINOUT!) / 1000    'Output range (A)
    SNM% = SENSORNUM%

    IF (SNM% >= 3 AND SNM% <= 6) AND LIN% = 0 THEN
        CALSPAN! = Iout!(SENSOROUT!(GNCALIN!, 0)) - Iout!(SENSOROUT!(OSCALIN!, 0)) 'Adjustment range is +/- x% of +f.s.
                        'Output not linear w/ input
    ELSE                                        'temperature.
        CALSPAN! = Iout!(GNCALIN!) - Iout!(OSCALIN!) 'Adjustment range is +/- x% of +f.s.
    END IF
       
    CLS
    TESTTITLE$ = "Gain Calibration"
    CALL HEADERB(TESTTITLE$)
   
    CALL MODOUTLINE
    LOCATE 7
    PRINT TAB(44); CHR$(24);
    PRINT TAB(35); "GAIN POTENTIOMETER";
     
    IF CAL% = 2 THEN
        GERROR! = INITTOL!                      'tolerance for func. test (%)
        TOL! = .0001                            'Measurement tolerance, 1 pass test
    ELSEIF CAL% = 1 THEN
        GERROR! = ACCTOL!                       'tolerance for cal check
        TOL! = .0001                            'Measurement tolerance, 1 pass test
    ELSE
        GERROR! = CALTOL!                       'Gain calibration tolerance (%)
        TOL! = 0!                               'Measurement tolerance, continuous test
    END IF
       
    IF SNM% >= 5 AND SNM% <= 7 THEN             'Check if RTD in
        MAXIN! = SENSOROUT!(GNCALIN!, 0)        'Calc. +f.s. ohms
        CALL OHMSET(MAXIN!)                     'Set +f.s. input
    END IF
       
    IF LEFT$(SPECS.MODNAME, 7) <> "SCMHVAS" THEN
        LOCATE 19, 10
        PRINT "Observe that the LED between the potentiometers is ON."
        BEEP ': BEEP: BEEP
        LOCATE 20, 5
        PRINT "After you have verified the LED is ON, you may press any key to continue."
        CALL CONTINUE
    END IF

    DO
        TIME1! = TIMER                          'Start timer
        LOCATE 10, 10
        PRINT TAB(10); "Measuring input.  Please wait..."
        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
            SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)       'Disable power supply
            MAXINMEAS! = MEASRES!(MAXIN!, 3, "") + CONTRES! 'Measure simulated resistor
            SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)           'Set Vsupply to 24.0V
            PAUSE (2)
        ELSE
            IF SNM% = 3 THEN
                PTCV! = PARASITICTCV!(VCJC!)
                IF VCJC! = 99! THEN EXIT FUNCTION
            END IF
            MAXIN! = SENSOROUT!(GNCALIN!, PTCV!)        'Calc. maxin volts
            IF SNM% = 2 THEN
                MAXINMEAS! = SETCURRENTIN!(MAXIN!)
            ELSE
                CALL SETDAC(MAXIN!, 1, 0)               'Sets DAC
                IF CAL% = 0 OR MAXIN! > 10! THEN        'Always measure high voltage
                                                        'input to get exact setting
                    CALL WRITEDVM("S0", 0)                  'Slow reading rate for max accuracy
                    CALL LOADMUX(1, CON%)
                    CALL WRITEDVM(VODC$, MAXIN!)            'Sets meter to read
                    MAXINMEAS! = READDVM!(MAXIN! * .0002)   '0.02% tolerance
                    CALL LOADMUX(1, COFF%)
                    VERR! = MAXINMEAS! - MAXIN!
                    IF ABS(VERR!) > 1! THEN                  '1.0 V tolerance
                        BEEP
                        PRINT TAB(10); "Input voltage out of range"
                        PRINT TAB(10); "Error = "; VERR!; "V"
                        PRINT TAB(10); "Check all the test head connections."
                        PRINT TAB(10); "Notify engineering if problem persists."
                        CONTINUE
                        STOP
                    END IF
                ELSE
                    MAXINMEAS! = MAXIN!
                END IF
            END IF
        END IF
     
        CALL WRITEDVM("S1", 0)       'Medium reading rate
       
        IF (SNM% >= 3 AND SNM% <= 6) AND LIN% = 0 THEN  'Output not linear w/ input
                                                        'temperature.
            IOUTCALC! = Iout!(MAXINMEAS! + PTCV!) + CALGN! * ORANGE!
                        
        ELSE
            IOUTCALC! = (Iout!(SENSORIN!(MAXINMEAS!, PTCV!)) + CALGN! * ORANGE!)
        END IF

        CALL LOADMUX(2, CON%)                  'Measure output
        CALL WRITEDVM(VODC$, (IOUTCALC! + CALSPAN! * INITTOL / 100!) * RSENSE!) 'Scale meter
        CALL PAUSE(2!)                              'Wait for output to settle.
     
        LOCATE 10, 10
        PRINT "Gain Error =  ";
        PRINT SPC(20);
           
        L% = 0

        DO
            L% = L% + 1
            ERRORPERC! = (READDVM!(TOL!) / RSENSE! - IOUTCALC!) / ORANGE! * 100!'Error (%)
            LOCATE 10, 24
            PRINT USING "+###.### %"; ERRORPERC!
       
            LOCATE 15, 10
            IF CAL% > 0 THEN
                CONREADS% = 5
            ELSEIF ABS(ERRORPERC!) < GERROR! THEN
                SOUND 400, .5
                PRINT "Stop turning gain potentiometer          "
                CONREADS% = CONREADS% + 1
            ELSEIF ERRORPERC! < 0 THEN
                PRINT "Turn gain potentiometer clockwise        "
                CONREADS% = 0
            ELSE
                PRINT "Turn gain potentiometer counter-clockwise"
                CONREADS% = 0
            END IF
           
            LOCATE 20, 10
            A$ = INKEY$
            IF UCASE$(A$) = "T" THEN
                PRINT TAB(10); "Trouble Shooting Mode"
                CALL WRITEDVM("*", IOUTCALC! * RSENSE!)
                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 40 cycles
            CALL PAUSE(.2)                          'Slow down loop
        LOOP WHILE CONREADS% < 5 AND L% < 150
       
        CALL LOADMUX(2, COFF%)                  'Measure output
       
        'IF CAL% = 0 OR MAXIN! > 10! THEN
        'CALL WRITEDVM("S1", 0)       'Medium reading rate
        'END IF
    LOOP WHILE CONREADS% < 5
       
    IF ABS(ERRORPERC!) <= GERROR! THEN
        GN$ = "PASS"
    ELSE
        GN$ = "FAIL"
        SOUND 1000, .5
    END IF
   
    LOCATE 15, 10
    PRINT "Status: "; GN$;
    PRINT SPC(30);
    PRINT TAB(10); "Gain calibration error is";
    PRINT TAB(50); USING "  +###.### %"; ERRORPERC!
    PRINT TAB(10); "Max. gain calibration error is";
    PRINT TAB(50); USING "+/-###.### %"; GERROR!
    
    GAINCAL$ = GN$ + STR$(ERRORPERC!) + "3"
  
    IF TH$ = "TE1164" THEN
        SL$ = SETPOWER$(VINADDR%, 999!, LOOPOFF$)       'Disable High Voltage
    ELSE
        SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)       'Disable power supply
    END IF

    CALL RESETTH                                    'Reset test head
    CALL PAUSE(1!)

END FUNCTION

FUNCTION GAINCALINT$ (CAL%)

    SENSOR$ = SPECS.SENTYPE
    MINOUT! = SPECS.MINOUT
    MAXOUT! = SPECS.MAXOUT
    CALTOL! = SPECS.CALTOL                  'Calibration tolerance (% span)
    GNCALIN! = SPECS.GNCALIN                'transmitter input for gain calibration
    OSCALIN! = SPECS.OSCALIN                'transmitter input for offset calibration
    CALGN! = SPECS.GNCALPT / 100!           'Convert from %
    CALOS! = SPECS.OSCALPT / 100!           'Convert from %
    LIN% = SPECS.LINEARIZED
  
    ORANGE! = (MAXOUT! - MINOUT!) / 1000    'Output range (A)
    SNM% = SENSORNUM%

    IF (SNM% >= 3 AND SNM% <= 6) AND LIN% = 0 THEN
    CALSPAN! = Iout!(SENSOROUT!(GNCALIN!, 0)) - Iout!(SENSOROUT!(OSCALIN!, 0)) 'Adjustment range is +/- x% of +f.s.
                        'Output not linear w/ input
    ELSE                                        'temperature.
    CALSPAN! = Iout!(GNCALIN!) - Iout!(OSCALIN!) 'Adjustment range is +/- x% of +f.s.
    END IF

    CLS
    TESTTITLE$ = "Gain Calibration"
    CALL HEADERB(TESTTITLE$)
    LOCATE 10, 10
    PRINT "Please wait..."
     
    GERROR! = CALTOL!                       'Gain calibration tolerance (%)
    TOL! = .0001

    SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)           'Set Vsupply to 24.0V
    
    DO

    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
        MAXINMEAS! = MEASRES!(MAXIN!, 3, "") + CONTRES! 'Measure simulated resistor
    ELSE
        IF SNM% = 3 THEN
        PTCV! = PARASITICTCV!(VCJC!)
        IF VCJC! = 99! THEN EXIT FUNCTION
        END IF
        MAXIN! = SENSOROUT!(GNCALIN!, PTCV!)        'Calc. maxin volts
        IF SNM% = 2 THEN
        MAXINMEAS! = SETCURRENTIN!(MAXIN!)
        ELSE
        CALL SETDAC(MAXIN!, 1, 0)               'Sets DAC
        IF CAL% = 0 OR MAXIN! > 10! THEN        'Always measure high voltage
                                'input to get exact setting
            CALL WRITEDVM("S0", 0)                  'Slow reading rate for max accuracy
            CALL LOADMUX(1, CON%)
            CALL WRITEDVM(VODC$, MAXIN!)            'Sets meter to read
            MAXINMEAS! = READDVM!(MAXIN! * .0002)   '0.02% tolerance
            CALL LOADMUX(1, COFF%)
        ELSE
            MAXINMEAS! = MAXIN!
        END IF
        END IF
    END IF
    
    CALL WRITEDVM("S1", 0)       'Medium reading rate
      
    IF (SNM% >= 3 AND SNM% <= 6) AND LIN% = 0 THEN
        IOUTCALC! = Iout!(MAXINMEAS! + PTCV!) + CALGN! * ORANGE!
                        'Output not linear w/ input
    ELSE                                'temperature.
        IOUTCALC! = Iout!(SENSORIN!(MAXINMEAS!, PTCV!)) + CALGN! * ORANGE!
    END IF

    CALL LOADMUX(2, CON%)               'Measure Iout
    CALL WRITEDVM(VODC$, IOUTCALC! * RSENSE!)
    CALL PAUSE(5!)                      'Wait for output to settle.
    
    ERRORPERC1! = (READDVM!(TOL!) / RSENSE! - IOUTCALC!) / ORANGE! * 100!'Error (%)
     
    LOCATE 10, 10
    PRINT USING "PLUS FULL SCALE ERROR = +###.### %"; ERRORPERC1!

    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
    ELSE
        IF SNM% = 3 THEN
        PTCV! = PARASITICTCV!(VCJC!)
        IF VCJC! = 99! THEN EXIT FUNCTION
        END IF
        MININ! = SENSOROUT!(OSCALIN!, PTCV!) 'Calc. minin volts, meas. vcjc
        IF SNM% = 2 THEN
        MININMEAS! = SETCURRENTIN!(MININ!)
        ELSE
        CALL SETDAC(MININ!, 1, 0)                   'Sets DAC
        IF CAL% = 0 OR MAXIN! > 10! THEN            'Always measure high voltage
                                'input to get exact reading
            CALL WRITEDVM("S0", 0)                  'Slow reading rate for max accuracy
            CALL LOADMUX(1, CON%)
            CALL WRITEDVM(VODC$, MININ!)            'Sets meter to read
            MININMEAS! = READDVM!(MININ! * .0002)   '0.02% tolerance
            CALL LOADMUX(1, COFF%)
        ELSE
            MININMEAS! = MININ!
        END IF
        END IF
    END IF
     
    CALL WRITEDVM("S1", 0)       'Medium reading rate
      
    IF (SNM% >= 3 AND SNM% <= 6) AND LIN% = 0 THEN
        IOUTCALC! = Iout!(MININMEAS! + PTCV!) + CALOS! * ORANGE!
                        'Output not linear w/ input
    ELSE                                'temperature.
        IOUTCALC! = Iout!(SENSORIN!(MININMEAS!, PTCV!)) + CALOS! * ORANGE!
    END IF
       
    CALL LOADMUX(2, CON%)                'Measure Vsense
    CALL WRITEDVM(VODC$, (IOUTCALC! + CALSPAN! * INITTOL / 100!) * RSENSE!) 'Scale meter
    CALL PAUSE(5!)                      'Wait for output to settle.
     
    ERRORPERC2! = (READDVM!(TOL!) / RSENSE! - IOUTCALC!) / ORANGE! * 100!'Error (%)
      
    PRINT TAB(10); USING "MINUS FULL SCALE ERROR = +###.### %"; ERRORPERC2!

    LOCATE 13, 10
    ERRORPERC3! = ERRORPERC1! - ERRORPERC2!
    IF ABS(ERRORPERC3!) > GERROR! THEN
        CONREADS% = 0
        IF ERRORPERC3! < 0 THEN
        PRINT "Turn GAIN potentiometer CLOCKWISE        "
        ELSE
        PRINT "Turn GAIN potentiometer COUNTER-CLOCKWISE"
        END IF
    ELSE
        CONREADS% = CONREADS% + 1
        SOUND 400, .5
        PRINT "STOP turning potentiometer";
        PRINT SPC(20); : PRINT
    END IF

    A$ = INKEY$
    IF UCASE$(A$) = "T" THEN
        PRINT TAB(10); "Trouble Shooting Mode"
        CALL WRITEDVM("*", IOUTCALC! * RSENSE!)
        CALL CONTINUE
        LOCATE 20, 10
        PRINT SPC(22);
    ELSEIF UCASE$(A$) = "C" THEN
        CONREADS% = 3
    END IF
    LOOP WHILE CONREADS% < 3
         
    IF ABS(ERRORPERC3!) < GERROR! THEN
    GN$ = "PASS"
    ELSE
    GN$ = "FAIL"
    SOUND 1000, .5
    END IF
         
    LOCATE 15, 10
    PRINT "Status: "; GN$;
    PRINT SPC(30);
    PRINT TAB(10); "Gain calibration error is";
    PRINT TAB(50); USING "  +###.### %"; ERRORUA3!
    PRINT TAB(10); "Max.gain calibration error is";
    PRINT TAB(50); USING "+/-###.### %"; GERROR!
    PRINT SPC(70);
   
    GAINCALINT$ = GN$ + STR$(ERRORPERC3!)
  
    CALL RESETTH                                    'Reset test head
    CALL PAUSE(1!)
      
END FUNCTION

FUNCTION GAINERR! (CAL%, CONTRES!, PFSMEAS!, INTERACT!, OSERR2!)
      
    'Measure the module gain error
    'Inputs;        calibration flag
    '       CAL%    0 = calibrate module; high accuracy input, loop until calibrated,
    '                   narrow error tolerance, AMPL! = 0, use SPECS.GNCALIN for DUT input
    '               1 = measure once and exit, high accuracy input,
    '                   narrow error tolerance, use AMPL! for DUT input.
    '               2 = functional test; coarse input setting, wide error tolerance,
    '                   measure once and exit, AMPL! = 0, use SPECS.GNCALIN for DUT input
    '
    '               measured contact resistance (used for resistance in only)
    
    SENSOR$ = SPECS.SENTYPE
    MINOUT! = SPECS.MINOUT
    MAXOUT! = SPECS.MAXOUT
    INITTOL! = 12                           'Uncalibrated offset tolerance
    ACCTOL! = SPECS.ACCURACY                'Final calibration tolerance
    CALTOL! = SPECS.CALTOL                  'Calibration tolerance (% span)
    OSCALIN! = SPECS.OSCALIN                'transmitter input for offset calibration
    GNCALIN! = SPECS.GNCALIN                'transmitter input for gain calibration
    BANDWIDTH! = SPECS.BANDWIDTH
    LIN% = SPECS.LINEARIZED
    CALGN! = SPECS.GNCALPT / 100!           'Convert from %
  
    ORANGE! = (MAXOUT! - MINOUT!) / 1000    'Output range (A)
    SNM% = SENSORNUM%

    IF (SNM% >= 3 AND SNM% <= 6) AND LIN% = 0 THEN
        CALSPAN! = Iout!(SENSOROUT!(GNCALIN!, 0)) - Iout!(SENSOROUT!(OSCALIN!, 0)) 'Adjustment range is +/- x% of +f.s.
                        'Output not linear w/ input
    ELSE                                        'temperature.
        CALSPAN! = Iout!(GNCALIN!) - Iout!(OSCALIN!) 'Adjustment range is +/- x% of +f.s.
    END IF
      
    CLS
    TESTTITLE$ = "Gain Calibration Verification"
    CALL HEADERB(TESTTITLE$)
    
    GERROR! = CALTOL!                       'tolerance for cal check
    TOL! = .0001                            'Measurement tolerance, 1 pass test
      
    IF SNM% >= 5 AND SNM% <= 7 THEN             'Check if RTD in
        MAXIN! = SENSOROUT!(GNCALIN!, 0)        'Calc. +f.s. ohms
        CALL OHMSET(MAXIN!)                     'Set +f.s. input
    END IF
      
    LOCATE 10, 10
    PRINT TAB(10); "Measuring input.  Please wait..."
    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
        SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)       'Disable power supply
        MAXINMEAS! = MEASRES!(MAXIN!, 3, "") + CONTRES! 'Measure simulated resistor
        SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)           'Set Vsupply to 24.0V
        PAUSE (2)
    ELSE
        IF SNM% = 3 THEN
            PTCV! = PARASITICTCV!(VCJC!)
            IF VCJC! = 99! THEN EXIT FUNCTION
        END IF
        MAXIN! = SENSOROUT!(GNCALIN!, PTCV!)        'Calc. maxin volts
        IF SNM% = 2 THEN
            MAXINMEAS! = SETCURRENTIN!(MAXIN!)
        ELSE
            CALL SETDAC(MAXIN!, 1, 0)               'Sets DAC
            IF CAL% = 0 OR MAXIN! > 10! THEN        'Always measure high voltage
                                                    'input to get exact setting
                CALL WRITEDVM("S0", 0)                  'Slow reading rate for max accuracy
                CALL LOADMUX(1, CON%)
                CALL WRITEDVM(VODC$, MAXIN!)            'Sets meter to read
                MAXINMEAS! = READDVM!(MAXIN! * .0002)   '0.02% tolerance
                CALL LOADMUX(1, COFF%)
                VERR! = MAXINMEAS! - MAXIN!
                IF ABS(VERR!) > 1! THEN                  '1.0 V tolerance
                    BEEP
                    PRINT TAB(10); "Input voltage out of range"
                    PRINT TAB(10); "Error = "; VERR!; "V"
                    PRINT TAB(10); "Check all the test head connections."
                    PRINT TAB(10); "Notify engineering if problem persists."
                    CONTINUE
                    STOP
                END IF
            ELSE
                MAXINMEAS! = MAXIN!
            END IF
        END IF
    END IF
    
    CALL WRITEDVM("S1", 0)       'Medium reading rate
      
    IF (SNM% >= 3 AND SNM% <= 6) AND LIN% = 0 THEN  'Output not linear w/ input
                                                        'temperature.
        IOUTCALC! = Iout!(MAXINMEAS! + PTCV!) + CALGN! * ORANGE!
    ELSE
        IOUTCALC! = (Iout!(SENSORIN!(MAXINMEAS!, PTCV!)) + CALGN! * ORANGE!)
    END IF

    CALL LOADMUX(2, CON%)                  'Measure output
    CALL WRITEDVM(VODC$, (IOUTCALC! + CALSPAN! * INITTOL / 100!) * RSENSE!) 'Scale meter
    CALL PAUSE(2!)                              'Wait for output to settle.
    
    LOCATE 10, 10
    PRINT "Gain Error =  ";
    PRINT SPC(20);
          
    ERRORPERC! = (READDVM!(TOL!) / RSENSE! - IOUTCALC!) / ORANGE! * 100!'Error (%)
    LOCATE 10, 24
    PRINT USING "+###.### %"; ERRORPERC!
      
    LOCATE 15, 10
    CONREADS% = 5
          
    LOCATE 20, 10
    A$ = INKEY$
    IF UCASE$(A$) = "T" THEN
        PRINT TAB(10); "Trouble Shooting Mode"
        CALL WRITEDVM("*", IOUTCALC! * RSENSE!)
        CALL CONTINUE
        CALL WRITEDVM("*T2S1", 0)          'Initialize Fluke meter
        LOCATE 20, 10
        PRINT SPC(22);
    ELSEIF UCASE$(A$) = "C" THEN
        CONREADS% = 5
    END IF
      
    CALL LOADMUX(2, COFF%)                  'Measure output
      
    IF ABS(ERRORPERC!) <= GERROR! THEN
        GN$ = "PASS"
    ELSE
        GN$ = "FAIL"
        SOUND 1000, .5
    END IF
  
    LOCATE 15, 10
    PRINT "Status: "; GN$;
    PRINT SPC(30);
    PRINT TAB(10); "Gain calibration error is";
    PRINT TAB(50); USING "  +###.### %"; ERRORPERC!
    PRINT TAB(10); "Max. gain calibration error is";
    PRINT TAB(50); USING "+/-###.### %"; GERROR!
   
    GAINERR! = ERRORPERC!
 
    IF TH$ = "TE1164" THEN
        SL$ = SETPOWER$(VINADDR%, 999!, LOOPOFF$)       'Disable High Voltage
    ELSE
        SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)       'Disable power supply
    END IF

    CALL RESETTH                                    'Reset test head

END FUNCTION

FUNCTION GENATTENR!

    'This routine is used for RTD or pot. input transmitters only.
    'It determines the simulated RTD input to the transmitter which
    'serves as a voltage divider for the function generator.
    'Series resistor from the function generator is 6.8Kohms.
    'Design for function generator offset of -5V

    IEXCMFS! = SPECS.IEXCMFS / 1000000!               'Convert to A
    MININ! = SENSOROUT!(SPECS.MININ, 0)         'Determine min in
    MAXIN! = SENSOROUT!(SPECS.MAXIN, 0)         'Determine max in
    RMID! = (MAXIN! - MININ!) / 2 + MININ!
    VOS! = -5
       
    'Solve the quadratic equation  ax^2 + bx + c = 0 where a,b,c are defined below.

    A! = IEXCMFS!
    B! = IEXCMFS! * (RFNGN! - RMID!) - VOS
    C! = -1 * RFNGN! * IEXCMFS! * RMID!

    'determine the positive root
    GENATTENR! = (-B + SQR(B ^ 2 - 4 * A * C)) / (2 * A)

END FUNCTION

SUB GENSET (GENAMPL!)

    MININ! = SENSOROUT!(SPECS.MININ, 0)             'Determine min in
    MAXIN! = SENSOROUT!(SPECS.MAXIN, 0)             'Determine max in
    INRANGE! = MAXIN! - MININ!
    ATTEN! = SPECS.ATTEN
    SNM% = SENSORNUM%
       
    IF SNM% >= 5 AND SNM% <= 7 THEN                 'Check if resistance in
        IEXC! = SPECS.IEXCMFS / 1000000!            'Convert to A
        R! = GENATTENR!                             'Find attenuator shunt R
        GENAMPL! = (IEXC! * INRANGE! * (RFNGN! + R!)) / R! * .9
        IF GENAMPL! > 10 THEN GENAMPL! = 10         'HP33120A limit.  Max amplitude
                                                    'is 2x offset.
        GENOS! = -5                                 'Offset
    ELSEIF SNM% = 2 THEN
        GENAMPL! = 5    '32-01, 32-02; Iin max = 5/(250+20) = 18.5mA, Iin min = 0mA
        GENOS! = 2.5                                'Offset
    ELSE
        ORANGE! = SPECS.MAXOUT! - SPECS.MINOUT!
                            'Set amplitude for > 5mV p-p signal out
        UNATTENOUT! = 10 ^ (ATTEN! / 20) * .005
        GENAMPL! = UNATTENOUT! / ORANGE! * INRANGE! * .9
                            'Convert to round numbers
                            'for ease of use
        IF GENAMPL! < 5 THEN
            GENAMPL! = 5
        ELSE
            GENAMPL! = 10
        END IF
   
        GATTEN! = INRANGE! / GENAMPL!           'Attenuator gain
   
        GENOS! = (MININ! + INRANGE! / 2!) / GATTEN!
    END IF

    IF GENAMPL! < .5 * ABS(GENOS!) THEN GENAMPL! = .5 * ABS(GENOS!)
    IF GENAMPL! > 20 - 2 * ABS(GENOS!) THEN GENAMPL! = 20 - 2 * ABS(GENOS!)
   
    CLS
    LOCATE 5, 10
    PRINT "Set the function generator as follows:"
    LOCATE 10, 27
    PRINT "Function Generator Settings"
    PRINT TAB(27); "---------------------------"
    PRINT TAB(31); USING "Frequency: ##### Hz"; SPECS.TESTFREQ
    PRINT TAB(31); USING "Amplitude:  ##.# V p-p"; GENAMPL!
    PRINT TAB(31); USING "DC Offset: +##.# V"; GENOS!
    CALL CONTINUE

END SUB

SUB GETADD (FILENAME$)
       
    'LPT$ = parallel printer port used to control ATE
    'MUX$ = multiplexer box address
    'TESTHEAD$ = test head address
    'PS1ADDR$ = Power Supply #1 address (module power)
    'PS2ADDR$ = Power Supply #2 address (high voltage input to dut)
    'PSPORTADDR$ = Power Supply serial port address
    'DVM$ = DVM address

    OPEN "C:\ATE\ADDR\" + FILENAME$ FOR RANDOM AS #3 LEN = 19
    FIELD #3, 3 AS LPT$, 2 AS MUX$, 2 AS TESTHEAD$, 2 AS DPSPSADDR$, 2 AS DPSVINADDR$, 2 AS PSPORTADDR$, 2 AS DVM$, 2 AS ABCPSADDR$, 2 AS ABCVINADDR$
    GET #3
    LPTADDR% = VAL(LPT$)
    MUXADDR% = VAL(MUX$)
    THADDR% = VAL(TESTHEAD$)
    DPSPSADDR% = VAL(DPSPSADDR$)
    DPSVINADDR% = VAL(DPSVINADDR$)
    PSPORT% = VAL(PSPORTADDR$)
    DVMADDR% = VAL(DVM$)
    ABCPSADDR% = VAL(ABCPSADDR$)
    ABCVINADDR% = VAL(ABCVINADDR$)
    CLOSE #3
END SUB

FUNCTION GETPSID%
CLS
LOCATE 3
PRINT TAB(10); "Identifying power supplies connected to test system"
PRINT
'****** First, assume KEPCO DPS125 for PSMODEL$ string assignment.
    PSMODEL$ = "DPS125"

'****** KEPCO DPS VIN supply address for serial interface.
'        PSADDR% = 2

'****** Obtain Identification string from KEPCO DPS 125.

    PRINT TAB(20); "KEPCO DPS125 Power Supply: ";
    DPSPS$ = POWERIO$(DPSPSADDR%, "ID")

'****** Assign corresponding address obtained from address file dependent
'****** on if the Power supply is DPS125 or ABC125.
    IF DPSPS$ = "KEPCO DPS 125-0.5M" THEN
        PSADDR% = DPSPSADDR%    'this value should = 2
        PRINT TAB(55); "Yes!"
        PSMODEL$ = "DPS125"
        CALL INITPS(DPSPSADDR%, PSILIMIT!, OVERV!)
        DPSPSFLAG! = 1!
    ELSE
        PRINT TAB(55); "Not present"
        DPSPSFLAG! = 0!
        PSADDR% = 0!
    END IF

'****** Check for High Voltage Power Supply
    
    PRINT TAB(20); "KEPCO DPS125 High-Voltage Input: ";
    DPSVIN$ = POWERIO$(DPSVINADDR%, "ID")

    IF DPSVIN$ = "KEPCO DPS 125-0.5M" THEN
        VINADDR% = DPSVINADDR%
        PRINT TAB(55); "Yes!"
        PRINT
        CALL INITPS(DPSVINADDR%, VINILIMIT!, VINOVERV!)
        DPSVINFLAG! = 1!
    ELSE
        PRINT TAB(55); "Not present"
        DPSVINFLAG! = 0!
        VINADDR% = 0!
    END IF

    IF DPSPSFLAG! = 0! AND DPSVINFLAG! = 0! THEN
          
        PSMODEL$ = "ABC125"
        PRINT TAB(20); "KEPCO ABC-125 Power Supply: ";
        ABCPS$ = READGPIB$(ABCPSADDR%, "*IDN?")
               IF LEFT$(ABCPS$, 14) = "KEPCO,ABC-1251" THEN
                PSADDR% = ABCPSADDR%
                CALL INITPS(ABCPSADDR%, PSILIMIT!, OVERV!)
                PRINT TAB(55); "Yes!"
               ELSE
                PRINT TAB(55); "Not present"
               END IF

        PRINT TAB(20); "KEPCO ABC-125 High-Voltage Input: ";
        ABCVIN$ = READGPIB$(ABCVINADDR%, "*IDN?")
               IF LEFT$(ABCVIN$, 14) = "KEPCO,ABC-1251" THEN
                VINADDR% = ABCVINADDR%
                CALL INITPS(ABCVINADDR%, VINILIMIT!, VINOVERV!)
                PRINT TAB(55); "Yes!"
                PRINT
               ELSE
                PRINT TAB(55); "Not present"
                PRINT
               END IF
    END IF
             
        IF PSADDR% = 0! AND VINADDR% = 0! THEN
            PRINT TAB(15); ">>>>>>>> No Power Supplies are connected <<<<<<<<"
            CALL CONTINUE
        END IF
      
    GETPSID% = 99      'This has yet to be utilized.  At this time there is
               'no requirement to pass anthing back to function call
END FUNCTION

SUB GETSN (SN$)

    CLS
    TESTTITLE$ = "Serial Number Entry"
    CALL HEADERB(TESTTITLE$)

    LOCATE 10, 10
    INPUT "Enter Work Order number "; WO$
    LOCATE , 10
    INPUT "Starting dash number (Press 'Enter' for 1) "; DS$
    IF DS$ = "" THEN DS$ = "1"
    SN$ = WO$ + "-" + DS$

END SUB

SUB GETSPECS

    DIM POINTER%(1000)

    CALL SORTDB(ENDFLAG%)
    IF ENDFLAG% = 1 THEN
        SPECS.MODNAME = "EXIT"
        EXIT SUB
    END IF
     
    CLS
    LOCATE , 30
    PRINT "Model Selection Menu"
    PRINT TAB(30); "--------------------"
    PRINT
 
    YINIT% = CSRLIN                 'Initialize starting rows
 
    OPEN "C:\ATE\SCTDATA\DBSORT2.DAT" FOR RANDOM AS #2 LEN = LEN(SORTDATA1)
  
    DO
        I% = I% + 1
        GET #2, I%, SORTDATA1
        IF SORTDATA1.RECNUM <> -1 THEN NUMRECORD! = NUMRECORD! + 1
    LOOP WHILE SORTDATA1.RECNUM <> -1

    SCRNCTR% = 40                   'display center
    NUMCHAR% = 20                   '14 char + 4 char for # + 2 spaces
    NUMLINES! = 19                  '# of lines for model display below header
    NUMCOLUMNS! = 1 + INT(NUMRECORD! / NUMLINES!)
                    'Model # length = 20 characters max
                    '-> 3 columns max per screen
                    '3 columns x 26 char = 78 spaces

    I% = 1
 
    FOR C% = 0 TO NUMCOLUMNS! - 1
        Y% = YINIT%
        TB% = SCRNCTR% - NUMCHAR% / 2 * NUMCOLUMNS! + NUMCHAR% * C%
        DO
            GET #2, I%, SORTDATA1
            IF SORTDATA1.RECNUM <> -1 THEN
                POINTER%(I%) = SORTDATA1.RECNUM
                LOCATE Y%, TB%
                PRINT USING "##.) &"; I%; SORTDATA1.MODNAME
                I% = I% + 1
                Y% = Y% + 1
            END IF
        LOOP WHILE SORTDATA1.RECNUM <> -1 AND Y% - YINIT% < NUMLINES!

    NEXT C%
 
    LOCATE Y%, TB%
    PRINT USING "##.) Exit"; I%

    CLOSE #2

    DO
        LOCATE 23, SCRNCTR% - NUMCHAR% / 2 * NUMCOLUMNS! + 1
        PRINT "Enter Selection ";
        INPUT SEL%
    LOOP WHILE SEL% < 1 OR SEL% > I%

    IF SEL% = I% THEN
        SPECS.MODNAME = "EXIT"
    ELSE
        OPEN "C:\ATE\SCTDATA\SCTMAIN.DAT" FOR RANDOM AS #1 LEN = LEN(SPECS)
        GET #1, POINTER%(SEL%), SPECS
        CLOSE #1
       
        IF TH$ <> "TE1164" THEN
            RSENSE! = MEASRES!(LPSEN!, 1, TH$)          'Measure loop sense resistor (check test head conn.)
       
            IF SENSORNUM% = 1 AND (SPECS.MAXIN > 10 OR SPECS.MININ < -10) THEN
                CLS
                LOCATE 10, 5
                PRINT "This module requires high voltage input."
                PRINT
                PRINT TAB(5); "Turn on the high voltage power supply and connect it to the test head."
                PRINT
                PRINT TAB(5); "DO NOT PROBE THE CIRCUITRY DURING TEST"
                PRINT
                PRINT TAB(5); "Remove the yellow connector from the meter +/-SENSE terminals."
                PRINT
                CALL CONTINUE
'****** Obtain communication with either DPS125 or ABC125 KEPCO power supply
'****** and assign appropriate PSMODEL$ and VINADDR%.
                PSCOUNTER! = 0          '03/18/08 TSO
                WHILE PSFLAG! = 0 AND PSCOUNTER! <> 3
                    PSID% = GETPSID% 'Determine and initiate communication with Power supply
                    IF VINADDR% <> 2 AND VINADDR% <> 6 THEN
                        LOCATE 10, 12: PRINT "A High Voltage Power Supply must be connected"
                        LOCATE 12, 10: PRINT "Attach either a KEPCO DPS-125 Power Supply as address 2"
                        LOCATE 13, 25: PRINT "or"
                        LOCATE 14, 7: PRINT "If system is KEPCO ABC-125 Compliant, attach this supply"
                        LOCATE 15, 7: PRINT "and set to address 6"
                        PSCOUNTER! = PSCOUNTER! + 1
                        CALL CONTINUE
                    ELSE
                        PSFLAG! = 1
                    END IF
                WEND
            END IF
        ELSE
            RSENSE! = 1000          'Loop sense resistor.  Use as a scale factor
        END IF
    END IF
   
END SUB

SUB GETSPECS2

    DIM POINTER%(1000)

    'Create a file containing just the model numbers of all of the
    'records in the database for the model family selected

    OPEN "C:\ATE\SCTDATA\DBSORT2.DAT" FOR RANDOM AS #2 LEN = LEN(SORTDATA1)
    OPEN "C:\ATE\SCTDATA\SCTMAIN.DAT" FOR RANDOM AS #1 LEN = LEN(SPECS)
    NUMRECORD% = LOF(1) / LEN(SPECS)

    N% = 0

    FOR I% = 1 TO NUMRECORD%
        GET #1, I%, SPECS
        SORTDATA1.MODNAME = SPECS.MODNAME
        SORTDATA1.RECNUM = I%
      
        'SPECS.MODNAME = "SCMVAS-MXXX
        IF LEFT$(SPECS.MODNAME, 7) = "SCMHVAS" THEN
            PUT #2, , SORTDATA1        'write record # and model number
            N% = N% + 1                'found a record
        END IF
    NEXT

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

    CLOSE #1
    CLOSE #2
   
    CLS
    LOCATE , 30
    PRINT "Model Selection Menu"
    PRINT TAB(30); "--------------------"
    PRINT

    YINIT% = CSRLIN                 'Initialize starting rows
    I% = 0

    OPEN "C:\ATE\SCTDATA\DBSORT2.DAT" FOR RANDOM AS #2 LEN = LEN(SORTDATA1)
 
    DO
        I% = I% + 1
        GET #2, I%, SORTDATA1
        IF SORTDATA1.RECNUM <> -1 THEN NUMRECORD! = NUMRECORD! + 1
    LOOP WHILE SORTDATA1.RECNUM <> -1

    SCRNCTR% = 40                   'display center
    NUMCHAR% = 20                   '14 char + 4 char for # + 2 spaces
    NUMLINES! = 19                  '# of lines for model display below header
    NUMCOLUMNS! = 1 + INT(NUMRECORD! / NUMLINES!)
                    'Model # length = 20 characters max
                    '-> 3 columns max per screen
                    '3 columns x 26 char = 78 spaces

    I% = 1

    FOR C% = 0 TO NUMCOLUMNS! - 1
        Y% = YINIT%
        TB% = SCRNCTR% - NUMCHAR% / 2 * NUMCOLUMNS! + NUMCHAR% * C%
        DO
            GET #2, I%, SORTDATA1
            IF SORTDATA1.RECNUM <> -1 THEN
                POINTER%(I%) = SORTDATA1.RECNUM
                LOCATE Y%, TB%
                PRINT USING "##.) &"; I%; SORTDATA1.MODNAME
                I% = I% + 1
                Y% = Y% + 1
            END IF
        LOOP WHILE SORTDATA1.RECNUM <> -1 AND Y% - YINIT% < NUMLINES!

    NEXT C%

    LOCATE Y%, TB%
    PRINT USING "##.) Exit"; I%

    CLOSE #2

    DO
        LOCATE 23, SCRNCTR% - NUMCHAR% / 2 * NUMCOLUMNS! + 1
        PRINT "Enter Selection ";
        INPUT SEL%
    LOOP WHILE SEL% < 1 OR SEL% > I%

    IF SEL% = I% THEN
        SPECS.MODNAME = "EXIT"
    ELSE
        OPEN "C:\ATE\SCTDATA\SCTMAIN.DAT" FOR RANDOM AS #1 LEN = LEN(SPECS)
        GET #1, POINTER%(SEL%), SPECS
        CLOSE #1
        RSENSE! = 1000          'Loop sense resistor.  Use as a scale factor
                    'since IOUT calculates output in amps.
    END IF
           
    FILENAME$ = "KSCTVIN.ADR"            'Parallel port, mux & test head addresses
    CALL GETADD(FILENAME$)              'Gets the Parallel port, Mux and Testhead address

END SUB

SUB HEADERA (SN$)

    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 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 HVPSMSG
       
        CLS
        LOCATE , 32
        PRINT "Test Head Setup"
        PRINT TAB(31); "-----------------"
        PRINT
        LOCATE 10, 10
        PRINT TAB(10); "Connect a KEPCO DPS125 or KEPCO ABC125 High Voltage programmable"
        PRINT TAB(10); "power supply to the test head Vin banana jack inputs."
        PRINT
        PRINT TAB(10); "If using KEPCO DPS125: set selector switches to address 2."
        PRINT
        PRINT TAB(5); "The newer KEPCO ABC 125 Power Supply's GPIB address is set to 6"
        PRINT TAB(5); "from the front panel by pressing: Menu, Menu, 06, ENTER, RESET."
        PRINT
        CALL CONTINUE

END SUB

FUNCTION IEXC1$ (IEXCSENSE!)

    'This routine tests current source I1 (-IN lead)
    '4-wire input transmitters use this current source.

    IEXCMFS! = SPECS.IEXCMFS                        'Excitation current (uA)
    IEXCTOL! = .02                            'Initial tolerance = +/-2.0%
                          'Changed from +/-1.6% 09/16/99
    SNM% = SENSORNUM%

    CLS
    TESTTITLE$ = "Excitation Current Source #1 Test"
    CALL HEADERB(TESTTITLE$)
    LOCATE 10, 10

    IF SNM% < 5 OR SNM% > 7 THEN            'Check if resistance in
    PRINT "This test is not performed on model "; SPECS.MODNAME
    CALL CONTINUE
    EXIT FUNCTION
    ELSE
    PRINT "Testing, please wait..."
    END IF

    IF SNM% = 5 OR SNM% = 7 THEN            'Check for 3-wire input
                                            'IEXCsense was measured in Iexc2
        CALL SETTEST(1)                     'Route I1 through sense R

        CALL LOADMUX(4, CON%)               'check for initial value of
                                            'I1 within spec
        CALL WRITEDVM(VODC$, IEXCSEN! * IEXCMFS! * .000001)
        IMINUSIN! = READDVM(.001) / IEXCSENSE! * 1000000!  'Excitation current (uA)

    ELSE                                    '4-wire input
                                            'Above test for 3-wire transmitters will
                                            'saturate 4-wire transmitters at the + rail
        CONTRES! = 0                        'Output is close enough w/o measuring
        MAXIN! = SENSOROUT!(SPECS.MAXIN, 0) 'Calc. +f.s. ohms
        CALL OHMSET(MAXIN!)                 'Set +f.s. input
        MAXINMEAS! = MEASRES!(MAXIN!, 3, "") + CONTRES!  'Measure simulated resistor
                                            'Test 2 set in MEASRES!
        SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)       'Set loop voltage to 24V
        CALL LOADMUX(1, CON%)               'Measure input voltage
        CALL WRITEDVM(VODC$, MAXIN! * IEXCMFS!)
        MEASVIN! = READDVM(MAXIN! * IEXCMFS! * .0005)  '.05% tolerance
        IMINUSIN! = MEASVIN! / MAXINMEAS! * 1000000!    '(uA)
    END IF
   
    IF IMINUSIN! < 25 THEN                  'Check if I1 is working
    IEXCMFS! = 99
    I1STAT$ = "FAIL"
    SOUND 1000, .5
    LOCATE 10, 10
    PRINT "Current source I1 (-IN terminal) is not working."
    CALL CONTINUE
    ELSEIF ABS(IMINUSIN! - IEXCMFS!) > IEXCMFS! * IEXCTOL! THEN
    I1STAT$ = "FAIL"
    SOUND 1000, .5
    LOCATE 10, 10
    PRINT "Current source I1 is out of tolerance."
    PRINT TAB(10); "Check tantalum capacitor for reverse leakage."
    PRINT TAB(10); "Check current source resistor, diode, transistor and amplifier."
    ELSE
    I1STAT$ = "PASS"
    END IF
     
    LOCATE 15, 10
    PRINT "Status: "; I1STAT$;
    PRINT TAB(10); "Measured value of I1 (-IN terminal) is";
    PRINT TAB(50); USING "####.# uA"; IMINUSIN!
    PRINT TAB(10); "Required value of I1 is";
    PRINT TAB(50); USING "####.# uA +/- ##.# uA"; IEXCMFS!; IEXCMFS! * IEXCTOL!

    IF I1STAT$ = "FAIL" THEN CALL CONTINUE          'Pause to read note
    
    CALL LOADMUX(4, COFF%)
    IEXC1$ = I1STAT$ + STR$(IMINUSIN!) + "1"
   
    CALL RESETTH                                    'Reset the test head
    CALL PAUSE(1!)

END FUNCTION

FUNCTION IEXC2$ (IEXCSENSE!)

    'This routine tests current source I2 (+IN lead)
    '4-wire input transmitters DO NOT use this current source.

    IEXCMFS! = SPECS.IEXCMFS                      'Excitation current (uA)
    IEXCTOL! = .02                          'Initial tolerance = +/-2.0%
                        'Changed from +/-1.6% 09/16/99
    RIN! = 100                              'Fixed input resistance

    CLS
    TESTTITLE$ = "Excitation Current Source #2 Test"
    CALL HEADERB(TESTTITLE$)
    LOCATE 10, 10
      
    SNM% = SENSORNUM%
     
    IF SNM% < 5 OR SNM% > 7 THEN            'Check if resistance in
    PRINT "This test is not performed on model "; SPECS.MODNAME
    CALL CONTINUE
    EXIT FUNCTION
    ELSE
    PRINT "Testing, please wait."
    END IF

    IEXCSENSE! = MEASRES!(IEXCSEN!, 2, "")  'Measure excitation current source
                        'sense resistor
      
    CALL OHMSET(1E+30)                      'Set input R = infinity
    CALL SETTEST(0)                         'Route I2 through sense R
    SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)           'Set loop voltage to 24V
      
    CALL LOADMUX(1, CON%)                   'Measure differential input
                        'voltage to check sense
                        'resistor matching
    CALL WRITEDVM(VODC$, .05)
    DIFFIN! = ABS(READDVM(.001))
    IF DIFFIN! > 10 THEN                    'Meter overrange, I2 is not working
    IEXCMFS! = 99
    I2STAT$ = "FAIL"
    SOUND 1000, .5
    LOCATE 10, 10
    PRINT "Current source I2 (+IN terminal) is not working."
    CALL CONTINUE
    ELSEIF DIFFIN! > IEXCMFS! * RIN! * 1.1 THEN    'Current source sense resistors
    IEXCMFS! = 99                          'are out of matching tolerance
    I2STAT$ = "FAIL"                    '10% tolerance
    SOUND 1000, .5
    LOCATE 10, 10
    PRINT "Current source sense resistors are out of matching tolerance."
    PRINT TAB(10); "Please notify engineering."
    CALL CONTINUE
    END IF

    CALL LOADMUX(1, COFF%)
      
    IF I2STAT$ <> "FAIL" THEN
    CALL LOADMUX(4, CON%)                   'check for initial value of
                        'I2 within spec
    CALL WRITEDVM(VODC$, IEXCSEN! * IEXCMFS! * .000001)
    IPLUSIN! = READDVM(.001) / IEXCSENSE! * 1000000! 'Excitation current (uA)
       
    IF ABS(IPLUSIN! - IEXCMFS!) <= IEXCMFS! * IEXCTOL! THEN
        I2STAT$ = "PASS"
    ELSE
        I2STAT$ = "FAIL"
        SOUND 1000, .5
        LOCATE 10, 10
        PRINT "Current source I2 is out of tolerance."
        PRINT TAB(10); "Check tantalum capacitor for reverse leakage."
        PRINT TAB(10); "Check current source resistor, diode, transistor and amplifier."
    END IF
      
    LOCATE 15, 10
    PRINT "Status: "; I2STAT$;
    PRINT TAB(10); "Measured value of I2 (+IN terminal) is";
    PRINT TAB(50); USING "####.# uA"; IPLUSIN!
    PRINT TAB(10); "Required value of I2 is";
    PRINT TAB(50); USING "####.# uA +/- ##.# uA"; IEXCMFS!; IEXCMFS! * IEXCTOL!

    CALL LOADMUX(4, COFF%)
    END IF

    IF I2STAT$ = "FAIL" THEN CALL CONTINUE          'Pause to read note
     
    IEXC2$ = I2STAT$ + STR$(IPLUSIN!) + "1"
    
    CALL PAUSE(1!)

END FUNCTION

FUNCTION IMATCH$ (I1$, I2$)

    'Current sources must be matched to a specified tolerance to
    'guarantee the lead resistance effect spec.
    'Not applicable to 4-wire input transmitters
      
    IEXCMFS! = SPECS.IEXCMFS                  'Excitation current (uA)
    IMATCHTOL! = SPECS.IMATCHTOL!       'Convert to percent
      
    'extract measured data (uA)
    IPLUSIN! = VAL(MID$(I1$, 5, LEN(I1$) - 5))
    IMINUSIN! = VAL(MID$(I2$, 5, LEN(I2$) - 5))

    CLS
    TESTTITLE$ = "Excitation Current Source Matching Test"
    CALL HEADERB(TESTTITLE$)
    LOCATE 10, 10

    DIFF! = (IPLUSIN! - IMINUSIN!) / IEXCMFS!
    IF ABS(DIFF!) <= IMATCHTOL! THEN
    IMSTAT$ = "PASS"
    ELSE
    IMSTAT$ = "FAIL"
    SOUND 1000, .5
    LOCATE 10, 10
    PRINT "Current source matching is out of tolerance."
    PRINT TAB(10); "Check tantalum capacitors for reverse leakage."
    PRINT TAB(10); "Check current source resistors for matching."
    END IF
      
    LOCATE 15, 10
    PRINT "Status: "; IMSTAT$;
    PRINT TAB(10); "Measured current source matching is";
    PRINT TAB(50); USING "+###.## %"; DIFF!
    PRINT TAB(10); "Required matching is";
    PRINT TAB(50); USING "+/-#.## %"; IMATCHTOL!
    
    IMATCH$ = IMSTAT$ + STR$(DIFF!) + "2"
   
    CALL RESETTH                                    'Reset test head
    CALL PAUSE(1!)
     
END FUNCTION

SUB INDIVID (SEL%)
       
    DIM TSIM!(102), IOUTCALC!(102), IOUTMEAS!(102), ERRORPERC!(102), ACCSTAT$(102)
    SNM% = SENSORNUM%
   
    IF SENSOROUT!(SPECS.MININ, 0) = 99! THEN        'Check for valid sensor type
        EXIT SUB
    ELSEIF SNM% = 2 THEN                            'Check if current input
        IINSEN.MEAS! = MEASRES!(IINSEN!, 5, "")     'Measure current source sense R
    ELSEIF SNM% = 3 THEN
        CALL TCDUTCONNECT
    END IF
   
    DO
        SELECT CASE SEL%

            CASE 1
                SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)       'Set loop V to 24.0V
                A$ = UNDERRANGE$
            CASE 2
                SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)       'Set loop V to 24.0V
                A$ = OVERRANGE$
            CASE 3
                SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)       'Set loop V to 24.0V
                A$ = MINLOOPV$
            CASE 4
                SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)       'Set loop V to 24.0V
                A$ = MAXLOOPV$
            CASE 5
                SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)       'Set loop V to 24.0V
                A$ = CJCCAL$
            CASE 6
                IF (SNM% = 5 AND LEFT$(SPECS.MODNAME, 4) <> "DSCT") OR (SNM% = 7 AND LEFT$(SPECS.MODNAME, 4) <> "DSCT") THEN
                    B$ = IEXC2$(IEXCSENSE!)
                    A$ = IEXC1$(IEXCSENSE!)
                    C$ = IMATCH$(A$, B$)
                ELSEIF (SNM% = 5 AND LEFT$(SPECS.MODNAME, 4) <> "SCT1") OR (SNM% = 7 AND LEFT$(SPECS.MODNAME, 4) <> "SCT1") THEN
                    A$ = SENSORIEXC$(0)             'min f.s. exc current
                    B$ = SENSORIEXC$(1)             'max f.s. exc current
                    C$ = "PASS"
                ELSE
                    A$ = IEXC1$(IEXCSENSE!)
                    B$ = "PASS"
                    C$ = "PASS"
                END IF
  '      IF SNM% = 5 OR SNM% = 7 THEN
  '          B$ = IEXC2$(IEXCSENSE!)
  '          A$ = IEXC1$(IEXCSENSE!)
  '          C$ = IMATCH$(A$, B$)
  '      ELSEIF SNM% = 6 THEN
  '          A$ = IEXC2$(IEXCSENSE!)
  '      END IF
                SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)   'Disable loop power
                CALL RESETTH
       
            CASE 7
                CALCOUNT% = 0
                DO                                      'Stay in loop until exit
                    IF CALCOUNT% = 0 THEN
                        SEL2% = 1                       'Go to offset/gain cal at start
                    ELSE
                        SEL2% = CALMENU%                'Ask user what to do next
                    END IF
                    SELECT CASE SEL2%                   'Changes S/N information as selected
                        CASE 1                          'offsel/gain cal
                            ITERATION% = 0
                            DO
                                'Check if resistance in
                                IF SNM% >= 5 AND SNM% <= 7 THEN             'Check if resistance in
                                    SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)       'Disable power supply
                                    CONTRES! = MEASRES!(1!, 4, "")          'Measure contact resistance
                                END IF
                  
                                A$ = OFFSETCAL$(CAL%, CONTRES!)             'Offset calibration
                                A$ = GAINCAL$(CAL%, CONTRES!, PFSMEAS!, INTERACT!, DELTAOS!)  'Gain calibration
                                OFFERR! = OFFSETERR!(CAL%, CONTRES!)
                               
                                ITERATION% = ITERATION% + 1
                            LOOP WHILE ABS(OFFERR!) >= ERRFACT * SPECS.CALTOL AND ITERATION% < 2
                            FIN$ = "N"
                            CONTINUE
                        CASE 2                             'Linearity and accuracy test
                            IF SNM% >= 5 AND SNM% <= 7 THEN
                                CALL WRITEDVM("S0", 0)          'Slow reading rate for max accuracy
                                CONTRES! = MEASRES!(1!, 4, "")  'Measure contact resistance
                            END IF
                            A$ = LINTEST$(ACC$, CONTRES!, TSIM!(), IOUTCALC!(), IOUTMEAS!(), ERRORPERC!(), ACCSTAT$())
                            FIN$ = "N"
                            CONTINUE
                        CASE 3                              'Exit to individual menu
                            FIN$ = "Y"
                    END SELECT
                    CALCOUNT% = CALCOUNT% + 1
                    SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)           'Disable power supply
                LOOP WHILE FIN$ <> "Y"

            CASE 8
                IF SNM% >= 5 AND SNM% <= 7 THEN
                    CALL WRITEDVM("S0", 0)          'Slow reading rate for max accuracy
                    CONTRES! = MEASRES!(1!, 4, "")  'Measure contact resistance
                END IF
                A$ = LINTEST$(ACC$, CONTRES!, TSIM!(), IOUTCALC!(), IOUTMEAS!(), ERRORPERC!(), ACCSTAT$())
           
            CASE 9
                SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)       'Set loop V to 24.0V
                A$ = LEADREFF$(TOTLRESPEC!)
           
            CASE 10
                SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)       'Set loop V to 24.0V
                A$ = LOOPVSEN$
           
            CASE 11
                SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)       'Set loop V to 24.0V
                A$ = INPUTR$
           
            CASE 12
                SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)       'Set loop V to 24.0V
                A$ = OPENTC$
           
            CASE 13
                SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)       'Set loop V to 24.0V
                CALL GENSET(GENAMPL!)
                A$ = FREQRESP$(GENAMPL!)
           
            CASE 14
                SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)       'Set loop V to 24.0V
                A$ = STEPRESP$
           
            CASE 15
                SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)       'Set loop V to 24.0V
                A$ = OUTNOISE$
       
            CASE 16
                CALL ONESHOTTEST

            END SELECT
           
        SELECTION% = SEL%
      
        IF SELECTION% <> 7 THEN                         'If not doing offset/gain cal
            CALL CONTINUE
            SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)           'Disable power supply
            RESP$ = REPEAT$(SPECS.MODNAME)
        ELSE                                            'For offset/gain cal
            RESP$ = "N"
        END IF
       
    LOOP WHILE RESP$ <> "N"
       
    IF SNM% = 1 AND (SPECS.MAXIN > 10 OR SPECS.MININ < -10) THEN
    PRINT
    PRINT TAB(5); "Insert the yellow connector into the meter +/-SENSE terminals."
    CALL CONTINUE
    ELSEIF SNM% = 3 THEN
        CALL TCDUTDISCONNECT
    END IF

END SUB

SUB INITTH (TH1$, TH2$)

CLS

IF TH1$ = "TE1088" THEN
    FILENAME$ = "KSCTVIN.ADR"            'Parallel port, mux & test head addresses
ELSE
    FILENAME$ = "KVAS.ADR"            'Parallel port, mux & test head addresses
END IF

CALL GETADD(FILENAME$)              'Gets the Parallel port, Mux and Testhead address

LOCATE 5, 20
PRINT "Initializing test system.  Please wait."

CALL INIT488(DVMADDR%)                  'Initialize the GPIB interface

PRINT TAB(20); "Initializing power supply..."
PSID% = GETPSID% 'Determine and initiate communication with Power supply

PRINT
PRINT TAB(20); "Initializing DVM..."
CALL WRITEDVM("*T2S1", 0)               'Initialize Fluke meter

PRINT TAB(20); "Initializing relay mux..."
CALL LOADMUX(0, CON%)                   'Resets all mux's, independent of mux address

IF TH1$ = "TE1088" THEN

    THID% = GETTHID%                    'Get test head ID #
    IF THID% = 6 THEN
        PRINT TAB(20); "Initializing test head "; TH1$; "..."
        CBVAL% = &HFF
        FOR BANK% = 0 TO 3                  'open all relays
            CALL SETTH(CBVAL%, BANK%)
            CALL PAUSE(.05)
        NEXT
        PRINT TAB(20); "Initializing DAC..."
        CALL CALDAC(TH1$)                    'Calibrate DAC
        IF TH1$ = "ERROR" THEN
            'BEEP
            PRINT
            PRINT TAB(20); "SYSTEM STARTUP ERROR"
            PRINT TAB(20); "DAC is not connected or is faulty."
            PRINT TAB(20); "Check system setup and restart program."
            STOP
        END IF
        CALL SETDAC(0!, 1, 0)           'Clear attenuator, short tx inputs
        TH$ = TH1$
    ELSE
        F% = F% + 1
    END IF
ELSE                                    'VAS test head case

    THID% = GETTHID%                    'Get test head ID #
    IF THID% = 0 THEN
        PRINT TAB(20); "Initializing test head "; TH1$; "..."
        TH$ = TH1$
    ELSE
        F% = 2
    END IF
END IF

IF TH2$ <> "" THEN
    FILENAME$ = "KSCTRIN.ADR"            'Parallel port, mux & test head addresses
    CALL GETADD(FILENAME$)              'Gets the Parallel port, Mux and Testhead address

'CALL INITPS(PSADDR%, PSILIMIT!, OVERV!)     'Initialize the Kepco DPS power supply
SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)       'Disable power supply
  
    THID% = GETTHID%                    'Get test head ID #
    IF THID% = 1 THEN
'                PRINT
        PRINT TAB(20); "Initializing test head "; TH2$; "..."
        OPEN "C:\ATE\SCTDATA\TE1035DT.DAT" FOR INPUT AS #5
        INPUT #5, DT$
        CLOSE #5
        IF DT$ <> DATE$ THEN
            CALL RTDTHCAL
            OPEN "C:\ATE\SCTDATA\TE1035DT.DAT" FOR OUTPUT AS #5
            WRITE #5, DATE$
            CLOSE #5
        END IF
       
        NOMRIN! = 100!
        CALL OHMSET(NOMRIN!)                'Nominal resistance input
        RSIM! = MEASRES!(NOMRIN!, 3, "")
        CALL SETTEST(2)                     'Initialize RTD test head for standard operation
        TH$ = TH2$
    ELSE
        F% = F% + 1
    END IF
END IF

IF F% = 2 THEN STOP                         'No test heads connected

END SUB

FUNCTION INPUTR$
       
    MAXIN! = SPECS.MAXIN                   '+f.s. input voltage (V)
    MININ! = SPECS.MININ                   '-f.s. input voltage (V)
    MINOUT! = SPECS.MINOUT / 1000           'Convert to A
    MAXOUT! = SPECS.MAXOUT / 1000

    SPEC! = SPECS.INPUTRES                  'Meg ohms

    INRANGE! = MAXIN! - MININ!
    ORANGE! = MAXOUT! - MINOUT!

    CLS
     
    TESTTITLE$ = "Input Resistance & Bias Current Test"
    CALL HEADERB(TESTTITLE$)
    LOCATE 10, 10

    SNM% = SENSORNUM%
       
    IF SNM% <> 1 OR MAXIN! > 10! THEN      'Check for V in and Vmax <= 10V
    PRINT "This test is not performed on model "; SPECS.MODNAME
    EXIT FUNCTION
    ELSE
    PRINT "Testing, please wait."
    END IF

    CALL SETDAC(MAXIN!, 1, 0)
       
'    CALL LOADMUX(2, CON%)                           'Measure Vsense
'    CALL WRITEDVM(VODC$, MAXOUT! * RSENSE!)
'    IO1! = READDVM!(.001) / RSENSE!                 'Loop current (A)
       
    CB0VAL% = CB0VAL% OR &H4                        '0 0 0 0  0 1 0 0
    CALL SETTH(CB0VAL%, CB0%)                       'Insert 5.1Mohm resistor
                            'in series with input.
    CALL LOADMUX(2, CON%)                           'Turns on mux, reset w/ resistor insert
    CALL WRITEDVM(VODC$, MAXOUT! * RSENSE!)
    IO2! = READDVM!(.001) / RSENSE!                 'Loop current (A)
    CALL LOADMUX(2, COFF%)

'    DELTAIO! = (IO2! - IO1!)                        'Output change (A)
'    MAXDELTA! = (MAXOUT! - IOUT!((SPEC! / (SPEC! + RSERIES!)) * MAXIN!)) * 1000!'max change (mA)
    PEDOS! = Iout!(0!)
    GAIN! = ORANGE! / INRANGE!
    RINMEAS! = ABS((IO2! - PEDOS!) * RSERIES! / (MAXIN! * GAIN! - IO2!) / 1000000!)
       
    IF RINMEAS! > 1000 THEN RINMEAS! = 1000
       
    IF RINMEAS! >= SPEC! THEN
    INR$ = "PASS"
    ELSE
    INR$ = "FAIL"
    SOUND 1000, .5
    END IF

    LOCATE 10, 10
    PRINT "Status: "; INR$;
    PRINT SPC(20);
    PRINT TAB(10); "Measured input resistance is";
    PRINT TAB(50); USING "   #### Mohms"; RINMEAS!
    PRINT TAB(10); "Required input resistance is";
    PRINT TAB(50); USING ">= #### Mohms"; SPEC!

    INPUTR$ = INR$ + STR$(RINMEAS!) + "0"
       
    CALL RESETTH                                'Reset the test head
    CALL PAUSE(1!)

END FUNCTION

FUNCTION Iout! (SENOUT!)

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

    MINOUT! = SPECS.MINOUT / 1000           'Convert to A
    MAXOUT! = SPECS.MAXOUT / 1000
    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 (A)
    INRANGE! = MAXIN! - MININ!              'Input range
  
    XFERFN! = ORANGE! / INRANGE!
    YINT! = MINOUT! - MININ! * XFERFN!      'Y-intercept
    Iout! = XFERFN! * SENOUT! + YINT!       'Output voltage (V)
       
END FUNCTION

FUNCTION LEADREFF$ (TOTLRESPEC!)

    'Test the effects of adding a 3.3 ohm series lead resistance in
    'the +IN and -IN leads.  Series resistance is not added in the +EXC
    'line because this only produces a common mode shift.

    SPEC! = SPECS.LEADRERR                  'deg. C/ohm or ohm/ohm
    LOWOHM! = SENSOROUT!(SPECS.MININ, 0)    'Convert Tin to ohms in
    HIGHOHM! = SENSOROUT!(SPECS.MAXIN, 0)   'Convert Tin to ohms in
    MAXOUT! = SPECS.MAXOUT / 1000!
    IMATCHTOL! = SPECS.IMATCHTOL!
    ORANGE! = (SPECS.MAXOUT - SPECS.MINOUT)
    INRANGE! = (SPECS.MAXIN - SPECS.MININ) * SPECS.IEXCMFS
    SNM% = SENSORNUM%
      
    CLS
    TESTTITLE$ = "Lead Resistance Effects Test"
    CALL HEADERB(TESTTITLE$)
    LOCATE 10, 10
       
    IF SNM% < 5 OR SNM% > 7 THEN   'Check if resistance in
    PRINT "This test is not performed on model "; SPECS.MODNAME
    EXIT FUNCTION
    ELSE
    PRINT "Testing, please wait..."
    END IF

    GAIN! = ORANGE! / INRANGE!              'A/C OR A/OHM
    RLEAD! = 3.3                            '3.3 ohm series R
    SPEC! = SPECS.LEADRERR                  'deg. C/ohm or ohm/ohm
    IEXCERR! = IMATCHTOL! * RLEAD! / (HIGHOHM! - LOWOHM!) 'Error from current source mis-match, % span
    RLEADERR! = .1 * RLEAD! / (HIGHOHM! - LOWOHM!)  'Error from mis-match in 3.3 ohm resistors in test head
                            'Assumes +/-5% matching
    TOTLRESPEC! = SPEC! + (IEXCERR! + RLEADERR!) * INRANGE! / RLEAD!
                        'Refer to output
                        'C/OHM * % * C / OHM
      
    CALL OHMSET(HIGHOHM!)                   'Set input R = plus f.s.
    CALL SETTEST(5)                         'Move +EXC to RTD (relay
                        ' contact R in each lead)
    CALL LOADMUX(2, CON%)                   'Measure Vsense
    CALL WRITEDVM(VODC$, MAXOUT! * RSENSE!)
    ILOOPNOR! = READDVM(.001) / RSENSE!     'Loop current, no series R (A)
    CALL SETTEST(4)                         'Insert series R in each lead

    CALL LOADMUX(2, CON%)                   'Measure Vsense
    ILOOPR! = READDVM(.001) / RSENSE!       'Loop current, w/ series R (A)
    CALL LOADMUX(2, COFF%)
     
    LRE! = (ILOOPR! - ILOOPNOR!) / GAIN! / RLEAD!
       
    IF ABS(LRE!) <= TOTLRESPEC! THEN
    LRE$ = "PASS"
    ELSE
    LRE$ = "FAIL"
    SOUND 1000, .5
    PRINT
    PRINT TAB(10); "Check the current source matching."
    END IF
       
    IF SNM% = 7 THEN                            'Choose units for output
    in$ = "ohm"                             'Pot in
    ELSE
    in$ = "C"                               'RTD in
    END IF

    LOCATE 10, 10
    PRINT "Status: "; LRE$;
    PRINT SPC(20);
    PRINT TAB(10); "Measured lead resistance effect is";
    PRINT TAB(50); USING "  +#.## &/ohm"; LRE!; in$
    PRINT TAB(10); "Required lead resistance effect is";
    PRINT TAB(50); USING "+/-#.## &/ohm"; TOTLRESPEC!; in$

    LEADREFF$ = LRE$ + STR$(LRE!) + "2"

    CALL RESETTH                                    'Reset test head
    CALL PAUSE(1!)

END FUNCTION

FUNCTION LINTEST$ (ACC$, CONTRES!, TSIM!(), IOUTCALC!(), IOUTMEAS!(), ERRORPERC!(), ACCSTAT$())

    SENSOR$ = SPECS.SENTYPE
    MININ! = SPECS.MININ
    MAXIN! = SPECS.MAXIN
    MINOUT! = SPECS.MINOUT / 1000!           'Convert to A
    MAXOUT! = SPECS.MAXOUT / 1000!
    MAXLINERR! = SPECS.LINEAR                ' %
    MAXACCERR! = SPECS.ACCURACY
    BANDWIDTH! = SPECS.BANDWIDTH
    LIN% = SPECS.LINEARIZED

    ORANGE! = MAXOUT! - MINOUT!              'Output range (A)

    CLS
    TESTTITLE$ = "Accuracy Test"
    CALL HEADERB(TESTTITLE$)
      
    SNM% = SENSORNUM%
    PRINT
    PRINT TAB(23); "Calculated"; TAB(37); "Measured"
    IF SNM% >= 3 AND SNM% <= 6 THEN         'Temperature input transmitters
    PRINT TAB(10); "Temp. (C)";
    ELSEIF SNM% = 2 THEN                    'Current input transmitters
    PRINT TAB(10); "Iin (mA)";
    VINSCALE! = 1
    ELSEIF SNM% = 7 THEN                 'Resistance input transmitters
    PRINT TAB(9); "Rin (ohms)";
    ELSE
    IF MAXIN! >= 1 THEN
        PRINT TAB(11); "Vin (V)";
        VINSCALE! = 1
    ELSE
        PRINT TAB(11); "Vin (mV)";
        VINSCALE! = 1000
    END IF
    END IF
   
    PRINT TAB(24); "Iout (mA)"; TAB(37); "Iout (mA)*";
    PRINT TAB(51); "Error (%)"; TAB(65); "Status"
    PRINT TAB(9); "----------"; TAB(23); "----------"; TAB(37); "----------";
    PRINT TAB(51); "----------"; TAB(64); "--------"
    '9             23            37            51           64
    'Rin (ohms)
    ' Temp. (C)
    ' Iin (mA)
    '  Vin (V)      Iout (mA)    Iout (mA)*    Error (%)     Status
    '----------    ----------    ----------    ---------    --------
    ' #####.##
    ' +####.##
    '+###.###       +##.###       +##.###      +###.###       &&&&

    IF PON% = 1 THEN
    LPRINT TAB(34); "ACCURACY TEST"
    LPRINT
    LPRINT TAB(23); "Calculated"; TAB(37); "Measured"
    IF SNM% >= 3 AND SNM% <= 6 THEN         'Temperature input transmitters
        LPRINT TAB(10); "Temp. (C)";
    ELSEIF SNM% = 2 THEN                    'Current input transmitters
        LPRINT TAB(10); "Iin (mA)";
    ELSEIF SNM% = 7 THEN                    'Resistance input transmitters
        LPRINT TAB(9); "Rin (ohms)";
    ELSE
        IF MAXIN! >= 1 THEN
        LPRINT TAB(11); "Vin (V)";
        ELSE
        LPRINT TAB(11); "Vin (mV)";
        END IF
    END IF
       
    LPRINT TAB(24); "Iout (mA)"; TAB(37); "Iout (mA)*";
    LPRINT TAB(51); "Error (%)"; TAB(65); "Status"
    LPRINT TAB(9); "----------"; TAB(23); "----------"; TAB(37); "----------";
    LPRINT TAB(51); "----------"; TAB(64); "--------"
    END IF
       
    INC% = 0                                        'Array element
    NUMPTS% = 5                                     'Number of points in test
                            'Optional statements for file output
    IF LOGDAT% > 0 THEN
    INPUT "Enter the number of points to be tested  "; NUMPTS%
    INPUT "Enter file name "; F$
'    F$ = "E:\ENGR\DESIGN\LINDESN\DSCT\" + F$
    F$ = "C:\QB45\JJM\" + F$
    OPEN F$ FOR OUTPUT AS #3
    WRITE #3, (MAXIN! - MININ!)
    WRITE #3, MININ!
    WRITE #3, NUMPTS%
    END IF
       
    FAILED% = 0

    LINSTEP! = (MAXIN! - MININ!) / (NUMPTS% - 1)
                            'LINSTEP!/2 ensures NUMPTS% test point
    FOR MODIN! = MININ! TO MAXIN! + LINSTEP! / 2 STEP LINSTEP!
    INC% = INC% + 1
    IF SNM% >= 5 AND SNM% <= 7 THEN             'Check if resistance in
        RIN! = SENSOROUT!(MODIN!, 0)            'Calc. ohms
        CALL OHMSET(RIN!)                       'Set input
        CALL WRITEDVM("S0", 0)     'Slow reading rate for max accuracy
        SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)       'Disable power supply
        MEASIN! = MEASRES!(RIN!, 3, "") + CONTRES!  'Measure simulated resistor
'                IF INC% = 1 THEN
        SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)       'Set Vsupply to 24.0V
        PAUSE (2)
'                END IF
    ELSE
        IF INC% = 1 THEN
        SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)       'Set Vsupply to 24.0V
        END IF
        IF SNM% = 3 THEN
        PTCV! = PARASITICTCV!(VCJC!)
        IF VCJC! = 99! THEN EXIT FUNCTION
        END IF
        IF SNM% = 2 THEN
        MEASIN! = SETCURRENTIN!(MODIN!)
        ELSE
        VIN! = SENSOROUT!(MODIN!, PTCV!)
        CALL SETDAC(VIN!, 1, 0)                 'Sets input voltage
        CALL WRITEDVM("S0", 0)                  'Slow reading rate for max accuracy
        CALL WRITEDVM(VODC$, VIN!)              'Sets meter to read
        CALL LOADMUX(1, CON%)
        CALL PAUSE(2!)
        MEASIN! = READDVM!(VIN! * .0002)        '0.02% tolerance
        WHILE ABS(VIN!) > 10 AND ABS(VIN!) - ABS(MEASIN!) > 1
                            'Power supply current limit tripped
            SL$ = SETPOWER$(VINADDR%, ABS(VIN!), FUNC$) 'Set Vin
            'CALL PAUSE(2!)
            MEASIN! = READDVM!(VIN! * .0002)        '0.02% tolerance
        WEND
        CALL LOADMUX(1, COFF%)
        END IF
    END IF
       
    CALL WRITEDVM("S1", 0)                      'Medium reading rate
       
    TSIM!(INC%) = SENSORIN!(MEASIN!, PTCV!)
       
    IF (SNM% >= 3 AND SNM% <= 6) AND LIN% = 0 THEN
        IOUTCALC!(INC%) = Iout!(MEASIN! + PTCV!)      'Output not linear w/ input
    ELSE                                        'temperature.
        IOUTCALC!(INC%) = Iout!(TSIM!(INC%))
    END IF
    
    CALL LOADMUX(2, CON%)
    CALL WRITEDVM(VODC$, IOUTCALC!(INC%) * RSENSE!) 'Sets meter to read output
     
    IF BANDWIDTH! < 10 THEN
        CALL PAUSE(1!)                  'Pause 1s for filter settling
    END IF
       
    IOUTMEAS!(INC%) = READDVM!(.0001) / RSENSE!       'Measured iout (A)
    ERRORPERC!(INC%) = (IOUTMEAS!(INC%) - IOUTCALC!(INC%)) / ORANGE! * 100! 'Error (*)
    IF LOGDAT% > 0 THEN
        IF LEFT$(SPECS.MODNAME, 4) = "SCT1" THEN
        WRITE #3, TSIM!(INC%), ERRORPERC!(INC%) / 100! * ORANGE! * RSENSE! * 1.2 / (.016 * RSENSE!) * 1000!'(mV out of a 0-1.2V span)
        ELSE
        WRITE #3, ERRORPERC!(INC%) / 100! * ORANGE! * RSENSE! * 2.5 / (.016 * RSENSE!) * 1000!'(mV out of a 0-2.5V span)
'        WRITE #3, TSIM!(INC%), ERRORPERC!(INC%) / 100! * ORANGE! * RSENSE! * 2.5 / (.016 * RSENSE!) * 1000!'(mV out of a 0-2.5V span)
        END IF
    END IF
    CALL LOADMUX(2, COFF%)

    IF ABS(VIN!) > 10 THEN
        SL$ = SETPOWER$(VINADDR%, 999!, LOOPOFF$)  'Disable power supply
    END IF
       
    IF ABS(ERRORPERC!(INC%)) <= MAXACCERR! THEN
        ACCSTAT$(INC%) = "PASS"
    ELSE
        ACCSTAT$(INC%) = "FAIL"
        FAILED% = FAILED% + 1
        SOUND 800, .5
    END IF
       
    IF SNM% >= 3 AND SNM% <= 6 THEN              'Temperature input transmitters
        PRINT TAB(10); USING "+####.##      +##.###       +##.###      +###.###"; TSIM!(INC%); IOUTCALC!(INC%) * 1000; IOUTMEAS!(INC%) * 1000; ERRORPERC!(INC%);
    ELSEIF SNM% = 7 THEN                         'Resistance input transmitters
        PRINT TAB(10); USING "#####.##      +##.###       +##.###      +###.###"; TSIM!(INC%); IOUTCALC!(INC%) * 1000; IOUTMEAS!(INC%) * 1000; ERRORPERC!(INC%);
    ELSE                                        'Voltage or current input transmitters
        PRINT TAB(9); USING "+###.###       +##.###       +##.###      +###.###"; TSIM!(INC%) * VINSCALE!; IOUTCALC!(INC%) * 1000; IOUTMEAS!(INC%) * 1000; ERRORPERC!(INC%);
    END IF
    PRINT TAB(66); ACCSTAT$(INC%)
        
       
    IF PON% = 1 THEN
        IF SNM% >= 3 AND SNM% <= 6 THEN              'Temperature input transmitters
        LPRINT TAB(10); USING "+####.##      +##.###       +##.###      +###.###"; TSIM!(INC%); IOUTCALC!(INC%) * 1000; IOUTMEAS!(INC%) * 1000; ERRORPERC!(INC%);
        ELSEIF SNM% = 7 THEN                         'Resistance input transmitters
        LPRINT TAB(10); USING "#####.##      +##.###       +##.###      +###.###"; TSIM!(INC%); IOUTCALC!(INC%) * 1000; IOUTMEAS!(INC%) * 1000; ERRORPERC!(INC%);
        ELSE                                        'Voltage or current input transmitters
        LPRINT TAB(9); USING "+###.###       +##.###       +##.###      +###.###"; TSIM!(INC%) * VINSCALE!; IOUTCALC!(INC%) * 1000; IOUTMEAS!(INC%) * 1000; ERRORPERC!(INC%);
        END IF
        LPRINT TAB(66); ACCSTAT$(INC%)
    END IF
         
    IF ABS(ERRORPERC!(INC%)) > ABS(ACCERR!) THEN
        ACCERR! = ERRORPERC!(INC%)
    END IF
           
    'Variables used to calculate the best fit line using linear regression.
    SMODIN! = SMODIN! + TSIM!(INC%)
    SSMODIN! = SSMODIN! + TSIM!(INC%) ^ 2
    SERR! = SERR! + ERRORPERC!(INC%)
    SPROD! = SPROD! + TSIM!(INC%) * ERRORPERC!(INC%)
       
    NEXT
           
    IF LOGDAT% > 0 THEN CLOSE #3

    IF FAILED% = 0 THEN
    ACC$ = "PASS"
    ELSE
    ACC$ = "FAIL"
    SOUND 800, .5
    END IF

    SLOPE! = ((NUMPTS% * SPROD!) - (SMODIN! * SERR!)) / ((NUMPTS% * SSMODIN!) - (SMODIN! ^ 2))
    OFFSET1! = ((SERR! * SSMODIN!) - (SMODIN! * SPROD!)) / ((NUMPTS% * SSMODIN!) - (SMODIN! ^ 2))
    
    BFERR! = ABS(BESTFIT!(SLOPE!, OFFSET1!, TSIM!(), NUMPTS%, ERRORPERC!()))
    IF ABS(BFERR!) <= MAXLINERR! THEN
    BF$ = "PASS"
    ELSE
    BF$ = "FAIL"
    SOUND 600, .5
    END IF

    PRINT
    PRINT TAB(10); "Accuracy status: "; ACC$
    PRINT TAB(10); "Measured accuracy error is";
    PRINT TAB(50); USING "  +###.### %"; ACCERR!
    PRINT TAB(10); "Maximum accuracy error is";
    PRINT TAB(50); USING "+/-###.### %"; MAXACCERR!
   
    PRINT
    PRINT TAB(10); "Linearity status: "; BF$
    PRINT TAB(10); "Measured best-fit linearity error is";
    PRINT TAB(50); USING "+/-###.### %"; BFERR!
    PRINT TAB(10); "Maximum best-fit linearity error is";
    PRINT TAB(50); USING "+/-###.### %"; MAXLINERR!

    ACC$ = ACC$ + STR$(ABS(ACCERR!)) + "3"   '% span
    LINTEST$ = BF$ + STR$(ABS(BFERR!)) + "3" 'append # decimal places
      
    CALL RESETTH                                    'Reset test head
    CALL PAUSE(1!)

END FUNCTION

SUB LOGIT (STATUS$(), SN$, TSIM!(), IOUTCALC!(), IOUTMEAS!(), ERRORPERC!(), ACCSTAT$(), LOWMA!, HIGHMA!, TOTLRESPEC!)

    IF FAILS%(STATUS$()) = 0 THEN
      
        OPEN "C:\ATE\LOGPATH.ADR" FOR INPUT AS #7
            INPUT #7, LOGPATH$
        CLOSE #7

        IF LEFT$(SPECS.MODNAME, 3) = "SCM" THEN
            OPEN "C:\ATE\VASLOG\" + RTRIM$(MID$(SPECS.MODNAME, 4, 8)) + ".DAT" FOR APPEND AS #4
            OPEN LOGPATH$ + "\VASLOG\" + RTRIM$(MID$(SPECS.MODNAME, 4, 8)) + ".DAT" FOR APPEND AS #8
       
        ELSE
            OPEN "C:\ATE\SCTLOG\" + RTRIM$(MID$(SPECS.MODNAME, 5, 8)) + ".DAT" FOR APPEND AS #4
            OPEN LOGPATH$ + "\SCTLOG\" + RTRIM$(MID$(SPECS.MODNAME, 5, 8)) + ".DAT" FOR APPEND AS #8
       
        END IF
        NUMPTS% = 5

        'builds a sequential file.  16 records required for 1 module
        WRITE #4, SPECS.MODNAME
        WRITE #8, SPECS.MODNAME

        FOR INC% = 1 TO NUMPTS%
            WRITE #4, TSIM!(INC%), IOUTCALC!(INC%), IOUTMEAS!(INC%), ERRORPERC!(INC%), ACCSTAT$(INC%)
            WRITE #8, TSIM!(INC%), IOUTCALC!(INC%), IOUTMEAS!(INC%), ERRORPERC!(INC%), ACCSTAT$(INC%)
        NEXT

        WRITE #4, TOTLRESPEC!
        WRITE #8, TOTLRESPEC!
          
        FOR INC% = 0 TO 15 STEP 4
            WRITE #4, STATUS$(INC% + 1), STATUS$(INC% + 2), STATUS$(INC% + 3), STATUS$(INC% + 4)
            WRITE #8, STATUS$(INC% + 1), STATUS$(INC% + 2), STATUS$(INC% + 3), STATUS$(INC% + 4)
        NEXT

        WRITE #4, SN$, DATE$
        WRITE #8, SN$, DATE$

        CLOSE #4
        CLOSE #8
    END IF

END SUB

FUNCTION LOOPVSEN$

    MINOUT! = SPECS.MINOUT / 1000!
    MAXOUT! = SPECS.MAXOUT / 1000!          'Convert to A
    VSEN! = SPECS.VSEN!                     '% / V
    VS1! = 20                               'Power supply voltage #1, .5V resolution
    VS2! = 90                               'Power supply voltage #2, .5V resolution

    ORANGE! = MAXOUT! - MINOUT!

    CLS
    TESTTITLE$ = "Loop Voltage Sensitivity Test"
    CALL HEADERB(TESTTITLE$)
   
    LOCATE 10, 10
    PRINT "Testing, please wait."

    SNM% = SENSORNUM%
     
    IF SNM% = 3 THEN
    PTCV! = PARASITICTCV!(VCJC!)
    IF VCJC! = 99! THEN EXIT FUNCTION
    END IF
  
    MAXIN! = SENSOROUT!(SPECS.MAXIN, PTCV!) 'Calc. maxin
    MININ! = SENSOROUT!(SPECS.MININ, PTCV!) 'Calc. minin
     
    IF SNM% >= 5 AND SNM% <= 7 THEN                 'Check if resistance in
        CALL OHMSET(MAXIN!)                         'Set Rin for +f.s input
    ELSE
        IF SNM% = 2 THEN
            A! = SETCURRENTIN!(MAXIN!)
        ELSE
            CALL SETDAC(MAXIN!, 1, 0)
        END IF
    END IF
   
    SL$ = SETPOWER$(PSADDR%, VS1!, FUNC$)                  'Set low supply voltage
     
    CALL LOADMUX(2, CON%)                           'Measure Vsense
    CALL WRITEDVM(VODC$, MAXOUT! * RSENSE!)         'Set up Meter
    ILOOP1! = READDVM(.0001) / RSENSE!              'Loop current (A)
    CALL LOADMUX(2, COFF%)                          'Turn off CH#2

    SL$ = SETPOWER$(PSADDR%, VS2!, FUNC$)                  'Set high supply voltage
   
    CALL LOADMUX(2, CON%)                           'Measure Vsense
    ILOOP2! = READDVM(.0001) / RSENSE!              'Loop current (A)
    CALL LOADMUX(2, COFF%)                          'Turn off CH#2
    DELTAIO! = (ILOOP2! - ILOOP1!) / ORANGE! * 100! / (VS2! - VS1!)'Change in output (%/V)
     
    SL$ = SETPOWER$(PSADDR%, 999!, LOOPOFF$)           'Disable power supply to avoid current spikes
    PAUSE (.1)
    SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)                   'Reset Vloop
'    IF SETPOWER$(PSADDR%, 999!, ISTAT$) = "RCS=01" THEN    'Check for over-current
'        SL$ = SETPOWER$(PSADDR%, 24!, FUNC$)       'Set loop V to 24.0V
'    END IF
   
    IF ABS(DELTAIO!) <= VSEN! THEN
    LPVSTAT$ = "PASS"
    ELSE
    LPVSTAT$ = "FAIL"
    SOUND 1000, .5
    END IF

    LOCATE 10, 10
    PRINT "Status: "; LPVSTAT$;
    PRINT SPC(20);
    PRINT TAB(10); "Measured change in loop current is";
    PRINT TAB(55); USING "###.#### %/V"; DELTAIO!
    PRINT TAB(10); "Required change in loop current is";
    PRINT TAB(55); USING "< #.#### %/V"; VSEN!
 
                            'Express meas. in % / V
    LOOPVSEN$ = LPVSTAT$ + STR$(DELTAIO!) + "4"
  
    CALL RESETTH                                    'Reset test head
    CALL PAUSE(1!)

END FUNCTION

SUB TCDUTCONNECT

        'Connect TE10302-2 to the DUT
  
        CLS
        PRINT TAB(29); "Connect CJC Box to DUT"
        PRINT TAB(29); "----------------------"
  
        CALL MODOUTLINE
        LOCATE 4, 30
        PRINT "x x"
        LOCATE 7, 31
        PRINT CHR$(24); "  "
        PRINT TAB(30); "P1"

        LOCATE 10, 4
        PRINT "Plug the CJC connector (blue and purple wires) into the P1 header on the"
        PRINT TAB(4); "module.  The purple lead goes on the pin closest to the brass blocks."
        PRINT
        PRINT TAB(4); "Grasp the TE10302 temperature sensor by the plastic base and insert"
        PRINT TAB(4); "it into the empty hole in the back of the module brass terminal blocks."
        CALL CONTINUE

END SUB

SUB TCDUTDISCONNECT

        'Disconnect TE10302-2 from the DUT

        CLS
        PRINT TAB(27); "Disconnect CJC Box to DUT"
        PRINT TAB(27); "-------------------------"
  
        CALL MODOUTLINE
        LOCATE 4, 30
        PRINT "x x"
        LOCATE 7, 31
        PRINT CHR$(24); "  "
        PRINT TAB(30); "P1"

        LOCATE 10, 4
        PRINT "Remove the CJC connector and temperature sensor from the DUT."
        CALL CONTINUE

END SUB

