;-----------------------------------------------------------------------------
; R&S NGE102(B)/NGE103(B) 2/3 channel PSU
;
; Revision 1.0  19 Feb 2022     Inital release
;
; Revision 1.11 13 Jul 2022     Add trigger configuration (option K103 only)
;                               Add channel 1/2 tracking
;                               Add NEG103(B) support
;                               Add dev  ice settings store/recall
;                               Add arbitrary settings store/recall
;                               Add arbitrary data read/write (basic)
;                               Add SCPI device initialization upload
;                               Add display of HW/FW version
;                               Add device reset
;                               Set date/time on startup based on host RTC
;                               Speed up periodic status update
;                               Remove CH1/2 tab
;                               GUI modifications
;                               Update Help URL
;
; Revision 1.2 28 Jul 2022      Add EasyArb upload/download from CSV file
;                               Add column selection option in download dialog
;
; Revision 1.3 29 Jul 2022      Add Hardcopy routine with timestamp per picture
;                               Add Duration [ms] or absulute Time [s] CSV format
;
;-----------------------------------------------------------------------------

#author   PL (based on HMC8043, WA)


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

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

#sections DEVICE_HAS_2_CHANNELS

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

#sections DEVICE_HAS_2_CHANNELS

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

#sections DEVICE_HAS_3_CHANNELS

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

#sections DEVICE_HAS_3_CHANNELS

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

#driver   SCPIx


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

; Internal: zero constant
#scpiCmd ZERO none
:setvar:
#scpiCmd ZERO? none?
:readmath: (0)

; Internal: show DIO configurations
#scpiCmd DIO:SHOW none
:setvar: dioshow=inputValue
#scpiCmd DIO:SHOW? none?
:readmath: varExists("dioshow")?(dioshow):(0)

; Internal: tracking
#scpiCmd TRACK none
:setvar: track=inputValue
#scpiCmd TRACK? none?
:readmath: varExists("track")?(track):(0)

; 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: recall arb index
#scpiCmd ARB:REC:INDEX none
:setvar: arbrecindex=inputValue
#scpiCmd ARB:REC:INDEX? none?
:readmath: varExists("arbrecindex")?(arbrecindex):(0)

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

; 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];

; set date according to host date
#scpiCmd SYST:DATE:SYNC
SYST:DATE (substring(date(),0,4)+","+substring(date(),4,6)+","+substring(date(),6,8))

; set time according to host time
#scpiCmd SYST:TIME:SYNC
SYST:TIME (substring(date(),8,10)+","+substring(date(),10,12)+","+substring(date(),12,14))


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

; A list of possible column name with unit and formatter (SI, Time, Int, D0..D6)
#value CH1_I A d3
#value CH1_V V d2
#value CH1_P W d2

#value CH2_I A d3
#value CH2_V V d2
#value CH2_P W d2

#metaSection DEVICE_HAS_3_CHANNELS
#value CH3_I A d3
#value CH3_V V d2
#value CH3_P W d2
#metaSection

; 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
#metaSection DEVICE_HAS_2_CHANNELS
#askValues INST:SEL OUT1;MEAS:CURR?;MEAS:VOLT?;MEAS:POW?;INST:SEL OUT2;MEAS:CURR?;MEAS:VOLT?;MEAS:POW?
#outputOff OUTP:GEN 0;INST:SEL OUT1;OUTP:STAT 0;INST:SEL OUT2;OUTP:STAT 0
#metaSection

#metaSection DEVICE_HAS_3_CHANNELS
#askValues INST:SEL OUT1;MEAS:CURR?;MEAS:VOLT?;MEAS:POW?;INST:SEL OUT2;MEAS:CURR?;MEAS:VOLT?;MEAS:POW?;INST:SEL OUT3;MEAS:CURR?;MEAS:VOLT?;MEAS:POW?
#outputOff OUTP:GEN 0;INST:SEL OUT1;OUTP:STAT 0;INST:SEL OUT2;OUTP:STAT 0;INST:SEL OUT3;OUTP:STAT 0
#metaSection

#initCmd   DIO:SHOW 0; SYST:REM; SYST:DATE:SYNC; SYST:TIME:SYNC;
#finalCmd  OUTP:GEN 0; SYST:LOC


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

#interface setVoltage    INST:SEL OUT(channel);VOLT (value)
#interface setCurrent    INST:SEL OUT(channel);CURR (value)
#interface setPower      INST:SEL OUT(channel);POW  (value)
#interface setOVP        INST:SEL OUT(value);VOLT:PROT:LEV (value)
#interface setOPP        INST:SEL OUT(value);POW:PROT:LEV  (value)
#interface setOn         INST:SEL OUT(channel);OUTP:SEL (value)
#interface setAllOn      OUTP:GEN (value)

#interface getVoltage    INST:SEL OUT(channel);VOLT?
#interface getCurrent    INST:SEL OUT(channel);CURR?
#interface getPower      INST:SEL OUT(channel);POW?
#interface getOPV        INST:SEL OUT(value);VOLT:PROT:LEV?
#interface getOPP        INST:SEL OUT(value);POW:PROT:LEV?
#interface getOn         INST:SEL OUT(channel);OUTP:SEL?
#interface getAllOn      OUTP:GEN?

#metaSection DEVICE_HAS_2_CHANNELS
#interfaceType PS P2:2
#interface readCurrent 0 3
#interface readVoltage 1 4
#interface readPower   2 5
#metaSection

#metaSection DEVICE_HAS_3_CHANNELS
#interfaceType PS P2:2 PS:3
#interface readCurrent 0 3 6
#interface readVoltage 1 4 7
#interface readPower   2 5 8
#metaSection


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

#cmdModeLayout 1 2

#cmdMode Arb_Start ARB_START
ARB:START

#cmdMode Arb_Stop ARB_STOP
ARB:STOP


;------------------------------------------------------------------------------------
; CH1
;------------------------------------------------------------------------------------

#cmdSetup Info CH_1 Out
:read:    INST:SEL OUT1;OUTP:MODE?

#cmdSetup Info CH_1 Out
:read:    INST:SEL OUT1;VOLT:PROT:TRIP?
:readmath: (getElement(",OVP",value,","))

#cmdSetup Info CH_1 Out
:read:    INST:SEL OUT1;POW:PROT:TRIP?
:readmath: (getElement(",OPP",value,","))

#cmdSetup Info CH_1 Out
:read:    INST:SEL OUT1;OTP:TRIP?
:readmath: (getElement(",OTP",value,","))

#cmdSetup Info CH_1 Out
:read:    INST:SEL OUT1;FUSE:TRIP?
:readmath: (getElement(",OCP",value,","))

#cmdSetup separator - Out
:color: (240,88,10)
3 100 Solid


#cmdSetup checkbox Set_1 Out
:read:    INST:SEL OUT1;VOLT:PROT:STAT?
:write:   INST:SEL OUT1;VOLT:PROT:STAT
:tip:     Over voltage protection (OVP)
OVP 0 1

#cmdSetup checkbox Set_1 Out
:read:    INST:SEL OUT1;FUSE:STAT?
:write:   INST:SEL OUT1;FUSE:UNLINK 1;FUSE:STAT
:tip:     FUSE
OCP 0 1

#cmdSetup checkbox Set_1 Out
:read:    INST:SEL OUT1;POW:PROT:STAT?
:write:   INST:SEL OUT1;POW:PROT:STAT
:tip:     Over power protection (OPP)
OPP 0 1

#cmdSetup checkbox Set_1 Out
:read:    INST:SEL OUT1;VOLT:RAMP:STAT?
:write:   INST:SEL OUT1;VOLT:RAMP:STAT #
:tip:     Ramp
Ramp 0 1

#cmdSetup checkbox Set_1 Out
:read:    ARB:STAT?
:write:   ARB:STAT #
:tip:     Set arbitrary waveform
Arb 0 1

#cmdSetup selector CH1_Selector Out
:read:    TRACK?
0         Out_Regular.
1         Out_Track.


#cmdSetup number V_ Out_Regular
:read:    INST:SEL OUT1;VOLT?
:write:   INST:SEL OUT1;VOLT
:tip:     Set voltage
V 0 32.50

