public void ConfigureMeasurementTest()
        {
            NIScope testScope = new NIScope("SIM", false, false, "Simulate = 1");

            MeasurementConfiguration measConfig = MeasurementConfiguration.GetDefault();

            ConfigureMeasurement(testScope, measConfig, "0");

            //Validate basic property sets
            Assert.AreEqual(measConfig.SampleRate_Hz, testScope.Acquisition.SampleRateMin);
            Assert.AreEqual(measConfig.ScopeTriggerSource, testScope.Trigger.Source.ToString());
            Assert.AreEqual(measConfig.TriggerEdge, testScope.Trigger.EdgeTrigger.Slope);
            Assert.AreEqual(measConfig.ScopeTriggerType, testScope.Trigger.Type);

            //Validate that the measurement time is properly calculated by teh code
            Assert.AreEqual(measConfig.MeasurementTime_s, testScope.Acquisition.TimePerRecord.TotalSeconds, 1e-6);

            //Validate that various trigges are setup correctly
            measConfig.ScopeTriggerType = ScopeTriggerType.Immediate;
            ConfigureMeasurement(testScope, measConfig, "0");
            Assert.AreEqual(measConfig.ScopeTriggerType, testScope.Trigger.Type);

            measConfig.ScopeTriggerType = ScopeTriggerType.Software;
            ConfigureMeasurement(testScope, measConfig, "0");
            Assert.AreEqual(measConfig.ScopeTriggerType, testScope.Trigger.Type);

            testScope.Close();
        }
        public static void ConfigureMeasurement(NIScope scope, MeasurementConfiguration measurementConfig, string channelNames = "0")
        {
            switch (measurementConfig.ScopeTriggerType)
            {
            case ScopeTriggerType.DigitalEdge:
                scope.Trigger.ConfigureTriggerDigital(ScopeTriggerSource.FromString(measurementConfig.ScopeTriggerSource),
                                                      measurementConfig.TriggerEdge, PrecisionTimeSpan.Zero, PrecisionTimeSpan.Zero);
                break;

            case ScopeTriggerType.Immediate:
                scope.Trigger.ConfigureTriggerImmediate();
                break;

            case ScopeTriggerType.Software:
                scope.Trigger.ConfigureTriggerSoftware(PrecisionTimeSpan.Zero, PrecisionTimeSpan.Zero);
                break;

            default:
                throw new System.NotImplementedException("The functionality for the requested NI-SCOPE trigger type has not been implemented.");
            }

            scope.Acquisition.SampleRateMin     = measurementConfig.SampleRate_Hz;
            scope.Acquisition.NumberOfPointsMin = (long)Math.Round(scope.Acquisition.SampleRate * measurementConfig.MeasurementTime_s);

            scope.Timing.NumberOfRecordsToAcquire = 1;
        }
示例#3
0
 public bool TryStopTask()
 {
     //如果是主卡,判断是否有任何从卡没有完成,否则不能出来
     if (_staticConfig.TriggerConfig.MasterOrSlave == AITriggerMasterOrSlave.Master)
     {
         bool canOut = false;
         while (!canOut)
         {
             canOut = true;
             lock (TClockDevice.Lock)
             {
                 foreach (var s in TClockDevice.SlaveOver)
                 {
                     if (s.Value == false)
                     {
                         canOut = false;
                     }
                 }
             }
         }
     }
     //如果是从卡,设置让主卡可以出来
     else if (_staticConfig.TriggerConfig.MasterOrSlave == AITriggerMasterOrSlave.Slave)
     {
         lock (TClockDevice.Lock)
         {
             TClockDevice.SlaveOver[_staticConfig.ResourceName] = true;
         }
     }
     lock (TClockDevice.Lock)
     {
         if (TClockDevice.SyncDevices != null && TClockDevice.SyncDevices.Contains(scopeSession))
         {
             TClockDevice.SyncDevices.Remove(scopeSession);
         }
     }
     try
     {
         if (tClockSession != null)
         {
             tClockSession = null;
         }
         if (scopeSession != null)
         {
             scopeSession.Close();
             scopeSession.Dispose();
             scopeSession = null;
         }
     }
     catch (Exception e)
     {
         throw new Exception(e.ToString());
     }
     AIState = Status.Idle;
     return(true);
 }
        public static void ConfigureScope(NIScope scope, ScopeConfiguration scopeConfig, string channelNames = "0")
        {
            scope.Channels[channelNames].Coupling         = scopeConfig.ScopeCouplingMode;
            scope.Channels[channelNames].InputImpedance   = (double)scopeConfig.InputImpedance;
            scope.Channels[channelNames].Range            = scopeConfig.VerticalRange_V;
            scope.Channels[channelNames].Offset           = scopeConfig.VerticalOffset_V;
            scope.Channels[channelNames].ProbeAttenuation = scopeConfig.ProbeAttenuation;

            scope.Timing.ReferenceClockSource = ScopeInputClockSource.FromString(scopeConfig.ScopeClockSource);

            scope.Channels[channelNames].Enabled = true;
        }
