diff --git a/DyeingComputer.csproj b/DyeingComputer.csproj index 3dec8a4..3dc9925 100644 --- a/DyeingComputer.csproj +++ b/DyeingComputer.csproj @@ -119,6 +119,7 @@ + diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs index f0454d1..35314ca 100644 --- a/Properties/Resources.Designer.cs +++ b/Properties/Resources.Designer.cs @@ -556,7 +556,7 @@ namespace DyeingComputer.Properties { } /// - /// 查找类似 的本地化字符串。 + /// 查找类似 Port 的本地化字符串。 /// public static string Port { get { diff --git a/Properties/Resources.zh-CN.resx b/Properties/Resources.zh-CN.resx index a043e44..ad52957 100644 --- a/Properties/Resources.zh-CN.resx +++ b/Properties/Resources.zh-CN.resx @@ -117,50 +117,26 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - 工作清单 - - - 工艺流程 - - - 系统 - - - 返回 - - - 更多 - - - 输入输出 + + 工艺曲线 - - 历史 + + 删除 - - 设备模拟 + + 结束时间 工程师 - - 工艺曲线 - - - 参数 - - - 程序组 - - - 系统数据丢失 + + 设备模拟 - - 工单号 + + 历史 - - 温度 + + 输入输出 锁定/解锁 @@ -168,26 +144,53 @@ 新建 - - 删除 + + 更多 - - 重染 + + 参数 - - 结束时间 + + 返回 工艺名 + + 程序组 + + + 重染 + 备注 开始时间 + + 系统数据丢失 + + + 系统 + + + 工艺流程 + + + 温度 + - 时间 + 时间[min] + + + 工作清单 + + + 工单号 + + + 准备 异常 @@ -201,23 +204,20 @@ 完成 - - 排队 - 计量 - - 准备 + + 排队 - - 状态 + + 未执行 确认 - - 步骤 + + 状态 编辑 @@ -225,47 +225,56 @@ 重命名 - - ID - - - 指令 + + 步骤 代码 - - 恢复 + + 指令 + + + ID 插入 + + 恢复 + 保存 退出 - - 温度控制 - 入水 + + 冷却 + + + 排水 + 流量 - - 水位 + + 温度控制 水洗 - - 冷却 + + 水位 - - 排水 + + 准备入布 + + + 准备出布 主泵排水 @@ -273,18 +282,12 @@ 运转 - - 准备入布 - - - 准备出布 + + 加药 呼叫输送 - - 加药 - 呼叫准备 @@ -327,81 +330,78 @@ 取样 - - 功能无效 - 功能 + + 功能无效 + - - 速率 + + 提前 - - 目标 + + 开头 + + + 容器 + + + 曲线 水源 + + + + + 搅拌 + 次数 压力 - - 容器 + + 速率(°C/min) - - - - - 提前 - - - 开头 + + 目标 类型 - - 搅拌 - - - 曲线 - 风机 - - 摆布 - 喷嘴 - - - 溢流 - - 工艺不存在 + + - - 未执行 + + 摆布 执行 + + 工艺不存在 + 连接丢失 diff --git a/UserClass/PID.cs b/UserClass/PID.cs new file mode 100644 index 0000000..73a0457 --- /dev/null +++ b/UserClass/PID.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DyeingComputer.UserClass +{ + public class PID + { + private static double Ts; // Sample period in seconds + private static double K; // Rollup parameter + private static double b0, b1, b2; // Rollup parameters + private static double a0, a1, a2; // Rollup parameters + private static double y0 = 0; // Current output + private static double y1 = 0; // Output one iteration old + private static double y2 = 0; // Output two iterations old + private static double e0 = 0; // Current error + private static double e1 = 0; // Error one iteration old + private static double e2 = 0; // Error two iterations old + + /// + /// PID构造器 + /// + /// 比例增益 + /// 积分增益 + /// 微分增益 + /// 微分滤波系数 + /// 控制器输出上限 + /// 控制器输出下限 + public PID(double Kp, double Ki, double Kd, double N, double OutputUpperLimit, double OutputLowerLimit) + { + this.Kp = Kp; + this.Ki = Ki; + this.Kd = Kd; + this.N = N; + this.OutputUpperLimit = OutputUpperLimit; + this.OutputLowerLimit = OutputLowerLimit; + } + + /// + /// PID迭代器,在每个采样周期调用此函数以获取当前控制器输出。 + /// 设定点和过程值应使用相同的单位。 + /// + /// 设定目标值 + /// 当前实际值 + /// 自上次迭代以来的时间跨度,对第一次调用使用默认采样周期 + /// Current Controller Output + public double PID_iterate(double setPoint, double processValue, TimeSpan ts) + { + // Ensure the timespan is not too small or zero. + Ts = (ts.TotalSeconds >= TsMin) ? ts.TotalSeconds : TsMin; + + // Calculate rollup parameters + K = 2 / Ts; + b0 = Math.Pow(K, 2) * Kp + K * Ki + Ki * N + K * Kp * N + Math.Pow(K, 2) * Kd * N; + b1 = 2 * Ki * N - 2 * Math.Pow(K, 2) * Kp - 2 * Math.Pow(K, 2) * Kd * N; + b2 = Math.Pow(K, 2) * Kp - K * Ki + Ki * N - K * Kp * N + Math.Pow(K, 2) * Kd * N; + a0 = Math.Pow(K, 2) + N * K; + a1 = -2 * Math.Pow(K, 2); + a2 = Math.Pow(K, 2) - K * N; + + // Age errors and output history + e2 = e1; // Age errors one iteration + e1 = e0; // Age errors one iteration + e0 = setPoint - processValue; // Compute new error + y2 = y1; // Age outputs one iteration + y1 = y0; // Age outputs one iteration + y0 = -a1 / a0 * y1 - a2 / a0 * y2 + b0 / a0 * e0 + b1 / a0 * e1 + b2 / a0 * e2; // Calculate current output + + // Clamp output if needed + if (y0 > OutputUpperLimit) + { + y0 = OutputUpperLimit; + } + else if (y0 < OutputLowerLimit) + { + y0 = OutputLowerLimit; + } + + return y0; + } + + /// + /// 重置控制器历史记录,有效重置控制器。 + /// + public static void ResetController() + { + e2 = 0; + e1 = 0; + e0 = 0; + y2 = 0; + y1 = 0; + y0 = 0; + } + + /// + /// 比例增益,如果此参数发生剧烈变化,请考虑重置控制器。 + /// + public double Kp { get; set; } + + /// + /// 积分增益,如果此参数发生剧烈变化,请考虑重置控制器。 + /// + public double Ki { get; set; } + + /// + /// 微分增益,如果此参数发生剧烈变化,请考虑重置控制器。 + /// + public double Kd { get; set; } + + /// + ///微分滤波系数。 + /// N越小,过滤效果越好 + /// N越大,过滤效果越差 + /// 如果此参数发生剧烈变化,请考虑重置控制器。 + /// + public double N { get; set; } + + /// + /// 避免除以零的最小允许采样周期! + /// Ts值可能会在第一次迭代时被错误地设置为过低的值或零。 + /// TsMin默认设置为1毫秒。 + /// + public double TsMin { get; set; } = 0.001; + + /// + /// 控制器的输出上限。 + /// 是一个比输出下限大的数值。 + /// + public double OutputUpperLimit { get; set; } + + /// + /// 控制器的输出下限。 + /// 是一个比输出上限小的数值。 + /// + public double OutputLowerLimit { get; set; } + } +} diff --git a/View/TechnologicalProcessView.xaml.cs b/View/TechnologicalProcessView.xaml.cs index b8c3594..d0a36de 100644 --- a/View/TechnologicalProcessView.xaml.cs +++ b/View/TechnologicalProcessView.xaml.cs @@ -53,6 +53,7 @@ namespace DyeingComputer.View private void UserControl_Loaded(object sender, RoutedEventArgs e) { if(workName !=null) TechnologicalProcess_sql(); + //Grid.SelectedIndex = 0; } } } diff --git a/ViewModel/MainWindowViewModel.cs b/ViewModel/MainWindowViewModel.cs index 27a178a..06ee2ff 100644 --- a/ViewModel/MainWindowViewModel.cs +++ b/ViewModel/MainWindowViewModel.cs @@ -32,30 +32,43 @@ namespace DyeingComputer.ViewModel public class ViewModelBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; - protected virtual void OnPropertyChanged(string propertyName) { if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } - - public void RaisePropertyChanged(string propertyName) + public void RaisePropertyChanged(string propertyName) { if (propertyName != null) { PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } - } public class MainWindowViewModel : ViewModelBase { - private UserClass.IniFile.IniFiles Configini = new UserClass.IniFile.IniFiles(Convert.ToString(System.AppDomain.CurrentDomain.BaseDirectory) + "DyeingComputer.ini"); + private SQLiteHelper SQLiteHelpers = null; //定义数据库 + private readonly string DBAddress = Environment.CurrentDirectory + "\\DataBase\\800COMPUTER.db"; //数据库路径 + private PID PID = null; + private IniFile.IniFiles Configini = new IniFile.IniFiles(Convert.ToString(System.AppDomain.CurrentDomain.BaseDirectory) + "DyeingComputer.ini"); + public MainWindowViewModel() { + SQLiteHelpers = new SQLiteHelper(DBAddress); //数据库连接路径 + SQLiteHelpers.Open(); //打开数据库 + double ST01 = Convert.ToDouble( SQLiteHelpers.ExecuteScalar("select value from system where ParameterID = 'ST01'", null)); //读取 + double ST02 = Convert.ToDouble( SQLiteHelpers.ExecuteScalar("select value from system where ParameterID = 'ST02'", null)); + double ST03 = Convert.ToDouble( SQLiteHelpers.ExecuteScalar("select value from system where ParameterID = 'ST03'", null)); + double ST04 = Convert.ToDouble(SQLiteHelpers.ExecuteScalar("select value from system where ParameterID = 'ST04'", null)); + double ST05 = Convert.ToDouble(SQLiteHelpers.ExecuteScalar("select value from system where ParameterID = 'ST05'", null)); + double ST06 = Convert.ToDouble(SQLiteHelpers.ExecuteScalar("select value from system where ParameterID = 'ST06'", null)); + SQLiteHelpers.Close(); + WorkNumder = "----------"; + PID pid=new PID(ST01,ST02,ST03,ST04,ST05,ST06); + CountDown(); //启动循环任务 SQL_data(); //读数据库 UPort(); //启动串口 @@ -68,21 +81,18 @@ namespace DyeingComputer.ViewModel get { return work_Temp; } set { work_Temp = value; OnPropertyChanged("Work_Temp"); } } - public string work_Numder; //显示工单号 public string Work_Numder //通知UI控件参数改变 { get { return work_Numder; } set { work_Numder = value; OnPropertyChanged("Work_Numder"); } } - public string status_Str; //显示状态 public string Status_Str //通知UI控件参数改变 { get { return status_Str; } set { status_Str = value; OnPropertyChanged("Status_Str"); } } - public string sys_Time; //显示系统时间 public string Sys_Time //通知UI控件参数改变 { @@ -113,7 +123,7 @@ namespace DyeingComputer.ViewModel }; disTimer.Tick += new EventHandler(DisTimer_100MS);//每一秒执行的方法 disTimer.Start();//计时开始 - } + }//时间周期初始化 public static object Name_err; public static object WorkNumder; @@ -203,8 +213,6 @@ namespace DyeingComputer.ViewModel }); } - private SQLiteHelper SQLiteHelpers = null; //定义数据库 - private readonly string DBAddress = Environment.CurrentDirectory + "\\DataBase\\800COMPUTER.db"; //数据库路径 public DataTable dt_d = new DataTable("DIO"); public DataTable dt_a = new DataTable("AIO"); public DataTable dt_m = new DataTable("M");