#cmdSetup number I_ Out_Regular
:read:    INST:SEL OUT1;CURR?
:write:   INST:SEL OUT1;CURR
:tip:     Set current
A 0 3


#cmdSetup number V_ Out_Track
:read:    INST:SEL OUT1;VOLT?
:write:   INST:SEL OUT1;VOLT #;INST:SEL OUT2;VOLT #
:color:   (240,88,10)
:tip:     Set voltage for CH 1/2
V 0 32.50

#cmdSetup number I_ Out_Track
:read:    INST:SEL OUT1;CURR?
:write:   INST:SEL OUT1;CURR #;INST:SEL OUT2;CURR #
:color:   (240,88,10)
:tip:     Set current CH 1/2
A 0 3


;------------------------------------------------------------------------------------
; CH2
;------------------------------------------------------------------------------------

#cmdSetup separator - Out
1 100 Empty

#cmdSetup Info CH_2 Out
:read:    INST:SEL OUT2;OUTP:MODE?

#cmdSetup Info CH_2 Out
:read:    INST:SEL OUT2;VOLT:PROT:TRIP?
:readmath: (getElement(",OVP",value,","))

#cmdSetup Info CH_2 Out
:read:    INST:SEL OUT2;POW:PROT:TRIP?
:readmath: (getElement(",OPP",value,","))

#cmdSetup Info CH_2 Out
:read:    INST:SEL OUT2;OTP:TRIP?
:readmath: (getElement(",OTP",value,","))

#cmdSetup Info CH_2 Out
:read:    INST:SEL OUT2;FUSE:TRIP?
:readmath: (getElement(",OCP",value,","))

#cmdSetup separator - Out
:color:   (0,121,186)
3 100 Solid


#cmdSetup checkbox Set_2 Out
:read:    INST:SEL OUT2;VOLT:PROT:STAT?
:write:   INST:SEL OUT2;VOLT:PROT:STAT
:tip:     Over voltage protection (OVP)
OVP 0 1

#cmdSetup checkbox Set_2 Out
:read:    INST:SEL OUT2;FUSE:STAT?
:write:   INST:SEL OUT2;FUSE:UNLINK 1;FUSE:STAT
:tip:     FUSE
OCP 0 1

#cmdSetup checkbox Set_2 Out
:read:    INST:SEL OUT2;POW:PROT:STAT?
:write:   INST:SEL OUT2;POW:PROT:STAT
:tip:     Over power protection (OPP)
OPP 0 1

#cmdSetup checkbox Set_2 Out
:read:    INST:SEL OUT2;VOLT:RAMP:STAT?
:write:   INST:SEL OUT2;VOLT:RAMP:STAT #
:tip:     Ramp
Ramp 0 1

#cmdSetup checkbox Set_2 Out
:read:    TRACK?
:write:   TRACK #
:update:  CH1_Selector
:tip:     Channel 1/2 tracking
Track 0 1


#cmdSetup number V_ Out
:read:    INST:SEL OUT2;VOLT?
:write:   INST:SEL OUT2;VOLT
:enable:  !Out.Set_2.Track
:tip:     Set voltage
V 0 32.50

#cmdSetup number I_ Out
:read:    INST:SEL OUT2;CURR?
:write:   INST:SEL OUT2;CURR
:enable:  !Out.Set_2.Track
:tip:     Set current
A 0 3


;------------------------------------------------------------------------------------
; CH3
;------------------------------------------------------------------------------------

#metaSection DEVICE_HAS_3_CHANNELS

#cmdSetup separator - Out
1 100 Empty

#cmdSetup Info CH_3 Out
:read:    INST:SEL OUT3;OUTP:MODE?

#cmdSetup Info CH_3 Out
:read:    INST:SEL OUT3;VOLT:PROT:TRIP?
:readmath: (getElement(",OVP",value,","))

#cmdSetup Info CH_3 Out
:read:    INST:SEL OUT3;POW:PROT:TRIP?
:readmath: (getElement(",OPP",value,","))

#cmdSetup Info CH_3 Out
:read:    INST:SEL OUT3;OTP:TRIP?
:readmath: (getElement(",OTP",value,","))

#cmdSetup Info CH_3 Out
:read:    INST:SEL OUT3;FUSE:TRIP?
:readmath: (getElement(",OCP",value,","))

#cmdSetup separator - Out
:color:   (242,203,45)
3 100 Solid


#cmdSetup checkbox Set_3 Out
:read:    INST:SEL OUT3;VOLT:PROT:STAT?
:write:   INST:SEL OUT3;VOLT:PROT:STAT
:tip:     Over voltage protection (OVP)
OVP 0 1

#cmdSetup checkbox Set_3 Out
:read:    INST:SEL OUT3;FUSE:STAT?
:write:   INST:SEL OUT3;FUSE:UNLINK 1;FUSE:STAT
:tip:     FUSE
OCP 0 1

#cmdSetup checkbox Set_3 Out
:read:    INST:SEL OUT3;POW:PROT:STAT?
:write:   INST:SEL OUT3;POW:PROT:STAT
:tip:     Over power protection (OPP)
OPP 0 1

#cmdSetup checkbox Set_3 Out
:read:    INST:SEL OUT3;VOLT:RAMP:STAT?
:write:   INST:SEL OUT3;VOLT:RAMP:STAT #
:tip:     Ramp
Ramp 0 1


#cmdSetup number V_ Out
:read:    INST:SEL OUT3;VOLT?
:write:   INST:SEL OUT3;VOLT
:tip:     Set voltage
V 0 32.50

#cmdSetup number I_ Out
:read:    INST:SEL OUT3;CURR?
:write:   INST:SEL OUT3;CURR
:tip:     Set current
A 0 3

#metaSection


;------------------------------------------------------------------------------------
; CH1 Channel Setup
;------------------------------------------------------------------------------------

#cmdSetup Info CH_1 Set_1

#cmdSetup separator - Set_1
:color: (240,88,10)
3 100 Solid


#cmdSetup comboboxhot OVP_Mode Set_1
:read:    INST:SEL OUT1;VOLT:PROT:MODE?
:write:   INST:SEL OUT1;VOLT:PROT:MODE
:tip:     Measured: return value of the instrument. Protected: adjusted value of the instrument.
:string:
Measure MEASured
Protect PROTected

#cmdSetup number OVP_Limit Set_1
:read:    INST:SEL OUT1;VOLT:PROT:LEV?
:write:   INST:SEL OUT1;VOLT:PROT:LEV
:tip:     OVP voltage limit
V 0 32.5


#cmdSetup number OPP_Limit Set_1
:read:    INST:SEL OUT1;POW:PROT:LEV?
:write:   INST:SEL OUT1;POW:PROT:LEV
:tip:     Set power limit
W 0 33.6


#cmdSetup number OCP_Delay Set_1
:read:    INST:SEL OUT1;FUSE:DELAY?
:write:   INST:SEL OUT1;FUSE:DELAY #
:tip:     When FUSE is active it will first trip after a short delay in CC mode.
s 0 10

#cmdSetup checkbox OCP_Link Set_1
:read:    INST:SEL OUT1;FUSE:LINK? 2
:write:   INST:SEL OUT1;(getElement("FUSE:UNLINK FUSE:LINK",value)) 2
:tip:     Enable FUSE linking
CH_2 0 1

#metaSection DEVICE_HAS_3_CHANNELS
#cmdSetup checkbox OCP_Link Set_1
:read:    INST:SEL OUT1;FUSE:LINK? 3
:write:   INST:SEL OUT1;(getElement("FUSE:UNLINK FUSE:LINK",value)) 3
:tip:     Enable FUSE linking
CH_3 0 1
#metaSection

#cmdSetup button Clear Set_1
:write:   INST:SEL OUT1;VOLT:PROT:CLEAR;POW:PROT:CLEAR
:update:  CH_1
:tip:     Resets the OVP and OPP state.


#cmdSetup separator - Set_1
1 100 Empty

#cmdSetup number Ramp Set_1
:read:    INST:SEL OUT1;VOLT:RAMP:DUR?
:write:   INST:SEL OUT1;VOLT:RAMP:DUR
:tip:     Set ramp duration
s 0 10