示例#5
0
        /// <summary>
        /// 配置已经实例化的 scopeSession,包括通道设置、时钟设置以及触发设置
        /// </summary>
        /// <param name="niTask"></param>
        /// <param name="channelConfiguration"></param>
        public static void MapAndConfigAll(NIScope scopeSession, NIScopeAIStaticConfig basicAIConifg, ref TClock tClockSession)
        {
            if (basicAIConifg.MoreRecordsThanMemoryAllowed == true)
            {
                throw new Exception("暂时不支持超内存采样!");
            }
            scopeSession.Timing.MoreRecordsThanMemoryAllowed = basicAIConifg.MoreRecordsThanMemoryAllowed;

            MapAndConfigTrigger(scopeSession, basicAIConifg.TriggerConfig, ref tClockSession);
            MapAndConfigClock(scopeSession, basicAIConifg.ClockConfig);
            MapAndConfigChannel(scopeSession, basicAIConifg.ChannelConfig);
        }
        public static MeasurementResults MeasureChannel(NIScope scope, string channelName = "0")
        {
            MeasurementResults results = new MeasurementResults();

            scope.Measurement.Initiate();
            AnalogWaveformCollection <double> resultWaveform = new AnalogWaveformCollection <double>();

            resultWaveform         = scope.Channels[channelName].Measurement.FetchDouble(PrecisionTimeSpan.FromSeconds(5), -1, null);
            results.ResultsTrace   = resultWaveform[0].GetRawData();
            results.AverageValue_V = scope.Channels[channelName].Measurement.FetchScalarMeasurement(PrecisionTimeSpan.FromSeconds(5),
                                                                                                    ScopeScalarMeasurementType.VoltageAverage)[0];
            scope.Measurement.Abort();

            return(results);
        }
示例#7
0
        public void StartAcquisition(string channelName, double sampleRate, double referencePosition,
                                     double range, int numberOfPoints, int numberOfRecords)
        {
            try
            {
                scopeDevices = new ModularInstrumentsSystem("NI-Scope");
                scopeName    = scopeDevices.DeviceCollection[0].Name;
                scopeSession = new NIScope(scopeName, false, true);
                scopeSession.DriverOperation.Warning += new EventHandler <ScopeWarningEventArgs>(DriverOperation_Warning);

                scopeSession.Channels[channelName].InputImpedance = 50;

                double offset = 0.0;
                ScopeVerticalCoupling coupling = ScopeVerticalCoupling.DC;
                double probeAttenuation        = 1.0;
                scopeSession.Channels[channelName].Configure(range, offset, coupling, probeAttenuation, true);

//                scopeSession.Channels[channelName]

                bool enforceRealtime = true;

                scopeSession.Timing.ConfigureTiming
                    (sampleRate, numberOfPoints, referencePosition, numberOfRecords, enforceRealtime);

                double               triggerLevel    = 1.6;
                ScopeTriggerSlope    triggerSlope    = ScopeTriggerSlope.Positive;
                ScopeTriggerCoupling triggerCoupling = ScopeTriggerCoupling.DC;
                PrecisionTimeSpan    triggerHoldoff  = PrecisionTimeSpan.Zero;
                PrecisionTimeSpan    triggerDelay    = PrecisionTimeSpan.Zero;
                ScopeTriggerSource   triggerSource   = ScopeTriggerSource.External;

                scopeSession.Trigger.EdgeTrigger.Configure
                    (triggerSource, triggerLevel, triggerSlope, triggerCoupling, triggerHoldoff, triggerDelay);

                recordLength     = scopeSession.Acquisition.RecordLength;
                sampleRate       = scopeSession.Acquisition.SampleRate;
                this.channelName = channelName;

                scopeSession.Measurement.Initiate();


                timeout = new PrecisionTimeSpan(5.0);
            }
            catch (Exception ex)
            {
                ShowError(ex);
            }
        }
        static void Main()
        {
            NIScope myScope = new NIScope("5154", false, false);

            ScopeConfiguration       scopeConfig = GetDefaultScopeConfiguration();
            MeasurementConfiguration measConfig  = GetDefaultMeasurementConfiguration();

            ConfigureScope(myScope, scopeConfig, "0");
            ConfigureMeasurement(myScope, measConfig, "0");

            MeasurementResults myResults = MeasureChannel(myScope, "0");

            Console.WriteLine(myResults.AverageValue_V);
            Console.ReadKey();
            myScope.Close();
        }
