﻿;-----------------------------------------------------------------------------
; R&S HMC8012 Bench Multimeter
;
; Revision 1.0  19 Feb 2022     Inital release
;
;          1.1  19 Jul 2022     Add CSV/TXT file upload
;                               Add SCPI initialization sequence upload
;                               Add logging control
;                               Add limit indication to read values
;                               Add save/recall/reset of device settings
;                               Update trigger dialog
;
;          1.2  24 Jul 2022     Add table column formatting
;                               Add logging file upload
;                               Add logging file load from HDD/USB stick
;
;          1.3  11 Aug 2022     Add Hardcopy routine with timestamp per picture
;                               Correct bug in Setup tab
;                               Correct bug in "Load from File" function
;                               Add support for logging to USB stick
;-----------------------------------------------------------------------------

#author PL ;(based on template of MikeLud)


;------------------------------------------------------------
; Devices
;------------------------------------------------------------

#idString Rohde&Schwarz,HMC8012,
#name     R&S HMC8012
#handle   HMC8012
#port     com 5025 LXI GPIB
#baudrate 115200

#driver   SCPIx


;------------------------------------------------------------
; Emulation Layer
;------------------------------------------------------------

; Internal: recall index
#scpiCmd REC:INDEX none
:setvar: recindex=inputValue
#scpiCmd REC:INDEX? none?
:readmath: varExists("recindex")?(recindex):(0)

; Internal: save index
#scpiCmd SAV:INDEX none
:setvar: savindex=inputValue
#scpiCmd SAV:INDEX? none?
:readmath: varExists("savindex")?(savindex):(0)

; Internal: current directory
#scpiCmd DATA:CDIR none
:setvar: savcdir=inputValue
#scpiCmd DATA:CDIR? none?
:readmath: varExists("savcdir")?(savcdir):("/int")

; get hardware version
#scpiCmd SYST:HWVERSION? *IDN?
:readmath: var v=split(value,",");v[2];

; get software version
#scpiCmd SYST:FWVERSION? *IDN?
:readmath: var v=split(value,",");v[3];

#scpiCmd DATA:LIST3? txrxn? 10 DATA:LIST?

#scpiCmd DATA:LIST2? tx DATA:LIST?;txrx *IDN?
;;:readmath: (0)

;------------------------------------------------------------
; Low-Level Interface
;------------------------------------------------------------

; A list of possible column name with unit and formatter (SI, Time, Int, D0..D6)
#value VoltageDC V si DC_Voltage,Diode
#value CurrentDC A si DC_Current
#value VoltageAC V si AC_Voltage
#value CurrentAC A si AC_Current
#value Resistance Ω si 2W_Resistance,4W_Resistance,Continuity
#value Capacitance F si Capacitance
#value Temperature °C D4 Temperature
#value VoltageAC V si Frequency_Voltage
#value CurrentAC A si Frequency_Current

; secondary reading
#value Frequency Hz si Frequency_Voltage
#value Frequency Hz si Frequency_Current
#value CurrentDC A si DCV_Power
#value VoltageDC V si DCI_Power
#value a dB si dB
#value L dBm si dBm

; ternary reading
#value PowerDC W si DCV_Power,DCI_Power

#value Limit - d0 Limit

; Statistics
#value Count - si Statistics
#value Max - si Statistics
#value Avg - si Statistics
#value Min - si Statistics
#value StdDev - si Statistics
#value Peak - si Statistics


; How to poll for data, this is used for table and #values?
; a #askMode, #cmdMode and #prepareSample is used before this is string is used.
; This is a single line command
#askValues FETC?[mode:Frequency_Voltage,Frequency_Current,DCV_Power,DCI_Power,dB,dBm];FETCH2?[mode:DCV_Power,DCI_Power];CALC:POW?[mode:Limit];STAT:QUES:COND?[mode:Statistics];CALC:AVER:COUN?;CALC:AVER:MAX?;CALC:AVER:AVER?;CALC:AVER:MIN?;CALC:AVER:SDEV?;CALC:AVER:PTP?

; Format of answer: f=float, u=remove trailing letters, x=skip, *=Zero upper case values if this value is 0
#askValuesReadFormat FFFFFFFFFF

; Accept this delay when reading values (seconds)
#readingDelay 3

; Mode change have a longer delay on reading values (seconds)
#modeChangeDelay 3

; Switch meter to this mode during start, leave empty to avoid any switching
;#initialMode

; String to ask about actual meter mode,
; This is a single line command
#askMode :SENSE:FUNCTION?
#askModeMathFormat unQuote(value);

; When one of these commands are used through the command interface a new configuration will be done before using #askMode
; Only one word for each #mayModifyMode
; Specify command without initial colon and in the shortest possible form
#mayModifyMode conf
#mayModifyMode calc
#mayModifyMode trig

; Prepare the meter to response to #askValues
#prepareSample

; Initial commands to meter when establishing connection
;#initCmd

; Final command to meter before breaking connection
#finalCmd SYSTEM:LOCAL


;------------------------------------------------------------------------------------
; Interface
;------------------------------------------------------------------------------------

#interfaceType DMM BMM

#interface readValue  0
#interface readValue2 1
#interface readPower  2


;------------------------------------------------------------------------------------
; Mode Commands
;------------------------------------------------------------------------------------

; Strings to configure device in different modes
; First parameter must match a #value (4 parameter) and second parameter must match what #askMode returns
; First parameter is also used in shortcut menu
;#cmdMode

#cmdModeLayout 3 7

#cmdMode DC_Voltage VOLT
*CLS;
CONF:VOLT:DC;[*OPC]

#cmdMode AC_Voltage VOLT:AC
*CLS;
CONF:VOLT:AC;[*OPC]

#cmdMode Frequency_Voltage FREQ
*CLS;
CALC:FUNC POW
CALC OFF
CONF:FREQ;[*OPC]


#cmdMode DC_Current CURR
*CLS;
CONF:CURR:DC;[*OPC]

#cmdMode AC_Current CURR:AC
*CLS;
CONF:CURR:AC;[*OPC]

#cmdMode Frequency_Current FREQ:CURR
*CLS;
CALC:FUNC POW
CALC OFF
CONF:FREQ:CURR;[*OPC]


#cmdMode 2W_Resistance RES
*CLS;
CONF:RES;[*OPC]

#cmdMode Diode DIOD
*CLS;
CONF:DIOD;[*OPC]

#cmdMode Capacitance CAP
*CLS;
CONF:CAP;[*OPC]


#cmdMode 4W_Resistance FRES
*CLS;
CONF:FRES;[*OPC]

#cmdMode Continuity CONT
*CLS;
CONF:CONT;[*OPC]

#cmdMode Temperature SENS
*CLS;
CONF:TEMP;[*OPC]


#cmdModeCheck DCV_Power m2 0
[localMode]*CLS;CALC:FUNC POW;CALC ON;[*OPC]
[localMode]*CLS;CALC:FUNC POW;CALC OFF;[*OPC]
DC_Voltage !dB !dBm