#cmdSetup number Arb_Loops Set_1
:read:    ARB:REP?
:write:   ARB:REP
:tip:     Set arbitrary waveform repititions
- 0 65000

#cmdSetup Info ArbPoints Set_1
:read:    ARB:POIN?

;#cmdSetup text Arb_Data Set_1
;:read:    ARB:DATA?
;:write:   ARB:DATA ("\""+replaceRX(replace(value," ",""),"[\n\t;]",",")+"\"")
;:readmath: substring(value,1,strlen(value)-8)
;:tip:     Copy/Paste: V1,I1,t1, ...
;0


;------------------------------------------------------------------------------------
; CH2 Channel Setup
;------------------------------------------------------------------------------------

#cmdSetup Info CH_2 Set_2

#cmdSetup separator - Set_2
:color:   (0,121,186)
3 100 Solid


#cmdSetup comboboxhot OVP_Mode Set_2
:read:    INST:SEL OUT2;VOLT:PROT:MODE?
:write:   INST:SEL OUT2;VOLT:PROT:MODE
:tip:     Measured: return value of the instrument. Protected: adjusted value of the instrument.
:string:
Measure MEASured
Protect PROTected

#cmdSetup number OVP_Limit Set_2
:read:    INST:SEL OUT2;VOLT:PROT:LEV?
:write:   INST:SEL OUT2;VOLT:PROT:LEV
:tip:     Set the OVP voltage limit.
V 0 32.5


#cmdSetup number OPP_Limit Set_2
:read:    INST:SEL OUT2;POW:PROT:LEV?
:write:   INST:SEL OUT2;POW:PROT:LEV
:tip:     Set the OPP power limit.
W 0 33.6


#cmdSetup number OCP_Delay Set_2
:read:    INST:SEL OUT2;FUSE:DELAY?
:write:   INST:SEL OUT2;FUSE:DELAY #
:tip:     When fuse it active it will first trip after a short delay in CC mode.
s 0 10

#cmdSetup checkbox OCP_Link Set_2
:read:    INST:SEL OUT2;FUSE:LINK? 1
:write:   INST:SEL OUT2;(getElement("FUSE:UNLINK FUSE:LINK",value)) 1
:tip:     Enable fuse linking
CH_1 0 1

#metaSection DEVICE_HAS_3_CHANNELS
#cmdSetup checkbox OCP_Link Set_2
:read:    INST:SEL OUT2;FUSE:LINK? 3
:write:   INST:SEL OUT2;(getElement("FUSE:UNLINK FUSE:LINK",value)) 3
:tip:     Enable FUSE linking
CH_3 0 1
#metaSection

#cmdSetup button Clear Set_2
:write:   INST:SEL OUT2;VOLT:PROT:CLEAR;POW:PROT:CLEAR
:update:  CH_2
:tip:     Resets the OVP and OPP state.


#cmdSetup separator - Set_2
1 100 Empty

#cmdSetup number Ramp Set_2
:read:    INST:SEL OUT2;VOLT:RAMP:DUR?
:write:   INST:SEL OUT2;VOLT:RAMP:DUR
:tip:     Set ramp duration
s 0 10


;------------------------------------------------------------------------------------
; CH3 Channel Setup
;------------------------------------------------------------------------------------

#metaSection DEVICE_HAS_3_CHANNELS

#cmdSetup Info CH_3 Set_3

#cmdSetup separator - Set_3
:color:   (242,203,45)
3 100 Solid


#cmdSetup comboboxhot OVP_Mode Set_3
:read:    INST:SEL OUT3;VOLT:PROT:MODE?
:write:   INST:SEL OUT3;VOLT:PROT:MODE
:tip:     Measured: return value of the instrument. Protected: adjusted value of the instrument.
:string:
Measure MEASured
Protect PROTected

#cmdSetup number OVP_Limit Set_3
:read:    INST:SEL OUT3;VOLT:PROT:LEV?
:write:   INST:SEL OUT3;VOLT:PROT:LEV
:tip: Set the OVP voltage limit.
V 0 32.5


#cmdSetup number OPP_Limit Set_3
:read:    INST:SEL OUT3;POW:PROT:LEV?
:write:   INST:SEL OUT3;POW:PROT:LEV
:tip:     Set the OPP power limit.
W 0 33.6


#cmdSetup number OCP_Delay Set_3
:read:    INST:SEL OUT3;FUSE:DELAY?
:write:   INST:SEL OUT3;FUSE:DELAY #
:tip:     When fuse it active it will first trip after a short delay in CC mode.
s 0 10

#cmdSetup checkbox OCP_Link Set_3
:read:    INST:SEL OUT3;FUSE:LINK? 1
:write:   INST:SEL OUT3;(getElement("FUSE:UNLINK FUSE:LINK",value)) 1
:tip:     Enable fuse linking
CH_1 0 1

#cmdSetup checkbox OCP_Link Set_3
:read:    INST:SEL OUT3;FUSE:LINK? 2
:write:   INST:SEL OUT3;(getElement("FUSE:UNLINK FUSE:LINK",value)) 2
:tip:     Enable FUSE linking
CH_2 0 1


#cmdSetup separator - Set_3
1 100 Empty

#cmdSetup button Clear Set_3
:write:   INST:SEL OUT3;VOLT:PROT:CLEAR;POW:PROT:CLEAR
:update:  CH_3
:tip:     Resets the OVP and OPP state.


#cmdSetup separator - Set_3
1 100 Empty

#cmdSetup number Ramp Set_3
:read:  INST:SEL OUT3;VOLT:RAMP:DUR?
:write: INST:SEL OUT3;VOLT:RAMP:DUR
:tip:   Set ramp duration
s 0 10

#metaSection


;------------------------------------------------------------------------------------
; Digital I/O
;------------------------------------------------------------------------------------

#cmdSetup selector K103 DIO
:read:    *OPT?
:readmath: inList("K103",value)
1 DIO_K103.
0 DIO_NONE.

#cmdSetup Info Option_K103_not_installed DIO_NONE

#cmdSetup separator - DIO_NONE
2 100 Solid

#cmdSetup checkbox Master DIO_K103
:read:    TRIG:MAST?
:write:   TRIG:MAST #
:tip:     Enable Triggers
Enable 0 1

#cmdSetup radio Port DIO_K103
:read:    DIO:SHOW?
:write:   DIO:SHOW #
:update:  SelectDIO
:string:
DIO_1 0
DIO_2 1
DIO_3 2
DIO_4 3

#cmdSetup selector SelectDIO DIO_K103
:read:    DIO:SHOW?
0 DIO1.
1 DIO2.
2 DIO3.
3 DIO4.


; ----- DIO1 -----------------------------------------------------------------------
#cmdSetup separator - DIO1
2 100 Solid

#cmdSetup comboboxhot Status DIO1
:read:    TRIG:ENAB:DIO1?
:write:   TRIG:ENAB:DIO1 #
:tip:     Set trigger enable
Disabled 0
Enabled 1

#cmdSetup comboboxhot Channel DIO1
:read:    TRIG:IN:SOUR:DIO1?
:write:   TRIG:IN:SOUR:DIO1 #
:update:  DIO1_Selector
:tip:     Set trigger channel
Ch_1 CH1
Ch_2 CH2
#metaSection DEVICE_HAS_3_CHANNELS
Ch_3 CH3
#metaSection

#cmdSetup comboboxhot Logic DIO1
:read:    TRIG:LOG:DIO1?
:write:   TRIG:LOG:DIO1 #
:tip:     Set trigger logic
Active_High HIGH
Active_Low  LOW

#cmdSetup comboboxhot Direction DIO1
:read:    TRIG:DIR:DIO1?
:write:   TRIG:DIR:DIO1 #
:update:  DIO1_Selector
:tip:     Set trigger direction
Trigger_In  INPut
Trigger_Out OUTPut

#cmdSetup selector DIO1_Selector DIO1
:read:    TRIG:DIR:DIO1?
INPut     DIO1_Input.
OUTPut    DIO1_Output.

