public static TxPServoResults TxPServoPower(RFmxWlanMX wlanSignal, NIRfsg rfsgSession, TxPServoConfiguration servoConfig, AutoLevelConfiguration autoLevelConfig, string selectorString = "") { //Duplicate the existing configuration so that we can select only TxP for the power servo to save time, //but not disrupt all of the other user enabled measurements. wlanSignal.CloneSignalConfiguration("servo_txp", out RFmxWlanMX servoTxpSession); servoTxpSession.SelectMeasurements(selectorString, RFmxWlanMXMeasurementTypes.Txp, false); double[] servoTrace = new double[servoConfig.MaxNumberOfIterations]; double powerLevel = 0, outputPower = 0, margin = 0; bool servoSucess = false; for (int i = 0; i < servoConfig.MaxNumberOfIterations; i++) { if (autoLevelConfig.Enabled) { servoTxpSession.AutoLevel(selectorString, autoLevelConfig.MeasurementInterval_s); } servoTxpSession.Initiate(selectorString, ""); powerLevel = rfsgSession.RF.PowerLevel; servoTxpSession.Txp.Results.FetchMeasurement(selectorString, 10, out outputPower, out _); margin = servoConfig.TargetTxPPower_dBm - outputPower; servoTrace[i] = outputPower; if (Math.Abs(margin) <= servoConfig.Tolerance_dBm) //Servo complete; exit the loop { servoSucess = true; break; } else //Still more room to go { rfsgSession.RF.PowerLevel = powerLevel + margin; rfsgSession.Utility.WaitUntilSettled(1000); } } //If we auto-leveled we need to set the original configuration to the newly calculated ref level servoTxpSession.GetReferenceLevel(selectorString, out double newRefLevel); wlanSignal.ConfigureReferenceLevel(selectorString, newRefLevel); servoTxpSession.Dispose(); TxPServoResults servoResults = new TxPServoResults(); servoResults.FinalInputPower_dBm = powerLevel; servoResults.FinalOutputPower_dBm = outputPower; servoResults.ServoTrace = servoTrace; if (!servoSucess) { throw new System.TimeoutException("WLAN TxP Power Servo exceeded max iterations without success."); } return(servoResults); }