private void InstantiateDefaultPIDSettingsInstances() { initial_defaults = new PIDSettings(); empty_air_defaults = new PIDSettings(); empty_n2_defaults = new PIDSettings(); quarter_full_air_defaults = new PIDSettings(); quarter_full_n2_defaults = new PIDSettings(); half_full_air_defaults = new PIDSettings(); half_full_n2_defaults = new PIDSettings(); threequarters_full_air_defaults = new PIDSettings(); threequarters_full_n2_defaults = new PIDSettings(); full_air_defaults = new PIDSettings(); full_n2_defaults = new PIDSettings(); }
private void SetPIDDefaultFromDisplayButton_Click(object sender, EventArgs e) { switch (DefaultPIDSettingsSelectorComboBox.SelectedIndex) { case 0: empty_air_defaults = GetPIDSettings_FromControls(); break; case 1: empty_n2_defaults = GetPIDSettings_FromControls(); break; case 2: quarter_full_air_defaults = GetPIDSettings_FromControls(); break; case 3: quarter_full_n2_defaults = GetPIDSettings_FromControls(); break; case 4: half_full_air_defaults = GetPIDSettings_FromControls(); break; case 5: half_full_n2_defaults = GetPIDSettings_FromControls(); break; case 6: threequarters_full_air_defaults = GetPIDSettings_FromControls(); break; case 7: threequarters_full_n2_defaults = GetPIDSettings_FromControls(); break; case 8: full_air_defaults = GetPIDSettings_FromControls(); break; case 9: full_n2_defaults = GetPIDSettings_FromControls(); break; default: initial_defaults = GetPIDSettings_FromControls(); break; } }
private void SetPIDSettings_ToControls(PIDSettings pid_settings) { this.CycleTimeInSecondsNumericUpDown.Value = (decimal)pid_settings.cycle_time_in_seconds; this.OuterProportionalBandNumericUpDown.Value = (decimal)pid_settings.proportional_band_EachZone[0]; this.SampleZoneProportionalBandNumericUpDown.Value = (decimal)pid_settings.proportional_band_EachZone[1]; this.InnerProportionalBandNumericUpDown.Value = (decimal)pid_settings.proportional_band_EachZone[2]; this.OuterOffsetNumericUpDown.Value = (decimal)pid_settings.offset_EachZone[0]; this.SampleZoneOffsetNumericUpDown.Value = (decimal)pid_settings.offset_EachZone[1]; this.InnerOffsetNumericUpDown.Value = (decimal)pid_settings.offset_EachZone[2]; this.OuterRateNumericUpDown.Value = (decimal)pid_settings.rate_EachZone[0]; this.SampleZoneRateNumericUpDown.Value = (decimal)pid_settings.rate_EachZone[1]; this.InnerRateNumericUpDown.Value = (decimal)pid_settings.rate_EachZone[2]; this.OuterResetNumericUpDown.Value = (decimal)pid_settings.reset_EachZone[0]; this.SampleZoneResetNumericUpDown.Value = (decimal)pid_settings.reset_EachZone[1]; this.InnerResetNumericUpDown.Value = (decimal)pid_settings.reset_EachZone[2]; }
private PIDSettings GetPIDSettings_FromControls() { PIDSettings pid_settings = new PIDSettings(); pid_settings.cycle_time_in_seconds = (double)this.CycleTimeInSecondsNumericUpDown.Value; pid_settings.proportional_band_EachZone[0] = (double)this.OuterProportionalBandNumericUpDown.Value; pid_settings.proportional_band_EachZone[1] = (double)this.SampleZoneProportionalBandNumericUpDown.Value; pid_settings.proportional_band_EachZone[2] = (double)this.InnerProportionalBandNumericUpDown.Value; pid_settings.offset_EachZone[0] = (double)this.OuterOffsetNumericUpDown.Value; pid_settings.offset_EachZone[1] = (double)this.SampleZoneOffsetNumericUpDown.Value; pid_settings.offset_EachZone[2] = (double)this.InnerOffsetNumericUpDown.Value; pid_settings.rate_EachZone[0] = (double)this.OuterRateNumericUpDown.Value; pid_settings.rate_EachZone[1] = (double)this.SampleZoneRateNumericUpDown.Value; pid_settings.rate_EachZone[2] = (double)this.InnerRateNumericUpDown.Value; pid_settings.reset_EachZone[0] = (double)this.OuterResetNumericUpDown.Value; pid_settings.reset_EachZone[1] = (double)this.SampleZoneResetNumericUpDown.Value; pid_settings.reset_EachZone[2] = (double)this.InnerResetNumericUpDown.Value; return(pid_settings); }
private PIDSettings GetPIDSettings_FromControls() { PIDSettings pid_settings = new PIDSettings(); pid_settings.cycle_time_in_seconds = (double)this.CycleTimeInSecondsNumericUpDown.Value; pid_settings.proportional_band_EachZone[0] = (double)this.OuterProportionalBandNumericUpDown.Value; pid_settings.proportional_band_EachZone[1] = (double)this.SampleZoneProportionalBandNumericUpDown.Value; pid_settings.proportional_band_EachZone[2] = (double)this.InnerProportionalBandNumericUpDown.Value; pid_settings.offset_EachZone[0] = (double)this.OuterOffsetNumericUpDown.Value; pid_settings.offset_EachZone[1] = (double)this.SampleZoneOffsetNumericUpDown.Value; pid_settings.offset_EachZone[2] = (double)this.InnerOffsetNumericUpDown.Value; pid_settings.rate_EachZone[0] = (double)this.OuterRateNumericUpDown.Value; pid_settings.rate_EachZone[1] = (double)this.SampleZoneRateNumericUpDown.Value; pid_settings.rate_EachZone[2] = (double)this.InnerRateNumericUpDown.Value; pid_settings.reset_EachZone[0] = (double)this.OuterResetNumericUpDown.Value; pid_settings.reset_EachZone[1] = (double)this.SampleZoneResetNumericUpDown.Value; pid_settings.reset_EachZone[2] = (double)this.InnerResetNumericUpDown.Value; return pid_settings; }
// This function implements PID control in the oven, by using three // USB-TC output channels. It calls the functions channel_out() to // control the heater coils according to the known setup. private void PID_control() { int count = 0; oven_pid_settings = Program.pid_settings_form.ProgramPidSettings; set_point_temperature = MaxTemp_copy; double[] CurrentTemp_EachZone = new double[3] { 0, 0, 0 }; double[] PreviousTemp_EachZone = new double[3] { 0, 0, 0 }; int heat_increment_time_in_milliseconds = (int)((oven_pid_settings.cycle_time_in_seconds / 110) * 1000); //Heat per each zone int[] heat_EachZone = new int[3] { 0, 0, 0 }; //rate correction per each zone double[] rate_correction_EachZone = new double[3] { 0, 0, 0 }; bool fill_n2_check = false; bool n2_running_check = false; bool outer_coil_on = false; bool inner_coil_on = false; bool sample_zone_coil_on = false; SetOvenChannelOutput(OvenChanEnum.AllOff); // start with all oven channels off SetAirRelayChannelOutput(AirChanStatusEnum.AirOff); //Start with air switched off if (CoolMethod_copy == "1" && n2_running_check == false) { // Flow high pressure nitrogen for 10 seconds to fill // the oven cavity with nitrogen if (fill_n2_check == false) { count = 0; SetAirRelayChannelOutput(AirChanStatusEnum.HighN2); while (count <= 10) { Thread.Sleep(1000); count++; } fill_n2_check = true; SetAirRelayChannelOutput(AirChanStatusEnum.AirOff); } // Low pressure N2 trickle begins SetAirRelayChannelOutput(AirChanStatusEnum.LowN2); n2_running_check = true; bool low_n2_adjusted = false; while (!low_n2_adjusted) { MessageBox.Show( "Please change the Low N2 Gauge Level (by twisting the Gauge now) until " + "the black indicator bead is beween the two black arrows. ", "Set Gauge Level", MessageBoxButtons.OK); DialogResult result = MessageBox.Show( "Is the Low N2 Gauge set to the correct level?", "Verify Gauge Level", MessageBoxButtons.YesNo); if (result == System.Windows.Forms.DialogResult.Yes) { low_n2_adjusted = true; } } } EnableStartOvenButton start_oven_button_del = new EnableStartOvenButton(EnableStartCoolingButton); StartCoolingButton.BeginInvoke(start_oven_button_del); HeatingStarted = true; while (oven_check == ComponentCheckStatusEnum.Running) { Heat_Time = DateTime.Now; DateTime start_heat_increment; DateTime end_heat_increment; for (int i = 1; i <= 100; i++) { start_heat_increment = DateTime.Now; if (heat_EachZone[0] > 0) { if (!outer_coil_on) { SetOvenChannelOutput(OvenChanEnum.Outer, OvenHeatOnOffEnum.On); outer_coil_on = true; } } else { SetOvenChannelOutput(OvenChanEnum.Outer, OvenHeatOnOffEnum.Off); outer_coil_on = false; } if (heat_EachZone[1] > 0) { if (!sample_zone_coil_on) { SetOvenChannelOutput(OvenChanEnum.SampleZone, OvenHeatOnOffEnum.On); sample_zone_coil_on = true; } } else { SetOvenChannelOutput(OvenChanEnum.SampleZone, OvenHeatOnOffEnum.Off); sample_zone_coil_on = false; } if (heat_EachZone[2] > 0) { if (!inner_coil_on) { SetOvenChannelOutput(OvenChanEnum.Inner, OvenHeatOnOffEnum.On); inner_coil_on = true; } } else { SetOvenChannelOutput(OvenChanEnum.Inner, OvenHeatOnOffEnum.Off); inner_coil_on = false; } for (int j = 0; j < 3; j++) { heat_EachZone[j]--; } end_heat_increment = DateTime.Now; TimeSpan heat_increment_duration = (end_heat_increment - start_heat_increment); if (heat_increment_duration.TotalMilliseconds < heat_increment_time_in_milliseconds) { System.Threading.Thread.Sleep((int)(heat_increment_time_in_milliseconds - heat_increment_duration.TotalMilliseconds)); } //If Set Temp Reached and Start Set Temp Hold Time not set //Set Start Set Temp Hold Time if (MaxTempPlateauReached && !MaxTemp_StartTime_Set) { MaxTemp_StartTime = DateTime.Now; MaxTemp_StartTime_Set = true; } //If Set Temp Reached, then wait Hold Time till start cool down //Use MaxTemp_StartTime to determine the curent duration of the Hold Peak Time if (MaxTempPlateauReached) { TimeSpan peak_duration = DateTime.Now - MaxTemp_StartTime; double hold_time_minutes = HoldTime_copy.TotalMinutes; HoldTimeRemaining_copy = (hold_time_minutes - peak_duration.TotalMinutes).ToString("#0.0#"); HoldTimeRemainingTextBox.BeginInvoke((Action)(() => HoldTimeRemainingTextBox.Text = HoldTimeRemaining_copy)); if (peak_duration.TotalMinutes > hold_time_minutes) { oven_check = ComponentCheckStatusEnum.None; } } } //turn off oven heat outside of heating cycle SetOvenChannelOutput(OvenChanEnum.OvenOff); inner_coil_on = false; outer_coil_on = false; sample_zone_coil_on = false; /////////////////////////////////////////////////////////////// //Set interlock for PID cycle reading temperature IsLockedCurrentTemp_Array = true; //Select Max Temperature on the Outer Zone of the Sample tray CurrentTemp_EachZone[0] = Math.Max(CurrentTemperatures[0], CurrentTemperatures[5]); //Select Max Temperature at Sample Tray in Sample Zone CurrentTemp_EachZone[1] = Math.Max(CurrentTemperatures[1], CurrentTemperatures[4]); //Select Max Temperature at Sample Tray in Inner Zone CurrentTemp_EachZone[2] = Math.Max(CurrentTemperatures[2], CurrentTemperatures[3]); IsLockedCurrentTemp_Array = false; for (int i = 0; i < 3; i++) { //Make sure a Previous Temp of Zero is never used //this will throw off the rate correction parameter if (PreviousTemp_EachZone[i] == 0) PreviousTemp_EachZone[i] = CurrentTemp_EachZone[i]; //Calculate the rate correction - D in PID rate_correction_EachZone[i] = (PreviousTemp_EachZone[i] - CurrentTemp_EachZone[i]) * 100 * oven_pid_settings.rate_EachZone[i]; //Calculate the heat duty cycle % parameter from P, I, & D heat_EachZone[i] = (int)((100 / oven_pid_settings.proportional_band_EachZone[i]) * (set_point_temperature - CurrentTemp_EachZone[i]) + oven_pid_settings.offset_EachZone[i] + rate_correction_EachZone[i]); //Anti-windup - prevent I from incrementing unless we're heating //and at set-point if (heat_EachZone[i] < 100 && heat_EachZone[i] > 0 && rate_correction_EachZone[i] == 0) oven_pid_settings.offset_EachZone[i] += (set_point_temperature - CurrentTemp_EachZone[i]) * oven_pid_settings.reset_EachZone[i]; //Store current temp to previous temp for next cycle's calculation of the //Rate Correction (D) component. PreviousTemp_EachZone[i] = CurrentTemp_EachZone[i]; } } oven_start_check = ComponentCheckStatusEnum.None; //turn off oven heat outside of heating cycle SetOvenChannelOutput(OvenChanEnum.OvenOff); inner_coil_on = false; outer_coil_on = false; sample_zone_coil_on = false; HeatingStopped = true; MaxTempPlateauReached = false; MaxTemp_StartTime_Set = false; HeatingStarted = false; HeatingStarted_logged = false; MaxTempReached_logged = false; //If not thread aborting, start cooling if (oven_control_thread.ThreadState == ThreadState.AbortRequested || oven_control_thread.ThreadState == ThreadState.Aborted) return; if (oven_check == ComponentCheckStatusEnum.Aborted) return; oven_cooling_check = ComponentCheckStatusEnum.Running; DoOvenCooling(); }