// Analog input quick start for C# / .NET. // // Works with every model on the site — only the device and channel names change. // // 1. Add a reference to NationalInstruments.DAQmx.dll // 2. dotnet run --project DaqQuickStart -- Dev1 ai0:3 // // The synchronous read loop below is the simplest correct pattern. For // continuous acquisition use a DaqStream / AnalogMultiChannelReader with a // callback, or an async Task, so the UI thread is never blocked. using System; using System.Linq; using NationalInstruments.DAQmx; internal static class DaqQuickStart { private static int Main(string[] args) { string device = args.Length > 0 ? args[0] : "Dev1"; string channels = args.Length > 1 ? args[1] : "ai0:3"; Console.WriteLine($"Device : {device}"); Console.WriteLine($"Channels : {channels}"); Console.WriteLine(); try { ReadSinglePoints(device, channels, samples: 10); ReadBufferedBlock(device, channels, rate: 10_000.0, samplesPerChannel: 1_000); } catch (DaqException ex) { Console.Error.WriteLine($"DAQ error ({ex.Error}): {ex.Message}"); Console.Error.WriteLine("Check the device name with NI MAX or the configuration utility."); return 1; } Console.WriteLine("Done."); return 0; } /// Software-timed single-point reads — for slow signals. private static void ReadSinglePoints(string device, string channels, int samples) { Console.WriteLine($"Single-point reads on {device}/{channels}"); Console.WriteLine(new string('-', 56)); using (Task task = new Task()) { task.AIChannels.CreateVoltageChannel( $"{device}/{channels}", nameToAssignToChannel: "", terminalConfiguration: AITerminalConfiguration.Rse, minimumValue: -10.0, maximumValue: 10.0, voltageUnits: AIVoltageUnits.Volts); AnalogSingleChannelReader reader = new AnalogSingleChannelReader(task.Stream); for (int i = 0; i < samples; i++) { double value = reader.ReadSingleSample(); Console.WriteLine($" {i + 1,3} {value,10:F5} V"); System.Threading.Thread.Sleep(200); } } Console.WriteLine(); } /// Hardware-timed block using the device sample clock. private static void ReadBufferedBlock( string device, string channels, double rate, int samplesPerChannel) { Console.WriteLine($"Buffered acquisition on {device}/{channels}"); Console.WriteLine($"{rate:N0} S/s, {samplesPerChannel:N0} samples per channel"); Console.WriteLine(new string('-', 56)); using (Task task = new Task()) { task.AIChannels.CreateVoltageChannel( $"{device}/{channels}", nameToAssignToChannel: "", terminalConfiguration: AITerminalConfiguration.Rse, minimumValue: -10.0, maximumValue: 10.0, voltageUnits: AIVoltageUnits.Volts); task.Timing.ConfigureSampleClock( signalSource: "", rate: rate, sampleClockActiveEdge: SampleClockActiveEdge.Rising, sampleQuantityMode: SampleQuantityMode.FiniteSamples, samplesPerChannel: samplesPerChannel); AnalogMultiChannelReader reader = new AnalogMultiChannelReader(task.Stream); double[,] data = reader.ReadMultiSample(samplesPerChannel); int channelCount = data.GetLength(0); for (int ch = 0; ch < channelCount; ch++) { double min = double.MaxValue; double max = double.MinValue; double sum = 0.0; for (int i = 0; i < samplesPerChannel; i++) { double v = data[ch, i]; if (v < min) min = v; if (v > max) max = v; sum += v; } Console.WriteLine( $" ch{ch}: {samplesPerChannel:N0} samples " + $"min {min,+9:F4} V max {max,+9:F4} V mean {sum / samplesPerChannel,+9:F4} V"); } } Console.WriteLine(); } }