; TestController device configuration file for Racal-Dana 1998 en 1999 Frequency Counters
; Version 1.01
; Date 27-06-2023
; Written by Gertjan Miedema,  info at miedemageluid dot nl,  Username "Gertjan" at EEVblog.


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

; Some tips:
; - For use with the counter in the ADDRESSED MODE (GPIB dip switch 1 DOWN)
;
; - The counter is used in one-shot measurement mode. One measurement is made in each logging interval.
;
; - Take care to set the logging interval a bit longer than the gate-time, plus a bit overhead!
;
; - When logging, the first reading can be empty, when there was no previous measurement.
;   This is because the counter buffer is first read-out, then the next measurement is triggered.
;
; - When choosing NULL mode (relative mode), the difference between the measurement and the value stored as NULL reference is shown.
;   The value present in the counter buffer when pushing the NULL button is used as NULL reference.
;   So be sure there is a value in the counter buffer from a previous measurement!

; Known issues:
; - The counter buffer can be read-out only once. After read-out the buffer is cleared.
;   So, while logging, if you look at the "Current values" tab, or use a Readout popup, 
;   you will be missing values in in your log table.... (because those values were already read-out by something else)
;
; - With the Fenrir GPIB interface, the counter does not return to local control after ending TestController.
;   (Probably a Fenrir issue...) Use the LOCAL button on the counter to return to front panel control.
;
; - There is a bug in the GPIB implementation that HKJ has not fixed yet: It can only handle one device for each GPIB controller.



; Meta definition for Racal-Dana 1998 counter
#metadef
#idString Racal-Dana,1998
#name Racal-Dana 1998
#handle Racal1998


; Meta definition to also support Racal-Dana 1999 counter
#metadef
#idString Racal-Dana,1999
#name Racal-Dana 1999
#handle Racal1999

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

; The 1999 model does not have the Ratio B/A function
#remove #cmdMode Ratio_B/A RatioBA




#meta
#idString Racal-Dana,1998
#name Racal-Dana 1998
#handle Racal1998

#port GPIB
#driver Ascii
#interfaceType Counter

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

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

#notes  Device configuration file for Racal-Dana 1998 en 1999 Frequency Counters.

For use with a Prologix GPIB interface, or clone. (AR488!)
Use the counter in the ADDRESSED MODE. (Dip switch 1 DOWN)

- Take care to choose the logging interval longer than the gate-time!

- Do NOT use Readout popups etc. while logging, or there will be values missing in the log table.

- For more info, see the notes in the header of the device configuration file (Racal1998-1999.txt)


Configuration file version: 1.01



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

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

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

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

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



; ================= Original Racal-Dana commands to SCPI/TestController commands translations  ======================

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

; command to init
; [LLO]  Set device in remote control mode, i.e. the user interface on the device is disabled.
; REN    Remote
; IP     Set instrument to power up preset
; RE     Stop current measurement cycle and clear output buffer
; T1:    Select one-shot measurement mode
#scpiCmd init tx RE,IP,T1


; Command to initialize and set interface variables
#scpiCmd setVars tx none
:setvar: Function="FreqA"
:setvar: TrigStatus="trigSine"
:setvar: ImpA="AimpHigh"
:setvar: FilterA="AfilterOff"
:setvar: AttenA="AattenOff"
:setvar: Null="nullOff"
:setvar: NullValue="0"


; Final commands to counter before breaking connection, used to restore local control
; RE    Stop measurement cycle, and clear output buffer
; T0    Back to continuous measurement mode
; IP    Set instrument to power up state
; GTL   Go To Local
; UNL   UNListen
; [CLR] Do a "Selected Device Clear" function.
; [LOC] Set device in local control mode, i.e. the user interface on the device is active.

#scpiCmd reset tx RE,T0,IP

#scpiCmd goLocal tx [LOC]




; -----  Instrument identification    -----
; RUT  Recall unit type
; RMS  Recall Master software issue number
; RGS  Recall GPIB software issue number
 
; Recall the model number
#scpiCmd model? txrx? T1,RUT
:string: 
:readmath: substring(value,10,14);