;[localMode]*CLS;CONF:VOLT:DC;CALC:FUNC POW;CALC ON;[*OPC]
;[localMode]*CLS;CONF:VOLT:DC;[*OPC]

#cmdModeCheck dB m2 0
[localMode]*CLS;CALC:FUNC DB;CALC ON;[*OPC]
[localMode]*CLS;CALC:FUNC DB;CALC OFF;[*OPC]
!Frequency_Current !Frequency_Voltage !2W_Resistance !4W_Resistance !Diode !Continuity !Temperature !Capacitance !DCV_Power !DCI_Power !dBm

#cmdModeCheck Limit m2 0
[localMode]*CLS;CALC:FUNC LIM;CALC ON;[*OPC]
[localMode]*CLS;CALC:FUNC LIM;CALC OFF;[*OPC]
!Diode !Continuity !Temperature !Statistics


#cmdModeCheck DCI_Power m2 0
[localMode]*CLS;CALC:FUNC POW;CALC ON;[*OPC]
[localMode]*CLS;CALC:FUNC POW;CALC OFF;[*OPC]
DC_Current !dBm !dB

#cmdModeCheck dBm m2 0
[localMode]*CLS;CALC:FUNC DBm;CALC ON;[*OPC]
[localMode]*CLS;CALC:FUNC DBm;CALC OFF;[*OPC]
!Frequency_Current !Frequency_Voltage !2W_Resistance !4W_Resistance !Diode !Continuity !Temperature !Capacitance !DCV_Power !DCI_Power !dB

#cmdModeCheck Statistics m2 0
[localMode]*CLS;CALC:FUNC AVER;CALC ON;[*OPC]
[localMode]*CLS;CALC:FUNC AVER;CALC OFF;[*OPC]
!Limit


#cmdMode Sync _ _

#cmdMode Remote REMOTE
SYSTEM:REMOTE

#cmdMode Local LOCAL
SYSTEM:LOCAL


;------------------------------------------------------------------------------------
; Mode
;------------------------------------------------------------------------------------

#cmdSetup info Mode Main
:read: FUNC?
:readmath: getElement("Diode;DC Voltage;AC Voltage;DC Current;AC Current;Temperature;Capacitance;2W Resistance;4W Resistance;Frequency Voltage;Continuity;Frequency Current",listIndex(unQuote(value),"DIOD VOLT VOLT:AC CURR CURR:AC SENS CAP RES FRES FREQ CONT FREQ:CURR"," "),";")
:updatemodechange:

#cmdSetup separator - Main
2 100 Solid


;------------------------------------------------------------------------------------
; DC Current
;------------------------------------------------------------------------------------

#cmdSetup radio Range DC_Current
:write:   CURR:DC:RANGE:AUTO #
:read:    CURR:DC:RANGE:AUTO?
Auto 1
Manual 0
:updatemodechange:

#cmdSetup comboboxHot Range DC_Current
:write:   CURR:DC:RANGE #
:read:    CURR:DC:RANGE?
20mA  2.00000000E-02
200mA 2.00000000E-01
2A    2.00000000E+00
10A   1.00000000E+01
:updatemodechange:

#cmdSetup radio Null DC_Current
:write:   CURR:DC:NULL:STAT #
:read:    CURR:DC:NULL:STAT?
:update:  Null_Value
:updatedelayed: 0.0
Off 0
On  1
:updatemodechange:

#cmdSetup number Null_Value DC_Current
:read:    CURR:DC:NULL:VALUE?
:write:   CURR:DC:NULL:VALUE #
A -1.000000E+01 1.000000E+01
:updatemodechange:

#cmdSetup radio ADC_Rate DC_Current
:read: ADCRATE?
:write: ADCRATE #
:string:
Slow   SLOW
Medium MED
Fast   FAST
:updatemodechange:


;------------------------------------------------------------------------------------
; DC Voltage
;------------------------------------------------------------------------------------

#cmdSetup radio Range DC_Voltage
:read:    VOLT:DC:RANGE:AUTO?
:write:   VOLT:DC:RANGE:AUTO #
Auto   1
Manual 0
:updatemodechange:

#cmdSetup comboboxHot Range DC_Voltage
:write: VOLT:DC:RANGE #
:read:  VOLT:DC:RANGE?
400mV 4.00000000E-01
4V    4.00000000E+00
40V   4.00000000E+01
400V  4.00000000E+02
1000V 1.00000000E+03
:updatemodechange:

#cmdSetup radio Null DC_Voltage
:write:   VOLT:DC:NULL:STAT #
:read:    VOLT:DC:NULL:STAT?
:update:  Null_Value
:updatedelayed: 0.0
Off 0
On 1
:updatemodechange:

#cmdSetup number Null_Value DC_Voltage
:read:    VOLT:DC:NULL:VALUE?
:write:   VOLT:DC:NULL:VALUE #
V -10 1000
:updatemodechange:

#cmdSetup radio ADC_Rate DC_Voltage
:read:    ADCRATE?
:write:   ADCRATE #
:string:
Slow   SLOW
Medium MED
Fast   FAST
:updatemodechange:

#cmdSetup radio Auto_Zero DC_Voltage
:write:   VOLT:DC:ZERO:AUTO #
:read:    VOLT:DC:ZERO:AUTO?
Off 0
On  1
:updatemodechange:


;------------------------------------------------------------------------------------
; Diode
;------------------------------------------------------------------------------------

#cmdSetup radio Beeper Diode
:write:   DIOD:BEEP:STAT #
:read:    DIOD:BEEP:STAT?
Off 0
On 1
:updatemodechange:

#cmdSetup number Threshold Diode
:read:    DIOD:THR?
:write:   DIOD:THR #
:textwidth: 10
V 0 +4.95
:updatemodechange:


;------------------------------------------------------------------------------------
; Frequency Voltage
;------------------------------------------------------------------------------------

#cmdSetup radio Range Frequency_Voltage
:write:   FREQ:VOLT:RANGE:AUTO #
:read:    FREQ:VOLT:RANGE:AUTO?
Auto   1
Manual 0
:updatemodechange:

#cmdSetup comboboxHot Range Frequency_Voltage
:write: FREQ:VOLT:RANGE #
:read:  FREQ:VOLT:RANGE?
100mV +1.00000000E-01
1V    +1.00000000E+00
10V   +1.00000000E+01
100V  +1.00000000E+02
750V  +7.50000000E+02
:updatemodechange:

#cmdSetup radio Gate_Time Frequency_Voltage
:write:   FREQ:APER #
:read:    FREQ:APER?
10_ms  1.00000000E-02
100_ms 1.00000000E-01
1_s    1.00000000E+00
:updatemodechange:


;------------------------------------------------------------------------------------
; Frequency Current
;------------------------------------------------------------------------------------

#cmdSetup radio Range Frequency_Current
:write:   FREQ:CURR:RANGE:AUTO #
:read:    FREQ:CURR:RANGE:AUTO?
Auto   1
Manual 0
:updatemodechange:

