/// <summary> /// Creates a new DAQmx task and adds channels to it /// </summary> /// <param name="nodes">Graph nodes of type MetricAnalogInput</param> /// <exception cref="InvalidCastException">At least one element in <paramref name="nodes"/> not of type MetricAnalogInput</exception> /// <exception cref="InvalidOperationException">At least one element in <paramref name="nodes"/> not connected to the instance's specified device or task already created</exception> /// <exception cref="NidaqException">Task or channel could not be created</exception> public void CreateTask(IEnumerable <INidaqMetric> nodes) { if (TaskHandle != 0) { throw new InvalidOperationException("Task already created. First destroy the old task"); } if (!nodes.All(n => n is MetricAnalogInput)) { throw new InvalidCastException("all passed nodes must be of type MetricAnalogInput"); } if (!nodes.All(n => n.Channel.Device == Device)) { throw new InvalidOperationException("not all passed nodes are connected to device " + Device.Name); } foreach (var node in nodes.OfType <MetricAnalogInput>()) { node.Samplerate = ClockRate; } // 1. create task var taskHandle = new int[1]; var result = NidaQmxHelper.DAQmxCreateTask(null, taskHandle); if (result < 0) { throw new NidaqException(result); } TaskHandle = taskHandle[0]; // 2. create channels foreach (var input in nodes.OfType <MetricAnalogInput>()) { result = NidaQmxHelper.DAQmxCreateAIVoltageChan( maxVal: input.VMax, minVal: input.VMin, units: NidaQmxHelper.DaQmxValVolts, terminalConfig: (int)input.TerminalConfig, physicalChannel: input.Channel.Path, taskHandle: TaskHandle, nameToAssignToChannel: null, customScaleName: null ); if (result < 0) { CleanupAndThrow(result); } _nodes.Add(input); } // 3. configure clock SamplesPerChannel = ClockRate / 5; result = NidaQmxHelper.DAQmxCfgSampClkTiming( activeEdge: NidaQmxHelper.DaQmxValRising, sampleMode: NidaQmxHelper.DaQmxValContSamps, sampsPerChan: (ulong)SamplesPerChannel, taskHandle: TaskHandle, source: "", rate: ClockRate ); if (result < 0) { CleanupAndThrow(result); } State = SessionTaskState.Stopped; }
private bool CreateVirtualChannel(InOutPortFlags flags) { // ------------------------------------ if (flags.HasFlag(InOutPortFlags.UseInput)) { var inputs = _device.ListeningPorts.Where(port => port.Direction == ChannelDirection.Input) .Select(port => port.Name); if (inputs.Any()) { var inputPortStrings = string.Join(",", inputs); var result = NidaQmxHelper.DAQmxCreateAIVoltageChan( maxVal: 10.0, minVal: -10.0, units: NidaQmxHelper.DaQmxValVolts, terminalConfig: NidaQmxHelper.DaQmxValRse, physicalChannel: inputPortStrings, taskHandle: _device.InputTaskHandle, nameToAssignToChannel: "chanI" + _device.Name, customScaleName: null ); if (result < 0) { NidaQmxHelper.DAQmxClearTask(_device.InputTaskHandle); _device.ReportError(new DeviceErrorArgs(NidaQmxHelper.GetError(result))); return(false); } } } // ------------------------------------ if (flags.HasFlag(InOutPortFlags.UseOutput)) { var outputs = _device.ListeningPorts.Where(port => port.Direction == ChannelDirection.Output) .Select(port => port.Name); if (outputs.Any()) { var outputPortStrings = string.Join(",", outputs); var channelNumber = 0; foreach (var output in _device.ListeningPorts.Where(port => port.Direction == ChannelDirection.Output)) { ((NidaQmxChannelOutput)output).ChannelNumber = channelNumber++; } var result = NidaQmxHelper.DAQmxCreateAOVoltageChan( maxVal: 10.0, minVal: -10.0, units: NidaQmxHelper.DaQmxValVolts, physicalChannel: outputPortStrings, taskHandle: _device.OutputTaskHandle, nameToAssignToChannel: "chanO" + _device.Name, customScaleName: null ); if (result < 0) { NidaQmxHelper.DAQmxClearTask(_device.OutputTaskHandle); _device.ReportError(new DeviceErrorArgs(NidaQmxHelper.GetError(result))); return(false); } } } // ------------------------------------ return(true); }