public override void ArmAndWait() { lock (this) { if (!Environs.Debug) { inputTask.Start(); latestData = reader.ReadSingleSample(); inputTask.Stop(); //check that photodiode is not saturating if (latestData[lockCavityChannel] > 4.7) { hardwareControl.diodeSaturationError(); } else { hardwareControl.diodeSaturation(); } // send the new lock cavity data to the hardware controller normalized_Data = latestData[lockCavityChannel] / latestData[refCavityChannel]; hardwareControl.UpdateLockCavityData(normalized_Data); } else { // do nothing } } }
/// <summary> /// Locks the laser to a reference cavity. This method runs continuously until the laser is unlocked. /// When this method is called, the reference cavity is read in order to establish the lock point. /// The reference cavity is then read continuously and adjustments fed-back to the laser. /// </summary> public void Lock() { double singleValue; double singlerefValue; double averageValue = 0; int reads = 0; bool firstTime = true; DateTime oldCavityStamp = new DateTime(); DateTime newCavityStamp = new DateTime(); newCavityStamp = DateTime.Now; status = ControllerState.busy; ui.ControlVoltageEditorEnabledState(false); hardwareControl.LaserLocked = true; hardwareControl.SetAnalogOutputBlockedStatus("laser", true); while (status == ControllerState.busy) { if (!Environs.Debug) { oldCavityStamp = newCavityStamp; // read the cavity if (hardwareControl.AnalogInputsAvailable)//scanmaster not running { singleValue = 0; inputTask.Start(); latestData = cavityReader.ReadMultiSample(SAMPLES_PER_READ); inputTask.Stop(); singlerefValue = 0; inputrefTask.Start(); latestrefData = cavityrefReader.ReadMultiSample(SAMPLES_PER_READ); inputrefTask.Stop(); foreach (double d in latestData) { singleValue += d; } foreach (double e in latestrefData) { singlerefValue += e; } singleValue = singleValue / SAMPLES_PER_READ; singlerefValue = singlerefValue / SAMPLES_PER_READ; if (singleValue > 4.7) { hardwareControl.diodeSaturationError(); } else { hardwareControl.diodeSaturation(); } singleValue = singleValue / singlerefValue; newCavityStamp = DateTime.Now; hardwareControl.UpdateLockCavityData(singleValue); //hardwareControl.UpdateLockCavityData(singleValue / singlerefValue); } else { singleValue = hardwareControl.LastCavityData; newCavityStamp = hardwareControl.LastCavityTimeStamp; } // provided the last cavity read is recent, do something with it if (hardwareControl.TimeSinceLastCavityRead < LATENCY && newCavityStamp.CompareTo(oldCavityStamp) != 0) { // if this is the first read since throwing the lock, the result defines the set-point if (firstTime) { integratedDeviation = 0; // make sure we don't have a value that's out of range if (singleValue > UPPER_SETPOINT_LIMIT) { singleValue = UPPER_SETPOINT_LIMIT; } if (singleValue < LOWER_SETPOINT_LIMIT) { singleValue = LOWER_SETPOINT_LIMIT; } setPoint = singleValue; ui.SetSetPointNumericEditorValue(setPoint); firstTime = false; } // otherwise, use the last read to update the running average else { averageValue += singleValue; reads++; deviation = averageValue / reads - setPoint; integratedDeviation = integratedDeviation + deviation * hardwareControl.TimeSinceLastCavityRead; } // is it time to feed-back to the laser if (reads != 0 && (reads >= READS_PER_FEEDBACK || ui.SpeedSwitchState)) { averageValue = averageValue / reads; deviation = averageValue - setPoint; LaserVoltage = LaserVoltage + SignOfFeedback * proportionalGain * deviation + integralGain * integratedDeviation; //other terms to go here // update the deviation plot ui.DeviationPlotXYAppend(deviation); // reset the variables averageValue = 0; reads = 0; } } } else { // Debug mode ui.DeviationPlotXYAppend(hardwareControl.LaserFrequencyControlVoltage - setPoint); } Thread.Sleep(SLEEPING_TIME); } // we're out of the while loop - revert to the unlocked state status = ControllerState.free; hardwareControl.LaserLocked = false; ui.ControlVoltageEditorEnabledState(true); hardwareControl.SetAnalogOutputBlockedStatus("laser", false); }