#cmdSetup comboboxHot Range Frequency_Current
:write:   CURR:AC:RANGE #
:read:    CURR:AC:RANGE?
20mA  2.00000000E-02
200mA 2.00000000E-01
2A    2.00000000E+00
10A   1.00000000E+01
:updatemodechange:

#cmdSetup radio Gate_Time Frequency_Current
:write:   FREQ:APER #
:read:    FREQ:APER?
10_ms  1.00000000E-02
100_ms 1.00000000E-01
1_s    1.00000000E+00
:updatemodechange:


;------------------------------------------------------------------------------------
; Temperature
;------------------------------------------------------------------------------------

#cmdSetup comboboxHot Probe Temperature
:write:   TEMP:TRAN:TYPE #
:read:    TEMP:TRAN:TYPE?
:update:  Temperature_Settings
:updatedelayed: 0.0
RTD_2W RTD
RTD_4W FRTD
:updatemodechange:

#cmdSetup comboboxHot Probe Temperature
:write:   TEMP:TRAN:RTD:TYPE #
:read:    TEMP:TRAN:RTD:TYPE?
PT100  PT100
PT500  PT500
PT1000 PT1000
:updatemodechange:

#cmdSetup radio Null Temperature
:write:   TEMP:NULL:STAT #
:read:    TEMP:NULL:STAT?
:update:  Null_Value
:updatedelayed: 0.0
Off 0
On 1
:updatemodechange:

#cmdSetup number Null_Value Temperature
:read:    TEMP:NULL:VALUE?
:write:   TEMP:NULL:VALUE #
:textwidth: 8
°C -273 1000
:updatemodechange:


;------------------------------------------------------------------------------------
; 2W Resistance
;------------------------------------------------------------------------------------

#cmdSetup radio Range 2W_Resistance
:read:    RES:RANGE:AUTO?
:write:   RES:RANGE:AUTO #
Auto   1
Manual 0
:updatemodechange:

#cmdSetup comboboxHot Range 2W_Resistance
:write:   RES:RANGE #
:read:    RES:RANGE?
400Ω  4.00000000E+02
4kΩ   4.00000000E+03
40kΩ  4.00000000E+04
400kΩ 4.00000000E+05
4MΩ   4.00000000E+06
40MΩ  4.00000000E+07
250MΩ 2.50000000E+08
:updatemodechange:

#cmdSetup radio Null 2W_Resistance
:write:   RES:NULL:STAT #
:read:    RES:NULL:STAT?
:update:  Null_Value
:updatedelayed: 0.0
Off 0
On  1
:updatemodechange:

#cmdSetup number Null_Value 2W_Resistance
:read:    RES:NULL:VALUE?
:write:   RES:NULL:VALUE #
Ω 0 +250000000
:updatemodechange:

#cmdSetup radio ADC_Rate 2W_Resistance
:read:    ADCRATE?
:write:   ADCRATE #
:string:
Slow   SLOW
Medium MED
Fast   FAST
:updatemodechange:


;------------------------------------------------------------------------------------
; 4W Resistance
;------------------------------------------------------------------------------------

#cmdSetup radio Range 4W_Resistance
:read:    FRES:RANGE:AUTO?
:write:   FRES:RANGE:AUTO #
Auto   1
Manual 0
:updatemodechange:

#cmdSetup comboboxHot Range 4W_Resistance
:write:   FRES:RANGE #
:read:    FRES:RANGE?
400Ω  4.00000000E+02
4kΩ   4.00000000E+03
40kΩ  4.00000000E+04
400kΩ 4.00000000E+05
4MΩ   4.00000000E+06
:updatemodechange:

#cmdSetup radio Null 4W_Resistance
:write:   FRES:NULL:STAT #
:read:    FRES:NULL:STAT?
:update:  Null_Value
:updatedelayed: 0.0
Off 0
On  1
:updatemodechange:

#cmdSetup number Null_Value 4W_Resistance
:read:    FRES:NULL:VALUE?
:write:   FRES:NULL:VALUE #
Ω 0 +4000000
:updatemodechange:

#cmdSetup radio ADC_Rate 4W_Resistance
:read:    ADCRATE?
:write:   ADCRATE #
:string:
Slow   SLOW
Medium MED
Fast   FAST
:updatemodechange:


;------------------------------------------------------------------------------------
; AC Current
;------------------------------------------------------------------------------------

#cmdSetup radio Range AC_Current
:write:   CURR:AC:RANGE:AUTO #
:read:    CURR:AC:RANGE:AUTO?
Auto   1
Manual 0
:updatemodechange:

#cmdSetup comboboxHot Range AC_Current
:write:   CURR:AC:RANGE #
:read:    CURR:AC:RANGE?
20mA  2.00000000E-02
200mA 2.00000000E-01
2A    2.00000000E+00
10A   1.00000000E+01
:updatemodechange:

#cmdSetup radio Null AC_Current
:write:   CURR:AC:NULL:STAT #
:read:    CURR:AC:NULL:STAT?
:update:  Null_Value
:updatedelayed: 0.0
Off 0
On  1
:updatemodechange:

#cmdSetup number Null_Value AC_Current
:read:    CURR:AC:NULL:VALUE?
:write:   CURR:AC:NULL:VALUE #
A -1.000000E+01 1.000000E+01
:updatemodechange:

#cmdSetup radio ADC_Rate AC_Current
:read:    ADCRATE?
:write:   ADCRATE #
:string:
Slow   SLOW
Medium MED
Fast   FAST
:updatemodechange:

#cmdSetup radio AC_Filter AC_Current
:write:   CURR:AC:BAND #
:read:    CURR:AC:BAND?
:readFormat: u
>10Hz  10
>50Hz  50
>400Hz 400
:updatemodechange:


;------------------------------------------------------------------------------------
; AC Voltage
;------------------------------------------------------------------------------------

#cmdSetup radio Range AC_Voltage
:write:   VOLT:AC:RANGE:AUTO #
:read:    VOLT:AC:RANGE:AUTO?
Auto   1
Manual 0
:updatemodechange:

#cmdSetup comboboxHot Range AC_Voltage
:write:   VOLT:AC:RANGE #
:read:    VOLT:AC:RANGE?
400mV 4.00000000E-01
4V    4.00000000E+00
40V   4.00000000E+01
400V  4.00000000E+02
750V  7.50000000E+02
:updatemodechange:

#cmdSetup radio Null AC_Voltage
:write:   VOLT:AC:NULL:STAT #
:read:    VOLT:AC:NULL:STAT?
:update:  Null_Value
:updatedelayed: 0.0
Off 0
On  1
:updatemodechange:

#cmdSetup number Null_Value AC_Voltage
:read:    VOLT:AC:NULL:VALUE?
:write:  VOLT:AC:NULL:VALUE #
V 0 7.500000E+02
:updatemodechange:

