%% Measure Frequency on Keysight(R) 532xx Frequency Counter Using the IVI-C Driver
% This example shows how to initialize the driver, read a few properties of
% the driver and measure frequency using Keysight Technologies 532xx
% Frequency Counter and output the result in MATLAB(R).

%%
% Copyright 2015 The MathWorks, Inc.

%% Requirements
% This example requires the following:
%
% * Keysight IO libraries version 17.1 or newer
% * Keysight 532xx Frequency Counter IVI driver version 1.0.11.0 or newer
%

%% Enumerate Available IVI-C Drivers On The Computer
% This enumerates the IVI drivers that have been installed on the computer.
IviInfo = instrhwinfo('ivi');
IviInfo.Modules

%% Create MATLAB Instrument Driver And Connect To The Instrument

% Create the MATLAB instrument driver
makemid('Ag532xx','Ag532xx.mdd')

% Use icdevice with the MATLAB instrument driver name and instrument's
% resource name to create a device object. In this example the instrument
% is connected by GPIB at board index 0 and primary address 1.
myInstrument = icdevice('Ag532xx.mdd', 'GPIB0::01::INSTR','optionstring','simulate=true');

% Connect driver instance
connect(myInstrument);

%% Attributes and Variables Definition

% These values are defined in the driver's header file 'Ag532xx.h'
AG532XX_VAL_SLOPE_POSITIVE = 1;
AG532XX_VAL_TRIGGER_SOURCE_IMMEDIATE = 0;
AG532XX_VAL_ARM_MEASUREMENT_TYPE_FREQUENCY = 0;
AG532XX_VAL_ARM_SOURCE_ADVANCED = 3;
AG532XX_VAL_IMMEDIATE_ARM_TYPE = 1;
AG532XX_VAL_DELAY_HOLD_OFF_SOURCE_TIME = 1;

%% Get General Device Properties
% Query information about the driver and instrument

InherentIviAttributesDriverIdentification = get(myInstrument,'Inherentiviattributesdriveridentification');
InherentIviAttributesInstrumentIdentification = get(myInstrument,'Inherentiviattributesinstrumentidentification');
Utility = get(myInstrument, 'Utility');
Revision = invoke(Utility, 'revisionquery');
Vendor = get(InherentIviAttributesDriverIdentification, 'Specific_Driver_Vendor');
Description = get(InherentIviAttributesDriverIdentification, 'Specific_Driver_Description');
InstrumentModel = get(InherentIviAttributesInstrumentIdentification, 'Instrument_Model');
FirmwareRev = get(InherentIviAttributesInstrumentIdentification, 'Instrument_Firmware_Revision');

% Print the queried driver properties
fprintf('Revision:        %s\n', Revision);
fprintf('Vendor:          %s\n', Vendor);
fprintf('Description:     %s\n', Description);
fprintf('InstrumentModel: %s\n', InstrumentModel);
fprintf('FirmwareRev:     %s\n', FirmwareRev);
fprintf(' \n');

%% Basic Frequency Measurement

fprintf('\nBasic Frequency Measurement \n');
% Configure the counter for a frequency measurement on the specified
% channel
InstrumentSpecificFrequency = get(myInstrument,'Instrumentspecificfrequency');
invoke(InstrumentSpecificFrequency, 'frequencyconfigure', 1E6,1E-4,1);
% Sets the number of triggers that will be accepted by the instrument
% before returning to the "idle" trigger state
InstrumentSpecificTrigger = get(myInstrument,'Instrumentspecifictrigger');
set(InstrumentSpecificTrigger, 'Trigger_Count', 1);
% Sets trigger source for measurements.
% IMMediate (continuous) source immediately issues the trigger
set(InstrumentSpecificTrigger, 'Trigger_Source', AG532XX_VAL_TRIGGER_SOURCE_IMMEDIATE);
% Sets slope of the trigger signal on the rear-panel Trig In BNC
set(InstrumentSpecificTrigger, 'Trigger_Slope', AG532XX_VAL_SLOPE_POSITIVE);
% Initiates a measurement based on the current configuration.
MeasurementLowLevelMeasurement = get(myInstrument,'Measurementlowlevelmeasurement');
invoke(MeasurementLowLevelMeasurement, 'initiate');
% Does not return until previously started operations complete or more
% MaxTimeMilliseconds milliseconds of time have expired.
InstrumentSpecificSystem = get(myInstrument,'Instrumentspecificsystem');
invoke(InstrumentSpecificSystem, 'systemwaitforoperationcomplete', 10000);
% Retrieves the result from a previously initiated measurement.
RetVal = invoke(MeasurementLowLevelMeasurement, 'fetch');
fprintf('Data: %0.15g\n', RetVal);

