 2009 Fluke Corporation, All rights reserved               MET/CAL Procedure
=============================================================================
INSTRUMENT:            Sub Initialize /DMM Chs
INSTRUMENT:            Sub Reset /DMM Chs
INSTRUMENT:            Sub Measure /DMM Chs
INSTRUMENT:            Sub Setup /DMM Chs
INSTRUMENT:            Sub Read /DMM Chs
INSTRUMENT:            Sub Get Accuracy /DMM Chs
DATE:                  2009-12-29 08:59:00
AUTHOR:                Fluke
REVISION:              $Revision: 24551 $
ADJUSTMENT THRESHOLD:  70%
NUMBER OF TESTS:       4
NUMBER OF LINES:       414
CONFIGURATION:         Digital Multimeter
=============================================================================
#
#  Procedure Author:
#        DAC , DFM, ZY
#
#  Compatibility:
#        MET/CAL 7.2 or later
#
#  Subprocedures:
#        None
#
#  Required Files:
#        user_config_instr.ini
#
#  This procedure is intended for use with MET/CAL calibration software;
#  the terms and conditions set forth in your MET/CAL license apply to this
#  procedure.
#
#  Due to Fluke's policy of continuously updating our products, this procedure
#  may contain minor differences in methods used and/or specifications to
#  those found in the manual or other documentation. While every effort has
#  been made to ensure that this procedure is accurate, Fluke cannot be held
#  responsible for the consequences of error or omissions found within this
#  procedure.
#
#  The copyright in this procedure is owned by Fluke Corporation.
#
#    Initialize DMM parameters
#
#  Parameters       Values
#  ---------------  ---------------------------------------------------------
#  @DMM_Func        DC_Voltage | AC_Voltage | Resistance2W | Resistance4W
#                   DC_Current | AC_Current |
#                   HighDC_Current | HighAC_Current
#                   Frequency | Period
#
#  @DMM_Meas        This parameter is used for accuracy lookup and must
#                   contain the DMM reading prior to calling
#                     "Sub Get Accuracy /DMM Chs"
#
#  @DMM_Ampl        For frequency and period measurements, this parameter
#                   must contain the amplitude prior to calling
#                     "Sub Get Accuracy /DMM Chs"
#
#  @DMM_Freq        For AC amplitude measurements, this parameter must contain
#                   the frequency prior to calling
#                     "Sub Get Accuracy /DMM Chs"
#
#  @DMM_Guard       Int | Ext
#
#  @DMM_dB_Ref      <NR3>[][<prefix>]Ohm
#
#  Terminals        @DMM_InputHi, DMM_InputLo, DMM_SenseHi, DMM_SenseLo
#                   @DMM_CurrentHi, @DMM_CurrentLo,
#                   @DMM_HighCurrentHi, @DMM_HighCurrentLo,
#                   @DMM_GrdTerm, @DMM_OhmGrdTerm
#
#  Example Usage:
#
#      CALL         Sub Initialize /DMM Chs
#
#      IF           EMPTY(@DMM_OhmGrdTerm)
#      MATH         @DMM_OhmGrdTerm = @DMM_GrdTerm
#      ENDIF
#
#      CALL         Sub Reset /DMM Chs
#      DISP         £
#      DISP         [32]             [V @DMM_DevName]
#      DISP         [32] V/Ohm/Diode ----> [V @DMM_InputHi]
#      DISP         [32] COMMON ---------> [V @DMM_InputLo]
#      DISP         [32] V/Ohm/Diode ----> [V @DMM_SenseHi]
#      DISP         [32] COMMON ---------> [V @DMM_SenseLo]
#      DISP         [32] GUARD ----------> [V @DMM_OhmGrdTerm]
#      DISP
#      DISP         senseߵ!
#      MATH         @DMM_Func = "Resistance4W"; @DMM_Guard = "Int"
#      CALL         Sub Measure /DMM Chs
#      MATH         @DMM_Meas = MEM
#      CALL         Sub Get Accuracy /DMM Chs
#      MATH         L[1] = @DMM_Acc
#      ACC    100   Z              L1U
#      MEMC         100.0Z         1%
#
#      MATH         @DMM_Func = "AC_Voltage"; @DMM_Freq = 1E+3
#      MATH         @DMM_Guard = "Ext"
#      TARGET       -p
#      CALL         Sub Setup /DMM Chs
#      TARGET       -m
#      CALL         Sub Read /DMM Chs
#      MATH         @DMM_Meas = MEM;
#      CALL         Sub Get Accuracy /DMM Chs
#      MATH         L[1] = @DMM_Acc
#      ACC    100   V              L1U
#      MEMC         100.0V         1%            1kH
#
#      MATH         @DMM_Func = "Frequency"; @DMM_Ampl = 1
#      TARGET       -p
#      CALL         Sub Setup /DMM Chs
#      TARGET       -m
#      CALL         Sub Read /DMM Chs
#      MATH         @DMM_Meas = MEM; MEM = MEM / 1E+3
#      CALL         Sub Get Accuracy /DMM Chs
#      MATH         L[1] = @DMM_Acc / 1E+3
#      ACC    1     kH              L1U
#      MEMC         1.000kH         1%            1V
#
 STEP    FSC    RANGE NOMINAL        TOLERANCE     MOD1        MOD2  3  4 CON

  1.001  JMPL         INITIALIZE                   PSUBI("Initialize")
  1.002  JMPL         RESET                        PSUBI("Reset")
  1.003  JMPL         SETUP                        PSUBI("Measure")
  1.004  JMPL         SETUP                        PSUBI("Setup")
  1.005  JMPL         READ                         PSUBI("Read")
  1.006  JMPL         GET_ACCURACY                 PSUBI("Get Accuracy")
  1.007  DISP         ӳûз!
  1.008  END

  1.009  EVAL   Increment test number