示例#9
0
        private static void MapAndConfigClock(NIScope scopeSession, AIClockConfiguration clockConfiguration)
        {
            //无时钟源设置
            //采样数量,仅支持有限
            switch (clockConfiguration.SampleQuantityMode)
            {
            case AISamplesMode.FiniteSamples:
                break;

            default:
                throw new Exception("采样数量 SampleQuantityMode 设置错误!仅支持有限采样(0)!");
            }
            //无使能时钟沿
            //配置采样率,采样总数,采样次数
            int records = clockConfiguration.TotalSampleLengthPerChannel / clockConfiguration.ReadSamplePerTime;

            scopeSession.Timing.ConfigureTiming(clockConfiguration.SampleRate, clockConfiguration.TotalSampleLengthPerChannel, 0.0, records, true);
        }
        public void ConfigureScopeTest()
        {
            NIScope testScope = new NIScope("SIM", false, false, "Simulate = 1");

            ScopeConfiguration scopeConfig = ScopeConfiguration.GetDefault();

            ConfigureScope(testScope, scopeConfig, "0");

            //Check that all properties are properly applied to the scope session
            Assert.AreEqual((double)scopeConfig.InputImpedance, testScope.Channels["0"].InputImpedance, "Impedance");
            Assert.AreEqual(scopeConfig.ScopeCouplingMode, testScope.Channels["0"].Coupling, "Coupling");
            Assert.AreEqual(scopeConfig.VerticalOffset_V, testScope.Channels["0"].Offset, "Offset");
            Assert.AreEqual(scopeConfig.VerticalRange_V, testScope.Channels["0"].Range, "Range");
            Assert.AreEqual(scopeConfig.ProbeAttenuation, testScope.Channels["0"].ProbeAttenuation, "Probe Attenuation");
            Assert.AreEqual(scopeConfig.ScopeClockSource, testScope.Timing.ReferenceClockSource.ToString(), "Clock Source");


            testScope.Close();
        }
示例#11
0
        private static void MapAndConfigChannel(NIScope scopeSession, AIChannelConfiguration channelConfiguration)
        {
            //todo:检查是否真的是0,1,2……
            //var channels = ((JArray)channelConfiguration.ChannelName).ToObject<List<int>>(); 当ChannelName还是Object的时候
            var channels = ChannelNameTranslator.StringToListInt(channelConfiguration.ChannelName);

            double range = channelConfiguration.MaximumValue - channelConfiguration.MinimumValue;

            foreach (var c in channels)
            {
                //Todo:信号输入方式无法配置
                //配置信号输入方式
                switch (channelConfiguration.TerminalConfigType)
                {
                //目前只支持差分
                case AITerminalType.Differential:
                    scopeSession.Channels[c.ToString()].Configure(range, 0, ScopeVerticalCoupling.DC, 1.0, true);
                    break;

                default:
                    throw new Exception("输入方式 AITerminalType 定义无效!");
                }
            }
        }