%% Measure Frequency With Averaging Function
% Gets the mathematical average (mean) of all measurements taken since the
% last time statistics were cleared. The purpose of using averaging
% function is to increase the reliability and signal-to-noise ratio of the
% measurements.

fprintf('\nAveraging  \n');
% Configures the counter for a frequency measurement on the specified
% channel
invoke(InstrumentSpecificFrequency, 'frequencyconfigure', 1E6,1E-4,1);
% Sets the number of triggers that will be accepted by the instrument
% before returning to the "idle" trigger state
set(InstrumentSpecificTrigger, 'Trigger_Count', 1);
% Sets trigger source for measurements.
% Immediate (continuous) source immediately issues the trigger
set(InstrumentSpecificTrigger, 'Trigger_Source', AG532XX_VAL_TRIGGER_SOURCE_IMMEDIATE);
% Sets the number of measurements samples the instrument will take per trigger
set(InstrumentSpecificTrigger, 'Trigger_Sample_Count', 3);
% Sets slope of the trigger signal on the rear-panel Trig In BNC
set(InstrumentSpecificTrigger, 'Trigger_Slope', AG532XX_VAL_SLOPE_POSITIVE);
% Enables all calculate commands
InstrumentSpecificMath = get(myInstrument, 'Instrumentspecificmath');
set(InstrumentSpecificMath, 'Math_Enabled', true);
% Enables statistics computation
InstrumentSpecificMathStatistics = get(myInstrument,'Instrumentspecificmathstatistics');
set(InstrumentSpecificMathStatistics, 'Statistics_Enabled', true);
% Initiates a measurement based on the current configuration.
invoke(MeasurementLowLevelMeasurement, 'initiate');
% Does not return until previously started operations complete or more
% MaxTimeMilliseconds milliseconds of time have expired.
invoke(InstrumentSpecificSystem, 'systemwaitforoperationcomplete', 10000);
% Gets the mathematical average (mean) of all measurements taken since
% the last time statistics were cleared
Average = get(InstrumentSpecificMathStatistics, 'Statistics_Average');
fprintf('Average : %0.15g \n',  Average);

%% Measure Time Stamp
% Time stamp measurements record frequency signal edges as they occur on
% the counter input channels

fprintf('\nTime Stamp Measurement \n');
% Set all measurement parameters and trigger parameters to default
% values selectively for timestamp measurements, then immediately
% trigger a measurement.
InstrumentSpecificTimeStamp = get(myInstrument,'Instrumentspecifictimestamp');
% [VAL,VALACTUALSIZE] = INVOKE(OBJ,'timestampmeasure',COUNT,CHANNEL,VALBUFFERSIZE,VAL)
[Val, ValActualSize] = invoke(InstrumentSpecificTimeStamp, 'timestampmeasure', 10,1,10,zeros(10));
fprintf('%d Data Points: \n',ValActualSize);
for i= 1:ValActualSize
    fprintf('%0.15g\t\n', Val(i));
end

%% Measure Time Interval Between Two Channels
% The measurement starts on a positive (rising) edge on channel 1, and
% stops on a positive edge on channel 2.