# =============================== Initialize =================================

  2.001  LABEL        INITIALIZE
# Get and store device name.
  2.002  MATH         @DMM_DevName = INSTR("DMM")

# Get and store programming section name.
  2.003  MATH         @DMM_ProgSecName = RINFE(@DMM_DevName, "ProgSecName")

# Get and store FSC.
  2.004  MATH         @DMM_FSC = RINFE(@DMM_ProgSecName, "FSC")

# Get and store terminal names.
  2.005  MATH         @DMM_InputHi = RINFE(@DMM_ProgSecName, "InputHi")
  2.006  MATH         @DMM_InputLo = RINFE(@DMM_ProgSecName, "InputLo")

# 4-wire sense terminals are optional.
  2.007  MATH         @DMM_SenseHi = RINF(@DMM_ProgSecName, "SenseHi")

  2.008  IF           NOT(EMPTY(@DMM_SenseHi))
  2.009  MATH         @DMM_SenseLo = RINFE(@DMM_ProgSecName, "SenseLo")
  2.010  ENDIF

# If no current Hi terminal is specified, use Input Hi.
  2.011  MATH         @DMM_CurrentHi = RINF(@DMM_ProgSecName, "CurrentHi")

  2.012  IF           EMPTY(@DMM_CurrentHi)
  2.013  MATH         @DMM_CurrentHi = @DMM_InputHi
  2.014  ENDIF

# If no low current Lo terminal is specified, use Input Lo.
  2.015  MATH         @DMM_CurrentLo = RINF(@DMM_ProgSecName, "CurrentLo")

  2.016  IF           EMPTY(@DMM_CurrentLo)
  2.017  MATH         @DMM_CurrentLo =@DMM_InputLo
  2.018  ENDIF