#cmdSetup radio ADC_Rate AC_Voltage
:read:    ADCRATE?
:write:   ADCRATE #
:string:
Slow   SLOW
Medium MED
Fast   FAST
:updatemodechange:

#cmdSetup radio AC_Filter AC_Voltage
:write:   VOLT:AC:BAND #
:read:    VOLT:AC:BAND?
:readFormat: u
>10Hz  10
>50Hz  50
>400Hz 400
:updatemodechange:


;------------------------------------------------------------------------------------
; Capacitance
;------------------------------------------------------------------------------------

#cmdSetup radio Range Capacitance
:write:   Cap:RANGE:AUTO #
:read:    Cap:RANGE:AUTO?
Auto   1
Manual 0
:updatemodechange:

#cmdSetup comboboxHot Range Capacitance
:write:   Cap:RANGE #
:read:    Cap:RANGE?
5nF   5.00000000E-09
50nF  5.00000000E-08
500nF 5.00000000E-07
5uF   5.00000000E-06
50uF  5.00000000E-05
500uF 5.00000000E-04
:updatemodechange:

#cmdSetup radio Null Capacitance
:write:   Cap:NULL:STAT #
:read:    Cap:NULL:STAT?
:update:  Null_Value
:updatedelayed: 0.0
Off 0
On  1
:updatemodechange:

#cmdSetup number Null_Value Capacitance
:read:    Cap:NULL:VALUE?
:write:   Cap:NULL:VALUE #
:textwidth: 8
uF 0 500
:updatemodechange:


;------------------------------------------------------------------------------------
; Continuity
;------------------------------------------------------------------------------------

#cmdSetup radio Beeper Continuity
:write:   CONT:BEEP:STAT #
:read:    CONT:BEEP:STAT?
Off 0
On  1
:updatemodechange:

#cmdSetup number Threshold Continuity
:read:    CONT:THR?
:write:   CONT:THR #
:textwidth: 10
Ω 0 200000000
:updatemodechange:


;------------------------------------------------------------------------------------
; Selector
;------------------------------------------------------------------------------------

#cmdSetup selector Mode_settings Main
:read:    FUNC?
:readmath: unQuote(value)
:updatemodechange:
SENS      Temperature.
VOLT      DC_Voltage.
VOLT:AC   AC_Voltage.
CURR      DC_Current.
CURR:AC   AC_Current.
DIOD      Diode.
FREQ      Frequency_Voltage.
FREQ:CURR Frequency_Current.
RES       2W_Resistance.
FRES      4W_Resistance.
CAP       Capacitance.
CONT      Continuity.


;------------------------------------------------------------------------------------
; Setup
;------------------------------------------------------------------------------------

#cmdSetup Info Parameter Setup

#cmdSetup separator - Setup
2 100 Solid

#cmdSetup radio Beeper Setup
:write:   SYST:BEEP:STAT #
:read:    SYST:BEEP:STAT?
Off 0
On  1
:updatemodechange:

#cmdSetup number Limit_High Setup
:read:    CALC:LIM:UPP?
:write:   CALC:LIM:UPP #
:textwidth: 8
- -10G 10G
:updatemodechange:

#cmdSetup number Limit_Low Setup
:read:    CALC:LIM:LOW?
:write:   CALC:LIM:LOW #
- -10G 10G
:updatemodechange:

#cmdSetup selector SelectorDB Setup
:read:    FUNC?
:readmath: unQuote(value)
:updatemodechange:
SENS      Setup_NONE.
VOLT      Setup_DB.
VOLT:AC   Setup_DB.
CURR      Setup_DB.
CURR:AC   Setup_DB.
DIOD      Setup_NONE.
FREQ      Setup_DB.
FREQ:CURR Setup_DB.
RES       Setup_NONE.
FRES      Setup_NONE.
CAP       Setup_NONE.
CONT      Setup_NONE.

#cmdSetup separator - Setup_NONE
2 100 Empty

#cmdSetup number Reference_DB Setup_DB
:read:    CALC:DB:REF?
:write:   CALC:DB:REF #
V 1u 10
:updatemodechange:

#cmdSetup number Reference_DBm Setup_DB
:read:    CALC:DBM:REF?
:write:   CALC:DBM:REF #
Ω 1 65k
:updatemodechange:


;------------------------------------------------------------------------------------
; Trigger
;------------------------------------------------------------------------------------

#cmdSetup radio Mode Trigger
:read:    TRIG:MODE?
:write:   TRIG:MODE #
:string:
Auto   AUTO
Single SING
Manual MAN
:updatemodechange:

#cmdSetup separator - Trigger
2 100 Solid

#cmdSetup comboboxHot Type Trigger
:read:    TRIG:LEV:MODE?
:write:   TRIG:LEV:MODE #
:visible: Trigger.Mode=="AUTO"
:string:
Continue CONT
Above    ABOV
Below    BEL
:updatemodechange:

#cmdSetup number Level Trigger
:read:    TRIG:LEV?
:write:   TRIG:LEV #
:visible: Trigger.Mode=="AUTO"
:enable:  Trigger.Mode=="AUTO" && Trigger.Type!="CONT"
- -10G 10G
:updatemodechange:

#cmdSetup number Interval Trigger
:read:    TRIG:INT?
:write:   TRIG:INT #
:visible: Trigger.Mode=="SING"
s 0 3600
:updatemodechange:

#cmdSetup number Count Trigger
:read:    TRIG:COUN?
:write:   TRIG:COUN #
:visible: Trigger.Mode=="SING"
_ 0 50000
:updatemodechange:

#cmdSetup button Trigger Trigger
:visible: Trigger.Mode!="AUTO"
:enable:  Trigger.Mode!="AUTO"
:write:   *TRG


;------------------------------------------------------------------------------------
; Log
;------------------------------------------------------------------------------------

#cmdSetup radio Mode Log
:read:    DATA:LOG:MODE?
:write:   DATA:LOG:MODE #
:string:
Unlimited UNL
Count     COUN
Time      TIME
:updatemodechange:

#cmdSetup separator - Log
2 100 Solid

#cmdSetup text File Log
:read:    DATA:LOG:FNAM?
:write:   DATA:LOG:FNAM ("\""+replace(replace(value,"/INT/DATA/",""),"/USB_FRONT/","")+"\","+(indexOf(value, "/USB_FRONT") != -1 ? "EXT" : "INT"))
:tip: supported storage is /INT or /INT/DATA and /USB_FRONT
:updatemodechange:

#cmdSetup radio Format Log
:read:    DATA:LOG:FORM?
:write:   DATA:LOG:FORM #
:update:  Log.File
:string:
CSV    CSV
TXT    TXT
:updatemodechange:

#cmdSetup number Interval Log
:read:    DATA:LOG:INT?
:write:   DATA:LOG:INT #
:textwidth: 9
s 0 50000
:updatemodechange:

#cmdSetup number Time Log
:read:    DATA:LOG:TIME?
:write:   DATA:LOG:TIME #
:visible: Log.Mode=="TIME"
s 0 50000
:updatemodechange:

#cmdSetup number Count Log
:read:    DATA:LOG:COUN?
:write:   DATA:LOG:COUN #
:visible: Log.Mode=="COUN"
_ 0 50000
:updatemodechange:

#cmdSetup number Count Log
:visible: Log.Mode=="UNL"
:enable:  (0)
_ 0 50000

#cmdSetup separator - Log
2 100 Solid

#cmdSetup buttonsOn Log Log
:read:    DATA:LOG:STAT?
:write:   DATA:LOG:STAT
:update:  Log.File
:updatealloff:
:updatemodechange:
Off 0
On  1


;------------------------------------------------------------------------------------
; Device
;------------------------------------------------------------------------------------

#cmdSetup Info Settings Device

#cmdSetup separator - Device
2 100 Solid

#cmdSetup combobox Memory Device
:read:    SAV:INDEX?
:write:   SAV:INDEX #; *SAV #
:buttontext: Save
:string:
M1______________________________________ 0
M2 1
M3 2
M4 3
M5 4

#cmdSetup combobox Memory Device
:read:    REC:INDEX?
:write:   REC:INDEX #; *RCL #
:buttontext: Recall
:string:
:update:  Sync Beeper Limit_High Limit_Low Reference_DB Reference_DBm Mode Type Level Interval Count File Format Time
M1 0
M2 1
M3 2
M4 3
M5 4


#cmdSetup separator - Device
2 100 Empty

#cmdSetup Info Device Device

#cmdSetup separator - Device
2 100 Solid

#cmdSetup Info HW Device
:read:    SYST:HWVERSION?

#cmdSetup Info FW Device
:read:    SYST:FWVERSION?


#cmdSetup button Reset Device
:write:   *RST
:update:  Sync Beeper Limit_High Limit_Low Reference_DB Reference_DBm Mode Type Level Interval Count File Format Time


;------------------------------------------------------------------------------------
; Other
;------------------------------------------------------------------------------------

#otherList
menuItem[0]="Hardcopy....xxx";
menuItem[1]="Device Status....xxx"
menuItem[2]="Load Log....xxx";
menuItem[3]="Save Log....xxx";
menuItem[4]="Show Log....xxx";
menuItem[5]="Delete Log....xxx";
menuItem[6]="Change Drive....xxx";
menuItem[7]="Init Sequence.txt";
menuItem[8]="Device Settings.txt";

#otherFunc
var i;
var v1;
var v2;
var v3;
var v4;
var v5;
var samples;
var data;
var table;
var start;
var len;
var headerlines=21;
var filename;
var columns=4;
var match;
var bStatus=0;
var bFormat;
var list[1];
var file_name;

if (name == "Hardcopy....xxx")

  deviceWrite(handle, "HCOP:FORM PNG");

  var now   = date();
  var image = deviceReadBytes(handle, "HCOPY:DATA?");
  var timestamp;

  timestamp = substring(now,0,4)+"-" + substring(now,4,6) + "-" + substring(now,6,8);
  timestamp = timestamp + " " + substring(now,8,10)+":" + substring(now,10,12)+":" + substring(now,12,14);

  addImage(image, handle +" "+timestamp);

elseif (name == "Device Status....xxx")

  var data;

  data = unQuote(deviceRead(handle,"SYST:ERR:ALL?"));
  data = replace  (data, "\",","\"\r\n");

  if(indexOf(data, "No error") != -1)
    popupShowInfo("Error Queue: \r\n"+data, 1);
  else
    popupShowInfo("Error Queue: \r\n"+data, 3);
  endif

elseif (name=="Load Log....xxx")

  ; load dialog
  filename="";
  popupInit    ("Load Log");
  popupLabel   ("");
  popupLabel   ("  Load Table from a CSV logging file.  ");
  popupLabel   ("");
  popupFile    ("File", "filename", "", "csv",1);
  popupButtons ("OK", "bStatus", "Cancel");
  popupShow    ();

  if (bStatus)
    ; load data
    data    = fileReadText(filename);
    data    = replace(data,"\r\n","\n");
    start   = indexOf(data, "Actual Count")+15;
    samples = int(substring(data, start, start+14));

    ; skip header
    start   = indexOf(data, "Actual Count")+15+18;
    len     = strlen(data);
    table   = substring(data,start,len);

    ; preprocess
    table = replace(table,"\n",";");
    table = replace(table,"\"","");
    table = replace(table,"Timestamp","Time");

    ; detect number of columns
    match   = countMatch(table,";");
    columns = int(match/(1+samples));

    if (columns==5)
      ; table header
      v1=getElement(table,0,";");
      v2=getElement(table,1,";");
      v3=getElement(table,2,";");
      v4=getElement(table,3,";");
      v5=getElement(table,4,";");
      tableInitHeader(handle+".Index,"+handle+"."+v5+","+handle+"."+v1+","+handle+"."+v2+","+handle+"."+v3+","+handle+"."+v4);
      runScript("#ValueFormat "+handle+"."+v1+" SI");
      runScript("#ValueFormat "+handle+"."+v2+" SI");
      runScript("#ValueFormat "+handle+"."+v3+" SI");

      ; entries
      for i=1 to samples do
        v1=parseSI(getElement(table,i*5+1,";"));
        v2=parseSI(getElement(table,i*5+2,";"));
        v3=parseSI(getElement(table,i*5+3,";"));
        v4=getElement(table,i*5+4,";");
        v5=getElement(table,i*5+5,";");
        v5=int(parseHMS(substring(v5,1,strlen(v5)-4)));
        tableAddRow(i,v5,v1,v2,v3,0);
      endfor
    elseif (columns==4)
      ; table header
      v1=getElement(table,0,";");
      v2=getElement(table,1,";");
      v3=getElement(table,2,";");
      v4=getElement(table,3,";");
      tableInitHeader(handle+".Index,"+handle+"."+v4+","+handle+"."+v1+","+handle+"."+v2+","+handle+"."+v3);
      runScript("#ValueFormat "+handle+"."+v1+" SI");
      runScript("#ValueFormat "+handle+"."+v2+" SI");

      ; entries
      for i=1 to samples do
        v1=parseSI(getElement(table,i*4+1,";"));
        v2=parseSI(getElement(table,i*4+2,";"));
        v3=getElement(table,i*4+3,";");
        v4=getElement(table,i*4+4,";");
        v4=int(parseHMS(substring(v4,1,strlen(v4)-4)));
        tableAddRow(i,v4,v1,v2,0);
      endfor
    else
      ; table header
      v1=getElement(table,0,";");
      v2=getElement(table,1,";");
      v3=getElement(table,2,";");
      tableInitHeader(handle+".Index,"+handle+"."+v3+","+handle+"."+v1+","+handle+"."+v2);
      runScript("#ValueFormat "+handle+"."+v1+" SI");

      ; entries
      for i=1 to samples do
        v1=parseSI(getElement(table,i*3+1,";"));
        v2=getElement(table,i*3+2,";");
        v3=getElement(table,i*3+3,";");
        v3=int(parseHMS(substring(v3,1,strlen(v3)-4)));
        tableAddRow(i,v3,v1,0);
      endfor
    endif

    ;remaining columns
    runScript("#ValueFormat HMC8012.Index D0");
    runScript("#ValueFormat HMC8012.Time Time");
    runScript("#ValueFormat HMC8012.Flag D0");

    popupShowInfo("Loaded "+filename+" data to \r\nTable, Chart and Histogram.\r\n("+string(samples)+" data points)", 1);
  endif
  