#cmdSetup comboboxhot Response DIO1_Input
:read:    TRIG:IN:RESP:DIO1?
:write:   TRIG:IN:RESP:DIO1 #
:update:  DIO1_Response_Selector
:tip:     Set trigger resonse
Output_On      ON
Output_Off     OFF
Output_Toggle  TOGGle
Output_Inhibit INHibit
EasyArb_Active ARBitrary

#cmdSetup selector DIO1_Response_Selector DIO1_Input
:read:    TRIG:IN:RESP:DIO1?
ON        DIO1_Input_Level.
OFF       DIO1_Input_Level.
TOGGle    DIO1_Input_Pulse.
INHibit   DIO1_Input_Level.
ARBitrary DIO1_Input_Arb.

#cmdSetup comboboxhot Trigger DIO1_Input_Pulse
:read:    ZERO?
:enable:  (0)
Pulse 0

#cmdSetup comboboxhot Trigger DIO1_Input_Level
:read:    ZERO?
:enable:  (0)
Level 0

#cmdSetup comboboxhot Trigger DIO1_Input_Arb
:read:  TRIG:IN:ARB:DIO1?
:write: TRIG:IN:ARB:DIO1 #
:tip:   Set trigger trigger
Pulse PULSe
Level LEVel

#cmdSetup comboboxhot Condition DIO1_Output
:read:    TRIG:OUT:COND:DIO1?
:write:   TRIG:OUT:COND:DIO1 #
:update:  DIO1_Condition_Selector
:tip:     Set trigger condtion
Output_On      ON
Output_Off     OFF
Fuse_Tripped   FUSetrip
CC_Mode        CCMode
Voltage_Level  VOLTlevel
Current_Level  CURRlevel
Critical_Event CRITevent
EasyArb_Active ARBitrary

#cmdSetup selector DIO1_Condition_Selector DIO1_Output
:read:    TRIG:OUT:COND:DIO1?
ON        DIO1_Output_Spare.
OFF       DIO1_Output_Spare.
FUSetrip  DIO1_Output_Spare.
CCMode    DIO1_Output_Spare.
VOLTlevel DIO1_Output_Voltlevel.
CURRlevel DIO1_Output_Currlevel.
CRITevent DIO1_Output_Critevent.
ARBitrary DIO1_Output_Spare.

#cmdSetup Info _ DIO1_Output_Spare

#cmdSetup number _ DIO1_Output_Currlevel
:read:    TRIG:OUT:CURR:DIO1?
:write:   TRIG:OUT:CURR:DIO1 #
:tip:     Set current level
A 0 3.0

#cmdSetup number _ DIO1_Output_Voltlevel
:read:    TRIG:OUT:VOLT:DIO1?
:write:   TRIG:OUT:VOLT:DIO1 #
:tip: Set voltage level
V 0 32.50

#cmdSetup comboboxhot _ DIO1_Output_Critevent
:read:    TRIG:OUT:CRIT:DIO1?
:write:   TRIG:OUT:CRIT:DIO1 #
:tip:     Set trigger event
OVP OVP
OPP OPP
OTP OTP


; ----- DIO2 -----------------------------------------------------------------------
#cmdSetup separator - DIO2
2 100 Solid

#cmdSetup comboboxhot Status DIO2
:read:    TRIG:ENAB:DIO2?
:write:   TRIG:ENAB:DIO2 #
:tip:     Set trigger enable
Disabled 0
Enabled 1

#cmdSetup comboboxhot Channel DIO2
:read:    TRIG:IN:SOUR:DIO2?
:write:   TRIG:IN:SOUR:DIO2 #
:update:  DIO2_Selector
:tip:     Set trigger channel
Ch_1 CH1
Ch_2 CH2
#metaSection DEVICE_HAS_3_CHANNELS
Ch_3 CH3
#metaSection

#cmdSetup comboboxhot Logic DIO2
:read:    TRIG:LOG:DIO2?
:write:   TRIG:LOG:DIO2 #
:tip:     Set trigger logic
Active_High HIGH
Active_Low  LOW

#cmdSetup comboboxhot Direction DIO2
:read:    TRIG:DIR:DIO2?
:write:   TRIG:DIR:DIO2 #
:update:  DIO2_Selector
:tip:     Set trigger direction
Trigger_In  INPut
Trigger_Out OUTPut

#cmdSetup selector DIO2_Selector DIO2
:read:    TRIG:DIR:DIO2?
INPut     DIO2_Input.
OUTPut    DIO2_Output.

#cmdSetup comboboxhot Response DIO2_Input
:read:    TRIG:IN:RESP:DIO2?
:write:   TRIG:IN:RESP:DIO2 #
:update:  DIO2_Response_Selector
:tip:     Set trigger resonse
Output_On      ON
Output_Off     OFF
Output_Toggle  TOGGle
Output_Inhibit INHibit
EasyArb_Active ARBitrary

#cmdSetup selector DIO2_Response_Selector DIO2_Input
:read:    TRIG:IN:RESP:DIO2?
ON        DIO2_Input_Level.
OFF       DIO2_Input_Level.
TOGGle    DIO2_Input_Pulse.
INHibit   DIO2_Input_Level.
ARBitrary DIO2_Input_Arb.

#cmdSetup comboboxhot Trigger DIO2_Input_Pulse
:read:    ZERO?
:enable:  (0)
Pulse 0

#cmdSetup comboboxhot Trigger DIO2_Input_Level
:read:    ZERO?
:enable:  (0)
Level 0

#cmdSetup comboboxhot Trigger DIO2_Input_Arb
:read:    TRIG:IN:ARB:DIO2?
:write:   TRIG:IN:ARB:DIO2 #
:tip:     Set trigger trigger
Pulse     PULSe
Level     LEVel

#cmdSetup comboboxhot Condition DIO2_Output
:read:    TRIG:OUT:COND:DIO2?
:write:   TRIG:OUT:COND:DIO2 #
:update:  DIO2_Condition_Selector
:tip: Set trigger condtion
Output_On      ON
Output_Off     OFF
Fuse_Tripped   FUSetrip
CC_Mode        CCMode
Voltage_Level  VOLTlevel
Current_Level  CURRlevel
Critical_Event CRITevent
EasyArb_Active ARBitrary

#cmdSetup selector DIO2_Condition_Selector DIO2_Output
:read:    TRIG:OUT:COND:DIO2?
ON        DIO2_Output_Spare.
OFF       DIO2_Output_Spare.
FUSetrip  DIO2_Output_Spare.
CCMode    DIO2_Output_Spare.
VOLTlevel DIO2_Output_Voltlevel.
CURRlevel DIO2_Output_Currlevel.
CRITevent DIO2_Output_Critevent.
ARBitrary DIO2_Output_Spare.

#cmdSetup Info _ DIO2_Output_Spare

#cmdSetup number _ DIO2_Output_Currlevel
:read:    TRIG:OUT:CURR:DIO2?
:write:   TRIG:OUT:CURR:DIO2 #
:tip:     Set current level
A 0 3.0

#cmdSetup number _ DIO2_Output_Voltlevel
:read:    TRIG:OUT:VOLT:DIO2?
:write:   TRIG:OUT:VOLT:DIO2 #
:tip:     Set voltage level
V 0 32.50

#cmdSetup comboboxhot _ DIO2_Output_Critevent
:read:    TRIG:OUT:CRIT:DIO2?
:write:   TRIG:OUT:CRIT:DIO2 #
:tip:     Set trigger event
OVP OVP
OPP OPP
OTP OTP


; ----- DIO3 -----------------------------------------------------------------------
#cmdSetup separator - DIO3
2 100 Solid

#cmdSetup comboboxhot Status DIO3
:read:    TRIG:ENAB:DIO3?
:write:   TRIG:ENAB:DIO3 #
:tip:     Set trigger enable
Disabled 0
Enabled 1

#cmdSetup comboboxhot Channel DIO3
:read:    TRIG:IN:SOUR:DIO3?
:write:   TRIG:IN:SOUR:DIO3 #
:update:  DIO3_Selector
:tip:     Set trigger channel
Ch_1 CH1
Ch_2 CH2
#metaSection DEVICE_HAS_3_CHANNELS
Ch_3 CH3
#metaSection

