'**************************** TESTHV3 *********************************** ' NAME: TESTHV3.BAS ' PURPOSE: AUTOMATED TEST SOFTWARE FOR HIGH-VOLTAGE ' VOLTAGE-INPUT PRODUCT TESTING ' COMPILER: Quick Basic 4.5 ' AUTHOR: John Lehman ' DATE: 06/18/99 '************************* REVISION RECORD ******************************* 'DATE REV APPR DESCRIPTION '---- --- ---- ----------- '06/18/99 1.00 JL Initial Release ' ... ' ... See "Revs.txt" file for program update comments within this time interval. ' ... '2014/10/10 B.01 PWR Code cleanup and updates for datasheet and work order status file ' generation, etc., and use of the updated library (NLIBATE3) with ' work order number restrictions for the datasheet naming convention. ' Operator-entry pauses were removed in CHECKFILECREATE, etc. The ' ENABLE and HVRELAY subs were changed to properly update the DIO word ' and to check for invalid parameters. Added common variable DEBUGFLAG% ' to control debug messages and pauses in various routines. Updated ' Individual Test menu to remove non-HV tests and updated the INDIVID ' sub to account for the menu-number changes and to add form-feed ' as one of the choices. Added REPORT sub to FUNCTEST to display the ' test results, and updated the sub to use the global variable TTYPE% ' to leave out the accuracy results display in the functional test. ' Added INSTRERROR$ function and INSTRERRORS sub (replacing DASERROR$ ' and DASERRORS) to read the error status from either the Agilent ' 33120A or 34970A instruments. Added FINISHSUB declaration and call from ' the F10 trap. Added OUTSWITCH test to FUNCTEST (for SCM5B modules only). ' '10-21-16 MF Added limits for SETDAC3 '2-7-20 MF ADDED DELAY AT HS1 FUNCTION CONST PROGNAME$ = "TESTHV3.EXE" 'Executable file name of the program. CONST VERSION$ = "B.01 2014.10.10 PWR" 'Version (Revision Date) and initials of engr. CONST SOURCEFILES$ = "TESTHV3.BAS TESTHV4.BAS NLIBATE3.BAS" 'Source file names '******** Declare some useful constants ******* CONST MAXSTATUSINDEX = 17 'Maximum index of the Status array '***************** DEVICE COMMUNICATIONS ROUTINES ************************* 'Kepco DPS 125-0.5M control routines via RS-232C DECLARE SUB INIT488 (DEVADDR%) DECLARE SUB INITPS (DPSADDR%, OVERI!, OVERV!) 'Initializes supply DECLARE SUB SETDPS (DPSADDR%, VSUPPLY!) 'Sets Kepco DPS power supply DECLARE FUNCTION GETPSID% () DECLARE FUNCTION POWERIO$ (DPSADDR%, CMD$) 'Actual I/O commands DECLARE FUNCTION SETSCM5BPWR! (VSUPPLY!) 'Sets SCM5B supply voltage 'HP33120A (function generator) control routines via GPIB DECLARE SUB CONFDUTIN (ONOFF%) 'Configure test head for inverted or non-inverted DUT input power supply conn. DECLARE SUB IO488 (DDATA$, DEVADDR%, SEL%) 'HP34970A (data acquisition/switch unit) control routines via GPIB DECLARE SUB DVMCONF (CH%, FUNC$, RANGETXT$, RANGENUM!, RESOLTXT$, RESOLNUM!) 'Configure DVM DECLARE SUB DVMSENS (CH%, FUNC1$, FUNC2$, SETTXT$, SETNUM!) 'Configure DVM DECLARE SUB HVRELAY (RELAY%, ONOFF%) DECLARE SUB SETDAC3 (DACNUM%, VOLTAGE!) 'Set 34907 DACs DECLARE SUB SETSWITCH (CH%, STATE%) 'Set switch on 34903A 20-ch actuator DECLARE FUNCTION GETREADING! () '** Send trigger & read DVM DECLARE FUNCTION READDVM! (CH%, FUNC$, RANGETXT$, RANGENUM!, RESOLTXT$, RESOLNUM!) 'Fluke 760A (meter calibrator) routines DECLARE SUB FLUKE760APANEL (VALUE!, UNITS%) 'Display front panel settings '********************* TOP LEVEL TEST ROUTINES **************************** DECLARE SUB COMPTEST (STATUS$(), ITERATION%, CAL%, INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), NUMDUT%, TTYPE%, TSPEC$(), SERNO$()) 'Complete set of tests 'DECLARE SUB FUNCTEST (CAL%, STATUS$(), NUMDUT%) 'Routines for functional test DECLARE SUB FUNCTEST (STATUS$(), CAL%, INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), NUMDUT%, TTYPE%, TSPEC$(), SERNO$()) 'Routines for functional test DECLARE SUB INDIVID (SEL%, INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), STATUS$(), NUMDUT%) 'Performs the tests individually '********* USER INTERFACE, REPORTING, AND LOGGING ROUTINES **************** DECLARE FUNCTION MENU1% () 'Gets the Test Group selection DECLARE FUNCTION MENU2% () 'Gets the individual test # DECLARE FUNCTION MENU3% () 'Gets the module family DECLARE FUNCTION SNMENU$ (SLOTNO%, SERNO$, SNFLAG%) 'Selection menu to change the SN information of unit in slots 2 or higher DECLARE SUB CHANGEDN (SN$) 'Allow user to change dash number DECLARE SUB FOOTER (STATUS$(), L%) 'Sends footer to printer if all tests passed DECLARE SUB GETNEXTSN (TIME2!, SERNO$(), NUMDUT%) 'Allows user the change the SN info for a new group of modules DECLARE SUB GETSN (SN$) 'Gets DUT serial number from user DECLARE SUB HEADERA (SN$) 'Prints test sheet header DECLARE SUB HEADERB (TESTTITLE$, L%) 'Prints test screen header DECLARE SUB INPUTSN (SN$, SERNO$(), NUMDUT%) 'Gathers the SN information for the unit in channel 1 DECLARE SUB LOGIT (STATUS$(), SN$, INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), L%) 'Logs test results to disk DECLARE SUB MODOUTLINE () 'Draw module bottom view. DECLARE SUB NOTES () 'Notes on ATE operation DECLARE SUB REPORT (STATUS$(), SN$, INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), TSPEC$(), NUMDUT%, TTYPE%) 'Prints test data on screen DECLARE SUB SORTDB (ENDFLAG%) 'Sort model database '*********************** DATABASE OPERATIONS ****************************** DECLARE SUB GETADD () 'Get system component addresses DECLARE SUB GETSPECS (NUMDUT%) 'Gets module type and specifications DECLARE SUB TSPECS (TSPEC$()) 'Creates a string array of test specifications '**************** TEST DECISIONING / CALCULATION ROUTINES ****************** DECLARE FUNCTION BESTFIT! (SLOPE!, OFFSET1!, INSIM!(), NUMPTS%, ERROROUT!(), L%) DECLARE FUNCTION FAILS% (STATUS$(), NUMDUT%) 'Tests for failed tests DECLARE FUNCTION REPEAT$ (MN$, ELAP2!, TIME2!) 'Ask if you would like to repeat test DECLARE FUNCTION MEASRES! (OHM!, RESNUM%, L%) 'Measure specified sense resistor DECLARE FUNCTION MODULEOUT! (SENOUT!) 'calculates DUT output based on input DECLARE SUB INSTALLDUT (NUMDUT%) 'Direct installation of DUTs and return # DECLARE SUB SETOUTLOAD (LOAD!, NUMDUT%) 'Set output load for current output '*********************** CALIBRATION ROUTINES ****************************** DECLARE SUB CALSEQ (NUMDUT%, STATUS$()) 'Determine & perform calibration sequence DECLARE SUB GAINCAL (CAL%, AMPL!, INTERACT!, OSERR2!(), NUMDUT%, STATUS$()) 'Performs Gain Calibration DECLARE SUB OFFSETCAL (CAL%, NUMDUT%, STATUS$()) 'Performs Offset Calibration DECLARE FUNCTION SETDUTIN! (DUTIN!) 'Set high level RMS input to D.U.T. '************************* ACCURACY ROUTINES ******************************* DECLARE SUB LINTEST (INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), NUMDUT%, STATUS$()) 'Performs Accuracy and Linearity Tests '************************* OTHER DUT TESTS ********************************* DECLARE SUB ENABLE (DUT%, ONOFF%) 'Sets the state of the SCM5B output switch DECLARE SUB IOUTMAXL (NUMDUT%, STATUS$()) 'Test current source compliance DECLARE SUB OUTPUTNOISE (NUMDUT%, STATUS$()) 'Test module output noise DECLARE SUB OUTSWITCH (NUMDUT%, STATUS$()) 'Test SCM5B output switch operation DECLARE SUB SUPPLYI (NUMDUT%, STATUS$()) 'Measure module supply current DECLARE SUB SUPPLYSEN (NUMDUT%, STATUS$()) 'Measure module supply sensitivity '***************** MISCELLANEOUS HOUSEKEEPING ROUTINES ********************* DECLARE SUB CONTINUE () 'Waits for a key press DECLARE SUB PAUSE (TIME!) 'Delays program for TIME! DECLARE FUNCTION KEYBDIN$ () 'Gets input from keyboard DECLARE FUNCTION UPSN$ (OLDSN$) '** Increments dash# of serial# '******* Added Functions and Subs for Work Order Status File (etc.) version ********** DECLARE FUNCTION LIBVERVAL$ () 'Function to return the library source file version DECLARE FUNCTION PROGVERVAL$ () 'Function to return the program source file version DECLARE FUNCTION PROGNAMEVAL$ () 'Function to return the program executable file name DECLARE SUB CHECKRESOURCES (CHECKFILES%) 'Checks whether the datasheet and work order status files can be written. DECLARE FUNCTION CHECKFILECREATE% (FOLDERNAME$, FILENAME$, KEYTOPRESS$) 'Checks whether the file can be written to the folder. DECLARE FUNCTION CHECKPRINTER% (PrinterMessage$) 'Checks to see of the printer can print. DECLARE SUB FAILSTATUS (TSITE%, TESTVALUE$, YLOC%, XLOC%, TEXTVALUE$, SPACES%) DECLARE SUB INTERLUDE () ' WAIT FOR USER DECLARE SUB WORKORDERLINE (FAILSTATE%, SN$) DECLARE SUB WORKORDERPRINT (SN$) DECLARE SUB WORKORDERHEADER (SN$) DECLARE SUB GETDSFNAME (SN$, DSSNAME$, DSFNAME$) 'Gets datasheet search and file names from serial number DECLARE SUB HARDCOPY () DECLARE SUB SNPARSE (SN$, WO$, DS$) DECLARE FUNCTION WAITFORKEY$ (KEY$, TABPOS%, FORECOL%, BACKCOL%) DECLARE FUNCTION GETWOSFNAME$ (SN$) 'Returns work order status file name from serial number DECLARE SUB STARTCFG () 'Performs module-input configuration before testing DECLARE SUB ENDCFG () 'Performs module-input configuration after testing DECLARE SUB CLEARUNITSMSG () 'Displays message to clear modules from testhead DECLARE FUNCTION GETWO$ () 'Gets and returns the work order number DECLARE FUNCTION GETDS$ (ISNEWDS%, SN$) 'Gets and returns the dash number DECLARE FUNCTION ISDUPLICATESN% (SERNO$, NUMDUT%) 'Check for duplicate serial numbers DECLARE FUNCTION INSTRERROR$ (INSTRADDR%) 'Reads error status from the Agilent 33120A or 33970A DECLARE SUB INSTRERRORS (INSTRADDR%, DISPLAYERRS%) 'Clears the Agilent 33120A or 34970A error queue by reading all errors DECLARE SUB SHOWDIO (DIODATA%, WORNO%, DEBUGVAL%) 'Displays stored value for DIO word. DECLARE SUB FINISHSUB () 'Subroutine to run at "FINISH" label (after F10 keypress). 'Database Record definition for the specifications TYPE DBASE MODNAME AS STRING * 13 'DSCA-XXXX or SCM5B-XXXX INTYPE AS STRING * 3 ''V' OR 'A' MININ AS SINGLE 'Minus F.S. input (V or I) MAXIN AS SINGLE 'Plus F.S. input (V or I) OUTSIGTYPE AS STRING * 7 ''VOLTAGE' or 'CURRENT' MINOUT AS SINGLE 'Minus F.S. output (V or I) MAXOUT AS SINGLE 'Plus F.S. output (V or I) WAVESHPCAL AS STRING * 8 ''SINE', 'SQUARE', 'TRIANGLE', 'RAMP' FINCAL AS SINGLE 'Calibration Frequency input (Hz) FINMIN AS SINGLE 'Minimum Std. Frequency input (Hz) FINMAX AS SINGLE 'Highest Std. Frequency input (Hz) FINEXTMIN AS SINGLE 'Minimum Extd. Frequency input (Hz) FINEXTMAX AS SINGLE 'Highest Extd. Frequency input (Hz) INPROTECT AS SINGLE 'Rated input Protection (V or I) IOUTLIM AS SINGLE 'Current output limit (mA) VOUTLIM AS SINGLE 'Voltage output limit (V) OUTRES AS SINGLE 'Output resistance OUTNOISE AS SINGLE 'Output noise/ripple 100kHz BW (RMS) OSCALIN AS SINGLE 'Module input for offset calibration GNCALIN AS SINGLE 'Module input for gain calibration OSCALPT AS SINGLE 'Offset cal point (%span) GNCALPT AS SINGLE 'Gain cal point (%span) CALTOL AS SINGLE 'Calibration tolerance (%span) ADJ AS SINGLE 'User Adjustability Range (%span) LINEAR AS SINGLE 'Linearity (% span) at sine input and FINCAL ACCSINCAL AS SINGLE 'Sine accuracy (%span) at CALFIN ACCSINSTD AS SINGLE 'Sine accuracy (%span) from FINMIN to FIMMAX ACCSINEXT AS SINGLE 'Sine accuracy (%span) from FINEXTMIN to FINEXTMAX ACCCF12 AS SINGLE 'C.F. = 1 TO 2 accuracy (%span) at FINCAL ACCCF23 AS SINGLE 'C.F. = 2 TO 3 accuracy (%span) at FINCAL ACCCF34 AS SINGLE 'C.F. = 3 TO 4 accuracy (%span) at FINCAL ACCCF45 AS SINGLE 'C.F. = 4 TO 5 accuracy (%span) at FINCAL CMR AS SINGLE 'Common Mode Rejection (dB) STEPTIME AS SINGLE 'Test time for step response STEPPERC AS SINGLE '% F.S. @ STEPTIME STEPTOL AS SINGLE 'STEPPERC measurement tolerance LOOPVMIN AS SINGLE 'Output Loop Voltage min (V) LOOPVNOM AS SINGLE 'Output Loop Voltage nom (V) LOOPVMAX AS SINGLE 'Output Loop Voltage max (V) MAXLOADR AS SINGLE 'Maximum load resistance (ohms) MINVS AS SINGLE 'Lowest supply voltage (V) NOMVS AS SINGLE 'Nominal supply voltage (V) MAXVS AS SINGLE 'Highest supply voltage (V) ISMIN AS SINGLE 'Minimum supply current (mA) ISMAX AS SINGLE 'Supply current, full load (mA) PSS AS SINGLE 'Power supply sensitivity (ppm/% or %/% Delta Vs) END TYPE TYPE DBASE2 RECNUM AS INTEGER MODNAME AS STRING * 13 END TYPE '$INCLUDE: 'QB.BI2' 'Define common variables COMMON SHARED /SAMPLE/ SPECS AS DBASE COMMON SHARED /SAMPLE/ SORTDATA1 AS DBASE2 COMMON SHARED /SAMPLE/ SORTDATA2 AS DBASE2 COMMON SHARED IINSEN1.MEAS! COMMON SHARED IOUTSEN1.MEAS!() COMMON SHARED IOUTSEN2.MEAS!() COMMON SHARED IOUTSEN11.MEAS!() COMMON SHARED SERNO$() COMMON SHARED SN$ ' unit serial number COMMON SHARED PSCOM$ COMMON SHARED PSPORT% COMMON SHARED GENOUTMAX! COMMON SHARED PCBNO$ COMMON SHARED BADDRS% COMMON SHARED DPSADDR% COMMON SHARED DASADDR% COMMON SHARED GENADDR% COMMON SHARED DIOCH01DATA% COMMON SHARED DIOCH02DATA% COMMON SHARED /PRTSCR/ inreg AS RegType COMMON SHARED /PRTSCR/ outreg AS RegType COMMON SHARED PON%, TX%, TESTPAUSE%, LOGDAT% COMMON SHARED DPSVINADDR%, DPSVINADDR2% COMMON SHARED DEBUGFLAG%, CAL%, TTYPE% REM $DYNAMIC 'DIM STATUS(17, 4) AS STRING 'DIM TSPEC(17) AS STRING DIM STATUS(MAXSTATUSINDEX, 4) AS STRING DIM TSPEC(MAXSTATUSINDEX) AS STRING DIM INSIM!(4, 25) DIM OUTCALC!(4, 25) DIM OUTMEAS!(4, 25) DIM ERROROUT!(4, 25) DIM ACCSTAT$(4, 25) DIM IOUTSEN1.MEAS!(4) DIM IOUTSEN2.MEAS!(4) DIM IOUTSEN11.MEAS!(4) DIM SHARED SERNO$(1 TO 4) '******************************************************************** 'Assign constants to Kepco DPS power supply commands: CONST PSVOLT$ = "STV=" 'Set terminal voltage CONST SUPPLYON$ = "SOP=ON" 'Set output to ON CONST SUPPLYOFF$ = "SOP=OFF" 'Set output to OFF CONST ISTAT$ = "RCS" 'Read Current protection status CONST SETIMAX$ = "SOC=" 'Set overcurrent limit...4mA resolution. CONST CURRENT$ = "RTC" 'Read output current CONST OVERV.DSCA! = 125 'Module power supply over voltage limit, DSCA CONST OVERV.SCM5B! = 48 'Current loop power supply over voltage limit, SCM5B CONST PSILIMIT! = 2 'Module power supply over current limit '(max spec multiplier), DSCA CONST PSID$ = "ID" 'Power supply ID '******************************************************************** 'Assign constants to HP freq. gen. commands CONST FREQ$ = "FREQ", VOLT$ = "VOLT", OFFS$ = "VOLT:OFFS" CONST VUNIT$ = "VOLT:UNIT" CONST SINE$ = "FUNC:SHAP SIN", SQUARE.CF1$ = "FUNC:SHAP SQU", TRIANGLE$ = "FUNC:SHAP TRI" CONST SQUARE.CF2$ = "FUNC:USER ARB1", SQUARE.CF3$ = "FUNC:USER ARB2" CONST SQUARE.CF4$ = "FUNC:USER ARB3", SQUARE.CF5$ = "FUNC:USER ARB4" CONST BURSTON$ = "BM:STAT ON", BURSTOFF$ = "BM:STAT OFF" CONST BURSTCNT$ = "BM:NCYC", BURSTSRCINT$ = "BM:SOUR INT" CONST SETOUTP$ = "OUTP:LOAD INF" 'Generator output load is infinity CONST INITWAVE$ = "APPL:SIN 60, .1, 0" 'Sine wave, .1Vrms, 60Hz, 0V offset '******************************************************************** 'Assign constants to HP DAS commands CONST VDC$ = "VOLT:DC", VAC$ = "VOLT:AC", RES2W$ = "RES", RES4W$ = "FRES" CONST ADC$ = "CURR:DC", AUTO$ = "AUTO" CONST INTTIME$ = "NPLC", BW$ = "BAND", RANGE$ = "RANG" CONST OSCOMP$ = "OCOM" CONST DIGOUT$ = "SOUR:DIG:DATA", SETDAC$ = "SOUR:VOLT" CONST GENOUTMIN! = .1 'HP33120A minimum output amplitude CONST GENOUTMAXHF! = 7.07 '7.07Vrms max output, sine, any freq., 'HP33120A direct to D.U.T. ' '******************************************************************** 'Assign constants to HP DAS configuration CONST IINSEN2SOUR.CH% = 101 'Input current sense resistor, 100 ohm, source lines CONST VOUTDUT1.CH% = 102 'DUT#1 output CONST VOUTDUT2.CH% = 103 'DUT#2 output CONST VOUTDUT3.CH% = 104 'DUT#3 output CONST VOUTDUT4.CH% = 105 'DUT#4 output CONST IOUTSENDUT1SOUR.CH% = 106 'Output current sense resistor DUT#1, source lines CONST IOUTSENDUT1SEN.CH% = 116 'Output current sense resistor DUT#1, sense lines CONST IOUTSENDUT2SOUR.CH% = 107 'Output current sense resistor DUT#2, source lines CONST IOUTSENDUT2SEN.CH% = 117 'Output current sense resistor DUT#2, sense lines CONST IOUTSENDUT3SOUR.CH% = 108 'Output current sense resistor DUT#3, source lines CONST IOUTSENDUT3SEN.CH% = 118 'Output current sense resistor DUT#3, sense lines CONST IOUTSENDUT4SOUR.CH% = 109 'Output current sense resistor DUT#4, source lines CONST IOUTSENDUT4SEN.CH% = 119 'Output current sense resistor DUT#4, sense lines 'CH 10 NOT USED CONST IINSEN2SEN.CH% = 111 'Input current sense resistor, 100 ohm, sense lines CONST SCM5BVS.CH% = 112 'Supply voltage, SCM5B CONST VIN.CH% = 113 'DUT input 'CH 14 NOT USED CONST IINSEN1.CH% = 115 'Input current sense resistor, 0.15 ohm CONST MEASISUPPLY1.CH% = 121 'Supply current, DUT#1 & DUT#2 CONST MEASISUPPLY2.CH% = 122 'Supply current, DUT#3 & DUT#4 'CH 20 NOT USED CONST SWITCHISDUT1.CH% = 201 'DUT #1 supply current routing CONST SWITCHISDUT2.CH% = 202 'DUT #2 supply current routing CONST SWITCHISDUT3.CH% = 203 'DUT #3 supply current routing CONST SWITCHISDUT4.CH% = 204 'DUT #4 supply current routing CONST VLOOPDUT1.CH% = 205 'Connect Vloop to Vout, DUT#1 (SCM5B current out only) CONST VLOOPDUT2.CH% = 206 'Connect Vloop to Vout, DUT#2 (SCM5B current out only) CONST VLOOPDUT3.CH% = 207 'Connect Vloop to Vout, DUT#3 (SCM5B current out only) CONST VLOOPDUT4.CH% = 208 'Connect Vloop to Vout, DUT#4 (SCM5B current out only) CONST IOUTLOAD1DUT1.CH% = 209 'Current output main load, DUT#1, 250 ohm CONST IOUTLOAD2DUT1.CH% = 210 'Current output max load, DUT#1, 600 ohm typ. CONST IOUTLOAD1DUT2.CH% = 211 'Current output main load, DUT#2, 250 ohm CONST IOUTLOAD2DUT2.CH% = 212 'Current output max load, DUT#2, 600 ohm typ. CONST IOUTLOAD1DUT3.CH% = 213 'Current output main load, DUT#3, 250 ohm CONST IOUTLOAD2DUT3.CH% = 214 'Current output max load, DUT#3, 600 ohm typ. CONST IOUTLOAD1DUT4.CH% = 215 'Current output main load, DUT#4, 250 ohm CONST IOUTLOAD2DUT4.CH% = 216 'Current output max load, DUT#4, 600 ohm typ. CONST DUT3INPUT.CH% = 217 'DUT #1 input, V or A CONST DUT2INPUT.CH% = 218 'DUT #2 input, V or A CONST DUT1INPUT.CH% = 219 'DUT #3 input, V or A CONST VSSOURCE.CH% = 220 'D.U.T. Supply Voltage CONST HVRELAY.CH% = 301 'DIO LSB, Test head high voltage relay control CONST RDEN.CH% = 302 'DIO MSB, RD EN/, DUT 1-4 CONST DAC1.CH% = 304 'DAC #1 CONST DAC2.CH% = 305 'DAC #2 '******************************************************************** 'assign specifications which are constant for all modules CONST IINSEN1! = .15 'Input current source sense resistor, 0.15 ohm CONST IINSEN2! = 100 'Input current source sense resistor, 100 ohm CONST IOUTSEN1! = 250 'Output current sense resistor, 250 ohm. CONST IOUTSEN2! = 600 'Output current sense resistor, 600 ohm. CONST DELTALOADTOL! = 1 'Max change in output with load (%) 'Allows for 5.4 ohm lead resistance 'and 0.1% output change CONST NOISEFILTERR! = 160 'RC located @ meter input. 160 ohm series, 0.01uF shunt CONST IOUTSEN3! = 10001 'Disconnect output loading CONST WORD2INIT = 255 'Initial value of DIOCH02DATA% 'CONST WORD2INIT = 15 'Initial value of DIOCH02DATA% ' Variable initialization DEBUGFLAG% = 0 'Debug flag, "1" for debug (see in subs and functions). TESTPAUSE% = 0 '1 = Pause after the status display of each test TX% = 0 '1 = generate text files (datasheet and work order status) PON% = 0 '1 = print test data to screen LOGDAT% = 0 'Log linearity test data OFF BADDRS% = &H250 'Base address of PC4311 '488 controller DIOCH01DATA% = 0 'Digital I/O initialization, &H0 DIOCH02DATA% = WORD2INIT 'Digital I/O initialization, &HFF COLOR 11, 0, 0 'Cyan on black background 'HP34901A, 20 Channel Mux, Configuration 'Channel Description '------- --------------------------------------------------- ' 1 Iin sense resistor, 100 ohm, 4W, source lines ' 2 Vout, DUT1 ' 3 Vout, DUT2 ' 4 Vout, DUT3 ' 5 Vout, DUT4 ' 6 Iout sense resistor, DUT1, 250 ohm or 600 ohm, 4W or 2W, source lines ' 7 Iout sense resistor, DUT2, 250 ohm or 600 ohm, 4W or 2W, source lines ' 8 Iout sense resistor, DUT3, 250 ohm or 600 ohm, 4W or 2W, source lines ' 9 Iout sense resistor, DUT4, 250 ohm or 600 ohm, 4W or 2W, source lines ' 10 Vin ' 11 Iin sense resistor, 100 ohm, 4W, sense lines ' 12 SCM5B Supply Voltage ' 13 NC ' 14 NC ' 15 Iin sense resistor, 0.1 ohm, 2W ' 16 Iout sense resistor, DUT1, 250 ohm, 4W, sense lines ' 17 Iout sense resistor, DUT2, 250 ohm, 4W, sense lines ' 18 Iout sense resistor, DUT3, 250 ohm, 4W, sense lines ' 19 Iout sense resistor, DUT4, 250 ohm, 4W, sense lines ' 20 NC ' 21 SCM5B Supply Current, DUT1 & DUT2 ' 22 SCM5B Supply Current, DUT3 & DUT4 'HP34903A, 20 Channel Actuator, Configuration 'Channel Description '------- --------------------------------------------------- ' 1 NC = Select SCM5B Supply Current, DUT1 ' 2 NO = Select SCM5B Supply Current, DUT2 ' 3 NC = Select SCM5B Supply Current, DUT3 ' 4 NO = Select SCM5B Supply Current, DUT4 ' 5 NC = Measure Vout DUT1, NO = Connect Vloop to SCM5B DUT1 Vout ' 6 NC = Measure Vout DUT2, NO = Connect Vloop to SCM5B DUT2 Vout ' 7 NC = Measure Vout DUT3, NO = Connect Vloop to SCM5B DUT3 Vout ' 8 NC = Measure Vout DUT4, NO = Connect Vloop to SCM5B DUT4 Vout ' 9 NO = DUT1 Output Load 1, 250 ohm ' 10 NO = DUT1 Output Load 2, 600 ohm ' 11 NO = DUT2 Output Load 1, 250 ohm ' 12 NO = DUT2 Output Load 2, 600 ohm ' 13 NO = DUT3 Output Load 1, 250 ohm ' 14 NO = DUT3 Output Load 2, 600 ohm ' 15 NO = DUT4 Output Load 1, 250 ohm ' 16 NO = DUT4 Output Load 2, 600 ohm ' 17 NO = Vin DUT3, NC = Iin DUT1 ' 18 NO = Vin DUT2, NC = Iin DUT2 ' 19 NO = Vin DUT1, NC = Iin DUT3 ' 20 NO = Vsupply is Kepco DPS125 +15 to +30V, NC = Vsupply is +5V 'HP34907A, Multi-function Module, Configuration 'Port Line Assignment '---- ------ ---------- ' 1 7 MSB NC ' 6 NC ' 5 HVRELAY #6 0 = HP33120A input to Fluke 760A, 1 = HP33120A disconnected from Fluke 760A ' 4 HVRELAY #5 0 = Fluke 760A input to D.U.T., 1 = HP33120A input to D.U.T. ' * set lines 4 and 5 simultaneously low or high ' 3 HVRELAY #4 1 = Rsense Bypass ' 2 HVRELAY #3 1 = D.U.T. 2 Input Bypass ' 1 HVRELAY #2 1 = D.U.T. 3 Input Bypass ' 0 LSB HVRELAY #1 1 = D.U.T. 4 Input Bypass ' ' 2 7 MSB NC ' 6 NC ' 5 NC ' 4 NC ' 3 0 = D.U.T. 1 RD EN/ ' 2 0 = D.U.T. 2 RD EN/ ' 1 0 = D.U.T. 3 RD EN/ ' 0 LSB 0 = D.U.T. 4 RD EN/ ' ' DAC CH4 '****************** MAIN PROGRAM ****************** KEY(10) ON 'Activates F10 key ON KEY(10) GOSUB FINISH 'Traps for F10 key Exits if pressed CLS CALL GETADD COLOR 11, 0 'Text color to light cyan (blue) 'CLS LOCATE 5, 20: PRINT "Initializing test system. Please wait." LOCATE 7, 10: PRINT "EXECUTABLE: "; PROGNAMEVAL$ 'Executable file name LOCATE 8, 10: PRINT "VERSION: "; PROGVERVAL$ 'Main source code version LOCATE 9, 10: PRINT "LIB.VERSION: "; LIBVERVAL$ 'Library code version LOCATE 10, 10: PRINT "SOURCE FILES: "; SOURCEFILES$ 'List of all code files for the program CALL CONTINUE CLS LOCATE 12 'PRINT TAB(10); "Initializing Function Generator..." 'PRINT TAB(10); "Storing Arbitrary Waveforms in Generator" 'PRINT TAB(10); "Please wait...." PRINT TAB(20); "Initializing Function Generator..." CALL IO488("*RST", GENADDR%, 1) PRINT PRINT TAB(10); "Initializing Data Acquisition System..." CALL IO488("ABOR", DASADDR%, 1) 'Abort any scans in progress. CALL IO488("*CLS", DASADDR%, 1) 'Clear status (clear errors) CALL INSTRERRORS(DASADDR%, 1) 'Clears and displays Agilent 34970A error queue. CLS 'Clear messages. LOCATE 10, 10: PRINT SPC(70); LOCATE 11, 10: PRINT SPC(70); LOCATE 12, 10: PRINT SPC(70); LOCATE 13, 10: PRINT SPC(70); LOCATE 14, 10: PRINT SPC(70); LOCATE 15, 10: PRINT SPC(70); 'Display initial message. LOCATE 10, 10: PRINT "-----------------------------------------------" LOCATE 11, 10: PRINT "Initializing 34970A Data Acquisition System...." LOCATE 12, 10: PRINT "-----------------------------------------------" LOCATE 13, 10: PRINT "Please wait...." CALL PAUSE(1) 'Pause to message can be read. 'Initialize function generator. CALL INSTRERRORS(DASADDR%, 0) 'Clear Agilent 34970A errors. LOCATE 14, 10: PRINT "Resetting the 34970A data acquisition system." CALL IO488("*RST", DASADDR%, 1) 'Send a "clear status" command to the function generator (should clear errors). PAUSE (1) 'Pause so message can be read. LOCATE 14, 10: PRINT SPC(70); LOCATE 14, 10: PRINT "Aborting any scans in progress in 34970A." CALL IO488("ABOR", DASADDR%, 1) 'Abort any scans in progress. PAUSE (1) 'Pause so message can be read. LOCATE 14, 10: PRINT SPC(70); LOCATE 14, 10: PRINT "Clearing the 34970A data acquisition system." CALL IO488("*CLS", DASADDR%, 1) 'Send a "clear status" command to the function generator (should clear errors). PAUSE (1) 'Pause so message can be read. LOCATE 14, 10: PRINT SPC(70); LOCATE 14, 10: PRINT "Deleting stored states in Agilent 34970A (may beep)." CALL IO488("MEM:STAT:DEL 0", DASADDR%, 1) 'Delete store state 0. CALL IO488("MEM:STAT:DEL 1", DASADDR%, 1) 'Delete store state 1. CALL IO488("MEM:STAT:DEL 2", DASADDR%, 1) 'Delete store state 2. CALL IO488("MEM:STAT:DEL 3", DASADDR%, 1) 'Delete store state 3. CALL IO488("MEM:STAT:DEL 4", DASADDR%, 1) 'Delete store state 4. CALL IO488("MEM:STAT:DEL 5", DASADDR%, 1) 'Delete store state 5. CALL INSTRERRORS(DASADDR%, 0) 'Clear Agilent 34970A errors. PAUSE (1) 'Pause so message can be read. 'Clear messages. LOCATE 10, 10: PRINT SPC(70); LOCATE 11, 10: PRINT SPC(70); LOCATE 12, 10: PRINT SPC(70); LOCATE 13, 10: PRINT SPC(70); LOCATE 14, 10: PRINT SPC(70); LOCATE 15, 10: PRINT SPC(70); 'CALL DVMSENS(VIN.CH%, VAC$, BW$, "", 3) 'Set bandwidth for max accuracy. PRINT TAB(10); "Initializing Power Supply..." SP$ = POWERIO$(DPSADDR%, SUPPLYOFF$) 'Disable power supply SP$ = POWERIO$(DPSADDR%, PSID$) ' SP$ = POWERIO$(DPSVINADDR%, SUPPLYOFF$) 'Disable power supply SP$ = POWERIO$(DPSVINADDR%, PSID$) ' SP$ = POWERIO$(DPSVINADDR2%, SUPPLYOFF$) 'Disable power supply SP$ = POWERIO$(DPSVINADDR2%, PSID$) PRINT PRINT TAB(10); USING "&&"; SP$ + " = " + PSCOM$ PRINT TAB(10); "#1 KEPCO DPS125-0.5M Address = "; DPSADDR% PRINT TAB(10); "#2 KEPCO DPS125-0.5M Address = "; DPSVINADDR% PRINT TAB(10); "#3 KEPCO DPS125-0.5M Address = "; DPSVINADDR2% PRINT TAB(10); "HP34970A GPIB Address = "; DASADDR% PRINT TAB(10); "HP33120A GPIB Address = "; GENADDR% 'IF ASC(SP$) <> 75 THEN ' PRINT ' PRINT TAB(20); "Programmable Power Supply Failure" ' CALL CONTINUE ' GOTO FINISH 'END IF PRINT PRINT TAB(10); "Setting Internal Vsupply to Zero..." SP! = SETSCM5BPWR!(.01) 'Set Vsupply to zero PRINT PRINT TAB(10); "Initializing Test Head..." CALL PAUSE(1) DDATA$ = DIGOUT$ + STR$(DIOCH01DATA%) + ",(@" + STR$(HVRELAY.CH%) + ")" CALL IO488(DDATA$, DASADDR%, 1) 'Write configuration 'Port 2, data = WORD2INIT DIOCH02DATA% = WORD2INIT 'Digital I/O initialization, &HFF DDATA$ = DIGOUT$ + STR$(DIOCH02DATA%) + ",(@" + STR$(RDEN.CH%) + ")" CALL IO488(DDATA$, DASADDR%, 1) 'Write configuration CALL HVRELAY(4, 1) 'Bypass 100 ohm sense resistor CLS LOCATE 10 PRINT TAB(10); "Remove all modules from the test head." PRINT COLOR 14, 0, 0 'Yellow on black PRINT TAB(6); "-----------------------------------------------------------------" COLOR 28, 0, 0 'Flashing light red PRINT TAB(5); "Verify that there are no modules of any type currently installed " PRINT TAB(5); "in the test head! " COLOR 14, 0, 0 'Yellow on black PRINT TAB(6); "-----------------------------------------------------------------" 'BEEP DUMKEY$ = WAITFORKEY("N", 10, 14, 0) 'Waits for "N" key press (display bright yellow on black) CLS LOCATE 10, 10: PRINT "Measuring output current sense resistors." LOCATE 16, 10: PRINT "Please wait...." 'NOMVS! = 0, Vloop not connected during SETOUTLOAD. CALL SETOUTLOAD(IOUTSEN1!, 4) 'Set current output sense resistor FOR L% = 1 TO 4 IOUTSEN11.MEAS!(L%) = MEASRES!(IOUTSEN1!, 2, L%) 'Measure current output sense resistor NEXT CALL SETOUTLOAD(IOUTSEN2!, 4) 'Set max load resistor FOR L% = 1 TO 4 IOUTSEN2.MEAS!(L%) = MEASRES!(IOUTSEN2!, 3, L%) 'Measure current output sense resistor NEXT LOGDAT% = 0 'Log linearity test data OFF '********************* MAIN LOOP **************************** DO 'Main program loop SN$ = "" 'Reset serial number SEL% = MENU1% 'Gets the # of the sub program SELECT CASE SEL% 'Branches to the specific Tests '**************** Pre-Burn In Functional Test ******************* CASE 1 TTYPE% = 1 'Test type flag CAL% = 2 'Measure offset and gain, don't calibrate ITERATION% = 1 'Sets # of times to repeat offset/gain cal CALL GETSPECS(NUMDUT%) 'Gets module test specs CALL CLEARUNITSMSG 'Displays message to clear modules from testhead IF LEFT$(SPECS.MODNAME, 2) = "8B" THEN PCBNO$ = "0000" END IF IF LEFT$(SPECS.MODNAME, 4) <> "EXIT" THEN SN$ = "-1" 'Dummy value 'CALL INSTALLDUT(NUMDUT%) 'Gets number of modules to test 'CALL FUNCTEST(CAL%, STATUS$(), NUMDUT%) ' test CALL FUNCTEST(STATUS$(), CAL%, INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), NUMDUT%, TTYPE%, TSPEC$(), SERNO$()) 'Routines for functional test CALL SETDPS(DPSVINADDR%, 0) CALL SETDPS(DPSVINADDR2%, 0) CALL INSTRERRORS(DASADDR%, 1) 'Clears and displays Agilent 34970A error queue. PON% = 0 'Print Flag Printer OFF END IF '*********************** Pre-Encap Complete Test ****************************** CASE 2 TTYPE% = 2 'Test type flag CAL% = 0 'Calibrate offset & gain. ITERATION% = 1 'Sets # of times to repeat offset/gain cal CALL GETSPECS(NUMDUT%) 'Gets module test specs CALL CLEARUNITSMSG 'Displays message to clear modules from testhead IF LEFT$(SPECS.MODNAME, 2) = "8B" THEN PCBNO$ = "0000" END IF IF LEFT$(SPECS.MODNAME, 4) <> "EXIT" THEN SN$ = "-1" 'Dummy value CALL COMPTEST(STATUS$(), ITERATION%, CAL%, INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), NUMDUT%, TTYPE%, TSPEC$(), SERNO$()) 'Complete set of tests CALL ENDCFG 'Performs module-input configuration after testing CALL SETDPS(DPSVINADDR%, 0) CALL SETDPS(DPSVINADDR2%, 0) CALL INSTRERRORS(DASADDR%, 1) 'Clears and displays Agilent 34970A error queue. PON% = 0 'Print Flag Printer OFF END IF '**************** Post-Encap Complete Test *********************************** CASE 3 TTYPE% = 3 'Test type flag CAL% = 0 'calibrate offset & gain ITERATION% = 1 'Sets # of times to repeat offset/gain cal CALL GETSPECS(NUMDUT%) 'Gets module test specs CALL CLEARUNITSMSG 'Displays message to clear modules from testhead IF LEFT$(SPECS.MODNAME, 2) = "8B" THEN PCBNO$ = "0000" END IF IF LEFT$(SPECS.MODNAME, 4) <> "EXIT" THEN CALL COMPTEST(STATUS$(), ITERATION%, CAL%, INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), NUMDUT%, TTYPE%, TSPEC$(), SERNO$()) 'Complete set of tests CALL ENDCFG 'Performs module-input configuration after testing CALL SETDPS(DPSVINADDR%, 0) CALL SETDPS(DPSVINADDR2%, 0) CALL INSTRERRORS(DASADDR%, 0) 'Clear Agilent 34970A errors. PON% = 0 'Print Flag Printer OFF END IF '**************** Sealed Module Re-Test *********************************** CASE 4 TTYPE% = 4 'Test type flag 'CAL% = 0 'Calibrate offset & gain ITERATION% = 0 'Sets # of times to repeat offset/gain cal CALL GETSPECS(NUMDUT%) 'Gets module test specs CALL CLEARUNITSMSG 'Displays message to clear modules from testhead IF LEFT$(SPECS.MODNAME, 2) = "8B" THEN PCBNO$ = "0000" END IF IF LEFT$(SPECS.MODNAME, 4) <> "EXIT" THEN CALL COMPTEST(STATUS$(), ITERATION%, CAL%, INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), NUMDUT%, TTYPE%, TSPEC$(), SERNO$()) 'Complete set of tests CALL ENDCFG 'Performs module-input configuration after testing CALL SETDPS(DPSVINADDR%, 0) CALL SETDPS(DPSVINADDR2%, 0) CALL INSTRERRORS(DASADDR%, 1) 'Clears and displays Agilent 34970A error queue. PON% = 0 'Print Flag Printer OFF END IF '***********************Individual Test Routines****************************** CASE 5 TTYPE% = 5 'Test type flag. 'PON% = 0 'Print Flag Printer OFF. DO 'Start of Individual Tests loop. SEL% = MENU2% 'Gets # of test. 'IF SEL% <> 20 THEN 'Checks for exit. IF SEL% <> 13 THEN 'Checks for exit. 'IF SEL% = 17 THEN 'Checks for printer toggle. IF SEL% = 9 THEN 'Checks for printer toggle. 'Toggles printer status IF PON% = 1 THEN PON% = 0 ELSE PON% = 1 END IF 'ELSEIF SEL% = 16 THEN ELSEIF SEL% = 8 THEN CALL NOTES 'Show ATE notes. 'ELSEIF SEL% = 18 THEN ' 'Toggles log status ' 'LOGDAT% = -LOGDAT% ' IF LOGDAT% = 1 THEN ' LOGDAT% = 0 ' ELSE ' LOGDAT% = 1 ' END IF 'ELSEIF SEL% = 19 THEN ELSEIF SEL% = 10 THEN 'Checks for pause on each test toggle (character A). ' 'Toggles "pause on each test" flag IF TESTPAUSE% = 1 THEN TESTPAUSE% = 0 ELSE TESTPAUSE% = 1 END IF ELSEIF SEL% = 11 THEN 'Checks for debug flag toggle (character B). ' 'Toggles debug flag IF DEBUGFLAG% = 1 THEN DEBUGFLAG% = 0 ELSE DEBUGFLAG% = 1 END IF ELSEIF SEL% = 12 THEN 'Character C LPRINT CHR$(12) 'Form feed ELSE 'Individual Tests. CALL GETSPECS(NUMDUT%) 'Gets module specs. IF LEFT$(SPECS.MODNAME, 4) <> "EXIT" THEN SN$ = "-1" 'Dummy value TESTPAUSE% = 1 'Turn on "pause on each test" flag. CALL CLEARUNITSMSG 'Displays message to clear modules from testhead CALL INDIVID(SEL%, INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), STATUS$(), NUMDUT%) 'Performs individual test TESTPAUSE% = 0 'Turn off "pause on each test" flag. CALL ENDCFG 'Performs module-input configuration after testing END IF END IF END IF 'LOOP UNTIL SEL% = 20 'End of loop LOOP UNTIL SEL% = 13 'End of loop (character D). '*************************** End Program Selection ********************************* CASE 6 ENDPROG% = 1 'Sets end program flag END SELECT LOOP WHILE ENDPROG% <> 1 'Loops until end program flag set '******************** End Program Selection ******************* FINISH: CALL FINISHSUB END 'End of program '*********************************** SUB CALSEQ (NUMDUT%, STATUS$()) 'Determine which calibration sequence is required for the module 'and perform the offset and gain calibration. ' 'Inputs; None 'Outputs; WONTCAL% 0 = Module calibrated ' 1 = Module won't calibrate, exit sequence ' MAXOUT! = SPECS.MAXOUT MINOUT! = SPECS.MINOUT ACCLIM! = SPECS.ACCSINCAL ORANGE! = MAXOUT! - MINOUT! DIM OSERR2!(5), GNERR2!(5) IF (ABS(MINOUT!) <> MAXOUT! AND MINOUT! <> 0) OR SPECS.OSCALIN <> 0 THEN PEDOFFSET$ = "Y" INTERACT! = .0909 'Change in offset with change in gain. 'average value determined from data in CALDATA.DAT ITERATION% = 4 '4 passes MAX on initial cal ELSE PEDOFFSET$ = "N" INTERACT! = 1 ITERATION% = 1 END IF IF PEDOFFSET$ = "N" THEN 'Standard calibration sequence DO CAL% = 0 CALL OFFSETCAL(CAL%, NUMDUT%, STATUS$()) 'Calibrate offset CALL GAINCAL(CAL%, 0, INTERACT!, OSERR2!(), NUMDUT%, STATUS$()) 'Calibrate gain ITERATION% = ITERATION% - 1 LOOP WHILE ITERATION% > 0 'Tests for Offset/Gain calibration end ELSE CAL% = 1 CALL OFFSETCAL(CAL%, NUMDUT%, STATUS$()) 'Measure offset error after adjust FOR L% = 1 TO NUMDUT% IF LEFT$(STATUS$(1, L%), 4) <> "FAIL" AND LEFT$(STATUS$(13, L%), 4) <> "FAIL" AND LEFT$(STATUS$(14, L%), 4) <> "FAIL" THEN 'Check if module passes DATALEN% = LEN(STATUS$(13, L%)) OSERR2!(L%) = VAL(MID$(STATUS$(13, L%), 5, DATALEN% - 4)) END IF NEXT DO CAL% = 0 CALL GAINCAL(CAL%, 0, INTERACT!, OSERR2!(), NUMDUT%, STATUS$()) 'Calibrate gain CALL OFFSETCAL(CAL%, NUMDUT%, STATUS$()) 'Calibrate offset OSPASS% = 1 FOR L% = 1 TO NUMDUT% IF LEFT$(STATUS$(1, L%), 4) <> "FAIL" AND LEFT$(STATUS$(13, L%), 4) <> "FAIL" AND LEFT$(STATUS$(14, L%), 4) <> "FAIL" THEN 'Check if module passes DATALEN% = LEN(STATUS$(13, L%)) 'Get offset error OSERR2!(L%) = VAL(MID$(STATUS$(13, L%), 5, DATALEN% - 4)) IF ABS(OSERR2!(L%)) >= ACCLIM! THEN OSPASS% = 0 END IF NEXT CAL% = 0 CALL GAINCAL(CAL%, 0, INTERACT!, OSERR2!(), NUMDUT%, STATUS$()) 'Calibrate gain GNPASS% = 1 FOR L% = 1 TO NUMDUT% IF LEFT$(STATUS$(1, L%), 4) <> "FAIL" AND LEFT$(STATUS$(13, L%), 4) <> "FAIL" AND LEFT$(STATUS$(14, L%), 4) <> "FAIL" THEN 'Check if module passes DATALEN% = LEN(STATUS$(14, L%)) 'Get gain error GNERR2! = VAL(MID$(STATUS$(14, L%), 5, DATALEN% - 4)) 'Measured gain error in mV or uA IF ABS(GNERR2!(L%)) >= ACCLIM! THEN GNPASS% = 0 END IF NEXT ITERATION% = ITERATION% - 1 LOOP UNTIL (OSPASS% = 1 AND GNPASS% = 1) OR ITERATION% = 0 END IF END SUB SUB CLEARUNITSMSG 'Sub to display a message about what kind of modules can be tested, 'and the restriction against testing one type of module with other 'modules in the testhead. Then a message is displayed to remove ALL 'modules from the testhead. The sub is generally run only at the 'start of any kind of test. ' 'First message screen CLS LOCATE 1, 20: PRINT "SCM5B, 8B & DSCA AUTOMATED TEST EQUIPMENT" PRINT PRINT TAB(5); "Module type selected: "; SPECS.MODNAME PRINT PRINT PRINT TAB(5); "Up to 4 modules of a single type (SCM5B, 8B or DSCA can be" PRINT TAB(5); "tested at the same time. However, only ONE (1) type of module can" PRINT TAB(5); "be installed while testing!" PRINT PRINT COLOR 14, 0, 0 'Yellow on black PRINT TAB(6); "-----------------------------------------------------------------" COLOR 28, 0, 0 'Flashing light red PRINT TAB(5); "Verify that there are no modules of any type currently installed " PRINT TAB(5); "in the test head! " COLOR 14, 0, 0 'Yellow on black PRINT TAB(6); "-----------------------------------------------------------------" COLOR 11, 0, 0 'Cyan on black background PRINT 'BEEP DUMKEY$ = WAITFORKEY("N", 10, 14, 0) 'Waits for "N" key press (display bright yellow on black) END SUB '************************************ SUB COMPTEST (STATUS$(), ITERATION%, CAL%, INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), NUMDUT%, TTYPE%, TSPEC$(), SERNO$()) 'Complete set of tests 'Sub to run a complete set of tests, looping once each pass (and individually through each test channel 'for each test). In other legacy test code, the "once per test pass" loop was done in the MENU1% selection 'code, not within COMPTEST. ' NOMVS! = SPECS.NOMVS 'WAVESHPCAL$ = "FUNC:SHAP " + LEFT$(SPECS.WAVESHPCAL$, 3) FINCAL! = SPECS.FINCAL FINMAX! = SPECS.FINMAX FINEXTMAX! = SPECS.FINEXTMAX ACCCF12! = SPECS.ACCCF12 ACCCF23! = SPECS.ACCCF23 ACCCF34! = SPECS.ACCCF34 ACCCF45! = SPECS.ACCCF45 ACCSINCAL! = SPECS.ACCSINCAL ACCSINSTD! = SPECS.ACCSINSTD ACCSINEXT! = SPECS.ACCSINEXT OUTSIGTYPE$ = SPECS.OUTSIGTYPE LOOPVNOM! = SPECS.LOOPVNOM + SPECS.MAXOUT * NOISEFILTERR! DIM NOMOUTERR!(4) 'DIM TSPEC(17) AS STRING LOOPCYC% = 0 'Clear serial numbers and file flag FOR L% = 1 TO 4 SERNO$(L%) = "" NEXT LOCALSN$ = "" SN$ = "" TX% = 0 ' 'Text-file flag "off" IF ((TTYPE% = 3) OR (TTYPE% = 4)) THEN 'Post-Encap or Sealed Module test. Hardcopy (to printer) or 'not is asked, as well as the number of modules inserted. 'The module serial number or numbers is also determined and 'the "TX%" flag is set "on" (to create work order status and 'datasheet text files). ' TX% = 1 ' 'Text-file flag "on" 'Get information required before the first test pass CALL INSTALLDUT(NUMDUT%) 'Gets number of modules to test CALL INPUTSN(SN$, SERNO$(), NUMDUT%) 'Gets module serial # THIS IS WHERE YOU ENTER SN down the line calls GETSN CALL HARDCOPY 'Ask for hardcopy printout CALL CHECKRESOURCES(1) 'Check for ability to write datasheet and status files and to printer. TIME2! = TIMER 'Start (or re-start) test timer) 'Get channel 1 serial number (there will always be at least a module in channel 1) LOCALSN$ = SERNO$(1) CALL WORKORDERHEADER(LOCALSN$) 'Write header to work order status file ELSE 'NOT Post-Encap or Sealed Module: only the number of modules inserted 'is needed initially. TX% = 0 ' 'Text-file flag "off" CALL INSTALLDUT(NUMDUT%) 'Gets number of modules to test IF (PON% = 1) THEN CALL CHECKRESOURCES(0) 'Check for ability to write to printer. END IF END IF 'Configure module input CALL STARTCFG 'Performs module-input configuration before testing DO 'Complete test loop start (each loop is a complete test pass) LOOPCYC% = LOOPCYC% + 1 TIME2! = TIMER IF LOOPCYC% > 1 AND TTYPE% = 2 THEN 'Pre-Encap: only the number of modules inserted is needed for the 'next test pass. No serial numbers need to be entered. CALL INSTALLDUT(NUMDUT%) 'Gets number of modules to test ELSEIF LOOPCYC% > 1 AND (TTYPE% = 3 OR TTYPE% = 4) THEN 'Post-Encap or Sealed Module: the number of modules inserted and their 'serial numbers need to be entered before the next test pass. CALL GETNEXTSN(TIME2!, SERNO$(), NUMDUT%) 'Gets next # of modules and their serial numbers END IF IF LOOPCYC% = 1 THEN IF OUTSIGTYPE$ = "CURRENT" THEN CALL SETOUTLOAD(IOUTSEN1!, 4) 'Set current output sense resistor FOR L% = 1 TO 4 IOUTSEN1.MEAS!(L%) = IOUTSEN11.MEAS!(L%) NEXT ELSE 'IF OUTSIGTYPE$ = "VOLTAGE" THEN CALL SETOUTLOAD(1000000!, 4) 'Remove current output sense resistor FOR L% = 1 TO 4 IOUTSEN1.MEAS!(L%) = 1 NEXT END IF END IF 'FOR x% = 1 TO 17 FOR x% = 1 TO MAXSTATUSINDEX FOR L% = 1 TO NUMDUT% STATUS$(x%, L%) = "" 'Clear test result array NEXT NEXT IF NOT (LEFT$(SPECS.MODNAME, 5) = "SCM5B") THEN 'Turn off internal SCM7B (RDEN isolator) supply if not SCM5B. CALL ENABLE(5, 0) END IF '************************ ALL ***** IF OUTSIGTYPE$ <> "CURRENT" THEN CALL SETOUTLOAD(IOUTSEN3!, 4) 'TURN-OFF ALL RELAYS IF NOMVS! = 5 THEN 'Nom volts = 5V (8B or SCM5B) '***************************** SCM5B and 8B use 5V ****************************** CALL SETSWITCH(VSSOURCE.CH%, 0) 'DUT power is test head VCVS SP! = SETSCM5BPWR!(NOMVS!) 'Set Vsupply to nominal value IF SP! = -1 THEN CLS LOCATE 10 PRINT TAB(10); "One or more of the modules has high supply current." PRINT TAB(10); "Run the Supply Current test under the Individual Test Menu" PRINT TAB(10); "to find the faulty modules." CALL CONTINUE GOTO EXITTEST 'High supply current END IF IF LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN 'Enable output switch only for SCM5B (PWR 2014-05-08) FOR L% = 1 TO NUMDUT% CALL ENABLE(L%, 0) 'Enable output switch NEXT END IF IF OUTSIGTYPE$ = "CURRENT" THEN CALL SETDPS(DPSADDR%, LOOPVNOM!) 'Set Vloop to nominal value ELSE ' nom volts != 5v '****************** DSCA does not use 5v ********************************* CALL SETSWITCH(VSSOURCE.CH%, 1) 'D.U.T. Power is Kepco DPS CALL INITPS(DPSADDR%, SPECS.ISMAX! * PSILIMIT! * 4, OVERV.DSCA!) CALL SETDPS(DPSADDR%, NOMVS!) 'Set Vsupply to nominal value END IF '************************************* CALL SUPPLYI(NUMDUT%, STATUS$()) 'Supply current test F% = 0 'Initialize failure count (number of channels that have failed Supply Current test) FOR L% = 1 TO NUMDUT% IF LEFT$(STATUS$(1, L%), 4) = "FAIL" THEN F% = F% + 1 NEXT 'Exit if all modules failed supply current or one or more 'remaining modules has a high supply current IF F% = NUMDUT% THEN GOTO EXITTEST FOR L% = 1 TO ITERATION% 'Offset/Gain calibration loop CALL CALSEQ(NUMDUT%, STATUS$()) L% = L% + 1 NEXT F% = 0 FOR L% = 1 TO NUMDUT% IF LEFT$(STATUS$(13, L%), 4) = "FAIL" OR LEFT$(STATUS$(14, L%), 4) = "FAIL" THEN F% = F% + 1 END IF NEXT IF F% = NUMDUT% THEN GOTO EXITTEST 'All modules failed offset and/or gain calibration CALL LINTEST(INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), NUMDUT%, STATUS$()) 'Performs linearity and 'accuracy tests 'IF NOMVS! = 5 THEN 'Nominal voltage is 5v 8b and 5B SCM5B IF (LEFT$(SPECS.MODNAME, 5) = "SCM5B") THEN 'SCM5B CALL OUTSWITCH(NUMDUT%, STATUS$()) 'SCM5B output switch operation END IF F% = 0 FOR L% = 1 TO NUMDUT% IF LEFT$(STATUS$(2, L%), 4) = "FAIL" THEN F% = F% + 1 NEXT IF F% = NUMDUT% THEN GOTO EXITTEST 'All modules failed output switch test CALL SUPPLYSEN(NUMDUT%, STATUS$()) 'Power supply sensitivity NOMOUTERR!(1) = 1000 'Dummy value (+1000%) Measure 1st time, pass result for following tests '************** ALL ******************** CALL OUTPUTNOISE(NUMDUT%, STATUS$()) 'Test Output Noise IF SPECS.OUTSIGTYPE$ = "CURRENT" THEN 'Max load resistance test CALL IOUTMAXL(NUMDUT%, STATUS$()) END IF EXITTEST: IF NOMVS! = 5 THEN 'Nominal voltage is 5v 8b and 5B SCM5B SP! = SETSCM5BPWR!(.01) 'Set Vsupply to zero IF OUTSIGTYPE$ = "CURRENT" THEN SP$ = POWERIO$(DPSADDR%, SUPPLYOFF$) 'Disable power supply END IF IF LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN FOR L% = 1 TO NUMDUT% CALL ENABLE(L%, 1) 'Disable output switch NEXT END IF ELSE 'IF NOMVS! = 24 THEN SP$ = POWERIO$(DPSADDR%, SUPPLYOFF$) 'Disable power supply END IF 'LOCATE 10, 10: PRINT "Initializing Agilent DAS. " 'CALL IO488("*RST", DASADDR%, 1) 'CALL IO488("ABOR", DASADDR%, 1) 'Abort any scans in progress. 'CALL IO488("*CLS", DASADDR%, 1) 'Clear status (clear errors) CALL INSTRERRORS(DASADDR%, 1) 'Clears and displays Agilent 34970A error queue. 'Port 2, data = WORD2INIT LOCATE 10, 10: PRINT "Initializing Output Enable DIO lines. " DIOCH02DATA% = WORD2INIT 'Digital I/O initialization, &HFF DDATA$ = DIGOUT$ + STR$(DIOCH02DATA%) + ",(@" + STR$(RDEN.CH%) + ")" CALL IO488(DDATA$, DASADDR%, 1) 'Write configuration 'CALL SHOWDIO(DIOCH02DATA%, 2, 1) CALL INSTRERRORS(DASADDR%, 1) 'Clears and displays Agilent 34970A error queue. CALL TSPECS(TSPEC$()) 'Sets up a string with the test specifications WIDTH , 43 'Change screen lines to 43 CALL INSTRERRORS(DASADDR%, 1) 'Clears and displays Agilent 34970A error queue. CALL REPORT(STATUS$(), SN$, INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), TSPEC$(), NUMDUT%, TTYPE%)'Prints test data on screen WIDTH , 25 'Change screen lines to 25 ELAP2! = TIMER - TIME2! IF NOT LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN 'Turn internal SCM7B (RDEN isolator) supply back on if not SCM5B. CALL ENABLE(5, 1) END IF CALL INSTRERRORS(DASADDR%, 1) 'Clears and displays Agilent 34970A error queue. '============================================================= 'BELOW: The following code writes the datasheet file(s), 'stores the status for the tested module(s) in the work order 'status file, and asks to print the datasheet file(s). '============================================================= KEY(10) OFF 'Deactivates F10 key CLS 'Ask to print datasheet file(s) IF (TX% = 1) THEN 'Only if text-file flag is on (Post-Encap and 'Sealed Module tests) ' 'Determine if there are any datasheet files '(at least one good module) GOODMCOUNT% = 0 'Initialize to zero good modules FOR L% = 1 TO NUMDUT% IF (FAILS%(STATUS$(), L%) = 0) THEN 'Only count modules that pass GOODMCOUNT% = GOODMCOUNT% + 1 END IF NEXT 'Only ask whether to print the datasheets if there is 'at least one good module (and therefore at least one 'datasheet file) IF GOODMCOUNT% > 0 THEN COLOR 15, 0, 0 'Clear screen to bright white on black background CLS LOCATE 8, 10: PRINT "Do you want to print the datasheet file(s)?" FOR L% = 1 TO NUMDUT% IF (FAILS%(STATUS$(), L%) = 0) THEN 'Only list modules that pass LOCALSN$ = SERNO$(L%) CALL GETDSFNAME(LOCALSN$, DSSNAME$, DSFNAME$) PRINT TAB(10); "Module # "; L%; " File name: "; DSFNAME$ END IF NEXT PRINT TAB(10); "Either the 'Y' or 'N' must be pressed." DO 'Loop until the "Y" or "N" key is pressed A$ = INKEY$ A$ = UCASE$(A$) 'Set key value to uppercase LOOP WHILE (A$ <> "N") AND (A$ <> "Y") IF (A$ = "Y") THEN 'Print the datasheet file(s) FOR L% = 1 TO NUMDUT% LOCALSN$ = SERNO$(L%) IF (FAILS%(STATUS$(), L%) = 0) THEN 'If the current module has not failed any tests CLS 'Get datasheet search and file names from serial number CALL GETDSFNAME(LOCALSN$, DSSNAME$, DSFNAME$) LOCATE 8 PRINT TAB(10); "Printing: " + DSFNAME$ + ", wait until printing is complete." SHELL "COPY C:\STAGE\" + DSFNAME$ + " LPT1 > NUL" 'Print datasheet file LPRINT CHR$(12) 'Form feed COLOR 15, 0, 0 'Bright white on black background PRINT PRINT TAB(10); "Has the: " + DSFNAME$ + " file finished printing?" COLOR 11, 0, 0 'Cyan on black background DUMKEY$ = WAITFORKEY("F", 10, 14, 0) 'Waits for "F" key press (display bright yellow on black) END IF NEXT END IF END IF END IF COLOR 11, 0, 0 'Cyan on black background KEY(10) ON 'Reactivates F10 key '============================================================= 'ABOVE: The preceding code writes the datasheet file(s), 'stores the status for the tested module(s) in the work order 'status file, and asks to print the datasheet file(s). '============================================================= '******************************************* LOOP WHILE REPEAT$(SPECS.MODNAME, ELAP2!, TIME2!) <> "N" 'End of Complete Test loop 'Added for work order status file (PWR 2014-05-08) IF ((TTYPE% = 3) OR (TTYPE% = 4)) THEN CLS LOCATE 5 PRINT TAB(10); "Printing work order status file: "; WO$ + ".TXT" 'Print the work order status file after an "N" entry for the 'REPEAT$ function above (not testing more of same module type). 'Using the serial number of channel 1 (there will always at least 'be a module in channel 1) to generate the work order status file 'name (within the WORKORDERPRINT sub). CALL WORKORDERPRINT(SERNO$(1)) PRINT COLOR 15, 0, 0 'Bright white on black background PRINT PRINT TAB(10); "Has the work order status file finished printing?" COLOR 11, 0, 0 'Cyan on black background DUMKEY$ = WAITFORKEY("F", 10, 14, 0) 'Waits for "F" key press (display bright yellow on black) CLS END IF END SUB '**************************************** SUB CONFDUTIN (ONOFF%) 'Configure the test head for HV power supply connection to the DUT inputs through the 'HV test cable: ' ONOFF% = 1: Selects the HV power supply connection through the 33120A BNC to the DUT inputs. ' This is the non-inverting connection to the HV DUT input power supply. ' ONOFF% = 0: Selects the HV power supply connection through the 760A "pigtail connector". ' This is the inverting connection to the HV DUT input power supply (the power ' supply leads are swapped in the pigtail connector compared to the BNC connector). ' IF ONOFF% = 1 THEN 'CALL HVRELAY(6, 1) 'Disconnect the HP33120A BNC from the Fluke 760A BNC. 'NOTE: The RMS test program controlled both relays, but the HV test program only 'needs to control the input-swap relay (relay 5, DIO bit 4 - see below), not the 'BNC to BNC connect relay (relay 6, DIO bit 5 - see above), which is why the 'relay 6 command above is commented out. CALL HVRELAY(5, 1) 'Connect the HP33120A BNC to the DUT inputs (rather than the 760A "pigtail" conn.) ELSE CALL HVRELAY(5, 0) 'Connect the the 760A "pigtail" conn. to the DUT inputs (rather than the 760A BNC) 'NOTE: The RMS test program controlled both relays, but the HV test program only 'needs to control the input-swap relay (relay 5, DIO bit 4 - see above), not the 'BNC to BNC connect relay (relay 6, DIO bit 5 - see below), which is why the 'relay 6 command below is commented out. 'CALL HVRELAY(6, 0) 'Connect the HP33120A BNC to the Fluke 760A BNC END IF END SUB '********************************** SUB CONTINUE 'Preserve cursor position x% = POS(0) Y% = CSRLIN 'LOCATE 24, 10: PRINT "Press any key to continue " LOCATE 23, 10: PRINT "Press any key to continue " A$ = KEYBDIN$ 'Clear message 'LOCATE 24, 10: PRINT " " LOCATE 23, 10: PRINT " " 'Go back to preserved cursor position LOCATE Y%, x% END SUB '********************************** SUB ENABLE (DUT%, ONOFF%) 'Sub to set the DIO lines in the Agilent 34970A Data Acquisition 'System (DAS) for the Output (Read) Enable (RDEN) lines for the 'SCM5B modules. ' 'Parameters: ' DUT%: Selects the DUT channel (1 through 4) for which ' the active-low read enable (RDEN) line is to be ' enabled (set low) or disabled (set high). ' Special value of 5 is to enable or disable the ' the supply for the SCM7B modules inside the ' testhead that are used to isolate the RDEN lines ' from the 34970A DIO lines to the SCM5B DUTs. ' ONOFF%: State of the controlled lines. For DUT = 1 ' through 4 (the SCM5B RDEN lines: ' '0' = "On", '1' = "Off". ' For DUT = 5, the line to control the SCM7B ' supply: ' '1' = "On", '0' = "Off". ' 'Debug code. IF (DEBUGFLAG% = 1) THEN PRINT TAB(10); "...................................." PRINT TAB(10); "Initial values...." PRINT TAB(10); "ENABLE: DUT% = "; DUT%; " ONOFF% = "; ONOFF% PRINT TAB(10); "DIOCH02DATA% = "; DIOCH02DATA% END IF 'Check for proper parameter values. IF ((DUT% < 0) OR (DUT% > 5)) THEN PRINT TAB(10); "........................" PRINT TAB(10); "Error in "; "ENABLE"; " sub!" PRINT TAB(10); "DUT value = "; DUT% PRINT TAB(10); "No changes made!" PRINT TAB(10); "........................" EXIT SUB END IF IF ((ONOFF% <> 0) AND (ONOFF% <> 1)) THEN PRINT TAB(10); "........................" PRINT TAB(10); "Error in "; "ENABLE"; " sub!" PRINT TAB(10); "On/Off value = "; ONOFF% PRINT TAB(10); "No changes made!" PRINT TAB(10); "........................" EXIT SUB END IF 'Change word value based on parameters. BITWEIGHT% = 2 ^ (DUT% - 1) IF ONOFF% = 0 THEN 'Enable output switch. 'DIOCH02DATA% = DIOCH02DATA% - BITWEIGHT% DIOCH02DATA% = DIOCH02DATA% AND (NOT BITWEIGHT%) ELSE 'Disable output switch. 'DIOCH02DATA% = DIOCH02DATA% + BITWEIGHT% DIOCH02DATA% = DIOCH02DATA% OR BITWEIGHT% END IF 'Set GPIB string and send to Agilent 34970A. DDATA$ = DIGOUT$ + STR$(DIOCH02DATA%) + ",(@" + STR$(RDEN.CH%) + ")" CALL IO488(DDATA$, DASADDR%, 1) 'Write configuration 'Debug code. IF (DEBUGFLAG% = 1) THEN PRINT TAB(10); "...................................." PRINT TAB(10); "Final values...." PRINT TAB(10); "BITWEIGHT% = "; BITWEIGHT% PRINT TAB(10); "DIOCH02DATA% = "; DIOCH02DATA% PRINT TAB(10); "DDATA$: "; DDATA$ PRINT TAB(10); "...................................." CALL CONTINUE END IF END SUB SUB ENDCFG 'Sub to perform module-input configuration after testing ' CALL SETDPS(DPSVINADDR%, 0) 'Set input voltage (at ext. supply) to 0V CALL SETDPS(DPSVINADDR2%, 0) END SUB '************************************* FUNCTION FAILS% (STATUS$(), L%) FAILS% = 0 'FOR x% = 1 TO 17 FOR x% = 1 TO MAXSTATUSINDEX IF LEFT$(STATUS$(x%, L%), 1) = "F" THEN 'Tests for failed tests FAILS% = 1 END IF NEXT END FUNCTION SUB FINISHSUB 'Sub to run code at "FINISH" label (usually after F10 key is pressed). ' CLS LOCATE 10, 10: PRINT "Resetting Data Acquisition System via GPIB. " CALL IO488("*RST", DASADDR%, 1) CALL IO488("ABOR", DASADDR%, 1) 'Abort any scans in progress. CALL IO488("*CLS", DASADDR%, 1) 'Clear status (clear errors) LOCATE 10, 10: PRINT SPC(70); LOCATE 10, 10: PRINT "Resetting Function Generator via GPIB. " CALL IO488("*RST", GENADDR%, 1) LOCATE 10, 10: PRINT SPC(70); LOCATE 10, 10: PRINT "Initializing Data Acquisition System. " CALL INIT488(DASADDR%) 'clear bus LOCATE 10, 10: PRINT SPC(70); LOCATE 10, 10: PRINT "Set DUT input supply to 0V. " CALL SETDPS(DPSVINADDR%, 0) 'Set input voltage (at ext. supply) to 0V CALL SETDPS(DPSVINADDR2%, 0) LOCATE 10, 10: PRINT SPC(70); LOCATE 10, 10: PRINT "Write Data Acquisition System configuration."; "." 'Port 2, data = WORD2INIT DIOCH02DATA% = WORD2INIT 'Digital I/O initialization, &HFF DDATA$ = DIGOUT$ + STR$(DIOCH02DATA%) + ",(@" + STR$(RDEN.CH%) + ")" CALL IO488(DDATA$, DASADDR%, 1) 'Write configuration 'CALL SHOWDIO(DIOCH02DATA%, 2, 1) 'Port 1, data = 8 LOCATE 10, 10: PRINT SPC(70); LOCATE 10, 10: PRINT "Disconnect HP33120A as input to HP760A. " CALL HVRELAY(6, 1) 'Disconnect HP33120A as input to Fluke 760A LOCATE 10, 10: PRINT SPC(70); LOCATE 10, 10: PRINT "Select HP33120A as D.U.T. input. " CALL HVRELAY(5, 1) 'Select HP33120A as D.U.T. input LOCATE 10, 10: PRINT SPC(70); LOCATE 10, 10: PRINT "Set Vsupply to zero. " SP1! = SETSCM5BPWR!(.01) 'Set Vsupply to zero LOCATE 10, 10: PRINT SPC(70); LOCATE 10, 10: PRINT "Turn off loop power. " SP2$ = POWERIO$(DPSADDR%, SUPPLYOFF$) 'Turn off loop power LOCATE 10, 10: PRINT SPC(70); LOCATE 10, 10: PRINT "Return to local mode. " SP2$ = POWERIO$(DPSADDR%, "LOC") 'Return to local mode CHAIN "C:\ATE\MENUX" END SUB '************************************ SUB FOOTER (STATUS$(), L%) 'Sub to create footer (if there are no fails). The footer be sent to two 'places (screen and printer), so when updating remember to make any 'changes to both the "PRINT" and "LPRINT" sections. ' 'NOTE: Currently, the footer is only printed to the printer, not the screen. ' IF FAILS%(STATUS$(), L%) = 0 THEN 'If module did not fail any tests 'Send to screen 'PRINT TAB(5); "240 VAC Withstand"; TAB(71); "PASS" 'PRINT TAB(5); "Hi-Pot "; TAB(71); "PASS" 'PRINT TAB(5); 'FOR x = 5 TO 75 ' PRINT "_"; 'NEXT x 'PRINT TAB(35); "Check List" 'PRINT ' 'IF LEFT$(SPECS.MODNAME, 5) = "SCM5B" OR LEFT$(SPECS.MODNAME, 2) = "8B" THEN ' PRINT TAB(5); "Module Appearance: _____"; TAB(45); "Mounting Screw: _____" ' PRINT ' PRINT TAB(5); "Pins Straight: _____"; TAB(45); "Module Header: _____" ' PRINT 'END IF ' '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 LPRINT TAB(5); "240 VAC Withstand"; TAB(71); "PASS" LPRINT TAB(5); "Hi-Pot "; TAB(71); "PASS" LPRINT TAB(5); FOR x = 5 TO 75 LPRINT "_"; NEXT x LPRINT TAB(35); "Check List" LPRINT IF LEFT$(SPECS.MODNAME, 5) = "SCM5B" OR LEFT$(SPECS.MODNAME, 2) = "8B" THEN LPRINT TAB(5); "Module Appearance: _____"; TAB(45); "Mounting Screw: _____" LPRINT LPRINT TAB(5); "Pins Straight: _____"; TAB(45); "Module Header: _____" LPRINT END IF LPRINT TAB(5); "Tested by: _____________"; TAB(45); "QC: _______________" LPRINT LPRINT TAB(5); "It is hereby certified that the above product is in conformance with" LPRINT TAB(5); "all requirements to the extent specified. This product is not" LPRINT TAB(5); "authorized or warranted for use in life support devices and/or systems." LPRINT LPRINT TAB(5); "* NIST traceable calibration certificates support Measured Value data." LPRINT TAB(5); " Calibration services are available through ANSI/NCSL Z540-1 and" LPRINT TAB(5); " ISO Guide 25 Certified Metrology Labs." END IF END IF IF PON% = 1 THEN LPRINT CHR$(12) 'Send form feed to printer (regardless of module test status) END SUB '************************************ SUB FUNCTEST (STATUS$(), CAL%, INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), NUMDUT%, TTYPE%, TSPEC$(), SERNO$()) 'Routines for functional test 'Sub to run a short set of tests, looping once each pass (and individually through each test channel 'for each test) to determine if the main module circuits are functional. ' NOMVS! = SPECS.NOMVS MAXOUT! = SPECS.MAXOUT 'V or A WAVESHPCAL$ = "FUNC:SHAP " + LEFT$(SPECS.WAVESHPCAL$, 3) FINCAL! = SPECS.FINCAL OUTSIGTYPE$ = SPECS.OUTSIGTYPE LOOPVNOM! = SPECS.LOOPVNOM + MAXOUT! * NOISEFILTERR! DIM OSERR2!(5) LOOPCYC% = 0 CALL INSTALLDUT(NUMDUT%) 'Get number of modules installed IF (PON% = 1) THEN CALL CHECKRESOURCES(0) 'Check for ability to write to printer. END IF DO LOOPCYC% = LOOPCYC% + 1 TIME2! = TIMER IF LOOPCYC% > 1 THEN CALL INSTALLDUT(NUMDUT%) END IF IF LOOPCYC% = 1 THEN IF OUTSIGTYPE$ = "CURRENT" THEN CALL SETOUTLOAD(IOUTSEN1!, 4) 'Set current output sense resistor FOR L% = 1 TO 4 IOUTSEN1.MEAS!(L%) = IOUTSEN11.MEAS!(L%) NEXT ELSE CALL SETOUTLOAD(1000000!, 4) 'Remove current output sense resistor FOR L% = 1 TO 4 IOUTSEN1.MEAS!(L%) = 1 NEXT END IF END IF 'FOR x% = 1 TO 17 FOR x% = 1 TO MAXSTATUSINDEX FOR L% = 1 TO NUMDUT% STATUS$(x%, L%) = "" 'Clear test result array NEXT NEXT CONFLAG% = 0 IF NOT LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN 'Turn off internal SCM7B (RDEN isolator) supply if not SCM5B. CALL ENABLE(5, 0) END IF IF OUTSIGTYPE$ <> "CURRENT" THEN CALL SETOUTLOAD(IOUTSEN3!, 4) ' should be IF OUTSIGTYPE$ = "VOLTAGE" END IF IF NOMVS! = 5 THEN 'SCM5B CALL SETSWITCH(VSSOURCE.CH%, 0) 'D.U.T. Power is test head VCVS SP! = SETSCM5BPWR!(NOMVS!) 'Set Vsupply to nominal value IF SP! = -1 THEN EXIT SUB 'High supply current IF LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN FOR L% = 1 TO NUMDUT% CALL ENABLE(L%, 0) 'Enable output switch NEXT END IF IF OUTSIGTYPE$ = "CURRENT" THEN CALL SETDPS(DPSADDR%, LOOPVNOM!) 'Set Vloop to nominal value END IF ELSE 'IF NOMVS! = 24 THEN ' nom volts != 5v i.e. DSCA CALL SETSWITCH(VSSOURCE.CH%, 1) 'D.U.T. Power is Kepco DPS CALL INITPS(DPSADDR%, SPECS.ISMAX! * PSILIMIT! * 4, OVERV.DSCA!) CALL SETDPS(DPSADDR%, NOMVS!) 'Set Vsupply to nominal value END IF FOR FTEST% = 1 TO 3 SELECT CASE FTEST% CASE 1 CALL SUPPLYI(NUMDUT%, STATUS$()) FOR L% = 1 TO NUMDUT% IF LEFT$(STATUS$(1, NUMDUT%), 4) = "FAIL" THEN 'Check supply current CONFLAG% = 1 'Sets exit flag END IF NEXT CASE 2 CALL OFFSETCAL(CAL%, NUMDUT%, STATUS$()) FOR L% = 1 TO NUMDUT% IF LEFT$(STATUS$(13, NUMDUT%), 4) = "FAIL" THEN CONFLAG% = 1 END IF NEXT CALL GAINCAL(CAL%, 0, 1, OSERR2!(), NUMDUT%, STATUS$()) FOR L% = 1 TO NUMDUT% IF LEFT$(STATUS$(14, NUMDUT%), 4) = "FAIL" THEN CONFLAG% = 1 END IF NEXT CASE 3 IF (LEFT$(SPECS.MODNAME, 5) = "SCM5B") THEN 'SCM5B CALL OUTSWITCH(NUMDUT%, STATUS$()) 'SCM5B output switch operation END IF FOR L% = 1 TO NUMDUT% IF LEFT$(STATUS$(2, NUMDUT%), 4) = "FAIL" THEN CONFLAG% = 1 END IF NEXT END SELECT IF CONFLAG% <> 0 THEN EXIT FOR NEXT IF NOMVS! = 5 THEN 'SCM5B SP! = SETSCM5BPWR!(.01) 'Set Vsupply to zero IF OUTSIGTYPE$ = "CURRENT" THEN SP$ = POWERIO$(DPSADDR%, SUPPLYOFF$) 'Disable power supply END IF IF LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN FOR L% = 1 TO NUMDUT% CALL ENABLE(L%, 1) 'Disable output switch NEXT END IF ELSE 'IF NOMVS! = 24 THEN ' nom volts != 5v i.e. DSCA SP$ = POWERIO$(DPSADDR%, SUPPLYOFF$) 'Disable power supply END IF ELAP2! = TIMER - TIME2! IF NOT LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN 'Turn internal SCM7B (RDEN isolator) supply back on if not SCM5B. CALL ENABLE(5, 1) END IF CALL TSPECS(TSPEC$()) 'Sets up a string with the test specifications 'PWR 2014-09-11: Lines below added to display test status ' at the end of the functional test. WIDTH , 43 'Change screen lines to 43 CALL INSTRERRORS(DASADDR%, 1) 'Clears and displays Agilent 34970A error queue. CALL REPORT(STATUS$(), SN$, INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), TSPEC$(), NUMDUT%, TTYPE%)'Prints test data on screen WIDTH , 25 'Change screen lines to 25 LOOP WHILE REPEAT$(SPECS.MODNAME, ELAP2!, TIME2!) <> "N" 'Repeat for another set of modules END SUB '******************************** SUB GAINCAL (CAL%, AMPL!, INTERACT!, OSERR2!(), NUMDUT%, STATUS$()) '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 ' 3 = Use HP33120A direct to DUT, bypassing Fluke 760A ' Use AMPL! for DUT input, measure once and exit ' AMPL! Signal amplitude to be used for module input ' INTERACT! Calibration interaction factor ' OSERR2!(n) Measured offset error ' NUMDUT% = number of Devices Under Test ' 'Outputs STATUS$(14, n) array of results ' MINOUT! = SPECS.MINOUT 'V or A MAXOUT! = SPECS.MAXOUT INITTOL! = 8 'Uncalibrated gain tolerance (%) CALTOL! = SPECS.CALTOL 'Calibration tolerance (%) FINCAL! = SPECS.FINCAL 'Input wave frequency (Hz) FINEXTMAX! = SPECS.FINEXTMAX CALGN! = SPECS.GNCALPT / 100 ' ORANGE! = MAXOUT! - MINOUT! 'Output range (V or A) NOMVS! = SPECS.NOMVS! OUTSIGTYPE$ = SPECS.OUTSIGTYPE CALSPAN! = ORANGE! 'Adjustment range is +/- x% of +f.s. IF CAL% = 1 OR CAL% = 3 THEN 'Special input required for cal measurement GNCALIN! = AMPL! ELSE GNCALIN! = SPECS.GNCALIN 'input for gain calibration from database END IF IF (CAL% = 2) OR (TTYPE% = 1) THEN CLS TESTTITLE$ = "Gain Calibration" CALL HEADERB(TESTTITLE$, 0) GERROR! = INITTOL! 'Gain tolerance for func. test (%) TOL! = .0001 * ORANGE! 'Measurement tolerance, 1 pass test ELSE IF CAL% = 0 THEN CLS TESTTITLE$ = "Gain Calibration" CALL HEADERB(TESTTITLE$, 0) CALL MODOUTLINE LOCATE 7 TB1% = 26 TB2% = 31 PRINT TAB(TB1%); "Refer to label on board for"; PRINT TAB(TB2%); "gain potentiometer"; END IF GERROR! = CALTOL! 'Gain calibration tolerance (%) TOL! = 0! 'Measurement tolerance, continuous test END IF OUTCALC! = MAXOUT! 'seed value for 1st pass TIME1! = TIMER FIRSTTIMETHRU% = 1 FOR L% = 1 TO NUMDUT% CONREADS% = 0 LOCATE 1 IF L% <> 1 AND CAL% <> 1 AND CAL% <> 3 THEN CALL HEADERB(TESTTITLE$, 0) END IF 'Check if module previously failed supply current '(removed from test head), offset cal or gain cal '(not functional) or output switch test (not functional) IF LEFT$(STATUS$(1, L%), 4) <> "FAIL" AND LEFT$(STATUS$(2, L%), 4) <> "FAIL" AND LEFT$(STATUS$(13, L%), 4) <> "FAIL" AND LEFT$(STATUS$(14, L%), 4) <> "FAIL" THEN LOCATE 10, 25: PRINT "TESTING DEVICE IN CHANNEL #"; L% MAXINMEAS! = SETDUTIN!(GNCALIN!) DO IF FIRSTTIMETHRU% = 1 OR TIMER - TIME1! > 30 THEN LOCATE 12, 10 PRINT TAB(10); "Measuring input. Please wait... " MAXINMEAS! = SETDUTIN!(GNCALIN!) TIME1! = TIMER END IF LOCATE 12, 10 PRINT "Gain Error = "; PRINT SPC(30); IF OUTSIGTYPE$ = "CURRENT" THEN CH% = IOUTSENDUT1SEN.CH% END IF IF OUTSIGTYPE$ = "VOLTAGE" THEN IF LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN CH% = VOUTDUT1.CH% ELSE CH% = IOUTSENDUT1SOUR.CH% END IF END IF CALL DVMCONF(CH% + L% - 1, VDC$, "AUTO", 0, "", 0) CALL DVMSENS(CH% + L% - 1, VDC$, INTTIME$, "", 2) '6 1/2 digits, 21 bit resolution CALL PAUSE(.1) IF INTERACT! <> 1 THEN PFSMEAS! = GETREADING! / IOUTSEN1.MEAS!(L%) 'CALOS! is included in OSERR2!() OUTCALC! = PFSMEAS! - (1 / (1 - INTERACT!)) * (PFSMEAS! - MODULEOUT!(MAXINMEAS!) - ORANGE! * OSERR2!(L%) / 100!) ELSE OUTCALC! = MODULEOUT!(MAXINMEAS!) + CALGN! * ORANGE! END IF DO ERROROUT! = (GETREADING! / IOUTSEN1.MEAS!(L%) - OUTCALC!) / CALSPAN! * 100! 'Error (%) LOCATE 12, 24 PRINT USING "+###.### %"; ERROROUT! LOCATE 15, 10 IF CAL% > 0 THEN 'Non-calibration mode CONREADS% = 5 ELSEIF ABS(ERROROUT!) > INITTOL! * 1.5 THEN 'Circuit error, exit CONREADS% = 5 ELSEIF ABS(ERROROUT!) < GERROR! THEN SOUND 400, .5 PRINT "Stop turning gain potentiometer " CONREADS% = CONREADS% + 1 ELSEIF ERROROUT! < 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$) = "C" THEN CONREADS% = 5 END IF CALL PAUSE(.3) 'Slow down loop IF TIMER - TIME1! > 30 THEN EXIT DO LOOP WHILE CONREADS% < 5 LOOP WHILE CONREADS% < 5 IF CAL% = 0 OR CAL% = 2 THEN IF (TTYPE% = 1) THEN 'Functional test. DIG$ = "3" 'Display/print result to # of decimal places. ELSE 'Not functional test. DIG$ = "5" 'Flag: do not display/print result. END IF IF ABS(ERROROUT!) <= GERROR! THEN GN$ = "PASS" ELSE GN$ = "FAIL" 'Display results if test failed. DIG$ = "3" 'Display/print result to # of decimal places. SOUND 1000, .5 END IF 'Set DUT input voltage power supply to 0V (PWR 2014-10-08) CALL SETDPS(DPSVINADDR%, 0!) CALL SETDPS(DPSVINADDR2%, 0) 'LOCATE 15, 10: PRINT "MODULE #"; L%; " Status: "; GN$; LOCATE 16, 10 'Added PRINT SPC(30); PRINT TAB(10); "Gain calibration error is"; PRINT TAB(50); USING " +###.### %"; ERROROUT! PRINT TAB(10); "Max. gain calibration error is"; PRINT TAB(50); USING "+/-##.### %"; GERROR! CALL FAILSTATUS(L%, GN$, 15, 10, "Status: ", 20) 'Print test status to screen ELSE GN$ = "PASS" DIG$ = "5" 'Flag. Don't print result END IF FIRSTTIMETHRU% = FIRSTTIMETHRU% + 1 STATUS$(14, L%) = GN$ + STR$(ERROROUT!) + DIG$ END IF 'End if previous set of four tests passed. IF L% < NUMDUT% THEN 'Prevent to assign a not valid serial number SN$ = SERNO$(L% + 1) 'Use the next serial number on the array END IF CALL PAUSE(1!) IF L% <> NUMDUT% THEN LOCATE 15, 10 PRINT SPC(55); LOCATE 16, 10 PRINT SPC(55); LOCATE 17, 10 PRINT SPC(55); PRINT END IF CLS NEXT SN$ = SERNO$(1) CALL SETDPS(DPSVINADDR%, 0) 'Set input voltage (at ext. supply) to 0V CALL SETDPS(DPSVINADDR2%, 0) END SUB SUB GETADD 'Retrieve test system component addresses from address file. ' OPEN "C:\ATE\ADDR\HVIN.ADR" FOR RANDOM AS #3 LEN = 12 FIELD #3, 2 AS SUPPLYPORT$, 2 AS POWERSPLY$, 2 AS PS1ADDR$, 2 AS PS2ADDR$, 2 AS DASADDRESS$, 2 AS GENADDRESS$ GET #3 PSPORT% = VAL(SUPPLYPORT$) DPSADDR% = VAL(POWERSPLY$) DPSVINADDR% = VAL(PS1ADDR$) DPSVINADDR2% = VAL(PS2ADDR$) DASADDR% = VAL(DASADDRESS$) GENADDR% = VAL(GENADDRESS$) CLOSE #3 REM PRINT PSORT%, DPSADDR%, DPSVINADDR%, DPSVINADDR2%, DASADDR%, GENADDR% REM CALL CONTINUE REM DPSVINADDR% = DPSADDR% + 1 'Address of DUT input power supply REM DPSVINADDR2% = DPSADDR% + 2' Address of 2nd DUT input power supply END SUB SUB GETNEXTSN (TIME2!, SERNO$(), NUMDUT%) 'Sub to the next set of serial numbers after at least one 'pass through testing ' PRENUMDUT% = NUMDUT% 'Number of units just tested LASTSN$ = SERNO$(PRENUMDUT%) CALL INSTALLDUT(NUMDUT%) 'Gets number of modules to test DO 'Loop until serial numbers are confirmed good SERNO$(1) = SNMENU$(1, LASTSN$, 0) FOR I% = 2 TO NUMDUT% LOCALSN$ = SERNO$(I% - 1) 'Get serial number of module in previous test channel SERNO$(I%) = SNMENU$(I%, LOCALSN$, 1) ' NEXT 'Display the serial numbers entered. CLS LOCATE 5 IF (NUMDUT% > 1) THEN PRINT TAB(5); "The following serial numbers were entered:" ELSE PRINT TAB(5); "The following serial number was entered:" END IF FOR I% = 1 TO NUMDUT% PRINT TAB(5); "Test channel # "; I%; ": Serial number = "; SERNO$(I%) NEXT TIME2! = TIMER SN$ = SERNO$(1) 'Set initial serial number 'Check to see if there are any duplicate serial numbers IF (ISDUPLICATESN%(SERNO$, NUMDUT%) = 1) THEN 'There are duplicate serial numbers PRINT PRINT COLOR 28, 0, 0 'Flashing light red PRINT TAB(6); "DUPLICATE SERIAL NUMBERS WERE SET!" COLOR 11, 0, 0 'Cyan on black background PRINT PRINT PRINT TAB(5); "Retry entering the serial numbers after" PRINT TAB(5); "pressing the key listed below." PRINT BEEP DUMKEY$ = WAITFORKEY("S", 10, 14, 0) 'Waits for "S" key press (display bright yellow on black) ELSE 'There are no duplicate serial numbers - ask if the serial numbers are good PRINT PRINT PRINT TAB(10); "Are the serial numbers valid?" PRINT PRINT TAB(10); "Must enter 'Y' or 'N' (upper or lower case)." PRINT PRINT 'Get keyboard entry (must be 'Y' or 'N') DO ANS2$ = INKEY$ ANS2$ = UCASE$(ANS2$) LOOP WHILE (ANS2$ <> "N") AND (ANS2$ <> "Y") IF ANS2$ = "N" THEN PRINT PRINT TAB(5); "Retry entering the serial numbers after" PRINT TAB(5); "pressing the key listed below." PRINT ; DUMKEY$ = WAITFORKEY("S", 10, 14, 0) 'Waits for "S" key press (display bright yellow on black) END IF END IF LOOP WHILE (ANS2$ <> "Y") 'Set initial serial number and proceed on to testing SN$ = SERNO$(1) 'Set initial serial number 'Wait to acknowledge serial number(s) PRINT PRINT PRINT PRINT PRINT TAB(5); "Ready to start testing...." DUMKEY$ = WAITFORKEY("T", 10, 14, 0) 'Waits for "T" key press (display bright yellow on black) PRINT PRINT TAB(5); "Testing...." TIME2! = TIMER 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" '****** Assign corresponding address obtained from address file dependent '****** on if the Power supply is DPS125 or ABC125. DPSPSFLAG! = 0! '****** Check for High Voltage Power Supply VINILIMIT! = 125! 'Set DUT input power supply voltage limit to 125V VINOVERV! = .05 'Set DUT input power supply current limit to 50mA (0.050A) PRINT TAB(10); "KEPCO DPS125 High-Voltage Input: "; DPSVIN$ = POWERIO$(DPSVINADDR%, "ID") IF DPSVIN$ = "KEPCO DPS 125-0.5M" THEN VINADDR% = DPSVINADDR% PRINT TAB(45); "Yes!" PRINT PSMODEL$ = "DPS125" CALL INITPS(DPSVINADDR%, VINILIMIT!, VINOVERV!) CALL INITPS(DPSVINADDR2%, VINILIMIT!, VINOVERV!) DPSVINFLAG! = 1! ELSE PRINT TAB(45); "Not present" DPSVINFLAG! = 0! VINADDR% = 0! END IF IF DPSPSFLAG! = 0! AND DPSVINFLAG! = 0! THEN PSMODEL$ = "ABC125" PRINT TAB(10); "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(45); "Yes!" PRINT ELSE PRINT TAB(45); "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 anything back to function call END FUNCTION '***************************************** SUB GETSN (SN$) 'Sub to get work order number and dash number to generate serial number for module ' 'Get work order number WO$ = GETWO$ 'Get work order number from function 'Get dash number DS$ = GETDS$(0, SN$) 'Get (starting) dash number from function 'Create serial number from work order number and dash number SN$ = WO$ + "-" + DS$ 'CALL CONTINUE END SUB SUB GETSPECS (NUMDUT%) 'Sub to get the module inputs, outputs and limits from the 'module database ' DIM POINTER%(1000) TESTV! = 5 'Test current to measure sense resistor (50mADC = 5VDC/100ohm) 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\HVDATA\HVSORT.DAT" FOR RANDOM AS #2 LEN = LEN(SORTDATA1) DO 'Loop through database program limits 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% = 19 '13 char + 4 char for # + 2 spaces NUMLINES! = 19 '# of lines for model display below header 'Set number of columns for the displayed model menu, given 'that the model # length is 20 characters max and there 'are a maximum of 3 columns per screen: '3 columns x 26 char = 78 spaces NUMCOLUMNS! = 1 + INT(NUMRECORD! / NUMLINES!) I% = 1 'Initialize 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! PRINT "Enter Selection "; INPUT SEL% LOOP WHILE SEL% < 1 OR SEL% > I% IF SEL% = I% THEN SPECS.MODNAME = "EXIT" ELSE OPEN "C:\ATE\HVDATA\HVIN.DAT" FOR RANDOM AS #1 LEN = LEN(SPECS) GET #1, POINTER%(SEL%), SPECS CLOSE #1 'CALL INSTALLDUT(NUMDUT%) IINSEN1.MEAS! = 1 END IF SEL% = POINTER%(SEL%) 'pass back to main code for use in SAVEDATA END SUB SUB HEADERA (SN$) 'Sub to print datasheet header section to printer if print flag is "on" ' IF PON% = 1 THEN LPRINT TAB(5); "DATAFORTH CORPORATION"; TAB(51); "Phone: (520) 741-1404" LPRINT TAB(5); "3331 E. Hemisphere Loop"; TAB(51); "Fax: (520) 741-0762" LPRINT TAB(5); "Tucson, AZ 85706 USA"; TAB(51); "email: info@dataforth.com" LPRINT LPRINT TAB(33); "TEST DATA SHEET" LPRINT TAB(5); FOR x = 5 TO 75 LPRINT "~"; NEXT LOCATE 8 LPRINT TAB(5); "Date: "; DATE$ LPRINT TAB(5); "Model: "; SPECS.MODNAME LPRINT TAB(5); "SN: "; TAB(12); SN$ LPRINT END IF END SUB '*************************************** SUB HEADERB (TESTTITLE$, L%) 'Sub to display test title, model under test, and SN at top of the screen. ' IF L% = 0 THEN TITLEN = LEN(TESTTITLE$) + LEN(SPECS.MODNAME) PRINT TAB(40 - TITLEN / 2); SPECS.MODNAME; " "; TESTTITLE$; ELSE TITLEN = LEN(TESTTITLE$) PRINT TAB(40 - TITLEN / 2); TESTTITLE$; END IF IF SN$ <> "" AND LEFT$(TESTTITLE$, 6) <> "Fluke 760A" 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 HVRELAY (RELAY%, ONOFF%) 'Sub to set the DIO lines in the Agilent 34970A Data Acquisition 'System (DAS) for the high voltage/high current relays in the 'testhead. ' 'Parameters: ' RELAY%: Selects the RELAY (1 through 6) that is to ' be turned on or off. ' ONOFF%: New state of the specified relay: ' '1' = "On", '0' = "Off". ' 'Debug code. IF (DEBUGFLAG% = 1) THEN PRINT TAB(10); "...................................." PRINT TAB(10); "Initial values...." PRINT TAB(10); "ENABLE: RELAY% = "; RELAY%; " ONOFF% = "; ONOFF% PRINT TAB(10); "DIOCH01DATA% = "; DIOCH01DATA% END IF 'Check for proper parameter values. IF ((RELAY% < 1) OR (RELAY% > 6)) THEN PRINT TAB(10); "........................" PRINT TAB(10); "Error in "; "HVRELAY"; " sub!" PRINT TAB(10); "Relay number = "; RELAY% PRINT TAB(10); "No changes made!" PRINT TAB(10); "........................" EXIT SUB END IF IF ((ONOFF% <> 0) AND (ONOFF% <> 1)) THEN PRINT TAB(10); "........................" PRINT TAB(10); "Error in "; "HVRELAY"; " sub!" PRINT TAB(10); "On/Off value = "; ONOFF% PRINT TAB(10); "No changes made!" PRINT TAB(10); "........................" EXIT SUB END IF 'Change word value based on parameters. BITWEIGHT% = 2 ^ (RELAY% - 1) IF ONOFF% = 1 THEN 'Disable relay. 'DIOCH01DATA% = DIOCH01DATA% + BITWEIGHT% DIOCH01DATA% = DIOCH01DATA% OR BITWEIGHT% ELSE 'Enable relay. 'DIOCH01DATA% = DIOCH01DATA% - BITWEIGHT% DIOCH01DATA% = DIOCH01DATA% AND (NOT BITWEIGHT%) END IF 'Set GPIB string and send to Agilent 34970A. DDATA$ = DIGOUT$ + STR$(DIOCH01DATA%) + ",(@" + STR$(HVRELAY.CH%) + ")" CALL IO488(DDATA$, DASADDR%, 1) 'Write configuration 'Debug code. IF (DEBUGFLAG% = 1) THEN PRINT TAB(10); "...................................." PRINT TAB(10); "Final values...." PRINT TAB(10); "BITWEIGHT% = "; BITWEIGHT% PRINT TAB(10); "DIOCH01DATA% = "; DIOCH01DATA% PRINT TAB(10); "DDATA$: "; DDATA$ PRINT TAB(10); "...................................." CALL CONTINUE END IF END SUB '*********************************** SUB INDIVID (SEL%, INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), STATUS$(), NUMDUT%) 'Sub to run the individual tests. ' NOMVS! = SPECS.NOMVS WAVESHPCAL$ = "FUNC:SHAP " + LEFT$(SPECS.WAVESHPCAL$, 3) FINCAL! = SPECS.FINCAL FINMAX! = SPECS.FINMAX FINEXTMAX! = SPECS.FINEXTMAX ACCCF12! = SPECS.ACCCF12 ACCCF23! = SPECS.ACCCF23 ACCCF34! = SPECS.ACCCF34 ACCCF45! = SPECS.ACCCF45 ACCSINCAL! = SPECS.ACCSINCAL ACCSINSTD! = SPECS.ACCSINSTD ACCSINEXT! = SPECS.ACCSINEXT OUTSIGTYPE$ = SPECS.OUTSIGTYPE LOOPVNOM! = SPECS.LOOPVNOM + SPECS.MAXOUT * NOISEFILTERR! DIM NOMOUTERR!(4) LOOPCYC% = 0 CALL INSTALLDUT(NUMDUT%) DO LOOPCYC% = LOOPCYC% + 1 NOMOUTERR!(1) = 1000 'Flag indicating measure gain error IF LOOPCYC% > 1 THEN CALL INSTALLDUT(NUMDUT%) END IF IF LOOPCYC% = 1 THEN IF OUTSIGTYPE$ = "CURRENT" THEN CALL SETOUTLOAD(IOUTSEN1!, 4) 'Set current output sense resistor FOR L% = 1 TO 4 IOUTSEN1.MEAS!(L%) = IOUTSEN11.MEAS!(L%) NEXT ELSE 'IF OUTSIGTYPE = "VOLTAGE" THEN CALL SETOUTLOAD(1000000!, 4) 'Remove current output sense resistor FOR L% = 1 TO 4 IOUTSEN1.MEAS!(L%) = 1 NEXT END IF END IF 'FOR x% = 1 TO 17 FOR x% = 1 TO MAXSTATUSINDEX 'Clear test results. FOR L% = 1 TO NUMDUT% STATUS$(x%, L%) = "" NEXT NEXT TIME2! = TIMER IF NOT LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN 'Turn off internal SCM7B (RDEN isolator) supply if not SCM5B. CALL ENABLE(5, 0) END IF IF OUTSIGTYPE$ <> "CURRENT" THEN CALL SETOUTLOAD(IOUTSEN3!, 4) END IF IF NOMVS! = 5 THEN '*************** SCM5B and 8B *********************** CALL SETSWITCH(VSSOURCE.CH%, 0) 'D.U.T. Power is test head VCVS SP! = SETSCM5BPWR!(NOMVS!) 'Set Vsupply to nominal value IF SP! = -1 THEN EXIT SUB 'High supply current IF LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN FOR L% = 1 TO NUMDUT% CALL ENABLE(L%, 0) 'Enable output switch NEXT END IF IF OUTSIGTYPE$ = "CURRENT" THEN CALL SETDPS(DPSADDR%, LOOPVNOM!) 'Set Vloop to nominal value END IF ELSE 'IF NOMVS! = 24 THEN '************* DSCA only *************** CALL SETSWITCH(VSSOURCE.CH%, 1) 'D.U.T. Power is Kepco DPS CALL INITPS(DPSADDR%, SPECS.ISMAX! * PSILIMIT! * 4, OVERV.DSCA!) CALL SETDPS(DPSADDR%, NOMVS!) 'Set Vsupply to nominal value END IF SELECT CASE SEL% CASE 1 CALL SUPPLYI(NUMDUT%, STATUS$()) CASE 2 IF (LEFT$(SPECS.MODNAME, 4) = "DSCA") OR (LEFT$(SPECS.MODNAME, 2) = "8B") THEN '8B or DSCA CLS LOCATE 10, 10: PRINT "This test is not performed on model "; SPECS.MODNAME ELSE CALL OUTSWITCH(NUMDUT%, STATUS$()) END IF CASE 3 CAL% = 0 CALL CALSEQ(NUMDUT%, STATUS$()) CASE 4 CALL LINTEST(INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), NUMDUT%, STATUS$()) CASE 5 'Was 12. CALL SUPPLYSEN(NUMDUT%, STATUS$()) CASE 6 'Was 14. CALL OUTPUTNOISE(NUMDUT%, STATUS$()) CASE 7 'Was 15. IF OUTSIGTYPE$ = "VOLTAGE" THEN CLS LOCATE 10, 10: PRINT "This test is not performed on model "; SPECS.MODNAME ELSE CALL IOUTMAXL(NUMDUT%, STATUS$()) END IF END SELECT IF NOMVS! = 5 THEN 'SCM5B and 8B SP! = SETSCM5BPWR!(.01) 'Set Vsupply to zero IF OUTSIGTYPE$ = "CURRENT" THEN SP$ = POWERIO$(DPSADDR%, SUPPLYOFF$) 'Disable power supply END IF IF LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN FOR L% = 1 TO NUMDUT% CALL ENABLE(L%, 1) 'Disable output switch NEXT END IF ELSE 'IF NOMVS! = 24 THEN 'DSCA SP$ = POWERIO$(DPSADDR%, SUPPLYOFF$) 'Disable power supply END IF ELAP2! = TIMER - TIME2! IF NOT LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN 'Turn internal SCM7B (RDEN isolator) supply back on if not SCM5B. CALL ENABLE(5, 1) END IF CALL PAUSE(1!) 'CALL CONTINUE LOOP WHILE REPEAT$(SPECS.MODNAME, ELAP2!, TIME2!) <> "N" END SUB '************************** SUB INPUTSN (SN$, SERNO$(), NUMDUT%) 'Sub to get the serial number(s) for the modules under test by getting 'the work order number and starting dash number. If the passed number 'of modules to test (NUMDUT%) is more than one (1), questions are asked 'to determine the dash numbers (and ultimately the serial numbers) for 'the modules in test channels (slots) 2 through NUMDUT%. The sub also 'returns the current (channel 1) serial number as a parameter. ' DO 'Loop until serial numbers are confirmed good CALL GETSN(SN$) 'Get serial number for initial module CLS SERNO$(1) = SN$ 'Set channel 1 module serial number to initial serial number 'Determine serial numbers for modules in subsequent test channels (if any) IF NUMDUT% > 1 THEN 'If more than one module ask for custom or ordered numbering LOCATE 5 PRINT TAB(10); "Are the modules in channels 1 to"; NUMDUT% PRINT TAB(10); "in sequential order?"; PRINT PRINT PRINT TAB(10); "Must enter 'Y' or 'N' (upper or lower case)." PRINT PRINT 'Get keyboard entry (must be 'Y' or 'N') DO ANS$ = INKEY$ ANS$ = UCASE$(ANS$) LOOP WHILE (ANS$ <> "N") AND (ANS$ <> "Y") IF ANS$ = "Y" THEN 'Create sequential serial numbers FOR I% = 2 TO NUMDUT% LOCALSN$ = SERNO$(I% - 1) 'Get serial number of module in previous test channel SERNO$(I%) = UPSN(LOCALSN$) 'Get incremented (or new) serial number for this test channel NEXT ELSE 'Enter custom dash numbers to create custom serial numbers FOR I% = 2 TO NUMDUT% LOCALSN$ = SERNO$(I% - 1) 'Get serial number of module in previous test channel SERNO$(I%) = SNMENU$(I%, LOCALSN$, 1) ' NEXT END IF END IF 'Display the serial numbers entered. CLS LOCATE 5 IF (NUMDUT% > 1) THEN PRINT TAB(5); "The following serial numbers were entered:" ELSE PRINT TAB(5); "The following serial number was entered:" END IF FOR I% = 1 TO NUMDUT% PRINT TAB(5); "Test channel # "; I%; ": Serial number = "; SERNO$(I%) NEXT 'Check to see if there are any duplicate serial numbers IF (ISDUPLICATESN%(SERNO$, NUMDUT%) = 1) THEN 'There are duplicate serial numbers PRINT PRINT COLOR 28, 0, 0 'Flashing light red PRINT TAB(6); "DUPLICATE SERIAL NUMBERS WERE SET!" COLOR 11, 0, 0 'Cyan on black background PRINT PRINT PRINT TAB(5); "Retry entering the serial numbers after" PRINT TAB(5); "pressing the key listed below." PRINT BEEP DUMKEY$ = WAITFORKEY("S", 10, 14, 0) 'Waits for "S" key press (display bright yellow on black) ELSE 'There are no duplicate serial numbers - ask if the serial numbers are good PRINT PRINT PRINT TAB(10); "Are the serial numbers valid?" PRINT PRINT TAB(10); "Must enter 'Y' or 'N' (upper or lower case)." PRINT PRINT 'Get keyboard entry (must be 'Y' or 'N') DO ANS2$ = INKEY$ ANS2$ = UCASE$(ANS2$) LOOP WHILE (ANS2$ <> "N") AND (ANS2$ <> "Y") IF ANS2$ = "N" THEN PRINT PRINT TAB(5); "Retry entering the serial numbers after" PRINT TAB(5); "pressing the key listed below." PRINT ; DUMKEY$ = WAITFORKEY("S", 10, 14, 0) 'Waits for "S" key press (display bright yellow on black) END IF END IF LOOP WHILE (ANS2$ <> "Y") 'Set initial serial number and proceed on to testing SN$ = SERNO$(1) 'Set initial serial number 'Wait to acknowledge serial number(s) PRINT PRINT PRINT PRINT PRINT TAB(5); "Ready to start testing...." DUMKEY$ = WAITFORKEY("T", 10, 14, 0) 'Waits for "T" key press (display bright yellow on black) PRINT PRINT TAB(5); "Continuing on to test...." TIME2! = TIMER END SUB '******************************** SUB INSTALLDUT (NUMDUT%) 'Sub to display information about installation of the DUTs in the appropriate 'channels (test channels). The module checks the specified nominal supply voltage 'from the database for the module type already selected (SPECS.NOMVS) and uses 'this information to warn to remove 'Inputs: None 'Output: By reference parameter NUMDUT% = Number of Devices Under Test (1 to 4) ' 'First message screen CLS 'LOCATE 1, 20: PRINT "SCM5B, 8B & DSCA AUTOMATED TEST EQUIPMENT" 'PRINT 'PRINT TAB(5); "Module type selected: "; SPECS.MODNAME 'PRINT 'PRINT 'PRINT TAB(5); "Up to 4 modules of a single type (SCM5B, 8B or DSCA can be" 'PRINT TAB(5); "tested at the same time. However, only ONE (1) type of module can" 'PRINT TAB(5); "be installed while testing!" 'PRINT 'PRINT 'PRINT TAB(5); "Verify that there are no modules of any type currently installed" 'PRINT TAB(5); "in the test head!" 'DUMKEY$ = WAITFORKEY("N", 10, 14, 0) 'Waits for "N" key press (display bright yellow on black) 'Second message screen CLS LOCATE 1, 20: PRINT "SCM5B, 8B & DSCA AUTOMATED TEST EQUIPMENT" LOCATE 3 PRINT TAB(5); "Module type selected: "; SPECS.MODNAME LOCATE 10 COLOR 14, 0, 0 'Yellow on black PRINT TAB(5); "-----------------------------------------------------------------" COLOR 15, 0, 0 'Bright white on black background PRINT TAB(10); "Install the modules to be tested in the test head sockets." COLOR 14, 0, 0 'Yellow on black PRINT TAB(5); "-----------------------------------------------------------------" COLOR 11, 0, 0 'Cyan on black background PRINT 'Blank line PRINT TAB(5); "Start with channel 1 and continue with channel 2, channel 3" PRINT TAB(5); "and channel 4, in that order. If there are fewer than 4 " PRINT TAB(5); "modules, leave the higher channels empty. " PRINT 'Blank line COLOR 14, 0, 0 'Yellow on black PRINT TAB(5); "For the selected module type, do not leave channel 1" PRINT TAB(5); "empty or skip any channels if there is more than one" PRINT TAB(5); "module! " COLOR 11, 0, 0 'Cyan on black background CALL CONTINUE CLS 'Wait for valid keyboard entry (number of modules installed) DO 'List allowable values if a good entry was not found the first time through COLOR 15, 0, 0 'White on black 'Clear line of previous answer LOCATE 17, 5: PRINT " " 'Ask question LOCATE 17, 5: INPUT "How many modules are installed in the test head: "; KBINPUT$ NUMENTERED% = VAL(KBINPUT$) 'Clear any previous warning lines LOCATE 15, 5: PRINT " " PRINT TAB(5); " " 'Check for invalid entry IF (NUMENTERED% < 1) OR (NUMENTERED% > 4) THEN 'Invalid value (not 1 to 4) 'Warn of invalid value entered COLOR 28, 0, 0 'Flashing light red LOCATE 15, 5: PRINT "INVALID VALUE ENTERED FOR NUMBER OF MODULES!" COLOR 12, 0, 0 'Light red PRINT TAB(5); "Value entered = "; KBINPUT$ COLOR 15, 0, 0 'White on black BEEP LOOPEXIT% = 0 'Flag set for invalid value entered ELSE LOOPEXIT% = 1 'Flag set for valid value entered END IF LOOP WHILE (LOOPEXIT% <> 1) 'Set and display value entered NUMDUT% = NUMENTERED% 'Set return value (in parameter) COLOR 11, 0, 0 'Cyan on black background CLS LOCATE 1, 20: PRINT "SCM5B, 8B & DSCA AUTOMATED TEST EQUIPMENT" PRINT 'Blank line PRINT TAB(5); "Module type selected: "; SPECS.MODNAME COLOR 15, 0, 0 'White on black PRINT 'Blank line PRINT 'Blank line PRINT TAB(5); "Number of modules in test head: "; NUMDUT% PRINT 'Blank line PRINT 'Blank line COLOR 14, 0, 0 'Yellow on black PRINT TAB(6); "-----------------------------------------------------------------" COLOR 28, 0, 0 'Flashing light red PRINT TAB(6); " MAKE SURE THAT THE PROTECTIVE COVER IS CLOSED ON THE TESTHEAD! " COLOR 14, 0, 0 'Yellow on black PRINT TAB(6); "-----------------------------------------------------------------" PRINT PRINT PRINT TAB(5); "Continue on to testing after verifying that the cover" PRINT TAB(5); "is closed by pressing the key listed below." PRINT 'BEEP DUMKEY$ = WAITFORKEY("C", 10, 14, 0) 'Waits for "C" key press (display bright yellow on black) CLS LOCATE 5: PRINT TAB(5); "Continuing on to testing...." END SUB SUB IOUTMAXL (NUMDUT%, STATUS$()) 'Test operation of current output modules with max load resistance. 'Inputs; NUMDUT% = number of Devices Under Test 'Outputs; STATUS$(17, n) array of results ' MAXIN! = SPECS.MAXIN FINCAL! = SPECS.FINCAL 'Input waveshape frequency (Hz) MINOUT! = SPECS.MINOUT 'V or A MAXOUT! = SPECS.MAXOUT ORANGE! = MAXOUT! - MINOUT! 'Output range (V or A) OUTSIGTYPE$ = SPECS.OUTSIGTYPE MEAS.ACC! = SPECS.CALTOL / 100 / 10 'Measurement accuracy NOMVS! = SPECS.NOMVS LOOPVMIN! = SPECS.LOOPVMIN + MAXOUT! * (IOUTSEN2! + NOISEFILTERR!) LOOPVNOM! = SPECS.LOOPVNOM + MAXOUT! * NOISEFILTERR! CLS TESTTITLE$ = "Maximum Output Load Test" CALL HEADERB(TESTTITLE$, 0) IF OUTSIGTYPE$ = "VOLTAGE" THEN LOCATE 10, 10: PRINT "This test is not performed on model "; SPECS.MODNAME EXIT SUB ELSEIF NOMVS! = 5 THEN CALL SETDPS(DPSADDR%, LOOPVMIN!) 'Set Vloop to nominal value END IF MAXINMEAS! = SETDUTIN!(MAXIN!) FOR L% = 1 TO NUMDUT% LOCATE 1 IF L% <> 1 THEN CALL HEADERB(TESTTITLE$, 0) 'Check if module previously failed supply current '(removed from test head), offset cal or gain cal '(not functional) or output switch test (not functional) IF LEFT$(STATUS$(1, L%), 4) <> "FAIL" AND LEFT$(STATUS$(2, L%), 4) <> "FAIL" AND LEFT$(STATUS$(13, L%), 4) <> "FAIL" AND LEFT$(STATUS$(14, L%), 4) <> "FAIL" THEN LOCATE 10, 25: PRINT "TESTING DEVICE IN CHANNEL #"; L% CALL DVMCONF(IOUTSENDUT1SEN.CH% + L% - 1, VDC$, "", MAXOUT! * IOUTSEN1.MEAS!(1), "", 0) CALL DVMSENS(IOUTSENDUT1SEN.CH% + L% - 1, VDC$, INTTIME$, "", .02) '4 1/2 digits, 15 bit resolution OUTNOMLOAD! = GETREADING! / IOUTSEN1.MEAS!(L%) 'output at nominal load (250 ohm) CALL SETOUTLOAD(IOUTSEN2!, NUMDUT%) 'Set max load resistor CALL DVMCONF(IOUTSENDUT1SOUR.CH% + L% - 1, VDC$, "", MAXOUT! * IOUTSEN2! * 1.1, "", 0) CALL DVMSENS(IOUTSENDUT1SOUR.CH% + L% - 1, VDC$, INTTIME$, "", .02) '4 1/2 digits, 15 bit resolution OUTMAXLOAD! = GETREADING! / IOUTSEN2.MEAS!(L%) 'output at max. load (600 ohm) PERCOUTCHG! = (OUTMAXLOAD! - OUTNOMLOAD!) / ORANGE! * 100! IF ABS(PERCOUTCHG!) <= DELTALOADTOL! THEN ML$ = "PASS" ELSE ML$ = "FAIL" SOUND 1000, .5 END IF 'Set DUT input voltage power supply to 0V (PWR 2014-10-08) CALL SETDPS(DPSVINADDR%, 0!) CALL SETDPS(DPSVINADDR2%, 0) 'LOCATE 15, 10: PRINT TAB(10); "MODULE #"; L%; " Status: "; ML$; LOCATE 16, 10 'Added PRINT SPC(30); PRINT TAB(10); "Change in output current at max load is"; PRINT TAB(50); USING " +###.### %"; PERCOUTCHG! PRINT TAB(10); "Max. change in output current is"; PRINT TAB(50); USING "+/-##.### %"; DELTALOADTOL! CALL FAILSTATUS(L%, ML$, 15, 10, "Status: ", 20) 'Print test status to screen STATUS$(17, L%) = ML$ + STR$(PERCOUTCHG!) + "1" CALL SETOUTLOAD(IOUTSEN1!, NUMDUT%) 'Set current output sense resistor END IF IF L% < NUMDUT% THEN 'Prevent to assign a not valid serial number SN$ = SERNO$(L% + 1) 'Use the next serial number on the array END IF CALL PAUSE(1!) IF L% <> NUMDUT% THEN FOR M% = 15 TO 17 LOCATE M%, 10: PRINT SPC(65); NEXT PRINT END IF CLS NEXT SN$ = SERNO$(1) CALL SETDPS(DPSVINADDR%, 0) 'Set input voltage (at ext. supply) to 0V CALL SETDPS(DPSVINADDR2%, 0) IF NOMVS! = 5 THEN CALL SETDPS(DPSADDR%, LOOPVNOM!) 'Set Vloop to nominal value END IF END SUB FUNCTION ISDUPLICATESN% (SERNO$, NUMDUT%) 'Selection menu to change the SN information of unit in channels 2 or higher 'Function that returns "1" if there are duplicate serial numbers set 'and "0" if no serial number set matches any other. ' ISDUPLICATESN% = 0 'Initialize to "not duplicate" 'Dual loops. For each channel, check the complete serial number (work order/serial) 'against all others. FOR iIdx1 = 1 TO NUMDUT% FOR iIdx2 = 1 TO NUMDUT% IF (SERNO$(iIdx1) = SERNO$(iIdx2)) THEN IF NOT (iIdx1 = iIdx2) THEN 'Do not check to see if same serial number matches itself IF NOT (SERNO$(iIdx1) = "" OR SERNO$(iIdx2) = "") THEN 'Skip checking if the serial number is blank ' Duplicate work order/serial number for the channel. ISDUPLICATESN% = 1 'Set to "duplicate" END IF END IF END IF NEXT iIdx2 NEXT iIdx1 END FUNCTION SUB LINTEST (INSIM!(), OUTCALC!(), OUTMEAS!(), ERROROUT!(), ACCSTAT$(), NUMDUT%, STATUS$()) 'Measure accuracy over input range 'Inputs; ' NUMDUT% = number of Devices Under Test ' 'Outputs; ' INSIM!(m, n) array of measured input voltages or currents ' OUTCALC!(m, n) array of calculated output voltages or currents ' OUTMEAS!(m, n) array of measured output voltages or currents ' ERROROUT!(m, n) array of calculated error from ideal (% span) ' ACCSTAT$(m, n) array of accuracy status at each test point (PASS/FAIL) ' STATUS$(3, n) array of results, measured accuracy ' STATUS$(4, n) array of results, best fit linearity ' OSCALIN! = SPECS.OSCALIN FINCAL! = SPECS.FINCAL 'Input waveshape frequency (Hz) MAXIN! = SPECS.MAXIN MINOUT! = SPECS.MINOUT 'V or A MAXOUT! = SPECS.MAXOUT MAXLINERR! = SPECS.LINEAR ' % MAXACCERR! = SPECS.ACCSINCAL ' % MEAS.ACC! = SPECS.CALTOL / 100 / 10 'Measurement accuracy OUTSIGTYPE$ = SPECS.OUTSIGTYPE NOMVS! = SPECS.NOMVS MININ! = SPECS.MININ NUMPTS% = 5 ORANGE! = MAXOUT! - MINOUT! 'Output range (V or A) IRANGE! = MAXIN! - MININ! 'Input range (V for HV modules) IF OUTSIGTYPE$ = "VOLTAGE" THEN UNIT$ = "V" OUTSCALE! = 1! ELSE UNIT$ = "mA" OUTSCALE! = 1000! END IF LINSTEP! = (MAXIN! - MININ!) / (NUMPTS% - 1) CALL CONFDUTIN(0) CALL CONFDUTIN(1) 'LINSTEP!/2 ensures NUMPTS% test point FOR L% = 1 TO NUMDUT% CLS TESTTITLE$ = "Accuracy Test" CALL HEADERB(TESTTITLE$, 0) IF OUTSIGTYPE$ <> "CURRENT" THEN CALL SETOUTLOAD(10001, 4) END IF 'Header format: ' '5 19 36 53 67 'Iin (mAAC) 'Vin (mVAC) Output (mADC) Output (mADC) Error (%) Status '---------- ------------- ------------- ---------- -------- ' ###.### ##.### ##.### +###.### &&&& ' PRINT TAB(20); "Calculated"; TAB(38); "Measured" IF MAXIN! >= 1 THEN PRINT TAB(6); "Vin (VDC)"; INSCALE! = 1 ELSE PRINT TAB(5); "Vin (mVDC)"; INSCALE! = 1000 END IF PRINT TAB(19); "Output ("; UNIT$; "DC)"; TAB(36); "Output ("; UNIT$; "DC)"; PRINT TAB(54); "Error (%)"; TAB(68); "Status" PRINT TAB(5); "----------"; TAB(19); "------------"; TAB(36); "------------"; PRINT TAB(53); "----------"; TAB(67); "--------" 'Check if module previously failed supply current '(removed from test head), offset cal or gain cal '(not functional). IF LEFT$(STATUS$(1, L%), 4) <> "FAIL" AND LEFT$(STATUS$(13, L%), 4) <> "FAIL" AND LEFT$(STATUS$(14, L%), 4) <> "FAIL" THEN LOCATE 12, 10 PRINT "TESTING DEVICE IN CHANNEL #"; L% INC% = 0 'Array element FAILED% = 0 ACCERR! = 0 SMODIN! = 0 SSMODIN! = 0 SERR! = 0 SPROD! = 0 LOCATE 6 IF OUTSIGTYPE$ = "CURRENT" THEN CH% = IOUTSENDUT1SEN.CH% ELSE IF LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN CH% = VOUTDUT1.CH% ELSE 'DSCA CH% = IOUTSENDUT1SOUR.CH% END IF END IF 'CALL DVMSENS(CH% + L% - 1, VDC$, RANGE$, "", MAXOUT!)'Set range FOR MODIN! = MININ! TO MAXIN! + LINSTEP! / 2 STEP LINSTEP! INC% = INC% + 1 INSIM!(L%, INC%) = SETDUTIN!(MODIN!) * INSCALE! 'Expected DUT input voltage (set voltage) is "MODIN!", while the measured input 'voltage is "INSIM!(L%, INC%) / INSCALE!" (see above, with the scaling factor 'removed. The error between the two is the difference from the measured to the 'expected, divided by the input range. Times 100 give the percentage error 'of the measured input against the input range. ' 'Calculate the percentage error of the input here, then check to make sure it 'does not exceed the specified tolerance below. 'INPUTERR! = 100! * ((INSIM!(L%, INC%) / INSCALE!) - MODIN!) / MODIN! INPUTERR! = 100! * ((INSIM!(L%, INC%) / INSCALE!) - MODIN!) / IRANGE! 'Input err. % of input range (PWR 2014-07-25) OUTCALC!(L%, INC%) = MODULEOUT!(INSIM!(L%, INC%) / INSCALE!) CALL DVMCONF(CH% + L% - 1, VDC$, "", ABS(OUTCALC!(L%, INC%) * IOUTSEN1.MEAS!(1)), "", 0) CALL DVMSENS(CH% + L% - 1, VDC$, INTTIME$, "", 2)'6 1/2 digits,1 bit resolution PAUSE (1) OUTMEAS!(L%, INC%) = GETREADING! / IOUTSEN1.MEAS!(L%) * OUTSCALE! ERROROUT!(L%, INC%) = (OUTMEAS!(L%, INC%) / OUTSCALE! - OUTCALC!(L%, INC%)) / ORANGE! * 100!'Error (% span) 'Check for input error more than 10% of the expected voltage, in 'addition to the accuracy-step error (PWR 2014-07-24) IF (ABS(INPUTERR!) > 10!) THEN 'Input error more than 10% of set value = FAIL ACCSTAT$(L%, INC%) = "FAIL" FAILED% = FAILED% + 1 SOUND 800, .5 ELSEIF ABS(ERROROUT!(L%, INC%)) <= MAXACCERR! THEN 'Output error within limits = PASS ACCSTAT$(L%, INC%) = "PASS" ELSE 'Output error exceeds limits = FAIL ACCSTAT$(L%, INC%) = "FAIL" FAILED% = FAILED% + 1 SOUND 800, .5 END IF 'Original code commented out below (PWR 2014-07-24) 'IF ABS(ERROROUT!(L%, INC%)) <= MAXACCERR! THEN ' ACCSTAT$(L%, INC%) = "PASS" 'ELSE ' ACCSTAT$(L%, INC%) = "FAIL" ' FAILED% = FAILED% + 1 ' SOUND 800, .5 'END IF PRINT TAB(6); USING "+###.### +###.### +###.### +###.###"; INSIM!(L%, INC%); (OUTCALC!(L%, INC%)) * OUTSCALE!; OUTMEAS!(L%, INC%); ERROROUT!(L%, INC%); 'PRINT TAB(69); ACCSTAT$(L%, INC%) IF (LEFT$(ACCSTAT$(L%, INC%), 4) = "FAIL") THEN COLOR 12, 0 'Test value text color to light red ELSE COLOR 10, 0 'Test value text color to light green END IF PRINT TAB(69); ACCSTAT$(L%, INC%) COLOR 11, 0 'Back to light cyan (blue) on black background. IF ABS(ERROROUT!(L%, INC%)) > ABS(ACCERR!) THEN ACCERR! = ERROROUT!(L%, INC%) END IF 'Variables used to calculate the best fit line using linear regression. SMODIN! = SMODIN! + INSIM!(L%, INC%) SSMODIN! = SSMODIN! + INSIM!(L%, INC%) ^ 2 SERR! = SERR! + ERROROUT!(L%, INC%) SPROD! = SPROD! + INSIM!(L%, INC%) * ERROROUT!(L%, INC%) NEXT SLOPE! = ((NUMPTS% * SPROD!) - (SMODIN! * SERR!)) / ((NUMPTS% * SSMODIN!) - (SMODIN! ^ 2)) OFFSET1! = ((SERR! * SSMODIN!) - (SMODIN! * SPROD!)) / ((NUMPTS% * SSMODIN!) - (SMODIN! ^ 2)) BFERR! = ABS(BESTFIT!(SLOPE!, OFFSET1!, INSIM!(), NUMPTS%, ERROROUT!(), L%)) IF FAILED% = 0 THEN ACC$ = "PASS" ELSE ACC$ = "FAIL" SOUND 800, .5 END IF IF ABS(BFERR!) <= MAXLINERR! THEN BF$ = "PASS" ELSE SOUND 600, .5 BF$ = "FAIL" END IF 'Set DUT input voltage power supply to 0V (PWR 2014-10-08) CALL SETDPS(DPSVINADDR%, 0!) CALL SETDPS(DPSVINADDR2%, 0) 'LOCATE 13 'PRINT TAB(10); "Accuracy status: "; ACC$ LOCATE 14 'Added. 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! STATUS$(3, L%) = ACC$ + STR$(ACCERR!) + "3" '% span STATUS$(4, L%) = BF$ + STR$(BFERR!) + "3" 'append # decimal places CALL FAILSTATUS(L%, ACC$, 13, 10, "Accuracy status: ", 20) 'Print test status to screen CALL FAILSTATUS(L%, BF$, 16, 10, "Linearity status: ", 20) 'Print test status to screen END IF IF L% < NUMDUT% THEN 'Prevent to assign a not valid serial number SN$ = SERNO$(L% + 1) 'Use the next serial number on the array END IF CALL PAUSE(1!) CALL INSTRERRORS(DASADDR%, 1) 'Clears and displays Agilent 34970A error queue. CLS NEXT SN$ = SERNO$(1) 'CALL FUNGEN33120A(VOLT$, GENOUTMIN!) 'Set lowest input signal CALL SETDPS(DPSVINADDR%, 0!) 'Set DUT input voltage power supply to 0V (PWR 2014-07-24) CALL SETDPS(DPSVINADDR2%, 0) END SUB FUNCTION PROGNAMEVAL$ 'Function to return the library source file version PROGNAMEVAL$ = PROGNAME$ END FUNCTION FUNCTION PROGVERVAL$ 'Function to return the library source file version PROGVERVAL$ = VERSION$ END FUNCTION SUB STARTCFG 'Sub to perform module-input configuration before testing ' '--------------------------------------------------------------------------- 'Configure to measure input current sense resistors if current-input module '--------------------------------------------------------------------------- 'CALL INSTALLDUT(NUMDUT%) IINSEN1.MEAS! = 1 '---------------- 'Set module input '---------------- CLS LOCATE 5 PRINT TAB(10); "Module input successfully set for testing....."; PRINT PRINT END SUB