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>
This commit is contained in:
2026-04-12 17:02:20 -07:00
parent 499fd5d01a
commit 45083f4735
114 changed files with 35486 additions and 0 deletions

View File

@@ -0,0 +1,731 @@
'Database Modification Program for DSCA33
'DIN rail signal conditioning modules
'
'AUTHOR: John Lehman
'DATE: 08/30/99
'
' REVISION RECORD
'DATE APPR DESCRIPTION
'---- ---- -----------
'08/30/99 JL Create, start from DBDSC4.BAS
'10/30/06 JL Added suggested P.S. voltage levels of 19-29V.
DECLARE FUNCTION CHANGE (SPEC!)
DECLARE FUNCTION CHANGE2 (SPEC!, SCALE!)
DECLARE FUNCTION MENU1% ()
DECLARE FUNCTION MENU3% () 'Gets the module family
DECLARE FUNCTION REPEAT$ ()
DECLARE FUNCTION STRINGVAL% (A$)
DECLARE SUB MODDATA (SEL%)
DECLARE SUB GETSPECS (SEL%)
DECLARE SUB ENTDATA ()
DECLARE SUB SAVEDATA (SEL%)
DECLARE SUB SORTALL ()
DECLARE SUB SORTDB (ENDFLAG%)
'Database Record defintion for the specifications
TYPE DBASE
MODNAME AS STRING * 13 'DSCA33-XXXX or SCM5B33-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', 'ARBxxxxx'
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 suuply 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
'define common variables
COMMON SHARED /SAMPLE/ SPECS AS DBASE, SORTDATA1 AS DBASE2, SORTDATA2 AS DBASE
DO
SELECT CASE MENU1%
CASE 1
CALL ENTDATA
IF LEFT$(SPECS.MODNAME, 4) <> " " THEN
CALL SAVEDATA(0)
END IF
CASE 2
CALL GETSPECS(SEL%)
IF LEFT$(SPECS.MODNAME, 4) <> "EXIT" THEN
CALL MODDATA(SEL%)
CALL SAVEDATA(0)
END IF
CASE 3
CALL GETSPECS(SEL%)
IF LEFT$(SPECS.MODNAME, 4) <> "EXIT" THEN
CALL MODDATA(SEL%)
CALL SAVEDATA(SEL%)
END IF
CASE 4
CALL SORTALL
CASE 5
END
END SELECT
LOOP WHILE REPEAT$ <> "N"
FUNCTION CHANGE (SPEC!)
Y% = CSRLIN
X% = POS(0)
LOCATE Y%, X% + 1
INPUT A$
IF A$ <> "" THEN
CHANGE = VAL(A$)
ELSE
CHANGE = SPEC!
END IF
END FUNCTION
FUNCTION CHANGE2 (SPEC!, SCALE!)
Y% = CSRLIN
X% = POS(0)
LOCATE Y%, X% + 1
INPUT A$
IF A$ <> "" THEN
CHANGE2 = VAL(A$) / SCALE!
ELSE
CHANGE2 = SPEC!
END IF
END FUNCTION
SUB ENTDATA
'for specs which are not input for all models, default value is zero.
CLS
INPUT "SCM5B, SCM8B or DSCA Model Number (SCM5Bxx-xx, SCM8Bxx-xx or DSCAxx-xx, blank to exit) "; MN$
IF LEFT$(MN$, 1) = " " THEN
EXIT SUB
ELSE 'Check if model already exists
OPEN "T:\ENGR\ATE\ATE\HVU\HVDATA\HVIN.DAT" FOR RANDOM AS #1 LEN = LEN(SPECS)
NR% = LOF(1) / LEN(SPECS)
FOR N = 1 TO NR%
GET #1, N, SPECS
IF SPECS.MODNAME = MN$ THEN
BEEP
PRINT "This model already exists in the database."
PRINT "Press any key to continue."
DO
LOOP WHILE INKEY$ = ""
CLOSE #1
EXIT SUB
END IF
NEXT N
CLOSE #1
SPECS.MODNAME = UCASE$(MN$)
END IF
PRINT "Valid Sensor Types:"
PRINT TAB(5); "V (millivolt or volt source)"
' PRINT TAB(5); "A (milliamp or amp source)"
DO
INPUT "Sensor Type "; SPECS.INTYPE
LOOP WHILE LEFT$(UCASE$(SPECS.INTYPE), 1) <> "V" AND LEFT$(UCASE$(SPECS.INTYPE), 1) <> "A"
INPUT "Minus F.S. Input (V, A) "; SPECS.MININ
INPUT "Plus F.S. Input (V, A) "; SPECS.MAXIN
DO
INPUT "Output signal type ('VOLTAGE' or 'CURRENT')"; SPECS.OUTSIGTYPE
SPECS.OUTSIGTYPE$ = UCASE$(SPECS.OUTSIGTYPE)
LOOP WHILE SPECS.OUTSIGTYPE <> "VOLTAGE" AND SPECS.OUTSIGTYPE <> "CURRENT"
IF SPECS.OUTSIGTYPE = "CURRENT" THEN
UNIT$ = "mA"
SCALE! = 1000!
ELSE
UNIT$ = "V"
SCALE! = 1!
END IF
PRINT "Minus F.S. Output ("; UNIT$; ") ";
INPUT SPECS.MINOUT
SPECS.MINOUT = SPECS.MINOUT / SCALE! 'Convert to V or A
PRINT "Plus F.S. Output ("; UNIT$; ") ";
INPUT SPECS.MAXOUT
SPECS.MAXOUT = SPECS.MAXOUT / SCALE! 'Convert to V or A
' DO
' INPUT "Calibration Signal Waveshape (SINE, SQUARE, TRIANGLE, RAMP) = "; SPECS.WAVESHPCAL
' SPECS.WAVESHPCAL = UCASE$(SPECS.WAVESHPCAL)
'LOOP WHILE SPECS.WAVESHPCAL <> "SINE " AND SPECS.WAVESHPCAL <> "SQUARE " AND SPECS.WAVESHPCAL <> "TRIANGLE" AND SPECS.WAVESHPCAL <> "RAMP "
' INPUT "Calibration Signal Frequency (Hz, 60Hz standard) "; SPECS.FINCAL
' INPUT "Mininum Standard Input Frequency (Hz) "; SPECS.FINMIN
' INPUT "Maximum Standard Input Frequency (Hz) "; SPECS.FINMAX
' INPUT "Mininum Extended Input Frequency (Hz) "; SPECS.FINEXTMIN
' INPUT "Maximum Extended Input Frequency (Hz) "; SPECS.FINEXTMAX
'INPUT "Input Protection Rating, Max (V, A) "; SPECS.INPROTECT
'IF SPECS.OUTSIGTYPE = "CURRENT" THEN
' INPUT "Current Output Limit (mA) "; SPECS.IOUTLIM
'ELSE
' INPUT "Voltage Output Limit (V) "; SPECS.VOUTLIM
'END IF
'IF LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN
' INPUT "Output Resistance (Ohms) "; SPECS.OUTRES
'END IF
INPUT "Output noise/ripple (% span rms) "; SPECS.OUTNOISE
INPUT "Input for OFFSET calibration (V, A) "; SPECS.OSCALIN
INPUT "Input for GAIN calibration (V, A) "; SPECS.GNCALIN
INPUT "Offset Calibration Point (+/- % of span) "; SPECS.OSCALPT
INPUT "Gain Calibration Point (+/- % of span) "; SPECS.GNCALPT
INPUT "Offset and Gain Calibration Tolerance (+/- % of Span) "; SPECS.CALTOL
INPUT "Offset/Gain User Adjustability (+/- % of Span) "; SPECS.ADJ
INPUT "Nonlinearity (+/- % of span) "; SPECS.LINEAR
'PRINT USING "Accuracy z (+/- % of span) "; SPECS.FINCAL
INPUT "Accuracy (+/- % of span) "; SPECS.ACCSINCAL
' PRINT USING "Accuracy w/ Sine Input @ #####Hz to #####Hz (+/- % of span) "; SPECS.FINMIN; SPECS.FINMAX
' INPUT SPECS.ACCSINSTD
' PRINT USING "Accuracy w/ Sine Input @ #####Hz to #####Hz (+/- % of span) "; SPECS.FINEXTMIN; SPECS.FINEXTMAX
' INPUT SPECS.ACCSINEXT
' PRINT USING "Accuracy w/ Crest Factor 1 to 2 @ #####Hz (+/- % of span) "; SPECS.FINCAL
'INPUT SPECS.ACCCF12
'PRINT USING "Accuracy w/ Crest Factor 2 to 3 @ #####Hz (+/- % of span) "; SPECS.FINCAL
' INPUT SPECS.ACCCF23
' PRINT USING "Accuracy w/ Crest Factor 3 to 4 @ #####Hz (+/- % of span) "; SPECS.FINCAL
' INPUT SPECS.ACCCF34
' PRINT USING "Accuracy w/ Crest Factor 4 to 5 @ #####Hz (+/- % of span) "; SPECS.FINCAL
' INPUT SPECS.ACCCF45
' INPUT "Common Mode Rejection (dB) "; SPECS.CMR
INPUT "Step Response Test Delay (s, 0.1 typ.)"; SPECS.STEPTIME
PRINT "Nominal Response at #.### s (% span)"; SPECS.STEPTIME;
' INPUT SPECS.STEPPERC
' INPUT "Step Response Tolerance (%) "; SPECS.STEPTOL
IF SPECS.OUTSIGTYPE = "CURRENT" THEN
INPUT "Maximum Load Resistance (Ohms) "; SPECS.MAXLOADR
IF LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN
INPUT "Minimum Output Loop Voltage (V) "; SPECS.LOOPVMIN
INPUT "Nominal Output Loop Voltage (V) "; SPECS.LOOPVNOM
INPUT "Maximum Output Loop Voltage (V) "; SPECS.LOOPVMAX
END IF
END IF
INPUT "Minimum Supply Voltage (V) [5B/8B- 4.75V, DSCA- 19V]"; SPECS.MINVS
INPUT "Nominal Supply Voltage (V) [5B/8B- 5V, DSCA- 24V]"; SPECS.NOMVS
INPUT "Maximum Supply Voltage (V) [5B/8B- 5.25V, DSCA- 29V]"; SPECS.MAXVS
INPUT "Minimum Supply Current (mA) "; SPECS.ISMIN
INPUT "Maximum Supply Current (mA) "; SPECS.ISMAX
IF LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN
UNIT$ = "ppm / %"
ELSEIF LEFT$(SPECS.MODNAME, 2) = "8B" THEN
UNIT$ = "ppm / %"
ELSE
UNIT$ = "% / %"
END IF
PRINT "Power Supply Sensitivity ("; UNIT$; ") ";
INPUT SPECS.PSS
END SUB
SUB GETSPECS (SEL%)
DIM POINTER%(1000)
CALL SORTDB(ENDFLAG%)
IF ENDFLAG% = 1 THEN
SPECS.MODNAME = "EXIT"
EXIT SUB
END IF
CLS
LOCATE , 30
PRINT "Model Selection Menu"
PRINT TAB(30); "--------------------"
PRINT
YINIT% = CSRLIN 'Initialize starting rows
OPEN "T:\ENGR\ATE\HVU\HVDATA\HVSORT.DAT" FOR RANDOM AS #2 LEN = LEN(SORTDATA1)
DO
I% = I% + 1
GET #2, I%, SORTDATA1
IF SORTDATA1.RECNUM <> -1 THEN NUMRECORD! = NUMRECORD! + 1
LOOP WHILE SORTDATA1.RECNUM <> -1
SCRNCTR% = 40 'display center
NUMCHAR% = 19 '13 char + 4 char for # + 2 spaces
NUMLINES! = 19 '# of lines for model display below header
NUMCOLUMNS! = 1 + INT(NUMRECORD! / NUMLINES!)
'Model # length = 20 characters max
'-> 3 columns max per screen
'3 columns x 26 char = 78 spaces
I% = 1
FOR C% = 0 TO NUMCOLUMNS! - 1
Y% = YINIT%
TB% = SCRNCTR% - NUMCHAR% / 2 * NUMCOLUMNS! + NUMCHAR% * C%
DO
GET #2, I%, SORTDATA1
IF SORTDATA1.RECNUM <> -1 THEN
POINTER%(I%) = SORTDATA1.RECNUM
LOCATE Y%, TB%
PRINT USING "##.) &"; I%; SORTDATA1.MODNAME
I% = I% + 1
Y% = Y% + 1
END IF
LOOP WHILE SORTDATA1.RECNUM <> -1 AND Y% - YINIT% < NUMLINES!
NEXT C%
LOCATE Y%, TB%
PRINT USING "##.) Exit"; I%
CLOSE #2
DO
LOCATE 23, SCRNCTR% - NUMCHAR% / 2 * NUMCOLUMNS!
PRINT "Enter Selection ";
INPUT SEL%
LOOP WHILE SEL% < 1 OR SEL% > I%
IF SEL% = I% THEN
SPECS.MODNAME = "EXIT"
ELSE
OPEN "T:\ENGR\ATE\HVU\HVDATA\HVIN.DAT" FOR RANDOM AS #1 LEN = LEN(SPECS)
GET #1, POINTER%(SEL%), SPECS
CLOSE #1
END IF
SEL% = POINTER%(SEL%) 'pass back to main code for use in SAVEDATA
END SUB
FUNCTION MENU1%
CLS
LOCATE 5
PRINT TAB(18); "SCM5Bxx, SCM8Bxx & DSCAxx DATABASE MODIFICATION PROGRAM"
PRINT
PRINT TAB(17); "1.) Add New Module, Clean Start"
PRINT TAB(17); "2.) Add New Module, Start With Existing Module"
PRINT TAB(17); "3.) Modify Existing Module"
PRINT TAB(17); "4.) Sort Database"
PRINT TAB(17); "5.) Exit Program"
PRINT
PRINT TAB(17); "Enter your selection";
DO
A$ = INKEY$
LOOP WHILE VAL(A$) < 1 OR VAL(A$) > 5
MENU1% = VAL(A$)
END FUNCTION
FUNCTION MENU3%
CLS
LOCATE 3, 26
PRINT "Module Family Selection Menu"
PRINT TAB(26); "---------------------------"
PRINT
PRINT TAB(34); "1.) SCM5Bxx-xx"
PRINT TAB(34); "2.) DSCAxx-xx"
PRINT TAB(34); "3.) 8Bxx-xx"
PRINT TAB(34); "4.) Exit"
DO
I$ = INKEY$
LOOP WHILE VAL(I$) < 1 OR VAL(I$) > 4
MENU3% = VAL(I$)
END FUNCTION
SUB MODDATA (SEL%)
CLS
PRINT "Model Number: "; SPECS.MODNAME;
INPUT MN$
IF MN$ <> "" THEN
'Check if model already exists
OPEN "T:\ENGR\ATE\HVU\HVDATA\HVIN.DAT" FOR RANDOM AS #1 LEN = LEN(SPECS)
NR% = LOF(1) / LEN(SPECS)
FOR N% = 1 TO NR%
GET #1, N%, SPECS
IF SPECS.MODNAME = MN$ THEN
BEEP
PRINT "This model already exists in the database."
PRINT "Press any key to continue."
DO
LOOP WHILE INKEY$ = ""
CLOSE #1
EXIT SUB
END IF
NEXT
GET #1, SEL%, SPECS
SPECS.MODNAME = MN$
CLOSE #1
END IF
PRINT "Sensor Type: "; SPECS.INTYPE;
INPUT A$
IF A$ <> "" THEN
SPECS.INTYPE = A$
END IF
PRINT USING "Minus F.S. Input = +###.### (V, A)"; SPECS.MININ;
SPECS.MININ = CHANGE(SPECS.MININ)
PRINT USING "Plus F.S. Input = +###.### (V, A)"; SPECS.MAXIN;
SPECS.MAXIN = CHANGE(SPECS.MAXIN)
DO
PRINT "Output signal type = "; SPECS.OUTSIGTYPE;
INPUT A$
IF A$ <> "" THEN SPECS.OUTSIGTYPE = UCASE$(A$)
LOOP WHILE SPECS.OUTSIGTYPE <> "VOLTAGE" AND SPECS.OUTSIGTYPE <> "CURRENT"
IF SPECS.OUTSIGTYPE = "CURRENT" THEN
UNIT$ = "mA"
SCALE! = 1000!
ELSE
UNIT$ = "V"
SCALE! = 1!
END IF
PRINT USING "Minus F.S. Output = +#####.## &"; SPECS.MINOUT * SCALE!; UNIT$;
SPECS.MINOUT = CHANGE2(SPECS.MINOUT, SCALE!)
PRINT USING "Plus F.S. Output = +#####.## &"; SPECS.MAXOUT * SCALE!; UNIT$;
SPECS.MAXOUT = CHANGE2(SPECS.MAXOUT, SCALE!)
' DO
' PRINT "Calibration Signal Waveshape (SINE, SQUARE, TRIANGLE, RAMP) = "; SPECS.WAVESHPCAL
' INPUT A$
' IF A$ <> "" THEN SPECS.WAVESHPCAL = UCASE$(A$)
'LOOP WHILE SPECS.WAVESHPCAL <> "SINE " AND SPECS.WAVESHPCAL <> "SQUARE " AND SPECS.WAVESHPCAL <> "TRIANGLE" AND SPECS.WAVESHPCAL <> "RAMP "
' PRINT USING "Calibration Signal Frequency = ###### Hz"; SPECS.FINCAL;
' SPECS.FINCAL = CHANGE(SPECS.FINCAL)
' PRINT USING "Mininum Standard Input Frequency = ##### Hz"; SPECS.FINMIN;
' SPECS.FINMIN = CHANGE(SPECS.FINMIN)
' PRINT USING "Maximum Standard Input Frequency = ##### Hz"; SPECS.FINMAX;
' SPECS.FINMAX = CHANGE(SPECS.FINMAX)
' PRINT USING "Mininum Extended Input Frequency = ##### Hz"; SPECS.FINEXTMIN;
' SPECS.FINEXTMIN = CHANGE(SPECS.FINEXTMIN)
' PRINT USING "Maximum Extended Input Frequency = ###### Hz"; SPECS.FINEXTMAX;
' SPECS.FINEXTMAX = CHANGE(SPECS.FINEXTMAX)
' PRINT USING "Input Protection Rating, Max = #### (V or A)"; SPECS.INPROTECT;
' SPECS.INPROTECT = CHANGE(SPECS.INPROTECT)
' IF SPECS.OUTSIGTYPE = "CURRENT" THEN
' PRINT USING "Current Output Limit = ##.# mA"; SPECS.IOUTLIM;
' SPECS.IOUTLIM = CHANGE(SPECS.IOUTLIM)
'ELSE
' PRINT USING "Voltage Output Limit = ##.# V"; SPECS.VOUTLIM;
' SPECS.VOUTLIM = CHANGE(SPECS.VOUTLIM)
'END IF
'IF LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN
' PRINT USING "Output Resistance = ### Ohms"; SPECS.OUTRES;
' SPECS.OUTRES = CHANGE(SPECS.OUTRES)
'END IF
PRINT USING "Output Noise = #.### % span rms"; SPECS.OUTNOISE;
SPECS.OUTNOISE = CHANGE(SPECS.OUTNOISE)
PRINT USING "Input for OFFSET calibration = +###.### (V, A)"; SPECS.OSCALIN;
SPECS.OSCALIN = CHANGE(SPECS.OSCALIN)
PRINT USING "Input for GAIN calibration = +###.### (V, A)"; SPECS.GNCALIN;
SPECS.GNCALIN = CHANGE(SPECS.GNCALIN)
PRINT
PRINT "Offset and gain may be calibrated at a point other than -f.s. out"
PRINT "or +f.s. out."
PRINT USING "Offset Calibration Point = +#.### % of span"; SPECS.OSCALPT;
SPECS.OSCALPT = CHANGE(SPECS.OSCALPT)
PRINT USING "Gain Calibration Point = +#.### % of span"; SPECS.GNCALPT;
SPECS.GNCALPT = CHANGE(SPECS.GNCALPT)
PRINT USING "Offset and Gain Calibration Tolerance = +/- #.### % of span"; SPECS.CALTOL;
SPECS.CALTOL = CHANGE(SPECS.CALTOL)
PRINT USING "Offset/Gain User Adjustability = +/- ##.# % of span"; SPECS.ADJ;
SPECS.ADJ = CHANGE(SPECS.ADJ)
PRINT USING "Nonlinearity = +/- #.### % of span"; SPECS.LINEAR;
SPECS.LINEAR = CHANGE(SPECS.LINEAR)
PRINT USING "Accuracy = +/- #.### % of span"; SPECS.ACCSINCAL;
SPECS.ACCSINCAL = CHANGE(SPECS.ACCSINCAL)
' PRINT USING "Addt'l Error w/ Sine Input @ ##### Hz to ##### Hz = +/- #.### % of span"; SPECS.FINMIN; SPECS.FINMAX; SPECS.ACCSINSTD;
' SPECS.ACCSINSTD = CHANGE(SPECS.ACCSINSTD)
' PRINT USING "Addt'l Error w/ Sine Input @ ##### Hz to ##### Hz = +/- #.### % of span"; SPECS.FINEXTMIN; SPECS.FINEXTMAX; SPECS.ACCSINEXT;
' SPECS.ACCSINEXT = CHANGE(SPECS.ACCSINEXT)
' PRINT USING "Addt'l Error w/ Crest Factor 1 to 2 @ ##### Hz = +/- #.### % of span"; SPECS.FINCAL; SPECS.ACCCF12;
' SPECS.ACCCF12 = CHANGE(SPECS.ACCCF12)
' PRINT USING "Addt'l Error w/ Crest Factor 2 to 3 @ ##### Hz = +/- #.### % of span"; SPECS.FINCAL; SPECS.ACCCF23;
' SPECS.ACCCF23 = CHANGE(SPECS.ACCCF23)
' PRINT USING "Addt'l Error w/ Crest Factor 3 to 4 @ ##### Hz = +/- #.### % of span"; SPECS.FINCAL; SPECS.ACCCF34;
' SPECS.ACCCF34 = CHANGE(SPECS.ACCCF34)
' PRINT USING "Addt'l Error w/ Crest Factor 4 to 5 @ ##### Hz = +/- #.### % of span"; SPECS.FINCAL; SPECS.ACCCF45;
' SPECS.ACCCF45 = CHANGE(SPECS.ACCCF45)
' PRINT USING "Common Mode Rejection = ### dB"; SPECS.CMR;
' SPECS.CMR = CHANGE(SPECS.CMR)
PRINT USING "Step Response Test Delay = #.###### s"; SPECS.STEPTIME;
SPECS.STEPTIME = CHANGE(SPECS.STEPTIME)
' PRINT USING "Nominal Response at #.### s = ###.# % span"; SPECS.STEPTIME; SPECS.STEPPERC;
'SPECS.STEPPERC = CHANGE(SPECS.STEPPERC)
'PRINT USING "Step Response Tolerance = +/- ##.# % "; SPECS.STEPTOL;
'SPECS.STEPTOL = CHANGE(SPECS.STEPTOL)
IF SPECS.OUTSIGTYPE = "CURRENT" THEN
PRINT USING "Maximum Load Resistance = ##### Ohms"; SPECS.MAXLOADR;
SPECS.MAXLOADR = CHANGE(SPECS.MAXLOADR)
IF LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN
PRINT USING "Minimum Output Loop Voltage = ##.# V"; SPECS.LOOPVMIN;
SPECS.LOOPVMIN = CHANGE(SPECS.LOOPVMIN)
PRINT USING "Nominal Output Loop Voltage = ##.# V"; SPECS.LOOPVNOM;
SPECS.LOOPVNOM = CHANGE(SPECS.LOOPVNOM)
PRINT USING "Maximum Output Loop Voltage = ##.# V"; SPECS.LOOPVMAX;
SPECS.LOOPVMAX = CHANGE(SPECS.LOOPVMAX)
END IF
END IF
PRINT USING "Minimum Supply Voltage = ##.## V"; SPECS.MINVS;
SPECS.MINVS = CHANGE(SPECS.MINVS)
PRINT USING "Nominal Supply Voltage = ##.## V"; SPECS.NOMVS;
SPECS.MINVS = CHANGE(SPECS.MINVS)
PRINT USING "Maximum Supply Voltage = ##.## V"; SPECS.MAXVS;
SPECS.MAXVS = CHANGE(SPECS.MAXVS)
PRINT USING "Minimum Supply Current = ### mA"; SPECS.ISMIN;
SPECS.ISMIN = CHANGE(SPECS.ISMIN)
PRINT USING "Maximum Supply Current = ### mA"; SPECS.ISMAX;
SPECS.ISMAX = CHANGE(SPECS.ISMAX)
IF LEFT$(SPECS.MODNAME, 5) = "SCM5B" THEN
PRINT USING "Power Supply Sensitivity = #### ppm / %"; SPECS.PSS;
ELSEIF LEFT$(SPECS.MODNAME, 2) = "8B" THEN
PRINT USING "Power Supply Sensitivity = #### ppm / %"; SPECS.PSS;
ELSE
PRINT USING "Power Supply Sensitivity = #.#### % / %"; SPECS.PSS;
END IF
SPECS.PSS = CHANGE(SPECS.PSS)
END SUB
FUNCTION REPEAT$
CLS
LOCATE 10, 10
PRINT "Do you want to enter or modify another module ?";
DO
A$ = INKEY$
LOOP WHILE A$ = ""
REPEAT$ = A$
END FUNCTION
SUB SAVEDATA (SEL%)
CLS
LOCATE 10, 15
PRINT "Saving record in file HVIN.DAT"
T = TIMER
DO
LOOP WHILE (TIMER - T) < 1
OPEN "T:\ENGR\ATE\HVU\HVDATA\HVIN.DAT" FOR RANDOM AS #1 LEN = LEN(SPECS)
IF SEL% = 0 THEN
NR% = LOF(1) / LEN(SPECS)
SEL% = NR% + 1
END IF
PUT #1, SEL%, SPECS
CLOSE #1
END SUB
SUB SORTALL
'This sub does a bubble sort of the model numbers in the database
'records FOR ALL MODELS
CONST FALSE = 0, TRUE = NOT FALSE
OPEN "T:\ENGR\ATE\HVU\HVDATA\HVIN.DAT" FOR RANDOM AS #1 LEN = LEN(SPECS)
NUMRECORD% = LOF(1) / LEN(SPECS)
PRINT
PRINT TAB(10); "Sorting database, please wait."
'Sort according to string value
DO
Swaps% = FALSE
FOR I% = 1 TO NUMRECORD%
GET #1, I%, SPECS
A% = STRINGVAL%(SPECS.MODNAME)
GET #1, I% + 1, SORTDATA2
B% = STRINGVAL%(SORTDATA2.MODNAME)
'Do sort...
IF A% > B% THEN
PUT #1, I%, SORTDATA2
PUT #1, (I% + 1), SPECS
Swaps% = I%
END IF
NEXT I%
LOOP WHILE Swaps%
CLOSE #1
END SUB
SUB SORTDB (ENDFLAG%)
'This sub does a bubble sort of the model numbers in the database
'records FOR A SELECTED MODEL FAMILY
'CONST FALSE = 0, TRUE = NOT FALSE
'Create a file containing just the model numbers of all of the
'records in the database for the model family selected
OPEN "T:\ENGR\ATE\HVU\HVDATA\HVSORT.DAT" FOR RANDOM AS #2 LEN = LEN(SORTDATA1)
OPEN "T:\ENGR\ATE\HVU\HVDATA\HVIN.DAT" FOR RANDOM AS #1 LEN = LEN(SPECS)
NUMRECORD% = LOF(1) / LEN(SPECS)
SELFAM% = MENU3%
IF SELFAM% = 4 THEN
ENDFLAG% = 1
CLOSE #1
CLOSE #2
CLOSE #3
EXIT SUB 'exit selected from MENU3%
END IF
N% = 0
FOR I% = 1 TO NUMRECORD%
GET #1, I%, SPECS
MN$ = SPECS.MODNAME
SORTDATA1.MODNAME = MN$
SORTDATA1.RECNUM = I%
SELECT CASE SELFAM% 'Pick models in selected family
CASE 1
'SPECS.MODNAME = "SCM5Bxx-xxxx "
IF LEFT$(MN$, 3) = "SCM" THEN
PUT #2, , SORTDATA1 'write record # and model number
N% = N% + 1 'found a record
END IF
CASE 2
'SPECS.MODNAME = "DSCAxx-xxxx "
IF LEFT$(MN$, 3) = "DSC" THEN
PUT #2, , SORTDATA1 'write record # and model number
N% = N% + 1 'found a record
END IF
CASE 3
'SPECS.MODNAME = "8Bxx-xxxx "
IF LEFT$(MN$, 2) = "8B" THEN
PUT #2, , SORTDATA1 'write record # and model number
N% = N% + 1 'found a record
END IF
END SELECT
NEXT
SORTDATA1.MODNAME = "99999999-9999" 'always sorted to last value.
SORTDATA1.RECNUM = -1 'flag indicating end of new data (over writes old)
PUT #2, , SORTDATA1
CLOSE #1
CLOSE #2
CLOSE #3
END SUB
FUNCTION STRINGVAL% (A$)
'Calculate and return the value of the characters in A$
'which follow the hyphen
T% = LEN(A$)
DO
L% = L% + 1
LOOP UNTIL MID$(A$, L%, 1) = "-" OR L% = T%
STRINGVAL% = VAL(RIGHT$(A$, T% - L%))
END FUNCTION