# If no high current Hi terminal is specified, use Current Hi.
  2.019  MATH         HighCurrentHi = RINF(@DMM_ProgSecName, "HighCurrentHi")

  2.020  IF           EMPTY(HighCurrentHi)
  2.021  MATH         @DMM_HighCurrentHi = @DMM_CurrentHi
  2.022  ELSE
  2.023  MATH         @DMM_HighCurrentHi = HighCurrentHi
  2.024  ENDIF

# If no high current Lo terminal is specified, use Current Lo.
  2.025  MATH         HighCurrentLo = RINF(@DMM_ProgSecName, "HighCurrentLo")

  2.026  IF           EMPTY(HighCurrentLo)
  2.027  MATH         @DMM_HighCurrentLo = @DMM_CurrentLo
  2.028  ELSE
  2.029  MATH         @DMM_HighCurrentLo = HighCurrentLo
  2.030  ENDIF

  2.031  MATH         @DMM_GrdTerm    = RINF(@DMM_ProgSecName, "Guard")
  2.032  MATH         @DMM_OhmGrdTerm = RINF(@DMM_ProgSecName, "OhmGuard")

# Initialize parameters to the empty string (unset).
  2.033  MATH         @DMM_Func   = ""
  2.034  MATH         @DMM_dB_Ref = ""
  2.035  MATH         @DMM_Guard = ""

# Unset flag to trigger operator message to manually select guard, on DMMs
# with manual guard switch.
  2.036  MATH         @DMM_GuardSet = 0

# Get programming string for RESET FSC.
  2.037  MATH         ResetCmd = RINF(@DMM_ProgSecName, "RESET_FSC")

# If RESET_FSC is defined, establish the RESET FSC.
  2.038  IF           NOT(EMPTY(ResetCmd))

  2.039  IF           ZCMPI(ResetCmd, "[SDC]")
  2.040  RESET        [@DMM][SDC]
  2.041  ELSE
  2.042  RESET        [@DMM][V ResetCmd]
  2.043  ENDIF

  2.044  ENDIF

# See if input termination other than EOI is specified.
  2.045  MATH         InputTerm = RINF(@DMM_ProgSecName, "TERM")

# See CR or LF termination was specified...
  2.046  IF           ZCMPI(InputTerm, "CR")
  2.047  IEEE         [@DMM][TERM CR]
  2.048  ELSEIF       ZCMPI(InputTerm, "LF")
  2.049  IEEE         [@DMM][TERM LF]
  2.050  ENDIF

  2.051  END

# ================================= Reset ====================================

  2.052  LABEL        RESET
  2.053  MATH         @DMM_Cmd = RINF(@DMM_ProgSecName, "Reset")
  2.054  CALL         Sub Send Command /DMM
  2.055  END

  2.056  EVAL   Increment test number

# ============================== Setup or Measure ============================

  3.001  LABEL        SETUP

# -----  Function

  3.002  MATH         @DMM_Cmd = RINFE(@DMM_ProgSecName, @DMM_Func)
  3.003  CALL         Sub Send Command /DMM

# -----  dB Reference
  3.004  IF           NOT(EMPTY(@DMM_dB_Ref))
  3.005  MATH         dB_Ref = BASE(@DMM_dB_Ref)

# If there is a discrete command for 50, 75, 300, or 600 Ohms, use it.
# Otherwise the dB reference must be dynamically set.
  3.006  IF           dB_Ref == 50
  3.007  MATH         @DMM_Cmd = RINF(@DMM_ProgSecName, "dB_Ref50_Ohm")
  3.008  ELSEIF       dB_Ref == 75
  3.009  MATH         @DMM_Cmd = RINF(@DMM_ProgSecName, "dB_Ref75_Ohm")
  3.010  ELSEIF       dB_Ref == 300
  3.011  MATH         @DMM_Cmd = RINF(@DMM_ProgSecName, "dB_Ref300_Ohm")
  3.012  ELSEIF       dB_Ref == 600
  3.013  MATH         @DMM_Cmd = RINF(@DMM_ProgSecName, "dB_Ref600_Ohm")
  3.014  ENDIF

  3.015  IF           ZCMP(@DMM_Cmd, "")
  3.016  MATH         @DMM_Cmd = RINFE(@DMM_ProgSecName, "dB_Ref")
  3.017  MATH         @DMM_Cmd = REPL("<val>", dB_Ref, @DMM_Cmd)
  3.018  ENDIF

  3.019  CALL         Sub Send Command /DMM
  3.020  ENDIF        ; IF dB Reference