#cmdSetup comboboxhot Logic DIO3
:read:    TRIG:LOG:DIO3?
:write:   TRIG:LOG:DIO3 #
:tip:     Set trigger logic
Active_High HIGH
Active_Low  LOW

#cmdSetup comboboxhot Direction DIO3
:read:    TRIG:DIR:DIO3?
:write:   TRIG:DIR:DIO3 #
:update:  DIO3_Selector
:tip:     Set trigger direction
Trigger_In  INPut
Trigger_Out OUTPut

#cmdSetup selector DIO3_Selector DIO3
:read:    TRIG:DIR:DIO3?
INPut     DIO3_Input.
OUTPut    DIO3_Output.

#cmdSetup comboboxhot Response DIO3_Input
:read:    TRIG:IN:RESP:DIO3?
:write:   TRIG:IN:RESP:DIO3 #
:update:  DIO3_Response_Selector
:tip:     Set trigger resonse
Output_On      ON
Output_Off     OFF
Output_Toggle  TOGGle
Output_Inhibit INHibit
EasyArb_Active ARBitrary

#cmdSetup selector DIO3_Response_Selector DIO3_Input
:read:    TRIG:IN:RESP:DIO3?
ON        DIO3_Input_Level.
OFF       DIO3_Input_Level.
TOGGle    DIO3_Input_Pulse.
INHibit   DIO3_Input_Level.
ARBitrary DIO3_Input_Arb.

#cmdSetup comboboxhot Trigger DIO3_Input_Pulse
:read:    ZERO?
:enable:  (0)
Pulse 0

#cmdSetup comboboxhot Trigger DIO3_Input_Level
:read:    ZERO?
:enable:  (0)
Level 0

#cmdSetup comboboxhot Trigger DIO3_Input_Arb
:read:    TRIG:IN:ARB:DIO3?
:write:   TRIG:IN:ARB:DIO3 #
:tip:     Set trigger trigger
Pulse     PULSe
Level     LEVel

#cmdSetup comboboxhot Condition DIO3_Output
:read:    TRIG:OUT:COND:DIO3?
:write:   TRIG:OUT:COND:DIO3 #
:update:  DIO3_Condition_Selector
:tip:     Set trigger condtion
Output_On      ON
Output_Off     OFF
Fuse_Tripped   FUSetrip
CC_Mode        CCMode
Voltage_Level  VOLTlevel
Current_Level  CURRlevel
Critical_Event CRITevent
EasyArb_Active ARBitrary

#cmdSetup selector DIO3_Condition_Selector DIO3_Output
:read:    TRIG:OUT:COND:DIO3?
ON        DIO3_Output_Spare.
OFF       DIO3_Output_Spare.
FUSetrip  DIO3_Output_Spare.
CCMode    DIO3_Output_Spare.
VOLTlevel DIO3_Output_Voltlevel.
CURRlevel DIO3_Output_Currlevel.
CRITevent DIO3_Output_Critevent.
ARBitrary DIO3_Output_Spare.

#cmdSetup Info _ DIO3_Output_Spare

#cmdSetup number _ DIO3_Output_Currlevel
:read:    TRIG:OUT:CURR:DIO3?
:write:   TRIG:OUT:CURR:DIO3 #
:tip:     Set current level
A 0 3.0

#cmdSetup number _ DIO3_Output_Voltlevel
:read:    TRIG:OUT:VOLT:DIO3?
:write:   TRIG:OUT:VOLT:DIO3 #
:tip:     Set voltage level
V 0 32.50

#cmdSetup comboboxhot _ DIO3_Output_Critevent
:read:    TRIG:OUT:CRIT:DIO3?
:write:   TRIG:OUT:CRIT:DIO3 #
:tip:     Set trigger event
OVP OVP
OPP OPP
OTP OTP


; ----- DIO4 -----------------------------------------------------------------------
#cmdSetup separator - DIO4
2 100 Solid

#cmdSetup comboboxhot Status DIO4
:read:    TRIG:ENAB:DIO4?
:write:   TRIG:ENAB:DIO4 #
:tip:     Set trigger enable
Disabled 0
Enabled 1

#cmdSetup comboboxhot Channel DIO4
:read:    TRIG:IN:SOUR:DIO4?
:write:   TRIG:IN:SOUR:DIO4 #
:update:  DIO4_Selector
:tip:     Set trigger channel
Ch_1 CH1
Ch_2 CH2
#metaSection DEVICE_HAS_3_CHANNELS
Ch_3 CH3
#metaSection

#cmdSetup comboboxhot Logic DIO4
:read:    TRIG:LOG:DIO4?
:write:   TRIG:LOG:DIO4 #
:tip:     Set trigger logic
Active_High HIGH
Active_Low  LOW

#cmdSetup comboboxhot Direction DIO4
:read:    TRIG:DIR:DIO4?
:write:   TRIG:DIR:DIO4 #
:update:  DIO4_Selector
:tip:     Set trigger direction
Trigger_In  INPut
Trigger_Out OUTPut

#cmdSetup selector DIO4_Selector DIO4
:read:    TRIG:DIR:DIO4?
INPut     DIO4_Input.
OUTPut    DIO4_Output.

#cmdSetup comboboxhot Response DIO4_Input
:read:    TRIG:IN:RESP:DIO4?
:write:   TRIG:IN:RESP:DIO4 #
:update:  DIO4_Response_Selector
:tip:     Set trigger resonse
Output_On      ON
Output_Off     OFF
Output_Toggle  TOGGle
Output_Inhibit INHibit
EasyArb_Active ARBitrary

#cmdSetup selector DIO4_Response_Selector DIO4_Input
:read:    TRIG:IN:RESP:DIO4?
ON        DIO4_Input_Level.
OFF       DIO4_Input_Level.
TOGGle    DIO4_Input_Pulse.
INHibit   DIO4_Input_Level.
ARBitrary DIO4_Input_Arb.

#cmdSetup comboboxhot Trigger DIO4_Input_Pulse
:read:    ZERO?
:enable:  (0)
Pulse 0

#cmdSetup comboboxhot Trigger DIO4_Input_Level
:read:    ZERO?
:enable:  (0)
Level 0

#cmdSetup comboboxhot Trigger DIO4_Input_Arb
:read:    TRIG:IN:ARB:DIO4?
:write:   TRIG:IN:ARB:DIO4 #
:tip:     Set trigger trigger
Pulse     PULSe
Level     LEVel

#cmdSetup comboboxhot Condition DIO4_Output
:read:    TRIG:OUT:COND:DIO4?
:write:   TRIG:OUT:COND:DIO4 #
:update:  DIO4_Condition_Selector
:tip:     Set trigger condtion
Output_On      ON
Output_Off     OFF
Fuse_Tripped   FUSetrip
CC_Mode        CCMode
Voltage_Level  VOLTlevel
Current_Level  CURRlevel
Critical_Event CRITevent
EasyArb_Active ARBitrary

#cmdSetup selector DIO4_Condition_Selector DIO4_Output
:read:    TRIG:OUT:COND:DIO4?
ON        DIO4_Output_Spare.
OFF       DIO4_Output_Spare.
FUSetrip  DIO4_Output_Spare.
CCMode    DIO4_Output_Spare.
VOLTlevel DIO4_Output_Voltlevel.
CURRlevel DIO4_Output_Currlevel.
CRITevent DIO4_Output_Critevent.
ARBitrary DIO4_Output_Spare.

#cmdSetup Info _ DIO4_Output_Spare

#cmdSetup number _ DIO4_Output_Currlevel
:read:    TRIG:OUT:CURR:DIO4?
:write:   TRIG:OUT:CURR:DIO4 #
:tip:     Set current level
A 0 3.0

#cmdSetup number _ DIO4_Output_Voltlevel
:read:    TRIG:OUT:VOLT:DIO4?
:write:   TRIG:OUT:VOLT:DIO4 #
:tip:     Set voltage level
V 0 32.50

