public static MeasurementResults MeasureSupplyIV(NIDCPower supplyHandle, string channelNames = "")
        {
            MeasurementResults results;

            DCPowerMeasurementWhen measureMode = supplyHandle.Measurement.Configuration.MeasureWhen;
            int samplesToFetch = supplyHandle.Outputs[channelNames].Measurement.RecordLength;

            supplyHandle.Control.Initiate();
            switch (measureMode)
            {
            case DCPowerMeasurementWhen.OnMeasureTrigger:
            case DCPowerMeasurementWhen.AutomaticallyAfterSourceComplete:
                DCPowerFetchResult fetchResult = supplyHandle.Measurement.Fetch(channelNames, new PrecisionTimeSpan(1), samplesToFetch);
                results.Voltage_V = fetchResult.VoltageMeasurements;
                results.Current_A = fetchResult.CurrentMeasurements;
                break;

            case DCPowerMeasurementWhen.OnDemand:
            default:
                DCPowerMeasureResult measureResult = supplyHandle.Measurement.Measure(channelNames);
                results.Voltage_V = measureResult.VoltageMeasurements;
                results.Current_A = measureResult.CurrentMeasurements;
                break;
            }
            supplyHandle.Control.Abort();
            //Calculate power
            results.Power_W = new double[results.Voltage_V.Length];

            for (int i = 0; i < results.Voltage_V.Length; i++)
            {
                results.Power_W[i] = results.Voltage_V[i] * results.Current_A[i];
            }
            return(results);
        }
        public static void TurnSupplyOnOrOff(NIDCPower supplyHandle, SupplyPowerMode powerMode, string channelNames = "")
        {
            switch (powerMode)
            {
            case SupplyPowerMode.PowerOn:
                try
                {
                    supplyHandle.Outputs[channelNames].Source.Output.Enabled = true;
                    //Initiate sourcing and wait until the output settles
                    supplyHandle.Control.Initiate();
                    supplyHandle.Events.SourceCompleteEvent.WaitForEvent(new PrecisionTimeSpan(1));
                    supplyHandle.Control.Abort();
                    //Despite the fact that we have aborted, sourcing continues until output is disabled.
                    //We abort because we do not wish to make measurements until requested.
                }
                catch (Exception e)
                {
                    //Safety; disable output on any error
                    supplyHandle.Outputs[channelNames].Source.Output.Enabled = false;
                    supplyHandle.Control.Abort();
                    throw e;
                }
                break;

            case SupplyPowerMode.PowerOff:
                //To disable output, hardware needs to be in the running state.
                //Initiate, disable, then abort.
                supplyHandle.Control.Initiate();
                supplyHandle.Outputs[channelNames].Source.Output.Enabled = false;
                supplyHandle.Control.Abort();
                break;
            }
        }
        public static void ConfigureSupply(NIDCPower supplyHandle, SupplyConfiguration supplyConfig, string channelNames = "")
        {
            supplyHandle.Source.Mode = DCPowerSourceMode.SinglePoint;

            supplyHandle.Outputs[channelNames].Source.Output.Function   = supplyConfig.OutputFunction;
            supplyHandle.Outputs[channelNames].Source.TransientResponse = supplyConfig.TransientResponseMode;

            switch (supplyConfig.OutputFunction)
            {
            case DCPowerSourceOutputFunction.DCVoltage:
                supplyHandle.Outputs[channelNames].Source.Voltage.CurrentLimitAutorange = DCPowerSourceCurrentLimitAutorange.On;
                supplyHandle.Outputs[channelNames].Source.Voltage.VoltageLevelAutorange = DCPowerSourceVoltageLevelAutorange.On;

                supplyHandle.Outputs[channelNames].Source.Voltage.VoltageLevel = supplyConfig.VoltageLevel_V;
                supplyHandle.Outputs[channelNames].Source.Voltage.CurrentLimit = supplyConfig.CurrentLimit_A;
                break;

            case DCPowerSourceOutputFunction.DCCurrent:
                supplyHandle.Outputs[channelNames].Source.Current.CurrentLevelAutorange = DCPowerSourceCurrentLevelAutorange.On;
                supplyHandle.Outputs[channelNames].Source.Current.VoltageLimitAutorange = DCPowerSourceVoltageLimitAutorange.On;

                supplyHandle.Outputs[channelNames].Source.Current.CurrentLevel = supplyConfig.CurrentLevel_A;
                supplyHandle.Outputs[channelNames].Source.Current.VoltageLimit = supplyConfig.VoltageLimit_V;
                break;

            default:
                throw new NotImplementedException("Pulse voltage/current is not implemented.");
            }

            if (supplyConfig.TransientResponseMode == DCPowerSourceTransientResponse.Custom)
            {
                switch (supplyConfig.OutputFunction)
                {
                case DCPowerSourceOutputFunction.DCVoltage:
                    supplyHandle.Outputs[channelNames].Source.CustomTransientResponse.Voltage.CompensationFrequency =
                        supplyConfig.CustomTransientConfig.CompensationFrequency;
                    supplyHandle.Outputs[channelNames].Source.CustomTransientResponse.Voltage.GainBandwidth =
                        supplyConfig.CustomTransientConfig.GainBandwidth;
                    supplyHandle.Outputs[channelNames].Source.CustomTransientResponse.Voltage.PoleZeroRatio =
                        supplyConfig.CustomTransientConfig.PoleZeroRatio;
                    break;

                case DCPowerSourceOutputFunction.DCCurrent:
                    supplyHandle.Outputs[channelNames].Source.CustomTransientResponse.Current.CompensationFrequency =
                        supplyConfig.CustomTransientConfig.CompensationFrequency;
                    supplyHandle.Outputs[channelNames].Source.CustomTransientResponse.Current.GainBandwidth =
                        supplyConfig.CustomTransientConfig.GainBandwidth;
                    supplyHandle.Outputs[channelNames].Source.CustomTransientResponse.Current.PoleZeroRatio =
                        supplyConfig.CustomTransientConfig.PoleZeroRatio;
                    break;
                }
            }
        }
        public static void ConfigureMeasurement(NIDCPower supplyHandle, MeasurementConfiguration measConfig, string channelNames = "")
        {
            //On demand mode does not allow for multiple records to be acquired, so we need to validate the configuration given to this function.

            if (measConfig.MeasureWhenMode == DCPowerMeasurementWhen.OnDemand &&
                measConfig.MeasurementMode == MeasurementModeConfiguration.Record)
            {
                throw new ArgumentException("On Demand measurements can only be configured for a single measurement mode",
                                            "MeasurementMode, MeasureWhenMode");
            }

            supplyHandle.Measurement.Configuration.MeasureWhen          = measConfig.MeasureWhenMode;
            supplyHandle.Measurement.Configuration.IsRecordLengthFinite = true;

            if (measConfig.MeasureWhenMode == DCPowerMeasurementWhen.OnMeasureTrigger)
            {
                supplyHandle.Triggers.MeasureTrigger.DigitalEdge.Configure(
                    DCPowerDigitalEdgeMeasureTriggerInputTerminal.FromString(measConfig.MeasurementTriggerTerminal), DCPowerTriggerEdge.Rising);
            }

            supplyHandle.Outputs[channelNames].Measurement.Sense = measConfig.SenseMode;

            int    recordLength;
            double apertureTime;

            /*Single Point: Acquire a single measurement averaged over the duration of the Measurement Time
             * Record: Acquire samples at the maximum sampling rate of the supply for the total duration of Measurement Time. */
            switch (measConfig.MeasurementMode)
            {
            case MeasurementModeConfiguration.Record:
                //Set the aperture time to the minimum value and read it back. This sets the "sample rate".
                //Then, we calculate how many records we need to acquire at that sample rate to get the requested measurement time.
                supplyHandle.Outputs[channelNames].Measurement.ApertureTime = 0;
                double minApertureTime = supplyHandle.Outputs[channelNames].Measurement.ApertureTime;     //dt (Seconds per Sample)
                recordLength = (int)Math.Ceiling(measConfig.MeasurementTime_s / minApertureTime) + 1;     // (Time_s)/(dt S/s) = #of samples
                apertureTime = minApertureTime;
                break;

            case MeasurementModeConfiguration.SinglePoint:
            default:
                //Acquire a single record that is the average measurement over Measurement Time
                apertureTime = measConfig.MeasurementTime_s;
                recordLength = 1;
                break;
            }

            supplyHandle.Outputs[channelNames].Measurement.ApertureTimeUnits = DCPowerMeasureApertureTimeUnits.Seconds;
            supplyHandle.Outputs[channelNames].Measurement.ApertureTime      = apertureTime;
            supplyHandle.Outputs[channelNames].Measurement.RecordLength      = recordLength;
        }
        static void Main()
        {
            string    channelNames = "0";
            NIDCPower dcPower      = new NIDCPower("4139", channelNames, false);

            // Configure instrument settings
            SupplyConfiguration supplyConfig = SupplyConfiguration.GetDefault();

            supplyConfig.OutputFunction = DCPowerSourceOutputFunction.DCVoltage;
            supplyConfig.VoltageLevel_V = 3;
            supplyConfig.CurrentLevel_A = 1;

            ConfigureSupply(dcPower, supplyConfig, channelNames);

            // Configure measurement related parameters
            MeasurementConfiguration measConfig = new MeasurementConfiguration
            {
                MeasureWhenMode = DCPowerMeasurementWhen.AutomaticallyAfterSourceComplete,
                SenseMode       = DCPowerMeasurementSense.Remote,
                // A MeasurementMode of "Record" acquires multiple smaples over the requested measurement
                // time at the supply's maximum sampling rate. "Single Point" will take a single measurement
                // over that duration and average the power and current results.
                MeasurementMode            = MeasurementModeConfiguration.Record,
                MeasurementTime_s          = 2e-3,
                MeasurementTriggerTerminal = "PXI_Trig0"
            };

            ConfigureMeasurement(dcPower, measConfig, channelNames);

            TurnSupplyOnOrOff(dcPower, SupplyPowerMode.PowerOn, channelNames);

            MeasurementResults results = MeasureSupplyIV(dcPower, channelNames);

            // Calculate the average of the acquired results
            results = Utilities.CalculateAverageIV(results);

            Console.WriteLine($"The average voltage measured was {results.Voltage_V[0]} with a current of {results.Current_A[0]}");
            Console.WriteLine("Press any key to turn off the supply and exit the program.");

            Console.ReadKey();

            TurnSupplyOnOrOff(dcPower, SupplyPowerMode.PowerOff, channelNames);

            CloseSupply(dcPower, channelNames);
        }
        /// <summary>
        /// This example illustrates how to use the NI-DCPower APIs to configure the SMU and measure the results.
        /// </summary>
        static void Main()
        {
            string    channelNames = "0";
            NIDCPower dcPower      = new NIDCPower("4139", channelNames, false);

            // Configure instrument settings
            SupplyConfiguration supplyConfig = SupplyConfiguration.GetDefault();

            supplyConfig.OutputFunction = DCPowerSourceOutputFunction.DCVoltage;
            supplyConfig.VoltageLevel_V = 3;
            supplyConfig.CurrentLevel_A = 0.001;
            supplyConfig.VoltageLimit_V = 3;
            supplyConfig.CurrentLimit_A = 0.001;

            ConfigureSupply(dcPower, supplyConfig, channelNames);

            // Configure measurement related parameters
            MeasurementConfiguration measConfig = MeasurementConfiguration.GetDefault();

            measConfig.MeasureWhenMode   = DCPowerMeasurementWhen.AutomaticallyAfterSourceComplete;
            measConfig.MeasurementTime_s = 2e-3;

            ConfigureMeasurement(dcPower, measConfig, channelNames);

            TurnSupplyOnOrOff(dcPower, SupplyPowerMode.PowerOn, channelNames);

            MeasurementResults results = MeasureSupplyIV(dcPower, channelNames);

            // Calculate the average of the acquired results
            results = Utilities.CalculateAverageIV(results);

            Console.WriteLine($"The average voltage measured was {results.Voltage_V[0]} with a current of {results.Current_A[0]}");
            Console.WriteLine("Press any key to turn off the supply and exit the program.");

            Console.ReadKey();

            TurnSupplyOnOrOff(dcPower, SupplyPowerMode.PowerOff, channelNames);

            CloseSupply(dcPower);
        }
        static void Main()
        {
            string    channelNames = "0";
            NIDCPower dcPower      = new NIDCPower("4139", channelNames, false);

            SupplyConfiguration supplyConfig = new SupplyConfiguration();

            supplyConfig.SetDefaults();

            supplyConfig.OutputFunction        = DCPowerSourceOutputFunction.DCVoltage;
            supplyConfig.VoltageLevel_V        = 3;
            supplyConfig.CurrentLevel_A        = 1;
            supplyConfig.TransientResponseMode = DCPowerSourceTransientResponse.Fast;

            ConfigureSupply(dcPower, supplyConfig, channelNames);

            MeasurementConfiguration measConfig = new MeasurementConfiguration
            {
                MeasureWhenMode            = DCPowerMeasurementWhen.AutomaticallyAfterSourceComplete,
                SenseMode                  = DCPowerMeasurementSense.Remote,
                MeasurementMode            = MeasurementConfiguration.MeasurementModeConfiguration.SinglePoint,
                MeasurementTime_s          = 2e-3,
                MeasurementTriggerTerminal = "PXI_Trig0"
            };

            ConfigureMeasurement(dcPower, measConfig, channelNames);

            TurnSupplyOnOrOff(dcPower, SupplyPowerMode.PowerOn, channelNames);

            MeasurementResults results = MeasureSupplyIV(dcPower, channelNames);

            results = Utilities.CalculateAverageIV(results, 3);

            TurnSupplyOnOrOff(dcPower, SupplyPowerMode.PowerOff, channelNames);

            CloseSupply(dcPower, channelNames);
        }
 public static void CloseSupply(NIDCPower supplyHandle, string channelNames = "")
 {
     //Quickly ensures all outputs are disabled and resets the device
     supplyHandle.Utility.Disable();
     supplyHandle.Close();
 }