elseif (name == "Show Log....xxx")

  var dir_list[1];
  dir_list[0]     = "/int";
  dir_list[1]     = "/usb_front";
  var list[0];
  var j;
  var dir_current = unQuote(deviceRead(handle, "DATA:CDIR?"));
  var drive       = dir_current == "/int" ? "INT" : "EXT";
  var logfile     = unQuote(deviceRead(handle, "DATA:LOG:FNAM?"));
  var sep         = indexOf(logfile, ".");
  var extension   = substring(logfile, sep);
  var index_str   = getMatch(logfile, "[0-9]+");
  var index_len   = strlen(index_str);
  var maxindex;
  
  if (index_len > 0)
    var index     = int(index_str);
    var logid     = substring(logfile, lastIndexOf(logfile, "/")+1, sep-index_len);
    
    if (index_len == 1) 
      maxindex = 10;
    elseif (int(index_str)<30)
      maxindex = 30;
    else
      maxindex = 100;
    endif
  
    for j = 0 to maxindex-2 do
      list[j] = logid + formatInt(j+1, index_len, index_len)+extension;
    endfor
    
    if (index < 1)
      index = 1;
    endif
    file_name = logid + formatInt(index-1, index_len, index_len)+extension;
  else
    maxindex = 0;
    list[0] = substring(logfile, lastIndexOf(logfile, "/")+1);
    file_name = substring(logfile, lastIndexOf(logfile, "/")+1);
  endif
  
  ; upload dialog  
  popupInit    ("Show Log");
  popupLabel   ("");
  popupLabel   ("  Upload a logging file from device "+handle+" into Table.  ");
  popupLabel   ("");
  popupRadio   ("Drive", "dir_current", dir_list);
  if (maxindex == 0)
    popupText  ("From", "file_name", 16);
  else
    popupCombo ("From", "file_name", list);
  endif
  popupButtons ("OK", "bStatus", "Cancel");
  popupShow    ();

  if (bStatus)
    deviceWrite(handle, "DATA:CDIR \""+dir_current+"\"");
    drive   = dir_current == "/int" ? "INT" : "EXT";
  
    ; upload data
    samples = int(deviceRead(handle,"DATA:POIN? \""+file_name+"\", "+drive));
    data    = deviceRead(handle,"txrxn? "+string(headerlines+samples)+" DATA:DATA? \""+file_name+"\", "+drive);

    ; skip header
    start   = indexOf(data, "Actual Count")+15+18;
    len     = strlen(data);
    table   = substring(data,start,len);

    ; preprocess
    table = replace(table,"\n",";");
    table = replace(table,"\"","");
    table = replace(table,"Timestamp","Time");

    ; detect number of columns
    match   = countMatch(table,";");
    columns = int(match/(1+samples));

    if (columns==5)
      ; table header
      v1=getElement(table,0,";");
      v2=getElement(table,1,";");
      v3=getElement(table,2,";");
      v4=getElement(table,3,";");
      v5=getElement(table,4,";");
      tableInitHeader(handle+".Index,"+handle+"."+v5+","+handle+"."+v1+","+handle+"."+v2+","+handle+"."+v3+","+handle+"."+v4);
      runScript("#ValueFormat "+handle+"."+v1+" SI");
      runScript("#ValueFormat "+handle+"."+v2+" SI");
      runScript("#ValueFormat "+handle+"."+v3+" SI");

      ; entries
      for i=1 to samples do
        v1=parseSI(getElement(table,i*5+1,";"));
        v2=parseSI(getElement(table,i*5+2,";"));
        v3=parseSI(getElement(table,i*5+3,";"));
        v4=getElement(table,i*5+4,";");
        v5=getElement(table,i*5+5,";");
        v5=int(parseHMS(substring(v5,1,strlen(v5)-4)));
        tableAddRow(i,v5,v1,v2,v3,0);
      endfor
    elseif (columns==4)
      ; table header
      v1=getElement(table,0,";");
      v2=getElement(table,1,";");
      v3=getElement(table,2,";");
      v4=getElement(table,3,";");
      tableInitHeader(handle+".Index,"+handle+"."+v4+","+handle+"."+v1+","+handle+"."+v2+","+handle+"."+v3);
      runScript("#ValueFormat "+handle+"."+v1+" SI");
      runScript("#ValueFormat "+handle+"."+v2+" SI");

      ; entries
      for i=1 to samples do
        v1=parseSI(getElement(table,i*4+1,";"));
        v2=parseSI(getElement(table,i*4+2,";"));
        v3=getElement(table,i*4+3,";");
        v4=getElement(table,i*4+4,";");
        v4=int(parseHMS(substring(v4,1,strlen(v4)-4)));
        tableAddRow(i,v4,v1,v2,0);
      endfor
    else
      ; table header
      v1=getElement(table,0,";");
      v2=getElement(table,1,";");
      v3=getElement(table,2,";");
      tableInitHeader(handle+".Index,"+handle+"."+v3+","+handle+"."+v1+","+handle+"."+v2);
      runScript("#ValueFormat "+handle+"."+v1+" SI");

      ; entries
      for i=1 to samples do
        v1=parseSI(getElement(table,i*3+1,";"));
        v2=getElement(table,i*3+2,";");
        v3=getElement(table,i*3+3,";");
        v3=int(parseHMS(substring(v3,1,strlen(v3)-4)));
        tableAddRow(i,v3,v1,0);
      endfor
    endif

    ;remaining columns
    runScript("#ValueFormat HMC8012.Index D0");
    runScript("#ValueFormat HMC8012.Time Time");
    runScript("#ValueFormat HMC8012.Flag D0");

    popupShowInfo("Loaded "+file_name+" data to \r\nTable, Chart and Histogram.\r\n("+string(samples)+" data points)", 1);
    
  endif
  