# -----  Guard

  3.021  IF           NOT(EMPTY(@DMM_Guard))

  3.022  IF           ZCMPI(@DMM_Guard, "Int")
  3.023  MATH         Guard = "GuardInt"
  3.024  ELSE
  3.025  MATH         Guard = "GuardExt"
  3.026  ENDIF

  3.027  MATH         GuardSelect = RINF(@DMM_ProgSecName, "GuardSelect")

  3.028  IF           ZCMPI(GuardSelect, "Manual")

  3.029  IF           NOT(@DMM_GuardSet)
  3.030  MATH         Switch = RINFE(@DMM_ProgSecName, "GuardSwitch")
  3.031  MATH         Setting = RINFE(@DMM_ProgSecName, Guard)
  3.032  DISP         [V @DMM_DevName] [V Switch]ص[V Setting].
  3.033  MATH         @DMM_GuardSet = 1
  3.034  ENDIF        ; Prompt to set Reference Oscillator switch

  3.035  ELSEIF       ZCMPI(GuardSelect, "Auto")
#                     Automatice selection.  Nothing to do.
  3.036  ELSE
  3.037  MATH         @DMM_Cmd = RINFE(@DMM_ProgSecName, Guard)
  3.038  CALL         Sub Send Command /DMM
  3.039  ENDIF

  3.040  ENDIF        ; IF Guard

# Exit here if Setup.
  3.041  IF           PSUBI("Setup")
  3.042  END
  3.043  ENDIF

# Drop through for Measure.

# ============================== Read or Measure ============================

  3.044  LABEL        READ
# See if there is an initiate command.
  3.045  MATH         @DMM_Cmd = RINF(@DMM_ProgSecName, "Initiate")

# If there is an initiate command, send it.
  3.046  IF           NOT(EMPTY(@DMM_Cmd))
  3.047  CALL         Sub Send Command /DMM
  3.048  ENDIF

# If there is a frequency specific fetch command, use it.
  3.049  IF           ZCMPI(@DMM_Func, "Frequency")
  3.050  MATH         @DMM_Cmd = RINF(@DMM_ProgSecName, "FetchFreq")
# If there is a frequency specific fetch command, use it.
  3.051  ELSEIF       ZCMPI(@DMM_Func, "Period")
  3.052  MATH         @DMM_Cmd = RINF(@DMM_ProgSecName, "FetchPer")
  3.053  ELSE
  3.054  MATH         @DMM_Cmd = ""
  3.055  ENDIF

# Otherwise see if there is a general fetch command.
  3.056  IF           EMPTY(@DMM_Cmd)
  3.057  MATH         @DMM_Cmd = RINF(@DMM_ProgSecName, "Fetch")
  3.058  ENDIF

# If there is no fetch command simply get the reading.
  3.059  IF           EMPTY(@DMM_Cmd)
  3.060  IEEE         [@DMM][I]
# Otherwise send the fetch command and get the reading.
  3.061  ELSEIF       ZCMPI(@DMM_FSC, "SCPI")
  3.062  SCPI         [@DMM][V @DMM_Cmd][I]
  3.063  ELSEIF       ZCMPI(@DMM_FSC, "IEEE2")
  3.064  IEEE2        [@DMM][V @DMM_Cmd][I]
  3.065  ELSE
  3.066  IEEE         [@DMM][V @DMM_Cmd][I]
  3.067  ENDIF

# Inform MET/CAL that the measurement is the System Actual.
  3.068  TSET         MEAS = SA
  3.069  MATH         @DMM_Meas = MEM
  3.070  END

  3.071  EVAL   Increment Step Number

