// 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 Raytheon.Instruments.Dmm; using Raytheon.Units; using System.IO.Ports; using NLog; using Raytheon.Common; namespace Raytheon.Instruments { /// /// A Space Electronics (Squib meter) of the DMM interface /// public class DMMSquibMeter101SQBRAK : IDmm, IDisposable { #region PrivateMemberVariables private string _name; private readonly string _address; private readonly SerialPort _serialPort; private MeasurementFunction _lastType; private double _lastRange; private double _lastResolution; private State _state; private SelfTestResult _selfTestResult; private byte[] _readBuffer; private string versionInfo; /// /// NLog logger /// private readonly ILogger _logger; /// /// Raytheon configuration /// private readonly IConfigurationManager _configurationManager; private readonly IConfiguration _configuration; #endregion #region PrivateFunctions /// /// Dispose of this objects resources /// /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", MessageId = "_34461A")] protected virtual void Dispose(bool disposing) { try { if (disposing) { if (_state == State.Ready) { IOWrite("RST"); // send reset command IOWrite("LM"); // sets squib meter to local mode (it is set to remote in initilize) _serialPort.Close(); _state = State.Uninitialized; } } } catch (Exception) { try { //ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace); } catch (Exception) { //Do not rethrow. Exception from error logger that has already been garbage collected } } } /// /// /// /// /// private string ConvertToString(ref byte[] data) { string rsp = System.Text.Encoding.ASCII.GetString(data); return rsp; } /// /// Send a command to the squib meter and get the response. /// /// The command to send. /// The squib meter response as string. private string IOQuery(string commandString) { // Flush squib meter buffer _serialPort.Write("FS"); // clear our buffer Array.Clear(_readBuffer, 0, _readBuffer.Length); // send the data out _serialPort.Write(commandString); // read from the response int numBytesRead = _serialPort.Read(_readBuffer, 0, _readBuffer.Length); // convert response to a string string rspStr = ConvertToString(ref _readBuffer); // split out the command responce from the return data (divided by carriage return) string[] result = rspStr.Split(new string[] { "\n", "\r\n", "" }, StringSplitOptions.None); // Check command responce (0 = OK) if (result[0] == "1") { throw new Exception("Unknown Command"); } if (result[0] == "2") { throw new Exception("Command now allowed in present mode"); } return result[1]; } /// /// Sends a serial Command to the instrument. /// /// The serial Command to be sent to the instrument. private void IOWrite(string commandString) { // note each command sent has different return data/status/error formatting, IOWrite is just a direct write // IOQuery will do a read, and return all the data // send command to serial port _serialPort.Write(commandString); } #endregion #region PublicFunctions /// /// DMMSquibMeter101SQBRAK factory constructor /// /// /// public DMMSquibMeter101SQBRAK(string deviceName, IConfigurationManager configurationManager, ILogger logger) { Name = deviceName; _logger = logger; _configurationManager = configurationManager; _configuration = _configurationManager.GetConfiguration(Name); string comPortName = _configuration.GetConfigurationValue("DMMSquibMeter101SQBRAK", "ComPortName", "COM1"); _address = comPortName; int baudRate = _configuration.GetConfigurationValue("DMMSquibMeter101SQBRAK", "BaudRate", 9600); Parity parity = _configuration.GetConfigurationValue("DMMSquibMeter101SQBRAK", "Parity", Parity.None); int dataBits = _configuration.GetConfigurationValue("DMMSquibMeter101SQBRAK", "DataBits", 8); StopBits stopBits = _configuration.GetConfigurationValue("DMMSquibMeter101SQBRAK", "StopBits", StopBits.One); _serialPort = new SerialPort(comPortName, baudRate, parity, dataBits, stopBits); _lastType = 0; _lastRange = 0; _lastResolution = 0; _readBuffer = new byte[1000]; //created in Initialize() _state = State.Uninitialized; _selfTestResult = SelfTestResult.Unknown; } /// /// The constructor which opens the handle to the DMM and performs a self test on the instrument /// /// The name of this dmm /// The address of the DMM public DMMSquibMeter101SQBRAK(string name, string comPortName, int baudRate = 9600, Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One) { _name = name; _address = comPortName; _serialPort = new SerialPort(comPortName, baudRate, parity, dataBits, stopBits); _lastType = 0; _lastRange = 0; _lastResolution = 0; _readBuffer = new byte[1000]; _logger = LogManager.GetCurrentClassLogger(); //created in Initialize() _state = State.Uninitialized; _selfTestResult = SelfTestResult.Unknown; } /// /// The Finalizer which will release resources if required /// ~DMMSquibMeter101SQBRAK() { Dispose(false); } /// /// /// /// public bool ClearErrors() { throw new NotImplementedException(); // if serial command for clearing errors add here, if not leave as is } /// /// /// /// /// /// public void ConfigureCurrentMeasurement(MeasurementFunction type, Current range, Current resolution) { throw new NotImplementedException(); // if serial command for clearing errors add here, if not leave as is } /// /// /// /// /// /// public void ConfigureFrequencyMeasurement(MeasurementFunction type, Frequency range, Frequency resolution) { throw new NotImplementedException(); // if serial command for clearing errors add here, if not leave as is } /// /// /// /// /// /// public void ConfigureResistanceMeasurement(MeasurementFunction type, Resistance range, Resistance resolution) { if (type != MeasurementFunction.FourWireResistance && type != MeasurementFunction.TwoWireResistance) { throw new Exception("only FourWireResistance or TwoWireResistance is acceptable for param type: " + _lastType.ToString()); } _lastType = type; _lastRange = range.Ohms; _lastResolution = resolution.Ohms; } /// /// /// /// /// /// public void ConfigureVoltageMeasurement(MeasurementFunction type, Voltage range, Voltage resolution) { throw new NotImplementedException(); // if serial command for clearing errors add here, if not leave as is } /// /// /// public string DetailedStatus { get { versionInfo = IOQuery("VR"); return "Squib Meter version Information (Cage Code | Model Number | Serial Number | Firmware Version | Calibration Date): " + versionInfo; } } /// /// /// public bool DisplayEnabled { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } /// /// Dispose of this objects resources /// public void Dispose() { try { Dispose(true); GC.SuppressFinalize(this); } catch (Exception) { try { //ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace); } catch (Exception) { //Do not rethrow. Exception from error logger that has already been garbage collected } } } /// /// /// public bool FrontPanelEnabled { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } /// /// /// public InstrumentMetadata Info { get { throw new NotImplementedException(); } } /// /// /// public void Initialize() { if (_state == State.Uninitialized) { // Open the port _serialPort.Open(); // set the squib meter to remote state IOQuery("RM"); // Ensure continuous reading is off IOQuery("COFF"); // Flush FIFO buffer IOQuery("FS"); _state = State.Ready; } else { throw new Exception("expected the state to be Uninitialized, state was: " + _state.ToString()); } } /// /// /// public MeasurementFunction MeasurementType { get { throw new NotImplementedException(); } } /// /// /// /// /// public Current MeasureCurrent(int timeout) { throw new NotImplementedException(); } /// /// /// /// /// public Frequency MeasureFrequency(int timeout) { throw new NotImplementedException(); } /// /// /// /// /// public Resistance MeasureResistance(int timeout) { if (_lastType != MeasurementFunction.FourWireResistance && _lastType != MeasurementFunction.TwoWireResistance) { throw new Exception("only FourWireResistance or TwoWireResistance is acceptable for param type: " + _lastType.ToString()); } IOQuery("SR"); //todo need to add in range values // send serial command to send & read response // set range // set resolution // any other settings that need to be sent (write) before taking measurement string response = IOQuery("RV"); // parse the response //TODO Parse the return data (0= command ok, 1= unknown command, 2= command not allowed in present mode | reading | over range state | wiring error state | calibration state (ok or bad) | hardware state (ok or bad)) double rsp = Util.ConvertStringToDouble(response); //if string is only number this is ok, if there are any other char must strip them off return Resistance.FromOhms(rsp); } /// /// /// /// /// public Voltage MeasureVoltage(int timeout) { throw new NotImplementedException(); // if serial command for clearing errors add here, if not leave as is } /// /// /// public string Name { get { return _name; } set { _name = value; } } /// /// /// /// public SelfTestResult PerformSelfTest() { int testResult = 0; const string BatteryState = "LOW"; string result = IOQuery("RV"); // Set measurement input to backplane after performing self test. Default is front panel. // _dmm.Measurement.In = VTEXDmmInputSelectEnum.VTEXDmmInputSelectInternal; if (result == BatteryState) { _selfTestResult = Raytheon.Instruments.SelfTestResult.Fail; throw new Exception("Battery state: " + testResult + " Battery State Message: " + result); } _selfTestResult = Raytheon.Instruments.SelfTestResult.Pass; return _selfTestResult; } /// /// /// public void Reset() { IOWrite("RST"); } /// /// /// public SelfTestResult SelfTestResult { get { return _selfTestResult; } } /// /// /// public State Status { get { return _state; } } /// /// /// public void Shutdown() { if (_state == State.Ready) { IOWrite("RST"); // send reset command IOWrite("LM"); // sets squib meter to local mode (it is set to remote in initilize) _serialPort.Close(); _state = State.Uninitialized; } } #endregion } }