942 lines
29 KiB
C#
942 lines
29 KiB
C#
// UNCLASSIFIED
|
|
/*-------------------------------------------------------------------------
|
|
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
|
|
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
|
|
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
|
|
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
|
|
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
|
|
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
|
|
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
|
|
COMPANY.
|
|
|
|
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
|
|
GOVERNMENT.
|
|
|
|
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
|
-------------------------------------------------------------------------*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO.Ports;
|
|
using NationalInstruments.NI4882;
|
|
using NLog;
|
|
using Raytheon.Common;
|
|
using Raytheon.Units;
|
|
|
|
namespace Raytheon.Instruments
|
|
{
|
|
/// <summary>
|
|
/// This class interfaces to a Keysight N3300 Eload system
|
|
/// </summary>
|
|
public class EloadSystemScpiKeysight : IELoadSystem
|
|
{
|
|
|
|
#region PrivateClassMembers
|
|
|
|
private enum ControlInterface
|
|
{
|
|
COM_PORT,
|
|
GPIB
|
|
}
|
|
|
|
// system commands
|
|
private const string _CLEAREVENTREG = "*CLS";
|
|
private const string _CLEARSERVICEREQUEST = "*SRE 0";
|
|
private const string _CLEAREVENTSTATUSENABLEREGISTER = "*ESE 0";
|
|
private const string _ERRORCODE = "SYST:ERR?";
|
|
private const string _RESET = "*RST";
|
|
private const string _SELFTEST = "*TST?";
|
|
|
|
private string _systemName;
|
|
private SerialPort _serialPort;
|
|
private Device _gpibDevice;
|
|
private ControlInterface _interface;
|
|
private readonly SortedDictionary<string, IEload> _eloadChannelMap;
|
|
private readonly bool _isThereHardware;
|
|
private static object _syncObj = new Object();
|
|
// default the timeout for responses to 5 seconds
|
|
private const int _READ_TIMEOUT = 5000;
|
|
|
|
private readonly ILogger _logger;
|
|
|
|
private readonly IConfigurationManager _configurationManager;
|
|
private readonly IConfiguration _configuration;
|
|
|
|
public string DetailedStatus { get; protected set; }
|
|
|
|
public bool DisplayEnabled { get; set; }
|
|
public bool FrontPanelEnabled { get; set; }
|
|
|
|
public InstrumentMetadata Info { get; set; }
|
|
|
|
public string Name { get; protected set; }
|
|
|
|
public SelfTestResult SelfTestResult => PerformSelfTest();
|
|
|
|
public State Status { get; set; }
|
|
|
|
#endregion
|
|
|
|
#region PrivateFuctions
|
|
|
|
/// <summary>
|
|
/// Send a SCPI Command to the instrument and get a response.
|
|
/// </summary>
|
|
/// <param name="commandString">The command to send.</param>
|
|
/// <returns>The instrument response.</returns>
|
|
private string IOQuery(string commandString)
|
|
{
|
|
// not calling IOWrite() so IOWrite() can check for errors after each write
|
|
|
|
string rsp = "";
|
|
|
|
if (_interface == ControlInterface.COM_PORT)
|
|
{
|
|
_serialPort.WriteLine(commandString);
|
|
rsp = _serialPort.ReadLine();
|
|
}
|
|
else if (_interface == ControlInterface.GPIB)
|
|
{
|
|
_gpibDevice.Write(commandString);
|
|
rsp = _gpibDevice.ReadString();
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("unknown interface type: " + _interface.ToString());
|
|
}
|
|
|
|
rsp = rsp.Replace("\r", "");
|
|
|
|
// check for errors
|
|
int err = 0;
|
|
string errorMsg = GetErrorCode(out err);
|
|
if (err != 0)
|
|
{
|
|
throw new Exception(errorMsg);
|
|
}
|
|
|
|
return rsp;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sends a SCPI Command to the instrument.
|
|
/// </summary>
|
|
/// <param name="commandString">The command to send.</param>
|
|
private void IOWrite(string commandString)
|
|
{
|
|
if (_interface == ControlInterface.COM_PORT)
|
|
{
|
|
_serialPort.WriteLine(commandString);
|
|
}
|
|
else if (_interface == ControlInterface.GPIB)
|
|
{
|
|
_gpibDevice.Write(commandString);
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("unknown interface type: " + _interface.ToString());
|
|
}
|
|
|
|
int err = 0;
|
|
string errorMsg = GetErrorCode(out err);
|
|
if (err != 0)
|
|
{
|
|
throw new Exception(errorMsg);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resets the instrument and clears event registers, error queue,
|
|
/// service request enable register, and event status enable register.
|
|
/// </summary>
|
|
private void Reset()
|
|
{
|
|
IOWrite(_RESET);
|
|
|
|
IOWrite(_CLEAREVENTREG);
|
|
|
|
IOWrite(_CLEARSERVICEREQUEST);
|
|
|
|
IOWrite(_CLEAREVENTSTATUSENABLEREGISTER);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region PublicFuctions
|
|
|
|
/// <summary>
|
|
/// FlowMeterOmegaDPF20 factory constructor
|
|
/// </summary>
|
|
/// <param name="deviceName"></param>
|
|
/// <param name="configurationManager"></param>
|
|
public EloadSystemScpiKeysight(string deviceName, IConfigurationManager configurationManager)
|
|
{
|
|
Name = deviceName;
|
|
|
|
_logger = LogManager.GetLogger($"{this.GetType().Name} - {deviceName}");
|
|
|
|
_configurationManager = configurationManager;
|
|
_configuration = _configurationManager.GetConfiguration(Name);
|
|
|
|
_gpibDevice = null;
|
|
_serialPort = _configuration.GetConfigurationValue("ELoadScpiKeysight", "SerialPort", new SerialPort());
|
|
var flowControl = _configuration.GetConfigurationValue("ELoadScpiKeysight", "FlowControl", Handshake.None);
|
|
|
|
try
|
|
{
|
|
_interface = ControlInterface.COM_PORT;
|
|
|
|
_systemName = Name;
|
|
|
|
_serialPort.Open();
|
|
|
|
_serialPort.ReadTimeout = _READ_TIMEOUT;
|
|
_serialPort.Handshake = flowControl;
|
|
|
|
Reset();
|
|
|
|
_eloadChannelMap = new SortedDictionary<string, IEload>(StringComparer.InvariantCultureIgnoreCase);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
if (_serialPort.IsOpen == true)
|
|
{
|
|
_serialPort.Close();
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// The constructor for com port interface which open up the comm port, resets the system and waits for additional commands
|
|
/// </summary>
|
|
/// <param name="comPortName">The COM port name as it exists in windows device manager.</param>
|
|
/// <param name="baudRate">The bit rate of the host computer COM port.</param>
|
|
/// <param name="parity">The parity setting of the host computer. 0 = None, 1 = Odd, 2 = Even, 3 = Mark, 4 = Space.</param>
|
|
/// <param name="dataBits">The number of bits of data sent per transfer.</param>
|
|
/// <param name="stopBits">The number of stop bits used by host computer.</param>
|
|
/// <param name ="flowControl">Handshake method. 0 = None, 1 = XonXoff, 2 = RTS, 3 = RTSXonXoff.</param>
|
|
/// <param name="isThereHardware">Software operation mode. True = Hardware available, False = Simulation Only.</param>
|
|
public EloadSystemScpiKeysight(string systemName, string comPortName, int baudRate, Parity parity, int dataBits, StopBits stopBits, Handshake flowControl, bool isThereHardware)
|
|
{
|
|
try
|
|
{
|
|
_logger = LogManager.GetCurrentClassLogger();
|
|
|
|
_interface = ControlInterface.COM_PORT;
|
|
|
|
_systemName = systemName;
|
|
|
|
_isThereHardware = isThereHardware;
|
|
|
|
_serialPort = null;
|
|
_gpibDevice = null;
|
|
|
|
if (_isThereHardware == true)
|
|
{
|
|
_serialPort = new SerialPort(comPortName, baudRate, parity, dataBits, stopBits);
|
|
|
|
_serialPort.Open();
|
|
|
|
_serialPort.ReadTimeout = _READ_TIMEOUT;
|
|
_serialPort.Handshake = flowControl;
|
|
|
|
Reset();
|
|
}
|
|
|
|
_eloadChannelMap = new SortedDictionary<string, IEload>(StringComparer.InvariantCultureIgnoreCase);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (_serialPort.IsOpen == true)
|
|
{
|
|
_serialPort.Close();
|
|
}
|
|
_logger.Error(ex.Message);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The constructor for gpib interface which open up the comm port, resets the system and waits for additional commands
|
|
/// </summary>
|
|
/// <param name="systemName"></param>
|
|
/// <param name="boardNumber"></param>
|
|
/// <param name="primaryAddress"></param>
|
|
/// <param name="isThereHardware"></param>
|
|
public EloadSystemScpiKeysight(string systemName, int boardNumber, byte primaryAddress, bool isThereHardware)
|
|
{
|
|
try
|
|
{
|
|
_interface = ControlInterface.GPIB;
|
|
|
|
_systemName = systemName;
|
|
|
|
_isThereHardware = isThereHardware;
|
|
|
|
_serialPort = null;
|
|
_gpibDevice = null;
|
|
|
|
if (_isThereHardware == true)
|
|
{
|
|
_gpibDevice = new Device(boardNumber, primaryAddress);
|
|
|
|
//@@@ TBD if this make the newline go out after each write
|
|
_gpibDevice.EndOfStringCharacter = 0xa;
|
|
|
|
_gpibDevice.IOTimeout = TimeoutValue.T3s;
|
|
|
|
Reset();
|
|
}
|
|
|
|
_eloadChannelMap = new SortedDictionary<string, IEload>(StringComparer.InvariantCultureIgnoreCase);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
if (_gpibDevice != null)
|
|
{
|
|
_gpibDevice.Dispose();
|
|
_gpibDevice = null;
|
|
}
|
|
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The finalizer
|
|
/// </summary>
|
|
~EloadSystemScpiKeysight()
|
|
{
|
|
Dispose(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add an Eload to the system.
|
|
/// </summary>
|
|
/// <param name="name">The name of the channel (module) for reference.</param>
|
|
/// <param name="channelNumber">The channel number for the Eload..</param>
|
|
/// <param name="mode">The operation mode of the channel. Modes: Resistance, Voltage, Current.</param>
|
|
/// <param name="setpoint">The operation point of the load. This can be a voltage, current, or resistance</param>
|
|
/// <param name="overCurrentProtection">Overcurrent setpoint that will turn off the channel if exceeded.</param>
|
|
/// <param name="overVoltageProtection">Overvoltage setpoint that will turn off channel if exceeded (double check).</param>
|
|
public void AddEloadChannel(string name, int channelNumber, EloadModuleMode mode, double setpoint, Current overCurrentProtection, Voltage overVoltageProtection)
|
|
{
|
|
try
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(name.ToUpper()) == true)
|
|
{
|
|
throw new Exception("system already contains a module named: " + name.ToUpper());
|
|
}
|
|
|
|
IEload eload;
|
|
|
|
if (_isThereHardware)
|
|
{
|
|
if (_interface == ControlInterface.COM_PORT)
|
|
{
|
|
eload = new ELoadScpiKeysight(_serialPort, channelNumber, mode, setpoint, overCurrentProtection.Amps, overVoltageProtection.Volts);
|
|
}
|
|
else if (_interface == ControlInterface.GPIB)
|
|
{
|
|
eload = new ELoadScpiKeysight(_gpibDevice, channelNumber, mode, setpoint, overCurrentProtection.Amps, overVoltageProtection.Volts);
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("unknown interface: " + _interface.ToString());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
eload = new EloadSim(channelNumber, mode, setpoint, overCurrentProtection.Amps, overVoltageProtection.Volts);
|
|
}
|
|
|
|
_eloadChannelMap.Add(name.ToUpper(), eload);
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
if (_interface == ControlInterface.COM_PORT)
|
|
{
|
|
_serialPort.Close();
|
|
}
|
|
else if (_interface == ControlInterface.GPIB)
|
|
{
|
|
_gpibDevice.Dispose();
|
|
_gpibDevice = null;
|
|
}
|
|
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dispose of this object's resources.
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the error code.
|
|
/// </summary>
|
|
/// <returns>The error code.</returns>
|
|
public string GetErrorCode(out int errorCode)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_isThereHardware == true)
|
|
{
|
|
// not calling IOQuery() here so IOQuery() can call GetErrorCode() after each query
|
|
|
|
string rsp = "";
|
|
|
|
if (_interface == ControlInterface.COM_PORT)
|
|
{
|
|
_serialPort.WriteLine(_ERRORCODE);
|
|
rsp = _serialPort.ReadLine();
|
|
}
|
|
else if (_interface == ControlInterface.GPIB)
|
|
{
|
|
_gpibDevice.Write(_ERRORCODE);
|
|
rsp = _gpibDevice.ReadString();
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("unknown interface type: " + _interface.ToString());
|
|
}
|
|
|
|
rsp = rsp.Replace("\r", "");
|
|
|
|
string[] tokens = rsp.Split(',');
|
|
|
|
errorCode = Util.ConvertStringToInt32(tokens[0]);
|
|
|
|
// it should always be 2
|
|
if (tokens.Length >= 2)
|
|
{
|
|
return tokens[1];
|
|
}
|
|
else
|
|
{
|
|
return "";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
errorCode = 0;
|
|
|
|
return "";
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public List<string> GetModuleNames()
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
List<string> moduleNames = new List<string>();
|
|
|
|
foreach (KeyValuePair<string, IEload> modules in _eloadChannelMap)
|
|
{
|
|
moduleNames.Add(modules.Key);
|
|
}
|
|
|
|
return moduleNames;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetSystemName()
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
return _systemName;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Query if the Eload input is on.
|
|
/// </summary>
|
|
/// <param name="channelName">The name of the Eload.</param>
|
|
/// <returns>Status of Eload. True = On, False = Off.</returns>
|
|
public bool IsInputOn(string channelName)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(channelName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find module: " + channelName.ToUpper());
|
|
}
|
|
|
|
bool status = _eloadChannelMap[channelName.ToUpper()].IsInputOn();
|
|
|
|
return status;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Turn off the Eload input.
|
|
/// </summary>
|
|
/// <param name="channelName">The name of the Eload.</param>
|
|
public void Disable(string channelName)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(channelName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find module: " + channelName.ToUpper());
|
|
}
|
|
|
|
_eloadChannelMap[channelName.ToUpper()].Disable();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Turn on the Eload input.
|
|
/// </summary>
|
|
/// <param name="channelName">The name of the Eload.</param>
|
|
public void Enable(string channelName)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(channelName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find module: " + channelName.ToUpper());
|
|
}
|
|
|
|
_eloadChannelMap[channelName.ToUpper()].Enable();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="channelName"></param>
|
|
/// <param name="command"></param>
|
|
/// <returns></returns>
|
|
public string IOQuery(string channelName, string command)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(channelName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find module: " + channelName.ToUpper());
|
|
}
|
|
|
|
return _eloadChannelMap[channelName.ToUpper()].IOQuery(command);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="channelName"></param>
|
|
/// <param name="command"></param>
|
|
public void IOWrite(string channelName, string command)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(channelName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find module: " + channelName.ToUpper());
|
|
}
|
|
|
|
_eloadChannelMap[channelName.ToUpper()].IOWrite(command);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Reads the current of the Eload.
|
|
/// </summary>
|
|
/// <param name="channelName">The name of the Eload.</param>
|
|
/// <returns>Measured current (Amps).</returns>
|
|
public Current ReadCurrent(string channelName)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(channelName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find module: " + channelName.ToUpper());
|
|
}
|
|
|
|
var value = _eloadChannelMap[channelName.ToUpper()].ReadCurrent();
|
|
|
|
return value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reads all Eload data (voltage, current, resistance, setpoint, input state, mode).
|
|
/// </summary>
|
|
/// <param name="channelName">The name of the Eload.</param>
|
|
/// <param name="voltage">The measured voltage (Volts).</param>
|
|
/// <param name="current">The measured current (Amps).</param>
|
|
/// <param name="resistance">The measured resistance (Ohms).</param>
|
|
/// <param name="setpoint">The setpoint of the Eload. Depends on mode of operation.</param>
|
|
/// <param name="isInputOn">The state of the Eload.</param>
|
|
/// <param name="mode">The mode of the Eload.</param>
|
|
public void ReadData(string channelName, out Voltage voltage, out Current current, out Resistance resistance, out double setpoint, out bool isInputOn, out EloadModuleMode mode, out ushort status)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(channelName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find module: " + channelName.ToUpper());
|
|
}
|
|
|
|
voltage = _eloadChannelMap[channelName.ToUpper()].ReadVoltage();
|
|
|
|
current = _eloadChannelMap[channelName.ToUpper()].ReadCurrent();
|
|
|
|
resistance = _eloadChannelMap[channelName.ToUpper()].ReadResistance();
|
|
|
|
setpoint = _eloadChannelMap[channelName.ToUpper()].ReadSetpoint();
|
|
|
|
isInputOn = _eloadChannelMap[channelName.ToUpper()].IsInputOn();
|
|
|
|
mode = _eloadChannelMap[channelName.ToUpper()].ReadMode();
|
|
|
|
status = _eloadChannelMap[channelName.ToUpper()].ReadProtectionStatus();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reads the mode of the Eload
|
|
/// </summary>
|
|
/// <param name="channelName">The name of the Eload.</param>
|
|
/// <returns>The mode</returns>
|
|
public EloadModuleMode ReadMode(string channelName)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(channelName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find module: " + channelName.ToUpper());
|
|
}
|
|
|
|
EloadModuleMode value = _eloadChannelMap[channelName.ToUpper()].ReadMode();
|
|
|
|
return value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reads the overcurrent setting from an Eload.
|
|
/// </summary>
|
|
/// <param name="channelName">The name of the Eload.</param>
|
|
/// <returns>Overcurrent setting (Amps).</returns>
|
|
public Current ReadOverCurrentProtection(string channelName)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(channelName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find module: " + channelName.ToUpper());
|
|
}
|
|
|
|
var value = _eloadChannelMap[channelName.ToUpper()].ReadOverCurrentProtection();
|
|
|
|
return value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reads the overvoltage setting from an Eload.
|
|
/// </summary>
|
|
/// <param name="channelName">The name of the Eload.</param>
|
|
/// <returns>Overvoltage setting (Volts).</returns>
|
|
public Voltage ReadOverVoltageProtection(string channelName)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(channelName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find module: " + channelName.ToUpper());
|
|
}
|
|
|
|
var value = _eloadChannelMap[channelName.ToUpper()].ReadOverVoltageProtection();
|
|
|
|
return value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read the resistance.
|
|
/// </summary>
|
|
/// <param name="channelName">The name of the Eload.</param>
|
|
/// <returns>The resistance (Ohms).</returns>
|
|
public Resistance ReadResistance(string channelName)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(channelName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find module: " + channelName.ToUpper());
|
|
}
|
|
|
|
var value = _eloadChannelMap[channelName.ToUpper()].ReadResistance();
|
|
|
|
return value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reads the setpoint of the Eload.
|
|
/// </summary>
|
|
/// <param name="channelName">The name of the Eload.</param>
|
|
/// <returns>The setpoint. Depends on mode.</returns>
|
|
public double ReadSetpoint(string channelName)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(channelName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find module: " + channelName.ToUpper());
|
|
}
|
|
|
|
return _eloadChannelMap[channelName.ToUpper()].ReadSetpoint();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reads the voltage of the Eload.
|
|
/// </summary>
|
|
/// <param name="channelName">The name of the Eload.</param>
|
|
/// <returns>The voltage (Volts)</returns>
|
|
public Voltage ReadVoltage(string channelName)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(channelName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find module: " + channelName.ToUpper());
|
|
}
|
|
|
|
var value = _eloadChannelMap[channelName.ToUpper()].ReadVoltage();
|
|
|
|
return value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reads the protection status from an Eload.
|
|
/// </summary>
|
|
/// <param name="channelName">The name of the Eload.</param>
|
|
/// <returns>Protection status register.</returns>
|
|
public ushort ReadProtectionStatus(string channelName)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(channelName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find module: " + channelName.ToUpper());
|
|
}
|
|
|
|
ushort value = _eloadChannelMap[channelName.ToUpper()].ReadProtectionStatus();
|
|
|
|
return value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Run a self-test.
|
|
/// </summary>
|
|
public void Selftest()
|
|
{
|
|
try
|
|
{
|
|
// change the timeout to account for the long self test to 30 seconds
|
|
if (_interface == ControlInterface.COM_PORT)
|
|
{
|
|
//@@@ is this the right time?
|
|
_serialPort.ReadTimeout = 30000;
|
|
}
|
|
else if (_interface == ControlInterface.GPIB)
|
|
{
|
|
//@@@ TBD
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("unknown interface type: " + _interface.ToString());
|
|
}
|
|
|
|
// send the command
|
|
string rspStr = IOQuery(_SELFTEST);
|
|
|
|
// parse the response
|
|
string[] tokens = rspStr.Split('\n');
|
|
|
|
int rsp = Util.ConvertStringToInt32(tokens[0]);
|
|
|
|
if (rsp != 0)
|
|
{
|
|
string errorMsg = "returned an error: " + rsp.ToString();
|
|
throw new Exception(errorMsg);
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
// restore the timeout
|
|
if (_interface == ControlInterface.COM_PORT)
|
|
{
|
|
_serialPort.ReadTimeout = _READ_TIMEOUT;
|
|
}
|
|
else if (_interface == ControlInterface.GPIB)
|
|
{
|
|
//@@@ TBD
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("unknown interface type: " + _interface.ToString());
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resets all channels to config file values
|
|
/// </summary>
|
|
public void SetInitialSetting(string module)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(module.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find load: " + module.ToUpper());
|
|
}
|
|
|
|
_eloadChannelMap[module.ToUpper()].SetInitialSetting();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resets all channels to config file values
|
|
/// </summary>
|
|
public void SetInitialSettingAll()
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
foreach (KeyValuePair<String, IEload> eload in _eloadChannelMap)
|
|
{
|
|
_eloadChannelMap[eload.Key].SetInitialSetting();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Change the operation mode of the Eload.
|
|
/// </summary>
|
|
/// <param name="channelName">The name of the Eload.</param>
|
|
/// <param name="mode">The desired Eload mode.</param>
|
|
public void SetMode(string channelName, EloadModuleMode mode)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(channelName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find module: " + channelName.ToUpper());
|
|
}
|
|
|
|
_eloadChannelMap[channelName.ToUpper()].SetMode(mode);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Change the setpoint and operation mode of the Eload.
|
|
/// </summary>
|
|
/// <param name="channelName">The name of the Eload.</param>
|
|
/// <param name="newSetpoint">The desired setpoint of the Eload.</param>
|
|
/// <param name="mode">The desired Eload mode.</param>
|
|
public void SetSetpoint(string channelName, double newSetpoint, EloadModuleMode mode)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (_eloadChannelMap.ContainsKey(channelName.ToUpper()) == false)
|
|
{
|
|
throw new Exception("could not find module: " + channelName.ToUpper());
|
|
}
|
|
|
|
_eloadChannelMap[channelName.ToUpper()].SetSetpoint(newSetpoint, mode);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dispose of this objects resources
|
|
/// </summary>
|
|
/// <param name="disposing">True = currently disposing, False = not disposing.</param>
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (disposing)
|
|
{
|
|
foreach (KeyValuePair<string, IEload> entry in _eloadChannelMap)
|
|
{
|
|
entry.Value.Shutdown();
|
|
}
|
|
|
|
if (_serialPort != null)
|
|
{
|
|
Reset();
|
|
_serialPort.Dispose();
|
|
_serialPort = null;
|
|
}
|
|
|
|
if (_gpibDevice != null)
|
|
{
|
|
Reset();
|
|
_gpibDevice.Dispose();
|
|
_gpibDevice = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool ClearErrors()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public void Initialize()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public SelfTestResult PerformSelfTest()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
void IInstrument.Reset()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public void Shutdown()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
#endregion
|
|
}
|
|
}
|