private void OnTimedEvent(object source, ElapsedEventArgs args) { if (m_GotDataFinished) { HandleTimer(); return; } // we use the timer to update our data. TimeSpan elapsedTime = DateTime.UtcNow - m_AcquisitionOnTime; if (elapsedTime.TotalMilliseconds > m_DataPointSetInterval.TotalMilliseconds * (m_PacketIndex + 1)) { Int32 numberOfSpectraToGenerate = Convert.ToInt32((elapsedTime.TotalMilliseconds - m_DataPointSetInterval.TotalMilliseconds * (m_DataIndex + 1)) / m_DataPointSetInterval.TotalMilliseconds); for (int indexSpectrum = 0; indexSpectrum < numberOfSpectraToGenerate; indexSpectrum++) { // in minutes double dCurrentTime = m_AcquisitionOnRetention + (double)m_DataIndex / m_RateProperty.Value.Value / 60.0; m_ChannelTimeProperty.Update(dCurrentTime); int signal = ChannelTestDriver.CurrentDataValue(dCurrentTime); for (int indexDataPoint = 0; indexDataPoint < m_MyCmDevice.MaximumNumberOfDataPoints; indexDataPoint++) { m_Spectrum[indexDataPoint] = signal; } m_DataIndex++; m_MyCmDevice.UpdateData(false, m_DataIndex, m_Spectrum); // update the total number of spectra already acquired m_SpectraIndexProperty.Update(m_DataIndex); } m_PacketIndex++; } HandleTimer(); }
private void OnTimedEvent(object source, ElapsedEventArgs args) { if (m_GotDataFinished) { HandleTimer(); return; } // we use the timer to update our data. TimeSpan elapsedTime = DateTime.UtcNow - m_AcquisitionOnTime; if (elapsedTime.TotalMilliseconds > m_DataPointInterval.TotalMilliseconds * (m_PacketIndex + 1)) { // create as many data points as necessary Int32 numberOfDataPointsToGenerate = Convert.ToInt32((elapsedTime.TotalMilliseconds - m_DataPointInterval.TotalMilliseconds * (m_DataIndex + 1)) / m_DataPointInterval.TotalMilliseconds); m_DataPacket = new int[numberOfDataPointsToGenerate]; for (int i = 0; i < numberOfDataPointsToGenerate; i++) { // in minutes double dCurrentTime = m_AcquisitionOnRetention + (double)m_DataIndex / m_RateProperty.Value.Value / 60.0; m_ChannelTimeProperty.Update(dCurrentTime); m_DataPacket[i] = ChannelTestDriver.CurrentDataValue(dCurrentTime); m_DataIndex++; } // update the total number of data points already acquired m_DataIndexProperty.Update(m_DataIndex); m_PacketIndex++; m_MyCmDevice.UpdateData(0, m_DataPacket); } HandleTimer(); }
/// <summary> /// Create our Dionex.Chromeleon.Symbols.IDevice and our Properties and Commands /// </summary> /// <param name="cmDDK">The DDK instance</param> /// <param name="driver">The driver instance</param> /// <param name="name">The name for our device</param> /// <returns>our IDevice object</returns> internal IDevice OnCreate(ChannelTestDriver driver, IDDK cmDDK, string name) { m_Driver = driver; // Create our Dionex.Chromeleon.Symbols.IDevice m_MyCmDevice = cmDDK.CreateDevice(name, "This is the master device of the ChannelTest driver."); m_MyCmDevice.ImmediateNotReady = true; // NOTE: // Setting 'ImmediateNotReady' to true on the main device toggles the 'Ready' property for 5s(default) to false when entering TransferPreflightToRun, unless one updates the ready property explicitly. // Therefore it's also necessary to create a standard property 'Ready' which can be toggled and which can be added to instrument methods in a Wait statement. // More background: // In common LC/GC environments an injector is used in the instrument configuration and it's Inject command in the method would cause a natural delay. // In our example driver we have no delay like this and can run into a kind of data exchange delay issue. // Setting the parameter FixedRate in a method updates also the channel parameters TimeStepFactorProperty and TimeStepDevisorProperty. // If setting the parameter FixedRate is immediately followed by an AcqOn command, the 'Real Time Kernel' might not be updated via interprocess communication soon enough and // calculates the number of expected datapoints with old settings of TimeStepFactorProperty and TimeStepDevisorProperty. This might stop the data acquisition by 'OnDataFinished' when faulty 'enough' data points have been dumped. // To avoid this in this example, following to steps in combination are necessary: // 1) introducing a standard property 'Ready' which can be checked in the instrument method. // 2) Set ChannelTest.ImmediateNotReady to true // 3) Adding a Wait ChannelTest.Ready in the method before AcqOn. // This provides enough time when setting FixedRate in our example to update the 'Real Time Kernel's TimeStepFactorProperty and TimeStepDevisorProperty. // Create a command for the hardware error simulation. m_HardwareErrorCommand = m_MyCmDevice.CreateCommand("HardwareError", "This command simulates a hardware error."); m_HardwareErrorCommand.OnCommand += new CommandEventHandler(m_HardwareErrorCommand_OnCommand); //Create ready property ITypeInt tReady = cmDDK.CreateInt(0, 1); //Add named values tReady.AddNamedValue("NotReady", 0); tReady.AddNamedValue("Ready", 1); ReadyProperty = m_MyCmDevice.CreateStandardProperty(StandardPropertyID.Ready, tReady); ReadyProperty.Update(1); return(m_MyCmDevice); }