; Recall the firmware version
#scpiCmd getDeviceSW? txrx? T1,RMS
:string: 
:readmath: substring(value,6,14);

; Recall the GPIB firmware version.
#scpiCmd getDeviceGpibSW? txrx? T1,RGS
:string: 
:readmath: substring(value,6,14);

; Recall the device serial number 
; (Not available on these counters. For identification purposes TestController uses GPIB firmware as serial number)
#scpiCmd getDeviceSN? txrx? T1,RGS
:string: 
:readmath: substring(value,6,14);



; -----  data read out  -----

; Prepare the meter to response to #askValues
; T1   Select one-shot measurement mode
; T2   Take one measurement
#scpiCmd prepareSample tx T2

; command to read current value from the counter buffer.

#scpiCmd value? txrx?
:string: 
:readmath: substring(value,2);
:setvar: NullValue=value



; ----------------  control  -----------------

; Select continuous measurement mode
#scpiCmd measureCont tx T0

; Select one-shot measurement mode
#scpiCmd measureOneShot tx T1

; Take one measurement
#scpiCmd measureTake tx T2



; -----  Mode selection  ------
; FA   Frequency A
; FB   Frequency B
; PA   Period A
; RA   Ratio A/D
; RB   Ratio A/B
; CK   Check

; Recall Measurement Function
#scpiCmd askMode? none?
:readmath: Function

; Set Measurement function: Frequency A
#scpiCmd freqA tx FA
:setvar: Function="FreqA"

; Set Measurement function: Frequency B
#scpiCmd freqB tx FB
:setvar: Function="FreqB"

; Set Measurement function: Period A
#scpiCmd periodA tx PA
:setvar: Function="PerA"

; Set Measurement function: Check
#scpiCmd check tx CK
:setvar: Function="Check"

; Set Measurement function: Ratio B/A
#scpiCmd ratioBA tx RB
:setvar: Function="RatioBA"

; Set Measurement function: Ratio A/D
#scpiCmd ratioAD tx RA
:setvar: Function="RatioAD"


; -----  Set the Gate Time / Resolution  ------
; SRS6  gate time:  1ms
; SRS7  gate time: 10ms
; SRS8  gate time: 100ms
; SRS9  gate time:  1s
; SRS10 gate time: 20s

#scpiCmd gateTime tx SRS(value)

; Recall  Resolution (Query the Gate Time)
#scpiCmd gateTime? txrx? RRS
:string: 
:readmath: substring(value,2);


; -----  Set the trigger level  ------
; APS  A channel, positive pulse offset
; ASS  A channel, sine (no offset)
; ANS  A channel, negative pulse offset

#scpiCmd trigPos tx APS
:setvar: TrigStatus="trigPos"

#scpiCmd trigSine tx ASS
:setvar: TrigStatus="trigSine"

#scpiCmd trigNeg tx ANS
:setvar: TrigStatus="trigNeg"

; Query the status of the trigger level
#scpiCmd trigStatus? none?
:readmath: TrigStatus


; ----- Set A channel input impedance  -----
; AHI  A channel High Impedance (1M)
; ALI  A channel low Impedance (50R)

#scpiCmd AimpHigh tx AHI
:setvar: ImpA="AimpHigh"

#scpiCmd AimpLow tx ALI
:setvar: ImpA="AimpLow"

; Query the status of the input impedance
#scpiCmd Aimp? none?
:readmath: ImpA


; ----- Set A channel Attenuator  -----
; AAD  A channel Attenuator Disabled
; AAE  A channel Attenuator Enabled

#scpiCmd AattenOff tx AAD
:setvar: AttenA="AattenOff"

#scpiCmd AattenOn tx AAE
:setvar: AttenA="AattenOn"

; Query the status of the Ch.A Attenuator
#scpiCmd Aatten? none?
:readmath: AttenA


; ----- Set A channel Filter  -----
; AFD  A channel Filter Disabled
; AEE  A channel Filter Enabled