elseif (name == "Save Log....xxx")

  var dir_list[1];
  dir_list[0]     = "/int";
  dir_list[1]     = "/usb_front";
  var list[0];
  var j;
  var drive;
  var dir_current = unQuote(deviceRead(handle, "DATA:CDIR?"));
  var logfile     = unQuote(deviceRead(handle, "DATA:LOG:FNAM?"));
  var sep         = indexOf(logfile, ".");
  var extension   = substring(logfile, sep);
  var index_str   = getMatch(logfile, "[0-9]+");
  var index_len   = strlen(index_str);
  var maxindex;
  
  if (index_len > 0)
    var index     = int(index_str);
    var logid     = substring(logfile, lastIndexOf(logfile, "/")+1, sep-index_len);
    
    maxindex = int(index_str);
    if (maxindex > 100) 
      maxindex = 10;
    elseif (int(index_str)<30)
      maxindex = 30;
    else
      maxindex = 100;
    endif
  
    for j = 0 to maxindex-2 do
      list[j] = logid + formatInt(j+1, index_len, index_len)+extension;
    endfor
    
    if (index < 1)
      index = 1;
    endif
    file_name = logid + formatInt(index-1, index_len, index_len)+extension;
  else
    maxindex = 0;
    list[0] = substring(logfile, lastIndexOf(logfile, "/")+1);
    file_name = substring(logfile, lastIndexOf(logfile, "/")+1);
  endif
  
  ; upload dialog
  popupInit    ("Save Log");
  popupLabel   ("");
  popupLabel   ("  Upload logging data from device "+handle+" and save to a file.  ");
  popupLabel   ("");
  popupRadio   ("Drive", "dir_current", dir_list);
  if (maxindex == 0)
    popupText  ("From", "file_name", 16);
  else
    popupCombo ("From", "file_name", list);
  endif
  popupFile    ("To", "filename", "", "csv",0);
  popupButtons ("OK", "bStatus", "Cancel");
  popupShow    ();

  if (bStatus)
    deviceWrite(handle, "DATA:CDIR \""+dir_current+"\"");
  
    ; upload data
    drive   = dir_current == "/int" ? "INT" : "EXT";
    samples = int(deviceRead(handle,"DATA:POIN? \""+file_name+"\", "+drive));
    data    = deviceRead(handle,"txrxn? "+string(headerlines+samples)+" DATA:DATA? \""+file_name+"\", "+drive);

    fileDelete(filename);
    fileAppendText(filename, data);
    fileAppendClose(filename);

    popupShowInfo("Saved file "+file_name+" to file\r\n"+filename+"\r\n("+string(samples)+" data points)", 1);
  endif

elseif (name == "Delete Log....xxx")

  var bStatus = 1;
  var dir_current = unQuote(deviceRead(handle, "DATA:CDIR?"));
  var drive       = dir_current == "/int" ? "INT" : "EXT";
  var logfile     = unQuote(deviceRead(handle, "DATA:LOG:FNAM?"));
  var file_name   = substring(logfile, lastIndexOf(logfile, "/")+1);
  var points;
  
  ; upload dialog
  while (bStatus) do 
    popupInit    ("Delete Log");
    popupLabel   ("");
    popupLabel   ("  Delete log from the current directory on the remote device.  ");
    popupLabel   ("");
    popupLabel   (dir_current+"/");
    popupText    ("File", "file_name", 16);
    popupButtons ("Delete", "bStatus", "Close");
    popupShow    ();
    
    if (bStatus)
       ; NOTE: this line times out and terminates when the file is not available. This ensures
       ;       that no DEL statement is executed in this case (can corrupt HMC8012 state)
       points = deviceRead(handle, "DATA:POIN \""+file_name+"\", "+drive);
       deviceWrite(handle, "DATA:DEL \""+file_name+"\", "+drive);
       popupShowInfo("Deleted log on remote device\r\n"+file_name, 1);
    endif
  endwhile

elseif (name == "Change Drive....xxx")

  var dir_list[1];
  dir_list[0]     = "/int";
  dir_list[1]     = "/usb_front";
  var dir_current = unQuote(deviceRead(handle, "DATA:CDIR?"));
  file_name       = "";
  
  popupInit   ("Change Drive");
  popupLabel  ("");
  popupLabel  ("  Change to a new drive on the remote device.  ");
  popupLabel  ("");
  popupCombo  ("Drive", "dir_current", dir_list);
  popupButtons("Change", "bStatus", "Close");
  popupShow   ();

  if (bStatus)
     deviceWrite(handle, "DATA:CDIR \""+dir_current+"\"");
  endif
  
endif


#otherText
var headerlines=21;
var filename=name;
var samples;
var data;
var nl;
var func;
var all;