示例#12
0
        //读数据
        private void readData(NIScope scopeSession)
        {
            //var channels = ((JArray)_staticConfig.ChannelConfig.ChannelName).ToObject<List<int>>();
            var channels = ChannelNameTranslator.StringToListInt(_staticConfig.ChannelConfig.ChannelName);
            //开新线程等待读数据
            //await Task.Run(() =>
            //{
            int totalReadDataLength   = 0;
            PrecisionTimeSpan timeout = new PrecisionTimeSpan(1000000);  //无timeOut
            AnalogWaveformCollection <double> scopeWaveform = null;

            double[,] readData = new double[_staticConfig.ChannelCount, _staticConfig.ClockConfig.TotalSampleLengthPerChannel];

            //生成 channels
            string channelScope = null;
            //var sChannels = ((JArray)_staticConfig.ChannelConfig.ChannelName).ToObject<List<int>>();
            var sChannels = ChannelNameTranslator.StringToListInt(_staticConfig.ChannelConfig.ChannelName);

            foreach (var s in sChannels)
            {
                channelScope += s + ",";
            }
            channelScope = channelScope.Substring(0, channelScope.Length - 1);

            //一次采完
            //经过测试,发现在默认设置(不设置其它)情况下:
            // 1、如果多次 FetchDouble,则每 2 次的数据不连续(中间断一截)
            // 2、如果设置多个 records,则每 2 个 record 之间的数据不连续(中间断一截)
            //因此暂时只允许一个 record
            scopeWaveform = scopeSession.Channels[channelScope].Measurement.FetchDouble(timeout, _staticConfig.ClockConfig.TotalSampleLengthPerChannel, scopeWaveform);

            //一旦上面这里获取到数据,则表示采集开始
            AIState = Status.Running;

            // i 是读取次数
            // j 是通道计数
            // k 是每一波的每个点
            double[] temp;
            AnalogWaveform <double> waveform;

            for (int i = 0; i < _staticConfig.ClockConfig.TotalSampleLengthPerChannel / _staticConfig.ClockConfig.ReadSamplePerTime; i++)
            {
                //将一个通道的数据拷贝到 data[,] 的一行
                for (int j = 0; j < _staticConfig.ChannelCount; j++)
                {
                    waveform = scopeWaveform[i, j];
                    temp     = waveform.GetRawData();
                    for (int k = 0; k < _staticConfig.ClockConfig.ReadSamplePerTime; k++)
                    {
                        readData[j, i *_staticConfig.ClockConfig.ReadSamplePerTime + k] = temp[k];
                    }
                }

                totalReadDataLength += _staticConfig.ClockConfig.ReadSamplePerTime;
            }
            GC.Collect();
            Thread.Sleep(2000);

            //发布数据到达事件
            OnDataArrival(readData);

            //发布停止任务事件
            OnAITaskStopped();

            //等待,让外部保证获取到 Running 状态
            Thread.Sleep(2000);
            //});
        }
示例#13
0
        private void RealArm()
        {
            if (AIState != Status.Idle)
            {
                throw new Exception("If you want to arm, the AI state must be 'Idle'!");
            }
            else
            {
                if (scopeSession == null)
                {
                    try
                    {
                        //新建任务
                        scopeSession = new NIScope(_staticConfig.ResourceName, false, false);

                        //配置任务
                        NIScopeAIConfigMapper.MapAndConfigAll(scopeSession, _staticConfig, ref tClockSession);

                        //获取并设置通道数
                        _staticConfig.ChannelCount = scopeSession.Channels.Count;

                        AIState = Status.Ready;

                        if (_staticConfig.TriggerConfig.MasterOrSlave == AITriggerMasterOrSlave.NonSync)
                        {
                            scopeSession.Measurement.Initiate();
                        }
                        // Master 连同所有 Slaves 只需要一个 tClockSession.Initiate()
                        else if (_staticConfig.TriggerConfig.MasterOrSlave == AITriggerMasterOrSlave.Master)
                        {
                            tClockSession.Initiate();
                            TClockDevice.IsMasterReady = true;
                        }
                        //注意,这里从 Slave 是不会 Initiate 的,Slave 必须被 Master 带,也就是 Slave 需要等待 Master 准备就绪才能采集
                        else
                        {
                            while (!TClockDevice.IsSlaveCanAddIntoTDevice)
                            {
                                Thread.Sleep(300);
                            }
                            //等待主卡 Initiate
                            while (!TClockDevice.IsMasterReady)
                            {
                                Thread.Sleep(200);
                            }

                            lock (TClockDevice.Lock)
                            {
                                //表示没有完成,主卡不能 Idle
                                if (TClockDevice.SlaveOver.ContainsKey(_staticConfig.ResourceName))
                                {
                                    TClockDevice.SlaveOver[_staticConfig.ResourceName] = false;
                                }
                                else
                                {
                                    TClockDevice.SlaveOver.Add(_staticConfig.ResourceName, false);
                                }
                            }
                        }

                        //开始读取数据
                        readData(scopeSession);
                    }
                    catch (Exception e)
                    {
                        TryStopTask();
                        Console.WriteLine("炸了");
                        throw new Exception("任务因错误终止!" + e.ToString());
                    }
                }
            }
        }
