Files
Mike Swanson 45083f4735 Add SCMVAS/SCMHVAS datasheet pipeline extension (Dataforth)
Extends the Test Datasheet Pipeline on AD2:C:\Shares\testdatadb to
generate web-published datasheets for the SCMVAS-Mxxx (obsolete) and
SCMHVAS-Mxxxx (replacement) High Voltage Input Module product lines.
Both are tested either with the existing TESTHV3 software (production
VASLOG .DAT logs) or in Engineering with plain .txt output.

Key changes on AD2 (all deployed 2026-04-12 with dated backups):

- parsers/spec-reader.js: getSpecs() returns a `{_family:'SCMVAS',
  _noSpecs:true}` sentinel for SCMVAS/SCMHVAS/VAS-M/HVAS-M model prefixes
  so the export pipeline does not silently skip them for missing specs.
- templates/datasheet-exact.js: new Accuracy-only template branch
  (generateSCMVASDatasheet + helpers) that mirrors the existing shipped
  format byte-for-byte. Extraction regex covers both QuickBASIC STR$()
  output formats: scientific-with-trailing-status-digit (98.4% of
  records) and plain-decimal (1.6% of records above QB's threshold).
- parsers/vaslog-engtxt.js (new): parses the Engineering-Tested .txt
  files in TS-3R\LOGS\VASLOG\VASLOG - Engineering Tested\. Filename SN
  regex strips optional trailing 14-digit timestamp; in-file "SN:"
  header is the authoritative source when the filename is malformed.
- database/import.js: LOG_TYPES grows a VASLOG_ENG entry with
  subfolder + recursive flags. Pre-existing 7 log types keep their
  implicit recursive=true behaviour (config.recursive !== false).
  importFiles() routes VASLOG_ENG paths before the generic loop so a
  VASLOG - Engineering Tested/*.txt path does not mis-dispatch to the
  multiline parser.
- database/export-datasheets.js: VASLOG_ENG records are written
  verbatim via fs.copyFileSync(source_file, For_Web/<SN>.TXT) for true
  byte-level pass-through, with a graceful raw_data fallback when the
  source file is no longer on disk.

Deploy outcome:
- 27,503 SCMVAS/SCMHVAS datasheets rendered (27,065 from scientific +
  438 from plain-decimal PASS lines, post-patch rerun)
- 434 Engineering-Tested .txt files pass-through-copied to For_Web
- 0 errors across both batches

Repo layout added here:
- scmvas-hvas-research/: discovery artifacts (source .BAS, hvin.dat,
  sample .DAT + .txt, binary-format notes, IMPLEMENTATION_PLAN.md)
- implementation/: staged final code + deploy helpers + local test
  harness + per-step verification scripts
- backups/pre-deploy-20260412/: independent local snapshot of the 4
  AD2 files replaced, pulled byte-for-byte before deploy

All helper scripts fetch the AD2 password at runtime from the SOPS
vault (clients/dataforth/ad2.sops.yaml). None of the committed files
contain the plaintext credential. Known vault-entry hygiene issue
(stale shell-escape backslash before the `!`) is documented in the
fetcher comments and stripped at read-time; flagged separately for
cleanup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 07:36:45 -07:00

2949 lines
111 KiB
QBasic

'**************************** 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