#======= Sub Get Accuracy /DMM Chs==================================

  4.001  LABEL        GET_ACCURACY
  4.002  MATH         FreqAccToPerAcc = 0

# Get DMM mode string from ini file for accuracy lookup.
  4.003  IF           ZCMPI(@DMM_Func, "DC_Voltage")
  4.004  MATH         ModeStr = RINFE(@DMM_DevName, "ModeStringVDC")
# Set accuracy modifier (frequency) lookup switch to off.
  4.005  MATH         AC = 0
  4.006  ELSEIF       ZCMPI(@DMM_Func, "AC_Voltage")
  4.007  MATH         ModeStr = RINFE(@DMM_DevName, "ModeStringVAC")
  4.008  MATH         AC = 1; Modifier = @DMM_Freq
  4.009  ELSEIF       ZCMPI(@DMM_Func, "Resistance2W")
  4.010  MATH         ModeStr = RINFE(@DMM_DevName, "ModeStringRes2W")
  4.011  MATH         AC = 0
  4.012  ELSEIF       ZCMPI(@DMM_Func, "Resistance4W")
  4.013  MATH         ModeStr = RINFE(@DMM_DevName, "ModeStringRes4W")
  4.014  MATH         AC = 0
  4.015  ELSEIF       ZCMPI(@DMM_Func, "DC_Current")
  4.016  MATH         ModeStr = RINFE(@DMM_DevName, "ModeStringADC")
  4.017  MATH         AC = 0
  4.018  ELSEIF       ZCMPI(@DMM_Func, "AC_Current")
  4.019  MATH         ModeStr = RINFE(@DMM_DevName, "ModeStringAAC")
  4.020  MATH         AC = 1; Modifier = @DMM_Freq
  4.021  ELSEIF       ZCMPI(@DMM_Func, "HighDC_Current")
  4.022  MATH         ModeStr = RINFE(@DMM_DevName, "ModeStringADC")
  4.023  MATH         AC = 0
  4.024  ELSEIF       ZCMPI(@DMM_Func, "HighAC_Current")
  4.025  MATH         ModeStr = RINFE(@DMM_DevName, "ModeStringAAC")
  4.026  MATH         AC = 1; Modifier = @DMM_Freq
  4.027  ELSEIF       ZCMPI(@DMM_Func, "Frequency")
  4.028  MATH         ModeStr = RINFE(@DMM_DevName, "ModeStringFreq")
  4.029  MATH         AC = 1; Modifier = @DMM_Ampl
  4.030  ELSEIF       ZCMPI(@DMM_Func, "Period")
  4.031  MATH         ModeStr = RINF(@DMM_DevName, "ModeStringPer")

# If there is no "ModeStringPer" entry, lookup "ModeStringFreq".
  4.032  IF           EMPTY(ModeStr)
  4.033  MATH         ModeStr = RINFE(@DMM_DevName, "ModeStringFreq")
  4.034  MATH         FreqAccToPerAcc = 1
  4.035  ENDIF

  4.036  MATH         AC = 1; Modifier = @DMM_Ampl
  4.037  ENDIF

  4.038  MATH         Device = @DMM_DevName

  4.039  IF           FreqAccToPerAcc
  4.040  MATH         Freq = 1 / @DMM_Meas
  4.041  MATH         Freq_Acc = ACCV2(Device, ModeStr, Freq, Modifier)
  4.042  MATH         @DMM_Acc = (Freq_Acc / Freq) * @DMM_Meas
  4.043  ELSEIF       AC
  4.044  MATH         @DMM_Acc = ACCV2(Device, ModeStr, @DMM_Meas, Modifier)
  4.045  ELSE
  4.046  MATH         @DMM_Acc = ACCV(Device, ModeStr, @DMM_Meas)
  4.047  ENDIF

  4.048  END