fprintf('\nTime Intervals Measurement with delay \n');
% Configures instrument for a time interval measurement on the specified
% channels
InstrumentSpecificTimeInterval = get(myInstrument,'Instrumentspecifictimeinterval');
invoke(InstrumentSpecificTimeInterval, 'timeintervalconfigure', 1,2);
% Set the gate source for frequency measurement
InstrumentSpecificArm = get(myInstrument,'Instrumentspecificarm');
invoke(InstrumentSpecificArm, 'armsetsource', AG532XX_VAL_ARM_MEASUREMENT_TYPE_FREQUENCY,AG532XX_VAL_ARM_SOURCE_ADVANCED);
% Configures the Start Arm for armed measurements.
Configuration = get(myInstrument,'Configuration');
invoke(Configuration, 'configurestartarm', AG532XX_VAL_IMMEDIATE_ARM_TYPE);
% Set the source used to delay the arm start
InstrumentSpecificArmStartExternal = get(myInstrument,'Instrumentspecificarmstartexternal');
set(InstrumentSpecificArmStartExternal,'Start_External_Delay_Source', AG532XX_VAL_DELAY_HOLD_OFF_SOURCE_TIME);
% Set the delay, in seconds, used after an external armed measurement
% has been armed.
Arming = get(myInstrument,'Arming');
set(Arming, 'External_Start_Arm_Delay', 0.1);
% Configure the Stop Arm for armed measurements.
invoke(Configuration, 'configurestoparm', AG532XX_VAL_IMMEDIATE_ARM_TYPE);
% Set the source used to hold off enabling the stop Arm source
InstrumentSpecificArmStopExternal = get(myInstrument,'Instrumentspecificarmstopexternal');
set(InstrumentSpecificArmStopExternal, 'Stop_External_Hold_Off_Source', AG532XX_VAL_DELAY_HOLD_OFF_SOURCE_TIME);
% Specify the delay, in seconds, after the External Arm Stop event
% has occurred until the measurement stops.
set(Arming, 'External_Stop_Arm_Delay', 0.25);
% Sets the number of triggers that will be accepted by the instrument
% before returning to the "idle" trigger state
set(InstrumentSpecificTrigger, 'Trigger_Count', 1);
% Sets the number of measurements samples the instrument will take per trigger
set(InstrumentSpecificTrigger, 'Trigger_Sample_Count', 3);
% Initiates a measurement based on the current configuration.
invoke(MeasurementLowLevelMeasurement, 'initiate');
% Wait until initialization operation complete or 50000 milliseconds
% of time have expired
invoke(InstrumentSpecificSystem, 'systemwaitforoperationcomplete', 50000);
% Retrieves the result from a previously initiated measurement.
RetVal = invoke(MeasurementLowLevelMeasurement, 'fetch');
fprintf('Data: %0.15g\n', RetVal);
fprintf('\n');

%% Display Any Errors From The Driver

% If there are any errors, query the driver to retrieve and display them.
ErrorNum = 1;
while (ErrorNum ~= 0)
    [ErrorNum, ErrorMsg] = invoke(Utility, 'errorquery');
    fprintf('ErrorQuery: %d, %s\n', ErrorNum, ErrorMsg);
end

%% Disconnect Device Object and Clean Up
disconnect(myInstrument);
% Remove instrument objects from memory.
delete(myInstrument);

%%



%% Additional Information:
% This example shows the setup and acquisition of frequency from a Counter
% using the IVI driver. Once the measured frequency is retrieved from the 
% instrument, MATLAB can be used to visualize and perform analyses on the 
% data using the rich library of functions in the Signal Processing
% Toolbox(TM) and Communications Systems Toolbox(TM). Using Instrument
% Control Toolbox(TM), it is possible to automate control of instruments,
% and, build test systems that use MATLAB to perform analyses that may not
% be possible using the built-in capability of the hardware.