#cmdSetup comboboxhot _ DIO4_Output_Critevent
:read:    TRIG:OUT:CRIT:DIO4?
:write:   TRIG:OUT:CRIT:DIO4 #
:tip:     Set trigger event
OVP OVP
OPP OPP
OTP OTP


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

#cmdSetup Info Settings Device

#cmdSetup separator - Device
3 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
:update: I_ V_ Set_1 Set_2 Set_3 OVP_Mode OVP_Limit OPP_Limit OCP_Delay OCP_Link Ramp Arb_Loops
:string:
M1 0
M2 1
M3 2
M4 3
M5 4


#cmdSetup separator - Device
3 100 Empty

#cmdSetup Info Arbitrary Device

#cmdSetup separator - Device
3 100 Solid

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

#cmdSetup combobox Memory Device
:read:    ARB:REC:INDEX?
:write:   ARB:REC:INDEX #; ARB:RCL #
:update:  Arb_Loops  Arb_Data
:buttontext: Recall
:string:
M1 0
M2 1
M3 2
M4 3
M5 4


#cmdSetup separator - Device
3 100 Empty

#cmdSetup Info Device Device

#cmdSetup separator - Device
3 100 Solid

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

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


#cmdSetup button Reset Device
:write:   *RST
:update:  I_ V_ Set_1 Set_2 Set_3 OVP_Mode OVP_Limit OPP_Limit OCP_Delay OCP_Link Ramp Arb_Loops Arb_Data Master Status Channel Logic Direction Condition Response Trigger


;------------------------------------------------------------------------------------
; Master
;------------------------------------------------------------------------------------

#cmdSetup buttonsOn CH1
:read:    INST:SEL OUT1;OUTP:SEL?
:write:   INST:SEL OUT1;OUTP:SEL
:tip:     CH1 output
:color:   (240,88,10)
:update:  CH_1
:updatealloff:
Off 0
On 1

#cmdSetup buttonsOn CH2
:read:    INST:SEL OUT2;OUTP:SEL?
:write:   INST:SEL OUT2;OUTP:SEL
:tip:     CH2 output
:color:   (0,121,186)
:update:  CH_2
:updatealloff:
Off 0
On 1

#metaSection DEVICE_HAS_3_CHANNELS
#cmdSetup buttonsOn CH3
:read:    INST:SEL OUT3;OUTP:SEL?
:write:   INST:SEL OUT3;OUTP:SEL
:tip:     CH3 output
:color:   (242,203,45)
:update:  CH_3
:updatealloff:
Off 0
On 1
#metaSection

#cmdSetup buttonsOn Output
:read:    OUTP:GEN?
:write:   OUTP:GEN
:tip:     Master output
:color:   white
:update:  CH_1 CH_2
:updatealloff:
Off 0
On 1

#metaSection DEVICE_HAS_2_CHANNELS
#cmdSetup Updater update
:update: CH_1 CH_2 CH1 CH2 Output
1
#metaSection

#metaSection DEVICE_HAS_3_CHANNELS
#cmdSetup Updater update
:update: CH_1 CH_2 CH_3 CH1 CH2 CH3 Output
1
#metaSection


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

#otherList
menuItem[0] = "Hardcopy....xxx";
menuItem[1] = "Device Status....xxx"
menuItem[2] = "Show Arbitrary.xxx";
menuItem[3] = "Load Arbitrary....xxx";
menuItem[4] = "Save Arbitrary....xxx";
menuItem[5] = "Init Sequence.txt";
menuItem[6] = "Device Settings.txt";


#otherFunc
var i;
var v1;
var v2;
var v3;
var t3;
var col1;
var col2;
var col3;
var samples;
var data;
var command;
var filename;
var bFormat;
var bTimeFormat;
var save_options[1];
var load_options[2];
var time2;
var bStatus      = 0;
var DurationType = "Duration [ms]";
var TimeType     = "Time [s]";
var AutoType     = "Auto";

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

  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")

  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=="Show Arbitrary.xxx")

  samples=deviceRead(handle,"ARB:POIN?");
  data=unQuote(deviceRead(handle,"ARB:DATA?"));

  tableInitHeader(handle+".Index,"+handle+".ARB_t,"+handle+".ARB_V,"+handle+".ARB_I,"+handle+".ARB_d");

  time2 = 0.0;
  t3    = 0.0;
  for i=0 to samples-1 do
    v1 = getElement(data,i*3+0,",");
    v2 = getElement(data,i*3+1,",");
    v3 = getElement(data,i*3+2,",");
    tableAddRow(i+1, time2, v1, v2, v3);
	t3 = double(getElement(data, i*3+2, ","))/1000.0;
	time2 = time2 + t3;
  endfor
  tableAddRow(i+1,time2,0,0,0);

  runScript("#ValueFormat "+handle+".Index D0");
  runScript("#ValueFormat "+handle+".ARB_t D3");
  runScript("#ValueFormat "+handle+".ARB_V D2");
  runScript("#ValueFormat "+handle+".ARB_I D3");
  runScript("#ValueFormat "+handle+".ARB_d D0");

  popupShowInfo("Loaded EasyArb data to\r\nTable, Chart and Histogram.\r\n("+string(int(samples))+" data points)", 1);

elseif (name=="Save Arbitrary....xxx")

  filename        = "";
  bFormat         = DurationType;
  save_options[0] = DurationType;
  save_options[1] = TimeType;
  
  popupInit    ("Save Arbitrary");
  popupLabel   ("");
  popupLabel   ("Save channel 1 EasyArb data to a CSV file.");
  popupLabel   ("");
  popupFile    ("File", "filename", "", "csv",0);
  popupRadio   ("Format", "bFormat", save_options);
  popupButtons ("OK", "bStatus", "Cancel");
  popupShow    ();

  if (bStatus && filename != "")
    samples = deviceRead(handle, "ARB:POIN?");
    data    = unQuote(deviceRead(handle, "ARB:DATA?"));
    data    = substring(data, 0, strlen(data)-7);

    fileDelete(filename);
    if (bFormat == DurationType)
      fileAppendText(filename, "#Duration [ms];Voltage [V];Current [A]\n");
      for i=0 to samples-1 do
        v1 = getElement(data, i*3+0, ",");
        v2 = getElement(data, i*3+1, ",");
        v3 = getElement(data, i*3+2, ",");
        v1 = formatDouble(v1, 2, 2, 2, 2);
        v2 = formatDouble(v2, 1, 1, 3, 3);
        v3 = formatDouble(v3, 9, 3, 0, 0);
        fileAppendText(filename, v3+"; "+v1+"; "+v2+"\n");
      endfor
    else
      fileAppendText(filename, "#Time [s];Voltage [V];Current [A]\n");
      time2 = 0.0;
      for i=0 to samples-1 do
        v1 = getElement(data, i*3+0, ",");
        v2 = getElement(data, i*3+1, ",");
        t3 = double(getElement(data, i*3+2, ","))/1000.0;
        v1 = formatDouble(v1, 2, 2, 2, 2);
        v2 = formatDouble(v2, 1, 1, 3, 3);
        fileAppendText(filename, formatDouble(time2, 9, 3, 2, 2)+"; "+v1+"; "+v2+"\n");
        time2 = time2 + t3;
      endfor
      fileAppendText(filename, formatDouble(time2, 9, 3, 2, 2)+"; 00.00; 0.000\n");
    endif
    fileAppendClose(filename);

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

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

  var list[1];
  var columns;

  for i=0 to 9 do
    list[i] = string(i+1);
  endfor

  columns         = 3;
  col1            = 2;
  col2            = 3;
  col3            = 1;
  filename        = "";
  load_options[0] = AutoType;
  load_options[1] = DurationType;
  load_options[2] = TimeType;
  bFormat         = AutoType;
  
  popupInit   ("Load Arbitrary");
  popupLabel  ("");
  popupLabel  ("Load channel 1 EasyArb data from a CSV file.");
  popupLabel  ("");
  popupFile   ("File", "filename", "", "csv",1);
  popupLabel  ("");
  popupLabel  ("Options:");
  popupCombo  ("Columns", "columns", list);
  popupCombo  ("Time"   , "col3", list);
  popupCombo  ("Voltage", "col1", list);
  popupCombo  ("Current", "col2", list);
  popupRadio  ("Format", "bFormat", load_options);
  popupButtons("OK", "bStatus", "Cancel");
  popupShow   ();

  if (bStatus && filename != "")
    data = fileReadText(filename);
    data = replace  (data, "\r\n","\n");
    data = replaceRX(data, "[ \t]","");
    data = replaceRX(data, "[\n]+\n","\n");
	
    if (bFormat == TimeType)
      bTimeFormat = 1;
    elseif (bFormat == DurationType)
      bTimeFormat = 0;
    else
      bTimeFormat = equalsi(substring(data,0,5),"#Time") || equalsi(substring(data,0,4),"Time");
    endif
    
    data = replaceRX(data, "#[^\n]*\n","");
    data = replace  (data, ";",",");
    data = replace  (data, ",\n","\n");
    data = replace  (data, "\n",",");
    if (substring(data, 0, 1) == ",")
      data = substring(data, 1, strlen(data));
    endif
    if (substring(data, strlen(data)-1, strlen(data)) == ",")
      data = substring(data, 0, strlen(data)-1);
    endif
    samples = (countMatch(data,",")+1)/columns;

    command = "";
    if (bTimeFormat)
      t3      = 0;
      samples = samples-1;
      
      for i=0 to samples-1 do
        v1 = double(getElement(data, i*columns+col1-1, ","));
        v2 = double(getElement(data, i*columns+col2-1, ","));
        v3 = int(double(getElement(data, (i+1)*columns+col3-1, ","))*1000.0);
        command = command + v1 + "," + v2 + "," + string(v3-t3) + ",";
        t3 = v3;
      endfor
    else
      for i=0 to samples-1 do
        v1 = double(getElement(data, i*columns+col1-1, ","));
        v2 = double(getElement(data, i*columns+col2-1, ","));
        v3 = double(getElement(data, i*columns+col3-1, ","));
        command = command + v1 + "," + v2 + "," + v3 + ",";
      endfor
    endif
    
    deviceWrite(handle, "ARB:DATA \""+command+"\"");
    popupShowInfo("Loaded EasyArb data from file\r\n"+filename+"."+"\r\n("+string(int(samples))+" data points)", 1);
  endif