View File

@@ -0,0 +1,776 @@
DECLARE SUB INSTALLDUT (NUMDUT%)
'Library of functions used with SCM5B33 and DSCA33 test programs.
'Created from LIBATE.BAS
'Author: John Lehman
'Date: 06/21/99
'
' REVISION RECORD
'
'Date of Change Description
'-------------- -----------
'06/21/99 JL Initial Release
DECLARE SUB CHANGEDN (SN$) 'Allow user to change dash number
DECLARE SUB CONTINUE () 'Waits for a key press
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 INPUTSN (SERNO$(), NUMDUT%) 'Gathers the SN infor for the unit in slot 1
DECLARE SUB HS1 () 'GPIB communications handshake
DECLARE SUB pause (TIME!) 'Pause for TIME
DECLARE FUNCTION BESTFIT! (SLOPE!, OFFSET1!, INSIM!(), NUMPTS%, ERROROUT!(), L%)
DECLARE FUNCTION REPEAT2$ (MN$, ELAP2!, TIME2!, SN$)
'** Calculates besfit line and max error
DECLARE FUNCTION KEYBDIN$ () '** Get keyboard input
DECLARE FUNCTION REPEAT$ (MN$, ELAP2!, TIME2!) '** Ask if you would like to repeat test
DECLARE FUNCTION READDVM! (CH%, FUNC$, RANGETXT$, RANGENUM!, RESOLTXT$, RESOLNUM!) '**
DECLARE FUNCTION STRINGVAL% (A$) '**
DECLARE FUNCTION UPSN$ (SN$, NUMDUT%) '** Increments dash# of serial#
'** Function called from main programs.
' Declare in programs which call this function.
'GPIB Communication routines for dataforth GPIB card
DECLARE SUB HS2 ()
DECLARE SUB HS1 ()
DECLARE SUB INIT488 (DEVADDR%)
DECLARE SUB IO488 (DDATA$, DEVADDR%, SEL4%)
'Kepco DPS 125-0.5M control routines via RS-232C
DECLARE SUB INITPS (DPSADDR%, OVERI!, OVERV!) 'initializes supply
DECLARE SUB SETDPS (DPSADDR%, VSUPPLY!) 'Sets Kepco DPS power supply
DECLARE FUNCTION POWERIO$ (DPSADDR%, CMD$) '** Kepco DPS power supply I/O
'HP33120A (function generator) control routines via GPIB
DECLARE SUB FUNGEN33120A (CMD$, VALUE!) 'Write command to func. gen.
'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 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
'HP760A meter calibrator routines
DECLARE SUB HP760APANEL (VALUE!, UNITS%) 'Draw a display of instrument panel.
COMMON SHARED PON%, IINSEN1.MEAS!, IOUTSEN1.MEAS!(), IOUTSEN2.MEAS!(), SERNO$(), SN$, PSCOM$, GENOUTMAX!, PCBNO$
COMMON SHARED BADDRS%, DPSADDR%, PSPORT%, DASADDR%, GENADDR%, DIOCH01DATA%, DIOCH02DATA%
CONST MTA% = &H40 'GPIB talk address
CONST MLA% = &H20 'GPIB listen address
'********************************************************************
'Assign constants to Kepco DPS power supply commands:
CONST PSVOLT$ = "STV=" 'Set terminal voltage
CONST SUPPLYON$ = "SOP=ON" 'Set output to ON
CONST ISTAT$ = "RCS" 'Read Current protection status
CONST SETIMAX$ = "SOC=" 'Set overcurent limit...4mA resol.
'********************************************************************
'Assign constants to HP freq. gen. commands
CONST FREQ$ = "FREQ"
'********************************************************************
'Assign constants to HP DAS commands
CONST SETDAC$ = "SOUR:VOLT"
'********************************************************************
'Assign constants to HP DAS configuration
CONST DAC1.CH% = 304 'DAC #1
CONST DAC2.CH% = 305 'DAC #2
KEY(10) ON 'Activates F10 key
ON KEY(10) GOSUB FINISH 'Traps for F10 key Exits if pressed
FINISH: END
FUNCTION BESTFIT! (SLOPE!, OFFSET1!, INSIM!(), NUMPTS%, ERROROUT!(), L%)
'Calculates Max error of data from bestfit line
MTERR! = 0
MIN! = INSIM!(L%, 1)
MAX! = INSIM!(L%, NUMPTS%)
FOR INC% = 1 TO NUMPTS% 'Increments thru test points
BVEC! = INSIM!(L%, INC%) * SLOPE! + OFFSET1! 'Calculates point on best fit line
AVEC! = ERROROUT!(L%, INC%) 'Gets corresponding data point
TERR! = AVEC! - BVEC! 'Calculates difference
IF ABS(TERR!) > ABS(MTERR!) THEN 'Checks if bigger than last Max
MTERR! = TERR! 'Assigns max error
END IF
NEXT
BESTFIT! = MTERR! 'Passes Max error back
END FUNCTION
SUB CHANGEDN (SN$)
N = 1
NWO$ = ""
DO
C$ = MID$(SN$, N, 1)
NWO$ = NWO$ + C$
N = N + 1
LOOP WHILE C$ <> "-"
WO$ = LEFT$(SN$, N)
PRINT "Current serial number is: "; SN$
INPUT "Enter the new dash number (Press 'Enter' for 1) "; DS$
IF DS$ = "" THEN DS$ = "1"
SN$ = NWO$ + DS$
END SUB
SUB DVMCONF (CH%, FUNC$, RANGETXT$, RANGENUM!, RESOLTXT$, RESOLNUM!)
' Inputs:
' CH% = channel to be measured
' FUNC$ = parameter to be measured
' RANGETXT$ = measurement range, specified in text
' If 'N/A', don't include in command. Not needed for FUNC$
' If "", range specified in RANGENUM! or not specified
' RANGENUM! = measurement range, specified numerically
' If 0, range specified in RANGETXT$ or not specified
' RESOLTXT$ = indicate how resolution is specified. 0 = text, 1 = numerically
' If 'N/A', don't include in command. Not needed for FUNC$
' IF "", resolution specified in RESOLNUM! or not specified
' RESOLNUM! = measurement resolution
' 0 = Resolution specified in RESOLTXT$ or not specified
' Outputs: None
' Description - configures HP34970A to take a measurement
'
' Reference;
' MEAS and CONF use the following default instrument settings
' Integration Time 1PLC
' Input Resistane 10Mohm, fixed for all DCV ranges
' AC Filter 20Hz (medium)
' Scan List Redefined when command executed
' Scan Interval Source Immediate
' Scan Count 1 Scan Sweep
' Channel Delay Automatic Delay
IF RANGETXT$ = "N/A" THEN 'String command only.
'No range or resolution data.
DDATA$ = "CONF:" + FUNC$ + " (@" + STR$(CH%) + ")"
ELSE
IF RANGENUM! <> 0 THEN 'Range specified numerically
RG$ = STR$(RANGENUM!)
ELSE 'Range specified w/ text
RG$ = " " + RANGETXT$
END IF
IF RESOLNUM! <> 0 THEN 'Resolution specified numerically
RES$ = STR$(RESOLNUM!)
ELSE 'Resolution specified w/ text
IF RESOLTXT$ <> "" THEN
RES$ = RESOLTXT$
ELSE
RES$ = ""
END IF
END IF
DDATA$ = "CONF:" + FUNC$ + RG$ + RES$ + ",(@" + STR$(CH%) + ")"
END IF
'Y% = CSRLIN
'LOCATE 22
'PRINT "DVMCONF a" + DDATA$ + "b";
'PRINT SPC(10); : PRINT
'LOCATE Y%
CALL IO488(DDATA$, DASADDR%, 1) 'Write configuration
END SUB
SUB DVMSENS (CH%, FUNC1$, FUNC2$, SETTXT$, SETNUM!)
' Inputs:
' CH% = channel to be measured
' FUNC1$ = parameter to be measured
' FUNC2$ = parameter to be configured
' SETTXT$ = configuration, specified in text
' If "", specified in SETNUM!
' SETNUM! = configuration, specified numerically
' If 0, range specified in SETTXT$
' Outputs: None
' Description - configures HP34970A to take a measurement
'
' Reference;
' DC Voltage and Current Readings
' Integration Time Resolution Digits Bits
' 0.02PLC <0.0001 * Range 4 1/2 15
' 0.2PLC <0.00001 * Range 5 1/2 18
' 1PLC <0.000003 * Range 5 1/2 20
' 2PLC <0.0000022 * Range 6 1/2 21
' 10PLC <0.000001 * Range 6 1/2 24
' 20PLC <0.0000008 * Range 6 1/2 25
' 100PLC <0.0000003 * Range 6 1/2 26
' 200PLC <0.00000022 * Range 6 1/2 26
'
' AC Voltage and Current Readings
' Filter Readings/s Settling Delay Digits
' 3Hz 0.14 1.5s 6 1/2
' 20Hz 1 0.2s 6 1/2
' 200Hz 8 0.02s 6 1/2
IF SETNUM! <> 0 THEN 'specified numerically
ST$ = STR$(SETNUM!)
ELSE 'specified w/ text
ST$ = " " + SETTXT$
END IF
DDATA$ = "SENS:" + FUNC1$ + ":" + FUNC2$ + ST$ + ",(@" + STR$(CH%) + ")"
'Y% = CSRLIN
'LOCATE 23
'PRINT "DVMSENSE a" + DDATA$ + "b";
'PRINT SPC(10); : PRINT
'LOCATE Y%
CALL IO488(DDATA$, DASADDR%, 1) 'Write configuration
END SUB
SUB FUNGEN33120A (CMD$, VALUE!)
' Inputs - String of commands to be sent to the HP33120A
' Outputs - None
' Description - Writes a string of commands to the HP33120A
' function generator, through the IEEE 488 interface
' If VALUE! = -99 then the command is a string only
IF VALUE! = -99 THEN
VALUE2$ = "" 'Command contains no numerical value
ELSEIF CMD$ = FREQ$ AND ABS(VALUE!) < .0001 THEN
VALUE! = .0001 'Func. gen. min output = 100uHz
VALUE2$ = STR$(VALUE!)
ELSEIF (LEFT$(CMD$, 3) = "FSK" OR LEFT$(CMD$, 7) = "FREQ:ST") AND VALUE! <= .0001 THEN
VALUE! = .01 'Func. gen. min FSK value = 10mHz
VALUE2$ = STR$(VALUE!) 'Func. gen. min sweep value = 10mHz
ELSE
VALUE2$ = STR$(VALUE!)
END IF
DDATA$ = CMD$ + " " + VALUE2$
'Y% = CSRLIN
'LOCATE 20
'PRINT "FUNGEN33120A a" + DDATA$ + "b";
'PRINT SPC(10); : PRINT
'LOCATE Y%
CALL IO488(DDATA$, GENADDR%, 1) 'Write data to generator
END SUB
FUNCTION GETREADING!
' Inputs: None
' Outputs: None
' Description - configures HP34970A trigger source, sends a trigger
' command, reads the DVM and returns the reading.
DDATA$ = "TRIG:SOUR BUS" 'Trigger source = bus
CALL IO488(DDATA$, DASADDR%, 1)
DDATA$ = "INIT" 'set 'wait-for-trigger' state
CALL IO488(DDATA$, DASADDR%, 1)
DDATA$ = "*TRG" 'send trigger
CALL IO488(DDATA$, DASADDR%, 1)
DDATA$ = "FETC?" 'retrieve reading
CALL IO488(DDATA$, DASADDR%, 1)
CALL IO488(DDATA$, DASADDR%, 2)
GETREADING! = VAL(DDATA$)
END FUNCTION
SUB HP760APANEL (VALUE!, UNITS%)
'Print a display of the HP760A front panel to show number setting.
'Inputs; VALUE! = Value of voltage or current to be set
' UNITS% 1 = Voltage
' 2 = Current
' 3 = None, FUNCTION = STD BY
' 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75
'
DIM DIG%(7) 'Display digits
TOPLOC% = 16
IF UNITS% = 1 THEN
SCALE! = 1 'Max voltage output is 1000V
LEDTAB% = 34
ELSEIF UNITS% = 2 THEN
SCALE! = 100 'Max current output is 10A
LEDTAB% = 14
ELSE
LEDTAB% = 0
END IF
'Set meter for twice max D.U.T. input
'Set only one digit. Setting other digits
'after most significant digit does not
'always increase output signal magnitude.
IF VALUE! * 2 >= 100 THEN
SETVALUE! = CINT(VALUE! * 2 / 100) * 100 * SCALE!
ELSEIF VALUE! * 2 >= 10 THEN
SETVALUE! = CINT(VALUE! * 2 / 10) * 10 * SCALE!
ELSEIF VALUE! * 2 >= 1 THEN
SETVALUE! = CINT(VALUE! * 2) * SCALE!
ELSEIF VALUE! * 2 >= .1 THEN
SETVALUE! = CINT(VALUE! * 2 * 10) / 10 * SCALE!
ELSEIF VALUE! * 2 >= .01 THEN
SETVALUE! = CINT(VALUE! * 2 * 100) / 100 * SCALE!
ELSEIF VALUE! * 2 >= .001 THEN
SETVALUE! = CINT(VALUE! * 2 * 1000) / 1000 * SCALE!
ELSEIF VALUE! * 2 >= .0001 THEN
SETVALUE! = CINT(VALUE! * 2 * 10000) / 10000 * SCALE!
END IF
NUM$ = STR$(SETVALUE!)
FOR L% = 1 TO 7
DIG%(L%) = 0
NEXT
IF SETVALUE! >= 1000 THEN
DIG%(7) = 9
ELSEIF SETVALUE! >= 100 THEN
DIG%(7) = VAL(MID$(NUM$, 2, 1))
ELSEIF SETVALUE! >= 10 THEN
DIG%(6) = VAL(MID$(NUM$, 2, 1))
ELSEIF SETVALUE! >= 1 THEN
DIG%(5) = VAL(MID$(NUM$, 2, 1))
ELSEIF SETVALUE! >= .1 THEN
DIG%(4) = VAL(MID$(NUM$, 3, 1))
ELSEIF SETVALUE! >= .01 THEN
DIG%(3) = VAL(MID$(NUM$, 4, 1))
ELSEIF SETVALUE! >= .001 THEN
DIG%(3) = VAL(MID$(NUM$, 5, 1))
ELSEIF SETVALUE! >= .0001 THEN
DIG%(3) = VAL(MID$(NUM$, 6, 1))
END IF
FOR L% = 1 TO 7
LOCATE TOPLOC%, (L% - 1) * 10 + 7 'top left corner
PRINT CHR$(201)
FOR M% = 8 TO 10 'top horizontal line
LOCATE TOPLOC%, (L% - 1) * 10 + M%
PRINT CHR$(205)
NEXT M%
LOCATE TOPLOC%, (L% - 1) * 10 + 11 'top right corner
PRINT CHR$(187)
FOR N% = TOPLOC% + 1 TO TOPLOC% + 3
LOCATE N%, (L% - 1) * 10 + 7 'left vertical line
PRINT CHR$(186)
IF N% = TOPLOC% + 2 THEN 'print display digit
LOCATE N%, ((L% - 1) * 10 + 8)
PRINT DIG%(8 - L%)
END IF
LOCATE N%, (L% - 1) * 10 + 11 'right vertical line
PRINT CHR$(186)
NEXT N%
LOCATE TOPLOC% + 4, (L% - 1) * 10 + 7 'bottom left corner
PRINT CHR$(200)
FOR M% = 8 TO 10 'bottom horizontal line
LOCATE TOPLOC% + 4, (L% - 1) * 10 + M%
PRINT CHR$(205)
NEXT M%
LOCATE TOPLOC% + 4, (L% - 1) * 10 + 11 'bottom right corner
PRINT CHR$(188)
NEXT L%
IF LEDTAB% <> 0 THEN
LOCATE TOPLOC% + 2, LEDTAB% 'print LED location
PRINT CHR$(15)
END IF
END SUB
SUB HS1
' Module Name - HS1
'
' Inputs - None
' Outputs - None
' Description - HS1 waits for EOI to occur with ATN = 0
' >>>> Check Bit #4 for true (EOI)
BYTE% = 0
WHILE (BYTE% AND 16) = 0
BYTE% = INP(BADDRS% + 0)
WEND
END SUB
SUB HS2
' Module Name - HS2
'
' Inputs - None
' Outputs - None
' Description - HS1 checks that serial poll active state
' has occured with rsv set in the serial poll register.
' >>>>> Check Bit #5 for true (SPAS)
BYTE% = 0
WHILE NOT BYTE% AND 32 AND BYTE% <> 40
BYTE% = INP(BADDRS% + 0)
WEND
END SUB
SUB INIT488 (DEVADDR%)
' Module Name - INIT488
'
' Inputs - None
' Outputs - None
' Description - Initalizes the IEEE 488 interface
OUT (BADDRS% + 8), &H0 'Configure PC4311 as controller
OUT (BADDRS% + 3), &H80 'Release ACDS holdoff, set operation
OUT (BADDRS% + 3), &H0 'Software reset, set operation
OUT (BADDRS% + 4), DEVADDR% 'Enable dual primary addressing mode
OUT (BADDRS% + 0), &H0 'Disable all interrupts
OUT (BADDRS% + 3), &H8F 'Request control, clear operation
OUT (BADDRS% + 3), &HF 'Send remote enable, clear operation
OUT (BADDRS% + 3), &H90 'Listen only, set operation
END SUB
SUB INITPS (DPSADDR%, OVERI!, OVERV!)
'Initialize Kepco power supply
PS$ = POWERIO$(DPSADDR%, "ZER") 'Clear errors if any
PS$ = POWERIO$(DPSADDR%, "SMD=OC") 'Select over-current protection mode
'Set over-current limit
STLEN% = LEN(STR$(OVERI!))
PS$ = POWERIO$(DPSADDR%, SETIMAX$ + RIGHT$(STR$(OVERI!), STLEN% - 1))
STLEN% = LEN(STR$(OVERV!))
PS$ = POWERIO$(DPSADDR%, "SOV=" + RIGHT$(STR$(OVERV!), STLEN% - 1))'Set over-voltage limit
END SUB
SUB IO488 (DDATA$, DEVADDR%, SEL4%)
'***********************************************************************************************
'* *
'* Description: Output and input to GPIB device using PC4311 GPIB card *
'* *
'* Input : DDATA$ -- Data string to GPIB device *
'* DEVADDR% -- Device address desired *
'* SEL4% -- Write (1) or Read (2) command *
'* *
'* Output : DDATA$ -- Data string from GPIB device *
'* *
'***********************************************************************************************
CALL INIT488(DEVADDR%) 'Address GPIB card
SELECT CASE SEL4%
'Write...
CASE 1
BYTE% = MLA% OR DEVADDR% 'GPIB device address
OUT (BADDRS% + 7), BYTE% 'Send out to GPIB card
CALL HS1 'Wait for recieved status
OUT (BADDRS% + 3), &H8A 'Request control, clear operation
OUT (BADDRS% + 3), &HB 'Remote enable, clear
FOR X1 = 1 TO LEN(DDATA$) 'Create character and send out
BYTE% = ASC(MID$(DDATA$, X1, 1))
OUT (BADDRS% + 7), BYTE%
CALL HS1
NEXT
OUT (BADDRS% + 7), &HD 'Send CR, tell device to execute command
CALL HS1 'Wait for recieved status
OUT (BADDRS% + 7), &HA 'Send LF
CALL HS1 'Wait for recieved status
OUT (BADDRS% + 3), &HC 'Remote enable, set operation
OUT (BADDRS% + 3), &HA 'Clear talk only
OUT (BADDRS% + 7), &H3F 'Un-listen
'Read
CASE 2
DDATA$ = ""
BYTE% = MTA% OR DEVADDR% 'GPIB device address
OUT (BADDRS% + 7), BYTE% 'Send out to GPIB card
CALL HS1 'Wait for recieved status
OUT (BADDRS% + 3), &H89 'Request control, clear
OUT (BADDRS% + 3), &HB 'Remote enable, clear
DO
CALL HS2
DATABYTE = INP(BADDRS% + 7)
IF DATABYTE <> &HA THEN
DDATA$ = DDATA$ + CHR$(DATABYTE)
END IF
LOOP WHILE DATABYTE <> &HA
OUT (BADDRS% + 3), &HC 'Remote enable, set command
OUT (BADDRS% + 3), &H9 'Clear listen only
OUT (BADDRS% + 7), &H5F 'Un-talk command
END SELECT
CALL HS1 'Wait for recieved status
END SUB
FUNCTION KEYBDIN$
'Get input from keyboard
DO
X$ = INKEY$
LOOP WHILE X$ = ""
KEYBDIN$ = UCASE$(X$)
END FUNCTION
SUB pause (TIME!)
T1! = TIMER
DO
T2! = TIMER
LOOP UNTIL (T2! - T1!) > TIME!
END SUB
FUNCTION POWERIO$ (DPSADDR%, CMD$)
'This function sends commands and receives output from the
'Kepco DPS 125-0.5M programmable power supply.
'Inputs: power supply address, command
'Outputs: supply response, if any
'Open and initialize the power supply controller communications channel for I/O
PSCOM$ = "COM" + RIGHT$(STR$(PSPORT%), 1) + ":9600,N,8,1"
OPEN PSCOM$ FOR RANDOM AS #1
DEVSEL = DPSADDR% + &HE0
RXOK = DPSADDR% + &HC0
'DEVSEL must be sent without a <CR>
'prior to each command
'Send DEVSEL byte to DPS
PRINT #1, CHR$(DEVSEL);
N = 0
'Await input buffer to become non-zero
'print message if not successful
DO
IF N > 5000 THEN
PRINT "COM ERROR - INPUT BUFFER EMPTY"
CLOSE #1 'close power supply communication channel
END 'exit program
END IF
N = N + 1
LOOP WHILE (LOC(1) = 0)
'RXOK is returned (without a <CR>) in
'response to DEVSEL
A$ = INPUT$(1, #1) 'Input RXOK byte
PRINT #1, CMD$
'Await input buffer to become non-zero
DO
LOOP WHILE (LOC(1) = 0)
A$ = INPUT$(1, #1) 'Input first (non-ASCII) character of
'string and discard
INPUT #1, B$ 'Input balance of string
POWERIO$ = B$
CLOSE #1 'close power supply communication channel
END FUNCTION
FUNCTION READDVM! (CH%, FUNC$, RANGETXT$, RANGENUM!, RESOLTXT$, RESOLNUM!)
' Inputs:
' CH% = channel to be measured
' FUNC$ = parameter to be measured
' RANGETXT$ = indicate how range is specified. 0 = text, 1 = numerically
' If "", range specified in RANGENUM! or not specified
' RANGENUM! = measurement range
' If 0, range specified in RANGETXT$ or not specified
' RESOLTXT$ = indicate how resolution is specified. 0 = text, 1 = numerically
' IF "", resolution specified in RESOLNUM! or not specified
' RESOLNUM! = measurement resolution
' 0 = Resolution specified in RESOLTXT$ or not specified
' Outputs: None
' Description - configures HP34970A to take a measurement, reads
' the DVM and returns the reading.
'
' Reference;
' MEAS and CONF use the following default instrument settings
' Integration Time 1PLC (5 1/2 digits, 20 bits)
' Input Resistane 10Mohm, fixed for all DCV ranges
' AC Filter 20Hz (medium)
' Scan List Redefined when command executed
' Scan Interval Source Immediate
' Scan Count 1 Scan Sweep
' Channel Delay Automatic Delay
'
' DVM Accuracy;
' The following specs use the 3Hz filter
' ACV +/-0.06% reading +/-0.04% range, 10Hz-20KHz, 0.1V - 100V, 1 year
' ACV +/-0.06% reading +/-0.04% range, 10Hz-20KHz, 0.1V - 100V, 1 year
' ACV +/-0.05% reading +/-0.08% range, 10Hz-20KHz, 300V, 90 day
' ACV +/-0.05% reading +/-0.08% range, 10Hz-20KHz, 300V, 90 day
'
' If the 20Hz filter is used, add the following low frequency error
' +/-0.06% reading, 40Hz-100Hz
' +/-0.01% reading, 100Hz-200Hz
' +/-0.0% reading, 200Hz->1000Hz
IF RANGENUM! <> 0 THEN 'Range specified numerically
RG$ = STR$(RANGENUM!) + ","
ELSE 'Range specified w/ text
RG$ = RANGETXT$ + ","
END IF
IF RESOLNUM! <> 0 THEN 'Resolution specified numerically
RES$ = STR$(RESOLNUM!) + ","
ELSE 'Resolution specified w/ text
IF RESOLTXT$ <> "" THEN
RES$ = RESOLTXT$ + ","
ELSE
RES$ = ""
END IF
END IF
DDATA$ = "MEAS:" + FUNC$ + "?" + RG$ + RES$ + "(@" + STR$(CH%) + ")"
'Y% = CSRLIN
'LOCATE 21
'PRINT "READDVM a" + DDATA$ + "b";
'PRINT SPC(10); : PRINT
'LOCATE Y%
CALL IO488(DDATA$, DASADDR%, 1) 'Write configuration
CALL IO488(DDATA$, DASADDR%, 2) 'Read result
READDVM! = VAL(DDATA$)
END FUNCTION
FUNCTION REPEAT$ (MN$, ELAP2!, TIME2!)
CLS
LOCATE 10, 10
PRINT "Do you want to test another set of "; MN$; " modules?"
LOCATE 23, 49
PRINT USING "Test Time: ## Min. ## Sec."; INT(ELAP2! / 60); ELAP2! - INT(ELAP2! / 60) * 60
DO
A$ = INKEY$
LOOP WHILE A$ = ""
IF UCASE$(A$) <> "N" THEN
LOCATE 12, 10
PRINT "Insert the next set of modules, starting with channel 1."
CALL CONTINUE
END IF
TIME2! = TIMER
REPEAT$ = UCASE$(A$)
END FUNCTION
SUB SETDAC3 (DACNUM%, VOLTAGE!)
'Sets the HP34907 DACs
'Both DACs are;
' +/-12V out
' 10mA max
' 1mV resolution
' ground referenced, cannot float
'
'DAC1 is on CH04, DAC2 is on CH05
'Inputs; DACNUM% 1 = DAC1, 2 = DAC2
' VOLTAGE! Voltage to set
SELECT CASE DACNUM%
CASE 1
CH% = DAC1.CH%
CASE 2
CH% = DAC2.CH%
END SELECT
DDATA$ = SETDAC$ + " " + STR$(VOLTAGE!) + ",(@" + STR$(CH%) + ")"
'Y% = CSRLIN
'LOCATE 21
'PRINT "SETDAC3 a" + DDATA$ + "b";
'PRINT SPC(10); : PRINT
'LOCATE Y%
CALL IO488(DDATA$, DASADDR%, 1) 'Write configuration
END SUB
SUB SETDPS (DPSADDR%, VSUPPLY!)
'Set supply voltage
SETP$ = POWERIO$(DPSADDR%, PSVOLT$ + RIGHT$(STR$(VSUPPLY!), LEN(STR$(VSUPPLY!)) - 1))
SETP$ = POWERIO$(DPSADDR%, SUPPLYON$) 'enable power supply output
CALL pause(.02) '20ms over-current prot. delay
IF POWERIO$(DPSADDR%, ISTAT$) = "RCS=01" THEN 'Check for over-current
SOUND 1000, .5
PRINT
PRINT TAB(10); "Module supply current has exceeded maximum value."
PRINT TAB(10); "Power supply has been disabled."
CALL pause(1)
'PRINT TAB(10); "Press any key to continue"
'A$ = KEYBDIN$
END IF
END SUB
SUB SETSWITCH (CH%, STATE%)
' Inputs:
' CH% = channel to be closed
' STATE% = switch state, 1 = CLOSED, 0 = OPEN
' Outputs: None
' Description - sets the specified switch on the HP34903A 20-channel
' actuator
IF STATE% = 1 THEN 'close switch
DDATA$ = "ROUT:CLOS " + "(@" + STR$(CH%) + ")"
ELSE 'String command only
DDATA$ = "ROUT:OPEN " + "(@" + STR$(CH%) + ")"
END IF
'Y% = CSRLIN
'LOCATE 22
'PRINT "SETSWITCH a" + DDATA$ + "b";
'PRINT SPC(10); : PRINT
'LOCATE Y%
CALL IO488(DDATA$, DASADDR%, 1) 'Write configuration
END SUB
FUNCTION UPSN$ (SN$, NUMDUT%)
'SN$ = NNNN-DD
N% = 1
WHILE MID$(SN$, N%, 1) <> "-"
' PRINT MID$(SN$, N%, 1)
SNTEMP$ = SNTEMP$ + MID$(SN$, N%, 1)
N% = N% + 1
WEND
L% = LEN(SN$)
UPSN$ = SNTEMP$ + "-" + LTRIM$(STR$(VAL(MID$(SN$, N% + 1, L% - N%)) + NUMDUT%))
END FUNCTION

View File

@@ -0,0 +1,31 @@
High Input Voltage Units test program directory containing the archived and
release versions of the test and database programs.
Directory structure:
HVDATA: Current version of the high input voltage database file ("hvin.dat") is in this directory, while the archived previous versions are under the "History" subdirectory ("...\HVU\HVDATA\History").
Release: The current released test program source files and executable are in this directory, while the archived previous versions are under the "History" subdirectory ("...\HVU\Release\History").
DBpgm: The current released high input voltage database modification program source files and executable are in this directory, while the archived previous versions are under the "History" subdirectory ("...\HVU\DBpgm\History").
NOTE: The ongoing structure and naming convention for the archived ("history") files should include ALL of the source files (including the ".MAK" file) and the executable file for that version of the program, which should be located in a folder named for the date of release in this format: "year-month-date" with a four-digit year, two digit month (leading zero if required), and a two-digit date (leading zero if required). For example, "2014-07-31" for July 31, 2014. Maintaining this format will lead to consistent sorting when attempting to locate versions in the future. This folder should be created under the appropriate "History" subfolder (under "...\HVU\DBpgm\History" for database programs, ...\HVU\Release\History" for test programs, or "...\HVU\HVDATA\History" for database files.
FURTHER NOTE: Previously archived test and/or database programs do not necessarily follow the structure described above, and are all located under the "...\HVU\Released\History\_Old (Pre 2014-07-31)" folder.
Program release instructions:
-----------------------------
The updated test program executable (.EXE) file is copied to:
"T:\ENGR\ATE\ProdSW\ATE"
Then the batch file "TtoK.bat" is run (double-click on the file name in Window Explorer) in folder:
"T:\ENGR\ATE\ProdSW\ATE Software Transfer Programs"
Database release instructions:
-----------------------------
The updated test database (.DAT) file is copied to:
"T:\ENGR\ATE\ProdSW\ATE\HVDATA"
Then the batch file "TtoK.bat" is run (double-click on the file name in Window Explorer) in folder:
"T:\ENGR\ATE\ProdSW\ATE Software Transfer Programs"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
TESTHV3.BAS
TESTHV4.BAS
NLIBATE3.BAS

File diff suppressed because it is too large Load Diff