﻿; Testcontroller configuration file for Fluke 8840A Digital Multimeters
; Version 1.0
; Date 01-11-2023
; Written by Gertjan Miedema,  info at miedemageluid dot nl,  Username "Gertjan" at EEVblog.
; Menu structure inspired on HP 34401A menu by WA


; For use with TestController, software to control and log data: https://lygte-info.dk/project/TestControllerIntro%20UK.html
; For use with a Prologix GPIB interface, or clone. (AR488!)
; Tested with AR488 and official Prologix GPIB to USB adapters.


; Some tips:
;
; - Default 8840A GPIB address is 4 (rear panel dipswitch setting: 000100, = only A3 up).
;
; - Whenever the 8840A is in the local state, the GPIB address can be displayed on the front panel by pressing the LOCAL button.
;
; - Early models of the 8840A did not have a GPIB command for identification.
;   So, to be compatible with the early versions, by default this definition does NOT verify the model number.
;
;   But for later versions (ca post 1990) you can enable model identification by removing the semicolon
;   at the start of this line: "; #verifyDevice "8840A" model?"
;
;   You can test if you have a later version by typing on the TC command line: "model?". The correct answer should be : "8840A".
;   An earlier 8840A without model identification command will give no answer, and show a "71" error on its display.
;
;   Detailed info on GPIB board versions in this post:
;   https://www.eevblog.com/forum/testgear/fluke-8840aaf-gpib-board/msg4146250/#msg4146250
;
;
; - There are three Trigger modes to choose from:
;    T0 Int: Internal trigger mode, continuous trigger generated by 8840A
;    T2 Ext: External trigger mode, GPIB buss triggered, Settling Delay is ON  (default, most accurate)
;    T4 Ext: External trigger mode, GPIB buss triggered, Settling Delay is OFF (faster, but more reading error)
;
;
; - The Menu has a Display ON/OFF setting because in FAST reading rate, the measurements are more accurate with display OFF.
;
; - It is best to use Manual ranging during logging, to avoid glitches caused by the auto range switching.
;
; - If you are not using an AR488 with Chinese Nano clone, remark-out the line "#resetDelay 3.5", for a faster start of TC.


; Known issues:
;
; - There is a bug in the GPIB implementation that HKJ has not fixed yet: It can only handle one device for each GPIB controller.




#idString Fluke,8840A
#name Fluke 8840A
#handle FL8840A

#port GPIB
#driver Ascii
#interfaceType BMM

; Start up delay, only needed for AR488 with slow booting Chinese Nano clones
#resetDelay 3.5

; The author statement is used for the listing in the About window.
#author Gertjan Miedema



#notes  Device configuration file for Fluke 8840A DMM.


- Default 8840A GPIB address is 4 (rear panel dip switch setting: 000100, = only A3 up).

- Whenever the 8840A is in the local state, the GPIB address can be displayed on the front panel by pressing the LOCAL button.