if (name=="Device Settings.txt" || name=="Init Sequence.txt")
  all  = name=="Device Settings.txt";
  nl   = ";\r\n";
  func = unQuote(deviceRead(handle,"FUNC?"));

  if (all)
    print(";; Device settings, use commands in a script or copy to a terminal."+nl);
  else
    print(";; Initialize the current mode. Use commands in a script or copy to a terminal."+nl);
  endif

  print("FUNC "                +func+nl);
  if (all || func == "VOLT")
    print("VOLT:DC:RANGE:AUTO "  +deviceRead(handle,"VOLT:DC:RANGE:AUTO?")+nl);
    print("VOLT:DC:RANGE "       +deviceRead(handle,"VOLT:DC:RANGE?")+nl);
    print("VOLT:DC:NULL:STAT "   +deviceRead(handle,"VOLT:DC:NULL:STAT?")+nl);
    print("VOLT:DC:NULL:VALUE "  +deviceRead(handle,"VOLT:DC:NULL:VALUE?")+nl);
    print("VOLT:DC:ZERO:AUTO "   +deviceRead(handle,"VOLT:DC:ZERO:AUTO?")+nl);
  endif
  if (all || func == "VOLT:AC")
    print("VOLT:AC:RANGE:AUTO "  +deviceRead(handle,"VOLT:AC:RANGE:AUTO?")+nl);
    print("VOLT:AC:RANGE "       +deviceRead(handle,"VOLT:AC:RANGE?")+nl);
    print("VOLT:AC:NULL:STAT "   +deviceRead(handle,"VOLT:AC:NULL:STAT?")+nl);
    print("VOLT:AC:NULL:VALUE "  +deviceRead(handle,"VOLT:AC:NULL:VALUE?")+nl);
    print("VOLT:AC:BAND "        +deviceRead(handle,"VOLT:AC:BAND?")+nl);
  endif
  if (all || func == "CURR")
    print("CURR:DC:RANGE:AUTO "  +deviceRead(handle,"CURR:DC:RANGE:AUTO?")+nl);
    print("CURR:DC:RANGE "       +deviceRead(handle,"CURR:DC:RANGE?")+nl);
    print("CURR:DC:NULL:STAT "   +deviceRead(handle,"CURR:DC:NULL:STAT?")+nl);
    print("CURR:DC:NULL:VALUE "  +deviceRead(handle,"CURR:DC:NULL:VALUE?")+nl);
  endif
  if (all || func == "CURR:AC")
    print("CURR:AC:RANGE:AUTO "  +deviceRead(handle,"CURR:AC:RANGE:AUTO?")+nl);
    print("CURR:AC:RANGE "       +deviceRead(handle,"CURR:AC:RANGE?")+nl);
    print("CURR:AC:NULL:STAT "   +deviceRead(handle,"CURR:AC:NULL:STAT?")+nl);
    print("CURR:AC:NULL:VALUE "  +deviceRead(handle,"CURR:AC:NULL:VALUE?")+nl);
    print("CURR:AC:BAND "        +deviceRead(handle,"CURR:AC:BAND?")+nl);
  endif
  if (all || func == "FREQ")
    print("FREQ:VOLT:RANGE "     +deviceRead(handle,"FREQ:VOLT:RANGE?")+nl);
    print("FREQ:VOLT:RANGE:AUTO "+deviceRead(handle,"FREQ:VOLT:RANGE:AUTO?")+nl);
  endif
  if (all || func == "FREQ:CURR")
    print("FREQ:CURR:RANGE:AUTO "+deviceRead(handle,"FREQ:CURR:RANGE:AUTO?")+nl);
    print("FREQ:APER "           +deviceRead(handle,"FREQ:APER?")+nl);
  endif
  if (all || func == "RES")
    print("RES:RANGE:AUTO "      +deviceRead(handle,"RES:RANGE:AUTO?")+nl);
    print("RES:RANGE "           +deviceRead(handle,"RES:RANGE?")+nl);
    print("RES:NULL:STAT "       +deviceRead(handle,"RES:NULL:STAT?")+nl);
    print("RES:NULL:VALUE "      +deviceRead(handle,"RES:NULL:VALUE?")+nl);
  endif
  if (all || func == "FRES")
    print("FRES:RANGE:AUTO "     +deviceRead(handle,"FRES:RANGE:AUTO?")+nl);
    print("FRES:RANGE "          +deviceRead(handle,"FRES:RANGE?")+nl);
    print("FRES:NULL:STAT "      +deviceRead(handle,"FRES:NULL:STAT?")+nl);
    print("FRES:NULL:VALUE "     +deviceRead(handle,"FRES:NULL:VALUE?")+nl);
  endif
  if (all || func == "DIOD")
    print("DIOD:BEEP:STAT "      +deviceRead(handle,"DIOD:BEEP:STAT?")+nl);
    print("DIOD:THR "            +deviceRead(handle,"DIOD:THR?")+nl);
  endif
  if (all || func == "CONT")
    print("CONT:BEEP:STAT "      +deviceRead(handle,"CONT:BEEP:STAT?")+nl);
    print("CONT:THR "            +deviceRead(handle,"CONT:THR?")+nl);
  endif
  if (all || func == "CAP")
    print("CAP:RANGE:AUTO "      +deviceRead(handle,"CAP:RANGE:AUTO?")+nl);
    print("CAP:RANGE "           +deviceRead(handle,"CAP:RANGE?")+nl);
    print("CAP:NULL:STAT "       +deviceRead(handle,"CAP:NULL:STAT?")+nl);
    print("CAP:NULL:VALUE "      +deviceRead(handle,"CAP:NULL:VALUE?")+nl);
  endif
  if (all || func == "SENS")
    print("TEMP:TRAN:TYPE "      +deviceRead(handle,"TEMP:TRAN:TYPE?")+nl);
    print("TEMP:TRAN:RTD:TYPE "  +deviceRead(handle,"TEMP:TRAN:RTD:TYPE?")+nl);
    print("TEMP:NULL:STAT "      +deviceRead(handle,"TEMP:NULL:STAT?")+nl);
    print("TEMP:NULL:VALUE "     +deviceRead(handle,"TEMP:NULL:VALUE?")+nl);
  endif
  print("ADCRATE "             +deviceRead(handle,"ADCRATE?")+nl);
  print("SYST:BEEP:STAT "      +deviceRead(handle,"SYST:BEEP:STAT?")+nl);
  print("CALC:LIM:UPP "        +deviceRead(handle,"CALC:LIM:UPP?")+nl);
  print("CALC:LIM:LOW "        +deviceRead(handle,"CALC:LIM:LOW?")+nl);
  print("CALC:DB:REF "         +deviceRead(handle,"CALC:DB:REF?")+nl);
  print("CALC:DBM:REF "        +deviceRead(handle,"CALC:DBM:REF?")+nl);
  print("TRIG:MODE "           +deviceRead(handle,"TRIG:MODE?")+nl);
  print("TRIG:LEV:MODE "       +deviceRead(handle,"TRIG:LEV:MODE?")+nl);
  print("TRIG:LEV "            +deviceRead(handle,"TRIG:LEV?")+nl);
  print("TRIG:INT "            +deviceRead(handle,"TRIG:INT?")+nl);
  print("TRIG:COUN "           +deviceRead(handle,"TRIG:COUN?")+nl);
  print("DATA:LOG:MODE "       +deviceRead(handle,"DATA:LOG:MODE?")+nl);
  print("DATA:LOG:FNAM "       +deviceRead(handle,"DATA:LOG:FNAM?")+nl);
  print("DATA:LOG:FORM "       +deviceRead(handle,"DATA:LOG:FORM?")+nl);
  print("DATA:LOG:INT "        +deviceRead(handle,"DATA:LOG:INT?")+nl);
  print("DATA:LOG:TIME "       +deviceRead(handle,"DATA:LOG:TIME?")+nl);
  print("DATA:LOG:COUN "       +deviceRead(handle,"DATA:LOG:COUN?")+nl);
  print("DATA:LOG:STAT "       +deviceRead(handle,"DATA:LOG:STAT?")+nl);
else
  ; upload data
  samples = int(deviceRead(handle,"DATA:POIN? \""+filename+"\""));
  data    = deviceRead(handle,"txrxn? "+string(headerlines+samples)+" DATA:DATA? \""+filename+"\"");

  ; print data
  print(data);
endif


;------------------------------------------------------------------------------------
; Help
;------------------------------------------------------------------------------------

#notes
Press F1 in Mode or Setup window for device information.

ATTENTION:
When using Power, dB, dBm, Limit and Statistic sub modes, disable this modes before you switch to another instrument mode to prevent out-of-sync conditions.

Revision 1.0  19 Feb 2022
-  Inital release

Revision 1.1  19 Jul 2022
- Add CSV/TXT file upload
- Add SCPI initialization sequence upload
- Add logging control
- Add limit indication to read values
- Add save/recall/reset of device settings
- Update trigger dialog

Revision 1.2  24 Jul 2022
- Add table column formatting
- Add logging file upload
- Add logging file load from HDD/USB stick

Revision 1.3  11 Aug 2022
- Add Hardcopy routine with timestamp per picture
- Correct bug in Setup tab
- Correct bug in "Load from File" function
- Add support for logging to USB stick


#helpurl https://www.rohde-schwarz.com/de/file/HMC8012_SCPI_ProgrammersManual_en_01.pdf
;#helpurl https://scdn.rohde-schwarz.com/ur/pws/dl_downloads/dl_common_library/dl_manuals/gb_1/h/hmc8012_1/HMC8012_UserManual_de_en_05.pdf


;------------------------------------------------------------------------------------
; Debug
;------------------------------------------------------------------------------------

;#DEBUG HMC8012  +modeComm +valueComm +otherComm +commHex