示例#14
0
        private static void MapAndConfigTrigger(NIScope scopeSession, AITriggerConfiguration triggerConfiguration, ref TClock tClockSession)
        {
            //配置触发沿
            ScopeTriggerSlope triggerSlope;

            switch (triggerConfiguration.TriggerEdge)
            {
            case Edge.Rising:
                triggerSlope = ScopeTriggerSlope.Positive;
                break;

            case Edge.Falling:
                triggerSlope = ScopeTriggerSlope.Negative;
                break;

            default:
                throw new Exception("触发沿 TriggerEdge 设置错误!");
            }

            //设置触发源
            ScopeTriggerSource triggerSource = triggerConfiguration.TriggerSource.ToString();

            //设置触发模式
            switch (triggerConfiguration.TriggerType)
            {
            case AITriggerType.Immediate:
                scopeSession.Trigger.Type = ScopeTriggerType.Immediate;
                scopeSession.Trigger.ConfigureTriggerImmediate();
                break;

            case AITriggerType.DigitalTrigger:
                scopeSession.Trigger.Type = ScopeTriggerType.DigitalEdge;
                scopeSession.Trigger.ConfigureTriggerDigital(triggerSource, triggerSlope, PrecisionTimeSpan.Zero, new PrecisionTimeSpan(triggerConfiguration.Delay));
                break;

            case AITriggerType.AnalogTrigger:
                scopeSession.Trigger.Type = ScopeTriggerType.Edge;
                scopeSession.Trigger.EdgeTrigger.Configure(triggerSource, 2.5, triggerSlope, ScopeTriggerCoupling.DC, PrecisionTimeSpan.Zero, new PrecisionTimeSpan(triggerConfiguration.Delay));
                break;

            default:
                throw new Exception("触发模式 TriggerType 设置错误!");
            }

            //如果不是非同步
            //加入到TClock中
            if (triggerConfiguration.MasterOrSlave != AITriggerMasterOrSlave.NonSync)
            {
                lock (TClockDevice.Lock)
                {
                    if (TClockDevice.SyncDevices == null)
                    {
                        TClockDevice.SyncDevices = new List <NIScope>();
                    }
                    TClockDevice.SyncDevices.Add(scopeSession);
                }
            }

            //如果是主卡,则将所有的 SynchronizableDevices 实例化出来,这样写也就决定了只能有一个 Master( NI 机箱可级联支持双 Master)
            //这一行必须是在所有需要同步的卡 scopeSession 设置完毕之后
            if (triggerConfiguration.MasterOrSlave == AITriggerMasterOrSlave.Master)
            {
                TClockDevice.IsMasterReady            = false;
                TClockDevice.IsSlaveCanAddIntoTDevice = true;

                //因为主卡可能会和从卡同时被 Arm,因此先等待所有从卡设备加入 TClockDevice
                Thread.Sleep(1000);

                TClockDevice.IsSlaveCanAddIntoTDevice = false;

                ITClockSynchronizableDevice[] scopeSynchronizableDevices = new ITClockSynchronizableDevice[TClockDevice.SyncDevices.Count];
                for (int i = 0; i < TClockDevice.SyncDevices.Count; i++)
                {
                    scopeSynchronizableDevices[i] = TClockDevice.SyncDevices[i];
                }
                tClockSession = new TClock(scopeSynchronizableDevices);
                tClockSession.ConfigureForHomogeneousTriggers();
                tClockSession.Synchronize();
            }
        }
示例#15
0
 private static void InitializeSession(string deviceName)
 {
     _scopeSession = new NIScope(deviceName, false, false);
     _scopeSession.DriverOperation.Warning += DriverOperation_Warning;
 }