#scpiCmd AfilterOff tx AFD
:setvar: FilterA="AfilterOff"

#scpiCmd AfilterOn tx AFE
:setvar: FilterA="AfilterOn"

; Query the status of the Ch.A Filter
#scpiCmd Afilter? none?
:readmath: FilterA


; ----- Set NULL (relative) mode  -----
; ND  Null Disabled (normal)
; NE  Null Enabled (relative mode)
; SN  Store Null value
; RN  Recall Null value

#scpiCmd nullOff tx ND
:setvar: Null="nullOff"

#scpiCmd nullOn tx NE
:setvar: Null="nullOn"

; Query the status of the Null mode
#scpiCmd null? none?
:readmath: Null

; Store Null value
#scpiCmd nullValue tx SN(NullValue)


; Recall Null value
#scpiCmd nullValue? txRx? RN


; =================================  End command conversion Racal -> TC SCPI  ===========================



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

; A list of possible column name with unit and formatter (SI, Time, Int, D0..D6)
; Unit example for 10MHz: SI: 10M, D: 1.E7
; code: #value name unit format {selector}
#value Freq.A Hz SI Frequency_A
#value Freq.B Hz SI Frequency_B
#value Period sec SI Period_A
#value Ratio.B/A _ D6 Ratio_B/A 
#value Ratio.A/D _ D6 Ratio_A/D  

; Prepare the meter to response to #askValues
; Take a measurement in advance, to fill the buffer before the logging starts
#prepareSample prepareSample;[1500]

; This is a single line command
; First read the value of the previous measurement out of the buffer, then clear buffer and start the next measurement
#askValues value?;measureTake

#askMode askMode?





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

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

; Initial commands to meter when establishing connection, used to disable local control
; With "setVars" the Menu commands are executed to declare and set their variables
#initCmd init;setVars

; Final command to meter before breaking connection, used to restore local control
#finalCmd reset;goLocal;[1000];



; ================== Menu's  ================================

; -----  Mode (Function) menu  -----

; code: #cmdMode modeLabel deviceModeString SCPI commands
#cmdMode Frequency_A FreqA
freqA;measureOneShot

#cmdMode Frequency_B FreqB
freqB;measureOneShot

#cmdMode Period_A PerA
periodA;measureOneShot

;#cmdMode Check Check
;check;measureCont

#cmdMode Ratio_B/A RatioBA
ratioBA;measureOneShot

#cmdMode Ratio_A/D RatioAD
ratioAD;measureOneShot


; ----- Setup menu  -----

#cmdSetup radio Gate_Time
:read: gateTime?;
:write: gateTime #
:tip: <html>Set Resolution using the Gate Time:<br>1ms=6digits, 10ms=7digits, 100ms=8digits, 1sec=9digits, 20sec=10digits
1ms 6
10ms 7
100ms 8
1s 9
20s 10


#cmdSetup buttonsOn NULL_(relative_mode)
:read: null?
:string:
:write: nullValue;#
:tip: <html>Measure difference between measured and stored frequency<br>Last measurement value will be stored as NULL value
Off nullOff
Enabled nullOn


#cmdSetup separator Ch.A_Trigger_Level
2 100 Raised


#cmdSetup radio Ch.A_Trigger_Level
:read: trigStatus?;
:string:
:write: #
:tip: Set a +9mV positive, zero or -9mV negative Trigger Level
Pos_pulse trigPos
Sine trigSine
Neg_pulse trigNeg


#cmdSetup buttonsOn Ch.A_Input_Impedance
:read: Aimp?
:string:
:write: #
; :tip: Set the A channel input impedance
1_Meg AimpHigh
50_Ohm AimpLow


#cmdSetup buttonsOn Ch.A_Attenuator
:read: Aatten?
:string:
:write: #
:tip: Channel A input 20x attenuator
Off AattenOff
On AattenOn


#cmdSetup buttonsOn Ch.A_Low-Pass_Filter
:read: Afilter?
:string:
:write: #
:tip: Channel A 50kHz Low Pass filter
Off AfilterOff
On AfilterOn