endif


#otherText
var nl;
var func;
var all;
var enable;
var filename;
var samples;
var data;

if (name=="Device Settings.txt" || name=="Init Sequence.txt")
  all  = name=="Device Settings.txt";
  nl   = ";\r\n";

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

  print("INST:SEL OUT1"+nl);
  print("VOLT:PROT:STAT "  +deviceRead(handle,"INST:SEL OUT1;VOLT:PROT:STAT?")+nl);
  print("VOLT:PROT:MODE "  +deviceRead(handle,"INST:SEL OUT1;VOLT:PROT:MODE?")+nl);
  print("VOLT:PROT:LEV "   +deviceRead(handle,"INST:SEL OUT1;VOLT:PROT:LEV?")+nl);
  print("VOLT:RAMP:STAT "  +deviceRead(handle,"INST:SEL OUT1;VOLT:RAMP:STAT?")+nl);
  print("VOLT:RAMP:DUR "   +deviceRead(handle,"INST:SEL OUT1;VOLT:RAMP:DUR?")+nl);
  print("POW:PROT:STAT "   +deviceRead(handle,"INST:SEL OUT1;POW:PROT:STAT?")+nl);
  print("POW:PROT:LEV "    +deviceRead(handle,"INST:SEL OUT1;POW:PROT:LEV?")+nl);
  print("FUSE:STAT "       +deviceRead(handle,"INST:SEL OUT1;FUSE:STAT?")+nl);
  print("FUSE:DELAY "      +deviceRead(handle,"INST:SEL OUT1;FUSE:DELAY?")+nl);
  print("FUSE:"            +getElement("UNLINK LINK",int(deviceRead(handle,"INST:SEL OUT1;FUSE:LINK? 2")))+" 2"+nl);
#metaSection DEVICE_HAS_3_CHANNELS
  print("FUSE:"            +getElement("UNLINK LINK",int(deviceRead(handle,"INST:SEL OUT1;FUSE:LINK? 3")))+" 3"+nl);
#metaSection
  print("VOLT "            +deviceRead(handle,"INST:SEL OUT2;VOLT?")+nl);
  print("CURR "            +deviceRead(handle,"INST:SEL OUT2;CURR?")+nl);

  print("INST:SEL OUT2"+nl);
  print("VOLT:PROT:STAT "  +deviceRead(handle,"INST:SEL OUT2;VOLT:PROT:STAT?")+nl);
  print("VOLT:PROT:MODE "  +deviceRead(handle,"INST:SEL OUT2;VOLT:PROT:MODE?")+nl);
  print("VOLT:PROT:LEV "   +deviceRead(handle,"INST:SEL OUT2;VOLT:PROT:LEV?")+nl);
  print("VOLT:RAMP:STAT "  +deviceRead(handle,"INST:SEL OUT2;VOLT:RAMP:STAT?")+nl);
  print("VOLT:RAMP:DUR "   +deviceRead(handle,"INST:SEL OUT2;VOLT:RAMP:DUR?")+nl);
  print("POW:PROT:STAT "   +deviceRead(handle,"INST:SEL OUT2;POW:PROT:STAT?")+nl);
  print("POW:PROT:LEV "    +deviceRead(handle,"INST:SEL OUT2;POW:PROT:LEV?")+nl);
  print("FUSE:STAT "       +deviceRead(handle,"INST:SEL OUT2;FUSE:STAT?")+nl);
  print("FUSE:DELAY "      +deviceRead(handle,"INST:SEL OUT2;FUSE:DELAY?")+nl);
  print("FUSE:"            +getElement("UNLINK LINK",int(deviceRead(handle,"INST:SEL OUT2;FUSE:LINK? 1")))+" 1"+nl);
#metaSection DEVICE_HAS_3_CHANNELS
  print("FUSE:"            +getElement("UNLINK LINK",int(deviceRead(handle,"INST:SEL OUT2;FUSE:LINK? 3")))+" 3"+nl);
#metaSection
  print("VOLT "            +deviceRead(handle,"INST:SEL OUT2;VOLT?")+nl);
  print("CURR "            +deviceRead(handle,"INST:SEL OUT2;CURR?")+nl);

#metaSection DEVICE_HAS_3_CHANNELS
  print("INST:SEL OUT3"+nl);
  print("VOLT:PROT:STAT "  +deviceRead(handle,"INST:SEL OUT3;VOLT:PROT:STAT?")+nl);
  print("VOLT:PROT:MODE "  +deviceRead(handle,"INST:SEL OUT3;VOLT:PROT:MODE?")+nl);
  print("VOLT:PROT:LEV "   +deviceRead(handle,"INST:SEL OUT3;VOLT:PROT:LEV?")+nl);
  print("VOLT:RAMP:STAT "  +deviceRead(handle,"INST:SEL OUT3;VOLT:RAMP:STAT?")+nl);
  print("VOLT:RAMP:DUR "   +deviceRead(handle,"INST:SEL OUT3;VOLT:RAMP:DUR?")+nl);
  print("POW:PROT:STAT "   +deviceRead(handle,"INST:SEL OUT3;POW:PROT:STAT?")+nl);
  print("POW:PROT:LEV "    +deviceRead(handle,"INST:SEL OUT3;POW:PROT:LEV?")+nl);
  print("FUSE:STAT "       +deviceRead(handle,"INST:SEL OUT3;FUSE:STAT?")+nl);
  print("FUSE:DELAY "      +deviceRead(handle,"INST:SEL OUT3;FUSE:DELAY?")+nl);
  print("FUSE:"            +getElement("UNLINK LINK",int(deviceRead(handle,"INST:SEL OUT3;FUSE:LINK? 1")))+" 1"+nl);
  print("FUSE:"            +getElement("UNLINK LINK",int(deviceRead(handle,"INST:SEL OUT3;FUSE:LINK? 3")))+" 3"+nl);
  print("VOLT "            +deviceRead(handle,"INST:SEL OUT3;VOLT?")+nl);
  print("CURR "            +deviceRead(handle,"INST:SEL OUT3;CURR?")+nl);
