public HardwareChannel(string serverName, string deviceName, string channelName, string channelDescription, HardwareChannel.HardwareConstants.ChannelTypes ct, DataStructures.Gpib.Address gpibAddress, HardwareChannel.HardwareConstants.GPIBDeviceType gpibDeviceType) : this(serverName, deviceName, channelName,channelDescription, ct) { if (this.ChannelType != HardwareConstants.ChannelTypes.gpib) { throw new Exception("Do not call gpib channel constructor for a non gpib device."); } this.gpibAddress = gpibAddress; this.gpibDeviceType = gpibDeviceType; }
public HardwareChannel(string serverName, string deviceName, string channelName, string channelDescription, HardwareChannel.HardwareConstants.ChannelTypes ct, DataStructures.Gpib.Address gpibAddress, HardwareChannel.HardwareConstants.GPIBDeviceType gpibDeviceType) : this(serverName, deviceName, channelName, channelDescription, ct) { if (this.ChannelType != HardwareConstants.ChannelTypes.gpib) { throw new Exception("Do not call gpib channel constructor for a non gpib device."); } this.gpibAddress = gpibAddress; this.gpibDeviceType = gpibDeviceType; }
public HardwareChannel(string serverName, string deviceName, string channelName, string channelDescription, HardwareChannel.HardwareConstants.ChannelTypes ct) { gpibMasquerade = false; myGpibMasqueradeType = GpibMasqueradeType.NONE; this.serverName = serverName; this.deviceName = deviceName; this.channelName = channelName; this.channelDescription = channelDescription; this.channelType = ct; this.isUnAssigned = false; this.gpibAddress = new DataStructures.Gpib.Address(); this.gpibDeviceType = HardwareConstants.GPIBDeviceType.Unknown; }
/// <summary> /// This method is to be called on the server side, and is not open to use via remoting. Its purpose /// is to update the servers internal list of hardware channels by querying the National Instruments drivers. /// </summary> public void refreshHardwareLists() { System.Console.WriteLine("Running refreshHardwareLists()..."); try { // Set all the devices to disconnected. They will be set back to connected if they are detecter later in this method. foreach (DeviceSettings ds in serverSettings.myDevicesSettings.Values) ds.deviceConnected = false; myHardwareChannels = new List<HardwareChannel>(); //List of string identifiers for all devices detected in the process. detectedDevices = new List<string>(); Dictionary<string, string> myDeviceDescriptions = new Dictionary<string, string>(); // Detect National Instruments analog and digital channels. #region detect NI analog and digital (daqMx) System.Console.WriteLine("Accessing DaqSystem devices list..."); DaqSystem daqSystem = DaqSystem.Local; string[] devices = daqSystem.Devices; System.Console.WriteLine("...done."); System.Console.WriteLine("Found " + devices.Length.ToString() + " devices."); bool niDaqDevicesExistThatAreNotNamedDevSomething = false; for (int i = 0; i < devices.Length; i++) { if (!devices[i].ToUpper().Contains("DEV")) { niDaqDevicesExistThatAreNotNamedDevSomething = true; } System.Console.WriteLine("Querying device " + i + "..."); detectedDevices.Add(devices[i]); Device device = daqSystem.LoadDevice(devices[i]); myDeviceDescriptions.Add(devices[i], device.ProductType); string[] analogs = device.AOPhysicalChannels; string[] digitalLines = device.DOLines; if (!serverSettings.myDevicesSettings.ContainsKey(devices[i])) { serverSettings.myDevicesSettings.Add(devices[i], new DeviceSettings(devices[i], myDeviceDescriptions[devices[i]])); } // Special case: 6259 cards use 32-bit wide ports instead of 16 bit wide. if (myDeviceDescriptions[devices[i]].Contains("6259")) { serverSettings.myDevicesSettings[devices[i]].use32BitDigitalPorts = true; } // Add all the analog channels, but only if the device settings say this card is enabled if (serverSettings.myDevicesSettings.ContainsKey(devices[i]) && serverSettings.myDevicesSettings[devices[i]].DeviceEnabled) { if (serverSettings.myDevicesSettings[devices[i]].AnalogChannelsEnabled) { for (int j = 0; j < analogs.Length; j++) { string channelName = justTheChannelName(analogs[j], devices[i]); HardwareChannel hc = new HardwareChannel(this.myServerSettings.ServerName, devices[i], channelName, HardwareChannel.HardwareConstants.ChannelTypes.analog); if (!serverSettings.ExcludedChannels.Contains(hc)) { myHardwareChannels.Add(hc); } } } if (serverSettings.myDevicesSettings[devices[i]].DigitalChannelsEnabled) { for (int j = 0; j < digitalLines.Length; j++) { string channelName = justTheChannelName(digitalLines[j], devices[i]); HardwareChannel hc = new HardwareChannel(this.myServerSettings.ServerName, devices[i], channelName, HardwareChannel.HardwareConstants.ChannelTypes.digital); if (!serverSettings.ExcludedChannels.Contains(hc)) { myHardwareChannels.Add(hc); } } } } System.Console.WriteLine("...done."); } #endregion #region "detect" RFSG cards foreach (ServerSettings.rfsgDeviceName rfsgDevName in serverSettings.RfsgDeviceNames) { System.Console.WriteLine("Querying RFSG devices..."); string devName = rfsgDevName.DeviceName; HardwareChannel hc = new HardwareChannel(serverSettings.ServerName, devName, "rf_out", HardwareChannel.HardwareConstants.ChannelTypes.gpib); hc.gpibMasquerade = true; hc.myGpibMasqueradeType = HardwareChannel.GpibMasqueradeType.RFSG; myHardwareChannels.Add(hc); if (!serverSettings.myDevicesSettings.ContainsKey(devName)) { DeviceSettings devSettings = new DeviceSettings(devName, "RFSG driver library signal generator"); serverSettings.myDevicesSettings.Add(devName, devSettings); } System.Console.WriteLine("...done."); } #endregion #region detect NI GBIB // try a maxumimum of 10 GPIB boards... this is a totally arbitrary number. for (int i = 0; i < 10; i++) { System.Console.WriteLine("Querying or detecting GPIB Board Number " + i + "..."); try { NationalInstruments.NI4882.Board board = new NationalInstruments.NI4882.Board(i); board.SendInterfaceClear(); // board.BecomeActiveController(false); NationalInstruments.NI4882.AddressCollection listeners = board.FindListeners(); if (listeners.Count != 0) { foreach (NationalInstruments.NI4882.Address address in listeners) { int wait_delay = 100; try { NationalInstruments.NI4882.Device dev = new NationalInstruments.NI4882.Device(i, address); dev.Clear(); // ask the device for its identity Action<string> writeDelegate = new Action<string>(dev.Write); IAsyncResult result = writeDelegate.BeginInvoke("*IDN?\n", null, null); result.AsyncWaitHandle.WaitOne(wait_delay, true); if (!result.IsCompleted) { messageLog(this, new MessageEvent("GPIB device took longer than " + wait_delay + " ms to respond to id request. Aborting.")); dev.AbortAsynchronousIO(); continue; } string deviceDescription = dev.ReadString(); string deviceName = "GPIB" + i + "/" + gpibAddressToShortString(address); detectedDevices.Add(deviceName); myDeviceDescriptions.Add(deviceName, deviceDescription); HardwareChannel.HardwareConstants.GPIBDeviceType gpibDeviceType = new HardwareChannel.HardwareConstants.GPIBDeviceType(); // VERY IMPORTANT!!!!!!!!!! // ******************* THIS IS WHERE YOU ADD DEVICE-DETECTION CODE FOR NEW GPIB DEVICES *********************/ // detect the gpib device type if (deviceDescription.Contains("ESG-4000B")) { gpibDeviceType = HardwareChannel.HardwareConstants.GPIBDeviceType.Agilent_ESG_SIG_Generator; } // place any other device type detection code here as else ifs. else if (deviceDescription.Contains("N5181")) { gpibDeviceType = HardwareChannel.HardwareConstants.GPIBDeviceType.Agilent_ESG_SIG_Generator; } else { gpibDeviceType = HardwareChannel.HardwareConstants.GPIBDeviceType.Unknown; } HardwareChannel hc = new HardwareChannel(this.myServerSettings.ServerName, deviceName, gpibAddressToShortString(address), deviceDescription, HardwareChannel.HardwareConstants.ChannelTypes.gpib, dsAddress(address), gpibDeviceType); if (!serverSettings.ExcludedChannels.Contains(hc)) { myHardwareChannels.Add(hc); } } catch (Exception e) { messageLog(this, new MessageEvent("Exception when attempting to communicate with GPIB device " + "GPIB" + i + "/" + gpibAddressToShortString(address) + ". " + e.Message + "\n" + e.StackTrace)); } } } } catch (Exception) { // throw e; } System.Console.WriteLine("...done."); } /* NationalInstruments.NI4882.Board board = new NationalInstruments.NI4882.Board(); board.FindListeners( */ #endregion #region Detect NI RS232 ports System.Console.WriteLine("Querying NI VisaNS Serial Resources..."); string[] resourceNames = null; NationalInstruments.VisaNS.ResourceManager VisaRescources = null; System.Console.WriteLine("...done."); try { VisaRescources = NationalInstruments.VisaNS.ResourceManager.GetLocalManager(); resourceNames = VisaRescources.FindResources("/?*"); } catch (Exception e) { if (messageLogHandler != null) { messageLogHandler(this, new MessageEvent("Caught exception when attempting to detect serial ports: " + e.Message + e.StackTrace)); } else { MessageBox.Show("Caught exception when attempting to detect serial ports: " + e.Message + e.StackTrace); } } if (resourceNames != null) { foreach (string s in resourceNames) { try { System.Console.WriteLine("Querying Resource " + s); NationalInstruments.VisaNS.HardwareInterfaceType hType; short chanNum; VisaRescources.ParseResource(s, out hType, out chanNum); if (hType == NationalInstruments.VisaNS.HardwareInterfaceType.Serial) { NationalInstruments.VisaNS.SerialSession ss = (NationalInstruments.VisaNS.SerialSession)NationalInstruments.VisaNS.ResourceManager.GetLocalManager().Open(s); string description = ss.HardwareInterfaceName; HardwareChannel hc = new HardwareChannel(this.serverSettings.ServerName, "Serial", s, description, HardwareChannel.HardwareConstants.ChannelTypes.rs232); if (!serverSettings.ExcludedChannels.Contains(hc)) { MyHardwareChannels.Add(hc); } if (!detectedDevices.Contains("Serial")) { detectedDevices.Add("Serial"); myDeviceDescriptions.Add("Serial", "All local RS232 devices."); } ss.Dispose(); } } catch (Exception e) { System.Console.WriteLine("Caught exception when attempting to query serial resource named " + s + ". Displaying exception and then skipping this device."); ExceptionViewerDialog ev = new ExceptionViewerDialog(e); ev.ShowDialog(); } System.Console.WriteLine("...done."); } } #endregion // If necessary, add DeviceSettings entries for devices. foreach (string device in detectedDevices) { // If this device does not already have a settings object... if (!myServerSettings.myDevicesSettings.ContainsKey(device)) { myServerSettings.myDevicesSettings.Add(device, new DeviceSettings(device, myDeviceDescriptions[device])); } else { myServerSettings.myDevicesSettings[device].deviceConnected = true; } } #region FPGA Detection and configuration if (this.serverSettings.UseOpalKellyFPGA) { try { System.Console.WriteLine("Scanning for Opal Kelly FPGA devices..."); opalKellyDevices = new List<com.opalkelly.frontpanel.okCFrontPanel>(); opalKellyDeviceNames = new List<string>(); com.opalkelly.frontpanel.okCFrontPanel ok = new com.opalkelly.frontpanel.okCFrontPanel(); int fpgaDeviceCount = ok.GetDeviceCount(); System.Console.WriteLine("Found " + fpgaDeviceCount + " fpga device(s)."); for (int i = 0; i < fpgaDeviceCount; i++) { string name = ok.GetDeviceListSerial(i); com.opalkelly.frontpanel.okCFrontPanel fpgaDevice = new com.opalkelly.frontpanel.okCFrontPanel(); com.opalkelly.frontpanel.okCFrontPanel.ErrorCode errorCode; errorCode = fpgaDevice.OpenBySerial(name); if (errorCode != com.opalkelly.frontpanel.okCFrontPanel.ErrorCode.NoError) { System.Console.WriteLine("Unable to open FPGA device " + name + " due to error code " + errorCode.ToString()); continue; } if (!this.detectedDevices.Contains(name)) { this.detectedDevices.Add(name); } if (!myServerSettings.myDevicesSettings.ContainsKey(name)) { DeviceSettings newSettings = new DeviceSettings(name, "Opal Kelly FPGA Device"); newSettings.deviceConnected = true; newSettings.isFPGADevice = true; myServerSettings.myDevicesSettings.Add(name, newSettings); } else { myServerSettings.myDevicesSettings[name].deviceConnected = true; } bool deviceProgrammed = false; if (myServerSettings.myDevicesSettings[name].DeviceEnabled) { if (myServerSettings.myDevicesSettings[name].UsingVariableTimebase) { deviceProgrammed = true; if (myServerSettings.myDevicesSettings[name].MySampleClockSource == DeviceSettings.SampleClockSource.DerivedFromMaster) { errorCode = fpgaDevice.ConfigureFPGA("variable_timebase_fpga_internal.bit"); } else { errorCode = fpgaDevice.ConfigureFPGA("variable_timebase_fpga_external.bit"); } if (errorCode == com.opalkelly.frontpanel.okCFrontPanel.ErrorCode.NoError) { System.Console.WriteLine("Programmed fpga device " + name + ". Used fpga code version based on sample clock source " + myServerSettings.myDevicesSettings[name].MySampleClockSource.ToString()); opalKellyDeviceNames.Add(name); opalKellyDevices.Add(fpgaDevice); } else { System.Console.WriteLine("Error when attempting to program fpga device, error code " + errorCode.ToString()); } } } if (!deviceProgrammed) System.Console.WriteLine("Fpga device " + name + " not programmed, as it is not enable or varible timebase on that device is not enabled."); } } catch (Exception e) { if (e.InnerException != null && e.InnerException.InnerException != null) { Exception innerInner = e.InnerException.InnerException; if (innerInner is System.BadImageFormatException) { MessageBox.Show("You are probably running the wrong build of Atticus. As of version 1.56 Atticus now comes in a 64-bit or 32-bit versions (in the bin\\Release-x64 and bin\\Release-x86 subdirectories respectively). These builds make use of different versions of the Opal Kelly Frontpanel libraries. Please ensure you are using the correct Atticus build. The exception which gave rise to this error will now be displayed.", "Wrong build of Atticus?"); DataStructures.ExceptionViewerDialog dial = new ExceptionViewerDialog(e); dial.ShowDialog(); } else if (innerInner is System.DllNotFoundException) { MessageBox.Show("As of version 1.56, Atticus is now built to use the 4.0.8 version of the Opal Kelly Frontpanel libraries/drivers. Perhaps you have the wrong version of the libraries installed? You can find a driver-only installer for 4.0.8 in the \\Opal Kelly\\Opal Kelly 4.0.8\\ directory of the Cicero distribution. Please install the newer drivers from there, or contact Opal Kelly to receive a CD with the newest full Frontpanel distribution (or go to the download section of github page for the Cicero Word generator, and download and install Opal-Kelly-CD-4.0.8.zip. You may also need to plug an Opal Kelly device into this computer during installation of the drivers, to insure that the WINUSB windows subsystem gets installed. The exception which gave rise to this error will now be displayed.", "Wrong version of FrontPanel drivers installed?"); DataStructures.ExceptionViewerDialog dial = new ExceptionViewerDialog(e); dial.ShowDialog(); } else { MessageBox.Show("An unrecognized exception was encountered when scanning for Opal Kelly FPGA devices. The exception will now be displayed.", "Unrecognized exception."); DataStructures.ExceptionViewerDialog dial = new ExceptionViewerDialog(e); dial.ShowDialog(); } } else { MessageBox.Show("An unrecognized exception was encountered when scanning for Opal Kelly FPGA devices. The exception will now be displayed.", "Unrecognized exception."); DataStructures.ExceptionViewerDialog dial = new ExceptionViewerDialog(e); dial.ShowDialog(); } System.Console.WriteLine("Caught exceptions when attempting to scan for Opal Kelly FPGA devices. Aborted FPGA scan."); opalKellyDevices = null; } } else { System.Console.WriteLine("Opal Kelly FPGA not enabled, so not scanning for them."); opalKellyDevices = null; } #endregion System.Console.WriteLine("...done running refreshHardwareLists()."); if (niDaqDevicesExistThatAreNotNamedDevSomething) { System.Console.WriteLine("!! NOTE !! Some NI devices were detected whose name does not follow the Dev1, Dev2, Dev3, naming convention. This will cause problems."); MessageBox.Show("National Instruments cards were detected whose names do not corresponding to the Dev1, Dev2, Dev3, etc. naming convention. This convention is relied upon by Atticus. Not following this convention will cause problems when attempting to run sequences on these devices. Please use MAX (the NI-supplied program) to rename your NI devices to follow the convention.", "Invalid niDaq Device Names"); } } catch (Exception e) { System.Console.WriteLine("Unhandled exception when scanning connected hardware. Displaying exception, and then continuing to attempt to start Atticus."); ExceptionViewerDialog ev = new ExceptionViewerDialog(e); ev.ShowDialog(); MessageBox.Show("Atticus encountered an unhandled exception when scanning for connected hardware. Atticus will continue to run. It is unlikely to function correctly for driving outputs, but will allow you to edit your settings to disable whatever is causing the unhandled exception."); } }
long postRetriggerTime = 100; // corresponds to 10us. // A workaround to issue when using software timed groups in // fpga-retriggered words // the workaround: delay the software timed group by an immesurable amount // if it is started in a retriggered word // This functionality is sort of somewhat duplicated in sequencedata.generatebuffers. It would be good // to come up with a more coherent framework to do these sorts of operations. public bool generateBuffer(SequenceData sequence, DeviceSettings deviceSettings, HardwareChannel hc, int logicalChannelID, List <GpibRampCommandConverter> commandConverters) { this.logicalChannelID = logicalChannelID; this.deviceType = hc.GpibDeviceType; commandBuffer = new List <GpibCommand>(); if (deviceSettings.StartTriggerType != DeviceSettings.TriggerType.SoftwareTrigger) { throw new Exception("GPIB devices must have a software start trigger."); } // start by adding the initialization string to the command buffer // this does nothing for unknown device types // Modified by REO 11/25/08: Null strings produce errors if written to device, so check if (HardwareChannel.HardwareConstants.gpibInitializationCommands[(int)deviceType] != null) { commandBuffer.Add(new GpibCommand(HardwareChannel.HardwareConstants.gpibInitializationCommands[(int)deviceType], 0)); } if (deviceType == HardwareChannel.HardwareConstants.GPIBDeviceType.Unknown) { foreach (GpibRampCommandConverter conv in commandConverters) { //Modified by REO 11/25/08: Null strings produce errors if written to device, so check if (deviceSettings.DeviceDescription.Contains(conv.DeviceIdentifierSubstring) && conv.InitializationCommand != null) { commandBuffer.Add(new GpibCommand(AddNewlineCharacters(conv.InitializationCommand), 0)); } } } int currentStepIndex = -1; //measured in ticks. 1 tick = 100 ns. long currentTime = 0; // This functionality is sort of somewhat duplicated in sequencedata.generatebuffers. It would be good // to come up with a more coherent framework to do these sorts of operations. while (true) { currentStepIndex++; if (currentStepIndex >= sequence.TimeSteps.Count) { break; } TimeStep currentStep = sequence.TimeSteps[currentStepIndex]; if (!currentStep.StepEnabled) { continue; } if (currentStep.GpibGroup == null || !currentStep.GpibGroup.channelEnabled(logicalChannelID)) { currentTime += Shared.SecondsToTicks(currentStep.StepDuration.getBaseValue()); continue; } long postTime = 0; if (currentStep.RetriggerOptions.WaitForRetrigger) { postTime = postRetriggerTime; } // determine the index of the next step in which this channel has an action int nextEnabledStepIndex = sequence.findNextGpibChannelEnabledTimestep(currentStepIndex, logicalChannelID); long groupDuration = Shared.SecondsToTicks(sequence.timeBetweenSteps(currentStepIndex, nextEnabledStepIndex)); // now take action: GPIBGroupChannelData channelData = currentStep.GpibGroup.getChannelData(logicalChannelID); if (channelData.DataType == GPIBGroupChannelData.GpibChannelDataType.raw_string) { // Raw string commands just get added string stringWithCorrectNewlines = AddNewlineCharacters(channelData.RawString); commandBuffer.Add(new GpibCommand(stringWithCorrectNewlines, currentTime + postTime)); } else if (channelData.DataType == GPIBGroupChannelData.GpibChannelDataType.voltage_frequency_waveform) { GpibRampCommandConverter rampConverter = null; switch (hc.GpibDeviceType) { case HardwareChannel.HardwareConstants.GPIBDeviceType.Unknown: { foreach (GpibRampCommandConverter conv in commandConverters) { if (deviceSettings.DeviceDescription.Contains(conv.DeviceIdentifierSubstring)) { rampConverter = conv; } } if (rampConverter == null) { throw new Exception("Voltage/frequency ramp not supported for unknown gpib device " + hc.ToString() + "."); } } break; case HardwareChannel.HardwareConstants.GPIBDeviceType.Agilent_ESG_SIG_Generator: { rampConverter = ESG_SeriesRampConverter; } break; } double[] amplitudeArray; double[] frequencyArray; // get amplitude and frequency value arrays int nSamples = (int)(Shared.TicksToSeconds(groupDuration) * (double)deviceSettings.SampleClockRate); double secondsPerSample = Shared.TicksToSeconds(groupDuration) / (double)nSamples; amplitudeArray = channelData.volts.getInterpolation(nSamples, 0, Shared.TicksToSeconds(groupDuration), sequence.Variables, sequence.CommonWaveforms); frequencyArray = channelData.frequency.getInterpolation(nSamples, 0, Shared.TicksToSeconds(groupDuration), sequence.Variables, sequence.CommonWaveforms); List <DoubleIntPair> amplitudeIndexPairs = ConvertArrayToIndexValuePairs(amplitudeArray); List <DoubleIntPair> frequencyIndexPairs = ConvertArrayToIndexValuePairs(frequencyArray); int amplitudeIndex = 0; int frequencyIndex = 0; for (int i = 0; i < nSamples; i++) { bool amplitudeMatch = false; bool frequencyMatch = false; // determine if there is either a amplitude or frequency data point for this sample number if (amplitudeIndex < amplitudeIndexPairs.Count) { amplitudeMatch = amplitudeIndexPairs[amplitudeIndex].myInt == i; } if (frequencyIndex < frequencyIndexPairs.Count) { frequencyMatch = frequencyIndexPairs[frequencyIndex].myInt == i; } if (amplitudeIndex >= amplitudeIndexPairs.Count && frequencyIndex >= frequencyIndexPairs.Count) { break; } if (amplitudeMatch || frequencyMatch) { string command = ""; if (amplitudeMatch) { command += rampConverter.amplitudeCommand(amplitudeIndexPairs[amplitudeIndex].myDouble); amplitudeIndex++; } if (frequencyMatch) { command += rampConverter.frequencyCommand(frequencyIndexPairs[frequencyIndex].myDouble); frequencyIndex++; } long commandTime = currentTime + Shared.SecondsToTicks((double)i * secondsPerSample) + postTime; commandBuffer.Add(new GpibCommand(command, commandTime)); } } } else if (channelData.DataType == GPIBGroupChannelData.GpibChannelDataType.string_param_string) { if (channelData.StringParameterStrings != null) { foreach (StringParameterString sps in channelData.StringParameterStrings) { string commandWithCorrectNewlines = AddNewlineCharacters(sps.ToString()); commandBuffer.Add(new GpibCommand(commandWithCorrectNewlines, currentTime + postTime)); } } } currentTime += Shared.SecondsToTicks(currentStep.StepDuration.getBaseValue()); } return(true); }
public bool generateBuffer(SequenceData sequence, DeviceSettings deviceSettings, HardwareChannel hc, int logicalChannelID, List<GpibRampCommandConverter> commandConverters) { this.logicalChannelID = logicalChannelID; this.deviceType = hc.GpibDeviceType; commandBuffer = new List<GpibCommand>(); if (deviceSettings.StartTriggerType != DeviceSettings.TriggerType.SoftwareTrigger) { throw new Exception("GPIB devices must have a software start trigger."); } // start by adding the initialization string to the command buffer // this does nothing for unknown device types // Modified by REO 11/25/08: Null strings produce errors if written to device, so check if(HardwareChannel.HardwareConstants.gpibInitializationCommands[(int)deviceType]!= null) commandBuffer.Add(new GpibCommand(HardwareChannel.HardwareConstants.gpibInitializationCommands[(int)deviceType], 0)); if (deviceType == HardwareChannel.HardwareConstants.GPIBDeviceType.Unknown) { foreach (GpibRampCommandConverter conv in commandConverters) { //Modified by REO 11/25/08: Null strings produce errors if written to device, so check if (deviceSettings.DeviceDescription.Contains(conv.DeviceIdentifierSubstring) && conv.InitializationCommand != null) commandBuffer.Add(new GpibCommand(AddNewlineCharacters(conv.InitializationCommand), 0)); } } int currentStepIndex = - 1; //measured in ticks. 1 tick = 100 ns. long currentTime = 0; // This functionality is sort of somewhat duplicated in sequencedata.generatebuffers. It would be good // to come up with a more coherent framework to do these sorts of operations. while (true) { currentStepIndex++; if (currentStepIndex >= sequence.TimeSteps.Count) break; TimeStep currentStep = sequence.TimeSteps[currentStepIndex]; if (!currentStep.StepEnabled) continue; if (currentStep.GpibGroup == null || !currentStep.GpibGroup.channelEnabled(logicalChannelID)) { currentTime += seconds_to_ticks(currentStep.StepDuration.getBaseValue()); continue; } // determine the index of the next step in which this channel has an action int nextEnabledStepIndex = sequence.findNextGpibChannelEnabledTimestep(currentStepIndex, logicalChannelID); long groupDuration = seconds_to_ticks(sequence.timeBetweenSteps(currentStepIndex, nextEnabledStepIndex)); // now take action: GPIBGroupChannelData channelData = currentStep.GpibGroup.getChannelData(logicalChannelID); if (channelData.DataType == GPIBGroupChannelData.GpibChannelDataType.raw_string) { // Raw string commands just get added string stringWithCorrectNewlines = AddNewlineCharacters(channelData.RawString); commandBuffer.Add(new GpibCommand( stringWithCorrectNewlines, currentTime)); } else if (channelData.DataType == GPIBGroupChannelData.GpibChannelDataType.voltage_frequency_waveform) { GpibRampCommandConverter rampConverter = null; switch (hc.GpibDeviceType) { case HardwareChannel.HardwareConstants.GPIBDeviceType.Unknown: { foreach (GpibRampCommandConverter conv in commandConverters) { if (deviceSettings.DeviceDescription.Contains(conv.DeviceIdentifierSubstring)) rampConverter = conv; } if (rampConverter == null) { throw new Exception("Voltage/frequency ramp not supported for unknown gpib device " + hc.ToString() + "."); } } break; case HardwareChannel.HardwareConstants.GPIBDeviceType.Agilent_ESG_SIG_Generator: { rampConverter = ESG_SeriesRampConverter; } break; } double[] amplitudeArray; double[] frequencyArray; // get amplitude and frequency value arrays int nSamples = (int)(ticks_to_seconds(groupDuration) * (double)deviceSettings.SampleClockRate); double secondsPerSample = ticks_to_seconds(groupDuration) / (double) nSamples; amplitudeArray = channelData.volts.getInterpolation(nSamples, 0, ticks_to_seconds(groupDuration), sequence.Variables, sequence.CommonWaveforms); frequencyArray = channelData.frequency.getInterpolation(nSamples, 0, ticks_to_seconds(groupDuration), sequence.Variables, sequence.CommonWaveforms); List<DoubleIntPair> amplitudeIndexPairs = ConvertArrayToIndexValuePairs(amplitudeArray); List<DoubleIntPair> frequencyIndexPairs = ConvertArrayToIndexValuePairs(frequencyArray); int amplitudeIndex = 0; int frequencyIndex = 0; for (int i = 0; i < nSamples; i++) { bool amplitudeMatch = false; bool frequencyMatch = false; // determine if there is either a amplitude or frequency data point for this sample number if (amplitudeIndex < amplitudeIndexPairs.Count) amplitudeMatch = amplitudeIndexPairs[amplitudeIndex].myInt == i; if (frequencyIndex < frequencyIndexPairs.Count) frequencyMatch = frequencyIndexPairs[frequencyIndex].myInt == i; if (amplitudeIndex >= amplitudeIndexPairs.Count && frequencyIndex >= frequencyIndexPairs.Count) break; if (amplitudeMatch || frequencyMatch) { string command = ""; if (amplitudeMatch) { command += rampConverter.amplitudeCommand(amplitudeIndexPairs[amplitudeIndex].myDouble); amplitudeIndex++; } if (frequencyMatch) { command += rampConverter.frequencyCommand(frequencyIndexPairs[frequencyIndex].myDouble); frequencyIndex++; } long commandTime = currentTime + seconds_to_ticks((double)i * secondsPerSample); commandBuffer.Add(new GpibCommand(command, commandTime)); } } } else if (channelData.DataType == GPIBGroupChannelData.GpibChannelDataType.string_param_string) { if (channelData.StringParameterStrings != null) { foreach (StringParameterString sps in channelData.StringParameterStrings) { string commandWithCorrectNewlines = AddNewlineCharacters(sps.ToString()); commandBuffer.Add(new GpibCommand(commandWithCorrectNewlines, currentTime)); } } } currentTime += seconds_to_ticks(currentStep.StepDuration.getBaseValue()); } return true; }