- By default this definition does NOT verify the model number. (Early 8840A's do not have an ID command)
  But for later versions (ca post 1990) you can enable model identification by removing the semicolon at the start of this line: "; #verifyDevice "8840A" model?"

- For more info, tips and known issues, look in the header of this configuration file (Fluke8840A.txt)


Configuration file version: 1.0






;---------  GPIB settings  -------------
; Used to change the standard LF end of line to CR or CRLF.
; For eol a string is used, to write control character escapes must be used, use: /r for CR and /r/n for CRLF
#eol eoi

; The #gpibReadEol defines how the device terminates its answers, the default uses eoi. 
; Specifying "#gpibReadEol 10" would expect a LF character for terminating a answer.(13 = CR, 10 = LF)
; #gpibReadEol eoi

; Add a small delay after each GPIB write, this can slow down the processing for old slow devices. (in ms)
; #gpibWriteDelay 10

; Minimum time before trying to read a answer from a device in ms
; #gpibWriteReadDelay 10

; ++read_tmo_ms is controlled with #readingDelay
; This specifies the timeout value, in SECONDS, that is used by the ++read command to wait for a character
; to be transmitted while reading data from the GPIB bus. The timeout value may be set between 0 and 32 seconds.
#readingDelay 2




; ================= Original 8840A commands to SCPI/TestController commands translations  ======================

; There must be a line for each of the original device commands that will be used, converting it to a similar SCPI command


; command to init
; REN     Remote ENable
; *       Reset, Set the multimeter to the power-on state: F1, R0, S0, T0, D0, B0, Y0, W0.
; W0      Terminator commands select what terminator 8840A appends to every output string. W0 = CR,LF + EOI
; [CLR]   Do a "Selected Device Clear" function.
; [1000]  1000msec pause
; T2      Trigger External over GPIB, with settling delay
#scpiCmd init tx T2

; Command to go remote
#scpiCmd goRemote tx REN


; Command to initialize and set variables
#scpiCmd setVars none
:setvar: displayVar=0



; Final commands to counter before breaking connection, used to restore local control
; *        Reset, Set the multimeter to the power-on state: F1, R0, S0, T0, D0, B0, Y0, W0.
; [CLR]    Do a "Selected Device Clear" function.
; [LOC]    Go to Local, Set device in local control mode, i.e. the user interface on the device is active. 

#scpiCmd reset tx F1,R0,S0,T0,D0,B0,Y0,W0
#scpiCmd goLocal tx [LOC]
#scpiCmd clear tx [CLR]






; -----  Instrument identification    -----

; NOTE: On early 8840A's (pre 1990?) the G8 command is not implemented.
; G8    Get Instrument Identification. Answer: "FLUKE, 8840A, 0, V4.0" (V4.0 is GPIB interface version)

; Recall the model number
#scpiCmd model? txrx? G8?
:string: 
:readmath: trim(getElement(value,1,"[,]"));



; Use these commands to get a full id line and prevent connection to other devices
; #scpiCmd getDeviceSW? txrx? G8?
; :string: 
; :readmath: trim(getElement(value,3,"[,]"));




; ===========  Mode selection  ===========

; G0 Get instrument configuration. Answer: FRST F=function, R=range, S=reading rate, T=triggermode
;    F=1  VDC (default)
;    F=2  VAC
;    F=3  2-wire kOhm
;    F=4  4-wire kOhm
;    F=5  mA DC
;    F=6  mA AC

; Recall Measurement Function
#scpiCmd askMode? txrx? G0
:readmath: substring(value,0,1);

; Set Measurement function: Volt DC
#scpiCmd voltDC tx F1

; Set Measurement function: Volt AC
#scpiCmd voltAC tx F2

; Set Measurement function: Ohm 2-wire
#scpiCmd ohm2W tx F3

; Set Measurement function: Ohm 4-wire
#scpiCmd ohm4W tx F4

; Set Measurement function: DC Current
#scpiCmd currentDC tx F5

; Set Measurement function: AC Current
#scpiCmd currentAC tx F6



; ==========  Ranging  ===========

; -----  Auto Range  -----
; G5 Get IAB status. Answer: 1abc
;    a=0: FRONT inputs, a=1: REAR inputs
;    b=0: Auto ranging is ON, b=1: Auto ranging is OFF
;    c=0: Offset feature is OFF, c=1: Offset is feature ON

; Set  Auto Ranging
#scpiCmd autoRange tx R (value)

; Query Auto Ranging
#scpiCmd autoRange? txrx? G5
:readmath: (substring(value,2,3))*7;


; -----  Set Manual Range  -----

; Set Range commands:
;  R0 Auto range On (Default)
;  R1 200 mV, 200R
;  R2 2V, 2k
;  R3 20V, 20k
;  R4 200V, 200k
;  R5 1000Vdc, 700Vac, 2 M, 2000mA
;  R6 20 MR
;  R7 Auto range Off

; G0 Get instrument configuration. Answer: FRST F=function, R=range, S=reading rate, T=trigger mode
;    R=0 Auto range On (Default)
;    R=1 200 mV, 200R
;    R=2 2V, 2k
;    R=3 20V, 20k
;    R=4 200V, 200k
;    R=5 1000Vdc, 700Vac, 2M, 2000mA
;    R=6 20M
;    R=7 Auto range Off

; Set  Manual Range
#scpiCmd range tx R (value)

; Query Manual Range
#scpiCmd range? txrx? G0
:readmath: substring(value,1,2);




; -----  Data read out  -----

; command to read current value or values.
#scpiCmd read? txrx? ?



; ==========  Control  ==========


; -----  Reading Rate  ------

; Set Reading Rate
;  S0 Slow (Default)
;  S1 Medium
;  S2 Fast
#scpiCmd rate tx S (value)

; Recall Reading Rate
; G0 Get instrument configuration. Answer: FRST F=function, R=range, S=reading rate, T=triggermode
;    S=0 Slow (Default)
;    S=1 Medium
;    S=2 Fast
#scpiCmd rate? txrx? G0
:readmath: substring(value,2,3);


; -----  Offset commands  ------

; Set  Set Offset ON/OFF
; B0  Offset Off (Default)
; B1  Offset On
#scpiCmd offset tx B (value)

; Recall Offset status
; G5 Get IAB status. Answer: 1abc
;    c=0: Offset feature is OFF, c=1: Offset is feature ON
#scpiCmd offset? txrx? G5
:readmath: substring(value,3,4);



; -----  Trigger commands  ------

; COMMAND      TRIGGER   REAR PANEL  SETTLING
;              MODE      TRIGGER     DELAY
; T0 (Default) Internal  Disabled    auto    Internal trigger mode, continuous trigger generated by 8840A
; T1           External  Enabled     On 
; T2           External  Disabled    On      External trigger mode, GPIB buss triggered, Settling Delay is ON 
; T3           External  Enabled     Off
; T4           External  Disabled    Off     External trigger mode,GPIB buss triggered, Settling Delay is OFF

; Set Trigger mode
#scpiCmd trigger tx T (value)


; G0 Get instrument configuration. Answer: FRST F=function, R=range, S=reading rate, T=triggermode
;    T=0...4 Get Trigger mode

; Recall Trigger mode
#scpiCmd trigger? txrx? G0
:readmath: substring(value,3,4);


; -----  Display mode  ------

; D0  Normal Display (Default)
; D1  Blank Display

#scpiCmd display tx D (value)
:setvar: displayVar=inputValue;

; Recall Display mode
#scpiCmd display? none?
:readmath: displayVar



; =================================  End command conversion 8840A -> SCPI/TestController  ===========================





; ----------------------- Data read out  ------------------

; A list of possible column name with unit and formatter (SI, Time, Int, D0..D6)
; code: #value name unit format {selector}

#value Volt_DC VDC SI 1
#value Volt_AC VAC SI 2
#value Ohm_2W Ohm SI 3
#value Ohm_4W OhmF SI 4
#value Amp_DC ADC SI 5
#value Amp_AC AAC SI 6



; This is a single line command
#askValues read?



#askMode askMode?

#modeChangeDelay 0.5






; ------------------  Initial commands & Final command  --------------

; NOTE: For later 8840A versions (ca post 1990) you can enable model identification by removing the semicolon
; at the start of this line below: "; #verifyDevice "8840A" model?"
; You can test if you have a later version by typing on the TC command line: "model?". The correct answer should be : "8840A"
; (An earlier 8840A will give no answer, and show a "71" error on it's display)

; Command to get a full id line and prevent connection to other devices
; #verifyDevice "8840A" model?


; Initial commands to meter when establishing connection
; [LLO] Set device in remote control mode, i.e. the user interface on the device is disabled.
#initCmd [LLO];clear;reset;[500];init;setVars;


; Final command to meter before breaking connection
#finalCmd clear;reset;[500];goLocal;[1000];




; ========================== MENU'S  ================================


; ==========  Mode (Function) menu  ==========

; code: #cmdMode modeLabel deviceModeString SCPI commands

#cmdMode Volt_DC Volt_DC
voltDC;

#cmdMode Volt_AC Volt_AC
voltAC;

#cmdMode Ohm_2W Ohm_2W
ohm2W;

#cmdMode Ohm_4W Ohm_4W
ohm4W;

#cmdMode Current_DC Amp_DC
currentDC;

#cmdMode Current_AC Amp_AC
currentAC;



; ========== Setup menu  ===========

#cmdSetup info Active_Mode
:read: askMode?
:readmath: getElement("?;Volts DC;Volts AC;Ohm 2W;Ohm 4W;Current DC;Current AC", value)
:updatemodechange:


; ----- DC Volt  -----
#cmdSetup radio Range_Auto VDC
:read: autoRange?
:write: autoRange #;[500];
:updatedelayed: 0.5
:update: Range VDC
Auto 0
Manual 7
:updatemodechange:

#cmdSetup radio Range VDC
:read: range?
:write: range #;[500];
:updatedelayed: 0.5
:update: Range_Auto VDC
200mV 1
2V 2
20V 3
200V 4
1000V 5
:updatemodechange:


#cmdSetup separator Range VDC
2 100 Raised


#cmdSetup radio Reading_Rate VDC
:read: rate?
:write: rate #;[500];
:updatedelayed: 0.5
:tip: <html>Slow: maximum resolution, and optimum noise rejection<br>Fast: less resolution and noise reduction, but highest measurement speed
Slow 0
Medium 1
Fast 2
:updatemodechange:


#cmdSetup buttonsOn Offset VDC
:read: offset?
; Take a reading first, then store the reading as an offset
:write: read?;offset #;[500];
:updatedelayed: 0.5
:tip: <html>Store a reading as an Offset<br>which is subtracted from subsequent readings
Off 0
On 1
:updatemodechange:


#cmdSetup radio Trigger_mode VDC
:read: trigger?
:write: trigger #;[500];
:updatedelayed: 0.5
:tip: <html>Trigger modes: T0 int: internal, continuous trigger mode. T2 Ext: external, GPIB buss triggered WITH Settling Delay<br>T4 Ext: GPIB buss triggered, but WITHOUT Settling Delay (faster, but more error)
T0_Int 0
T2_Ext 2
T4_Ext 4
:updatemodechange:


#cmdSetup radio Display_mode VDC
:read: display?
:write: display #;[500];
:updatedelayed: 0.5
:tip: In fast reading, the 8840A display must be blanked to ensure best accuracy
Normal 0
Blank 1
:updatemodechange:




; ----- AC Volt  -----
#cmdSetup radio Range_Auto VAC
:read: autoRange?
:write: autoRange #;[500]
:updatedelayed: 0.5
:update: Range VAC
Auto 0
Manual 7
:updatemodechange:

#cmdSetup radio Range VAC
:read: range?
:write: range #;[500]
:updatedelayed: 0.5
:update: Range_Auto VAC
200mV 1
2V 2
20V 3
200V 4
700V 5
:updatemodechange:


#cmdSetup separator Range VAC
2 100 Raised


#cmdSetup radio Reading_Rate VAC
:read: rate?
:write: rate #;[500]
:updatedelayed: 0.5
:tip: <html>Slow: maximum resolution, and optimum noise rejection<br>Fast: less resolution and noise reduction, but highest measurement speed
Slow 0
Medium 1
Fast 2
:updatemodechange:


#cmdSetup buttonsOn Offset VAC
:read: offset?
; Take a reading first, then store the reading as an offset
:write: read?;offset #;[500];
:updatedelayed: 0.5
:tip: <html>Store a reading as an Offset<br>which is subtracted from subsequent readings
Off 0
On 1
:updatemodechange:


#cmdSetup radio Trigger_mode VAC
:read: trigger?
:write: trigger #;[500]
:updatedelayed: 0.5
:tip: <html>Trigger modes: T0 int: internal, continuous trigger mode. T2 Ext: external, GPIB buss triggered WITH Settling Delay<br>T4 Ext: GPIB buss triggered, but WITHOUT Settling Delay (faster, but more error)
T0_Int 0
T2_Ext 2
T4_Ext 4
:updatemodechange:


#cmdSetup radio Display_mode VAC
:read: display?
:write: display #;[500];
:updatedelayed: 0.5
:tip: In fast reading, the 8840A display must be blanked to ensure best accuracy
Normal 0
Blank 1
:updatemodechange:



; ----- Ohm 2W  -----
#cmdSetup radio Range_Auto Ohm
:read: autoRange?
:write: autoRange #;[500]
:updatedelayed: 0.5
:update: Range Ohm
Auto 0
Manual 7
:updatemodechange:

#cmdSetup radio Range Ohm
:read: range?
:write: range #;[500]
:updatedelayed: 0.5
:update: Range_Auto Ohm
200R 1
2k 2
20k 3
200k 4
2M 5
20M 6
:updatemodechange:


#cmdSetup separator Range Ohm
2 100 Raised


#cmdSetup radio Reading_Rate Ohm
:read: rate?
:write: rate #;[500]
:updatedelayed: 0.5
:tip: <html>Slow: maximum resolution, and optimum noise rejection<br>Fast: less resolution and noise reduction, but highest measurement speed
Slow 0
Medium 1
Fast 2
:updatemodechange:


#cmdSetup buttonsOn Offset Ohm
:read: offset?
; Take a reading first, then store the reading as an offset
:write: read?;offset #;[500];
:updatedelayed: 0.5
:tip: <html>Store a reading as an Offset<br>which is subtracted from subsequent readings
Off 0
On 1
:updatemodechange:


#cmdSetup radio Trigger_mode Ohm
:read: trigger?
:write: trigger #;[500]
:updatedelayed: 0.5
:tip: <html>Trigger modes: T0 int: internal, continuous trigger mode. T2 Ext: external, GPIB buss triggered WITH Settling Delay<br>T4 Ext: GPIB buss triggered, but WITHOUT Settling Delay (faster, but more error)
T0_Int 0
T2_Ext 2
T4_Ext 4
:updatemodechange:


#cmdSetup radio Display_mode Ohm
:read: display?
:write: display #;[500];
:updatedelayed: 0.5
:tip: In fast reading, the 8840A display must be blanked to ensure best accuracy
Normal 0
Blank 1
:updatemodechange:



; ----- Ohm 4W  -----
#cmdSetup radio Range_Auto OhmF
:read: autoRange?
:write: autoRange #;[500]
:updatedelayed: 0.5
:update: Range OhmF
Auto 0
Manual 7
:updatemodechange:

#cmdSetup radio Range OhmF
:read: range?
:write: range #;[500]
:updatedelayed: 0.5
:update: Range_Auto OHMF
200R 1
2k 2
20k 3
200k 4
2M 5
20M 6
:updatemodechange:


#cmdSetup separator Range OhmF
2 100 Raised


#cmdSetup radio Reading_Rate OhmF
:read: rate?
:write: rate #;[500]
:updatedelayed: 0.5
:tip: <html>Slow: maximum resolution, and optimum noise rejection<br>Fast: less resolution and noise reduction, but highest measurement speed
Slow 0
Medium 1
Fast 2
:updatemodechange:


#cmdSetup buttonsOn Offset OhmF
:read: offset?
; Take a reading first, then store the reading as an offset
:write: read?;offset #;[500];
:updatedelayed: 0.5
:tip: <html>Store a reading as an Offset<br>which is subtracted from subsequent readings
Off 0
On 1
:updatemodechange:


#cmdSetup radio Trigger_mode OhmF
:read: trigger?
:write: trigger #;[500]
:updatedelayed: 0.5
:tip: <html>Trigger modes: T0 int: internal, continuous trigger mode. T2 Ext: external, GPIB buss triggered WITH Settling Delay<br>T4 Ext: GPIB buss triggered, but WITHOUT Settling Delay (faster, but more error)
T0_Int 0
T2_Ext 2
T4_Ext 4
:updatemodechange:


#cmdSetup radio Display_mode OhmF
:read: display?
:write: display #;[500];
:updatedelayed: 0.5
:tip: In fast reading, the 8840A display must be blanked to ensure best accuracy
Normal 0
Blank 1
:updatemodechange:



; ----- DC Current  -----
#cmdSetup radio Range_Auto ADC
:read: autoRange?
:write: autoRange #;[500]
:updatedelayed: 0.5
:update: Range ADC
Auto 0
Manual 7
:updatemodechange:

#cmdSetup radio Range ADC
:read: range?
:write: range #;[500]
:updatedelayed: 0.5
:update: Range_Auto ADC
; 200mA 4
2A 5
:updatemodechange:


#cmdSetup separator Range ADC
2 100 Raised


#cmdSetup radio Reading_Rate ADC
:read: rate?
:write: rate #;[500]
:updatedelayed: 0.5
:tip: <html>Slow: maximum resolution, and optimum noise rejection<br>Fast: less resolution and noise reduction, but highest measurement speed
Slow 0
Medium 1
Fast 2
:updatemodechange:


#cmdSetup buttonsOn Offset ADC
:read: offset?
; Take a reading first, then store the reading as an offset
:write: read?;offset #;[500];
:updatedelayed: 0.5
:tip: <html>Store a reading as an Offset<br>which is subtracted from subsequent readings
Off 0
On 1
:updatemodechange:


#cmdSetup radio Trigger_mode ADC
:read: trigger?
:write: trigger #;[500]
:updatedelayed: 0.5
:tip: <html>Trigger modes: T0 int: internal, continuous trigger mode. T2 Ext: external, GPIB buss triggered WITH Settling Delay<br>T4 Ext: GPIB buss triggered, but WITHOUT Settling Delay (faster, but more error)
T0_Int 0
T2_Ext 2
T4_Ext 4
:updatemodechange:


#cmdSetup radio Display_mode ADC
:read: display?
:write: display #;[500];
:updatedelayed: 0.5
:tip: In fast reading, the 8840A display must be blanked to ensure best accuracy
Normal 0
Blank 1
:updatemodechange:



; ----- AC Current  -----
#cmdSetup radio Range_Auto AAC
:read: autoRange?
:write: autoRange #;[500]
:updatedelayed: 0.5
:update: Range AAC
Auto 0
Manual 7
:updatemodechange:

#cmdSetup radio Range AAC
:read: range?
:write: range #;[500]
:updatedelayed: 0.5
:update: Range_Auto AAC
; 200mA 4
2A 5
:updatemodechange:


#cmdSetup separator Range AAC
2 100 Raised


#cmdSetup radio Reading_Rate AAC
:read: rate?
:write: rate #;[500]
:updatedelayed: 0.5
:tip: <html>Slow: maximum resolution, and optimum noise rejection<br>Fast: less resolution and noise reduction, but highest measurement speed
Slow 0
Medium 1
Fast 2
:updatemodechange:


#cmdSetup buttonsOn Offset AAC
:read: offset?
; Take a reading first, then store the reading as an offset
:write: read?;offset #;[500];
:updatedelayed: 0.5
:tip: <html>Store a reading as an Offset<br>which is subtracted from subsequent readings
Off 0
On 1
:updatemodechange:


#cmdSetup radio Trigger_mode AAC
:read: trigger?
:write: trigger #;[500]
:updatedelayed: 0.5
:tip: <html>Trigger modes: T0 int: internal, continuous trigger mode. T2 Ext: external, GPIB buss triggered WITH Settling Delay<br>T4 Ext: GPIB buss triggered, but WITHOUT Settling Delay (faster, but more error)
T0_Int 0
T2_Ext 2
T4_Ext 4
:updatemodechange:


#cmdSetup radio Display_mode AAC
:read: display?
:write: display #;[500];
:updatedelayed: 0.5
:tip: In fast reading, the 8840A display must be blanked to ensure best accuracy
Normal 0
Blank 1
:updatemodechange:



;  ------  Mode menu selector  ------
#cmdSetup selector Mode_settings 
:read: askMode?
:updatemodechange:
1 VDC.
2 VAC.
3 Ohm.
4 OhmF.
5 ADC.
6 AAC.