#metaSection

  enable=int(deviceRead(handle,"ARB:STAT?"));
  if (all || enable)
    print("ARB:REP "             +deviceRead(handle,"ARB:REP?")+nl);
    print("ARB:DATA "            +deviceRead(handle,"ARB:DATA?")+nl);
  endif
  print("ARB:STAT "              +deviceRead(handle,"ARB:STAT?")+nl);

  enable=int(deviceRead(handle,"TRIG:ENAB:DIO1?"));
  if (all || enable)
    print("TRIG:IN:SOUR:DIO1 "   +deviceRead(handle,"TRIG:IN:SOUR:DIO1?")+nl);
    print("TRIG:IN:RESP:DIO1 "   +deviceRead(handle,"TRIG:IN:RESP:DIO1?")+nl);
    print("TRIG:IN:ARB:DIO1 "    +deviceRead(handle,"TRIG:IN:ARB:DIO1?")+nl);
    print("TRIG:OUT:COND:DIO1 "  +deviceRead(handle,"TRIG:OUT:COND:DIO1?")+nl);
    print("TRIG:OUT:CURR:DIO1 "  +deviceRead(handle,"TRIG:OUT:CURR:DIO1?")+nl);
    print("TRIG:OUT:VOLT:DIO1 "  +deviceRead(handle,"TRIG:OUT:VOLT:DIO1?")+nl);
    print("TRIG:OUT:CRIT:DIO1 "  +deviceRead(handle,"TRIG:OUT:CRIT:DIO1?")+nl);
    print("TRIG:LOG:DIO1 "       +deviceRead(handle,"TRIG:LOG:DIO1?")+nl);
    print("TRIG:DIR:DIO1 "       +deviceRead(handle,"TRIG:DIR:DIO1?")+nl);
  endif
  print("TRIG:ENAB:DIO1 "        +deviceRead(handle,"TRIG:ENAB:DIO1?")+nl);

  enable=int(deviceRead(handle,"TRIG:ENAB:DIO2?"));
  if (all || enable)
    print("TRIG:IN:SOUR:DIO2 "   +deviceRead(handle,"TRIG:IN:SOUR:DIO2?")+nl);
    print("TRIG:IN:RESP:DIO2 "   +deviceRead(handle,"TRIG:IN:RESP:DIO2?")+nl);
    print("TRIG:IN:ARB:DIO2 "    +deviceRead(handle,"TRIG:IN:ARB:DIO2?")+nl);
    print("TRIG:OUT:COND:DIO2 "  +deviceRead(handle,"TRIG:OUT:COND:DIO2?")+nl);
    print("TRIG:OUT:CURR:DIO2 "  +deviceRead(handle,"TRIG:OUT:CURR:DIO2?")+nl);
    print("TRIG:OUT:VOLT:DIO2 "  +deviceRead(handle,"TRIG:OUT:VOLT:DIO2?")+nl);
    print("TRIG:OUT:CRIT:DIO2 "  +deviceRead(handle,"TRIG:OUT:CRIT:DIO2?")+nl);
    print("TRIG:LOG:DIO2 "       +deviceRead(handle,"TRIG:LOG:DIO2?")+nl);
    print("TRIG:DIR:DIO2 "       +deviceRead(handle,"TRIG:DIR:DIO2?")+nl);
  endif
  print("TRIG:ENAB:DIO2 "        +deviceRead(handle,"TRIG:ENAB:DIO2?")+nl);

  enable=int(deviceRead(handle,"TRIG:ENAB:DIO2?"));
  if (all || enable)
    print("TRIG:IN:SOUR:DIO3 "   +deviceRead(handle,"TRIG:IN:SOUR:DIO3?")+nl);
    print("TRIG:IN:RESP:DIO3 "   +deviceRead(handle,"TRIG:IN:RESP:DIO3?")+nl);
    print("TRIG:IN:ARB:DIO3 "    +deviceRead(handle,"TRIG:IN:ARB:DIO3?")+nl);
    print("TRIG:OUT:COND:DIO3 "  +deviceRead(handle,"TRIG:OUT:COND:DIO3?")+nl);
    print("TRIG:OUT:CURR:DIO3 "  +deviceRead(handle,"TRIG:OUT:CURR:DIO3?")+nl);
    print("TRIG:OUT:VOLT:DIO3 "  +deviceRead(handle,"TRIG:OUT:VOLT:DIO3?")+nl);
    print("TRIG:OUT:CRIT:DIO3 "  +deviceRead(handle,"TRIG:OUT:CRIT:DIO3?")+nl);
    print("TRIG:LOG:DIO3 "       +deviceRead(handle,"TRIG:LOG:DIO3?")+nl);
    print("TRIG:DIR:DIO3 "       +deviceRead(handle,"TRIG:DIR:DIO3?")+nl);
  endif
  print("TRIG:ENAB:DIO3 "        +deviceRead(handle,"TRIG:ENAB:DIO3?")+nl);

  enable=int(deviceRead(handle,"TRIG:ENAB:DIO2?"));
  if (all || enable)
    print("TRIG:IN:SOUR:DIO4 "   +deviceRead(handle,"TRIG:IN:SOUR:DIO4?")+nl);
    print("TRIG:IN:RESP:DIO4 "   +deviceRead(handle,"TRIG:IN:RESP:DIO4?")+nl);
    print("TRIG:IN:ARB:DIO4 "    +deviceRead(handle,"TRIG:IN:ARB:DIO4?")+nl);
    print("TRIG:OUT:COND:DIO4 "  +deviceRead(handle,"TRIG:OUT:COND:DIO4?")+nl);
    print("TRIG:OUT:CURR:DIO4 "  +deviceRead(handle,"TRIG:OUT:CURR:DIO4?")+nl);
    print("TRIG:OUT:VOLT:DIO4 "  +deviceRead(handle,"TRIG:OUT:VOLT:DIO4?")+nl);
    print("TRIG:OUT:CRIT:DIO4 "  +deviceRead(handle,"TRIG:OUT:CRIT:DIO4?")+nl);
    print("TRIG:LOG:DIO4 "       +deviceRead(handle,"TRIG:LOG:DIO4?")+nl);
    print("TRIG:DIR:DIO4 "       +deviceRead(handle,"TRIG:DIR:DIO4?")+nl);
  endif
  print("TRIG:ENAB:DIO4 "        +deviceRead(handle,"TRIG:ENAB:DIO4?")+nl);

  print("TRIG:MAST "             +deviceRead(handle,"TRIG:MAST?")+nl);

  print("INST:SEL OUT1;OUTP:SEL "  +deviceRead(handle,"INST:SEL OUT1;OUTP:SEL?")+nl);
  print("INST:SEL OUT2;OUTP:SEL "  +deviceRead(handle,"INST:SEL OUT2;OUTP:SEL?")+nl);
#metaSection DEVICE_HAS_3_CHANNELS
  print("INST:SEL OUT3;OUTP:SEL "  +deviceRead(handle,"INST:SEL OUT3;OUTP:SEL?")+nl);
#metaSection
  print("OUTP:GEN "                +deviceRead(handle,"OUTP:GEN?")+nl);

endif


#otherData


#otherImage


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

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

Revision 1.0  19 Feb 2022
- Inital release

Revision 1.11 13 Jul 2022
- Add trigger configuration
- Add channel 1/2 tracking
- Add NEG103(B) support
- Add device settings store/recall
- Add arbiary settings store/recall
- Add display of HW/FW version
- Add device reset
- Add SCPI device initialization upload
- Set date/time on startup based on host RTC
- Speed up periodic status update
- Remove CH1/2 tab
- GUI modifications
- Update Help URL

Revision 1.2 25 Jul 2022
- Add EasyArb upload/download from CSV file
- Add column selection option in download dialog

Revision 1.3 29 Jul 2022
- Add Hardcopy routine with timestamp per picture
- Add Duration [ms] or absulute Time [s] CSV format


#helpurl https://www.rohde-schwarz.com/de/handbuch/nge100b/


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

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

