using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections.ObjectModel; using System.ComponentModel; using FLY.FeedbackRenZiJia.IService; using FLY.FeedbackRenZiJia.Common; using PropertyChanged; namespace FLY.FeedbackRenZiJia.Server { /// <summary> /// 加热棒检测 /// </summary> class HeatCheck:IHeatCheck,INotifyPropertyChanged { const int HEAT_WAIT = 3;//3s HeatCell mHeatCell; enum CHECK_MODE { /// <summary> /// 什么都不干 /// </summary> IDLE, /// <summary> /// 当前0输出,检测电流是否为0 /// </summary> CHECK_ZERO, /// <summary> /// 当前有输出, 电流不应该为0 /// </summary> CHECK_NOZERO, /// <summary> /// 检测每根加热棒 /// </summary> CHECK_EVERYONE } CHECK_MODE checkMode = CHECK_MODE.IDLE; int counter = 0; #region IHeatCheck public int HeatsOfGroup { get; set; } = 12; /// <summary> /// 有这个功能 /// </summary> public bool Has { get; set; } /// <summary> /// 动作使能 /// </summary> public bool Enable { get; set; } /// <summary> /// 有电流 /// </summary> public bool HasElectricity { get; set; } /// <summary> /// 当前正在检测的加热棒号, 1~88 /// </summary> public int CheckNo { get; set; } /// <summary> /// 当前检测的阶段 /// </summary> public int CheckStep { get; set; } #region 根据电流判断的加热棒状态 /// <summary> /// 加热棒是好的,但电流小,必须两条同时加热才可以; /// 加热棒分组 /// </summary> private int groupIdx; private List<GroupBad> groupBads = new List<GroupBad>(); class GroupBad { /// <summary> /// 分组号 /// </summary> public int group; /// <summary> /// 在 好的 maybe序号 /// </summary> public int goodIdx = -1; /// <summary> /// 全部待测的加热棒序号 /// </summary> List<int> maybe = new List<int>(); /// <summary> /// 已经测试过的 maybe序号 /// </summary> List<int> hasCheck = new List<int>(); /// <summary> /// 获取下一个 需要检查的 序号 /// </summary> /// <returns></returns> public bool GetNextIdx() { for (int i = 0; i < maybe.Count(); i++) { if (!hasCheck.Contains(i)) { //这个没检查过,可以 checkIdx1 = i; return true; } } return false; } /// <summary> /// 同时加热的加热棒0 /// </summary> int checkIdx0; /// <summary> /// 同时加热的加热棒1 /// </summary> int checkIdx1; public int NextCheckIdx { get { return checkIdx1 + 1; } } public int HeatIdx0 { get { return maybe[checkIdx0]; } } public int HeatIdx1 { get { return maybe[checkIdx1]; } } public bool GetCheckIdx(int startIdx) { if (startIdx >= maybe.Count() - 1) return false;//不够数 //同一个组可以一起加热测试 checkIdx0 = startIdx; checkIdx1 = startIdx + 1; return true; } public void PushToHasCheck() { if(!hasCheck.Contains(checkIdx0)) hasCheck.Add(checkIdx0); if (!hasCheck.Contains(checkIdx1)) hasCheck.Add(checkIdx1); } public void MarkGoodIdx() { goodIdx = checkIdx0; } public bool HasGood { get { return goodIdx != -1; } } public void Add(int heatIdx) { maybe.Add(heatIdx); } } /// <summary> /// 坏的加热棒 /// </summary> [DoNotCheckEquality] public bool[] Bads { get; set; } /// <summary> /// 没加热,也有电流, 电路板短路了 /// </summary> public bool ShortCircuit { get; set; } /// <summary> /// 没有上电, 或者电流计坏了 /// </summary> public bool PowerOff { get; set; } /// <summary> /// 有加热棒断路了 /// </summary> public bool OpenCircuit { get; set; } #endregion #endregion public void Init(HeatCell heatCell) { mHeatCell = heatCell; FObjBase.PollModule.Current.Poll_Config(FObjBase.PollModule.POLL_CONFIG.ADD, OnPoll, TimeSpan.FromSeconds(1)); Init(); Load(); mHeatCell.PropertyChanged += new PropertyChangedEventHandler(mHeatCell_PropertyChanged); this.PropertyChanged += HeatCheck_PropertyChanged; } private void HeatCheck_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == "Enable") { if (Enable) Start(); else Stop(); } } void mHeatCell_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == "ChannelCnt") { Init(); Load(); } } void Init() { Bads = new bool[mHeatCell.ChannelCnt]; OpenCircuit = false; PowerOff = false; ShortCircuit = false; } /// <summary> /// 启动 /// </summary> void Start() { checkMode = CHECK_MODE.CHECK_EVERYONE; CheckStep = 0; counter = 0; Array.Clear(Bads, 0, Bads.Count()); NotifyPropertyChanged("Bads"); OpenCircuit = false; PowerOff = false; ShortCircuit = false; } /// <summary> /// 停止 /// </summary> void Stop() { checkMode = CHECK_MODE.IDLE; //清空全部加热 mHeatCell.ClearPreHeats(); mHeatCell.HeatApply(); //保存Bads Save(); } void Load() { string path = "bads.xml"; FeedbackHeatsMark mark = FeedbackHeatsMark.Load(path); if ((mark != null) && (mark.heats != null)) { for (int i = 0; i < Bads.Count() ; i++) { if (i < mark.heats.Count()) Bads[i] = ((mark.heats[i] == 0) ? false : true); else Bads[i] = false; } NotifyPropertyChanged("Bads"); OpenCircuit = Bads.Any(b => b); } } void Save() { string path = "bads.xml"; FeedbackHeatsMark mark = new FeedbackHeatsMark(); mark.heats = (from b in Bads select (b) ? 1 : 0).ToArray(); mark.Save(path); } void OnPoll() { switch (checkMode) { case CHECK_MODE.CHECK_EVERYONE: OnPoll_Check(); break; default: OnPoll_Normal(); break; } } /// <summary> /// 平常,测有没电流 /// </summary> void OnPoll_Normal() { if (!Has) return; if (mHeatCell.Heats.All(h => h == 0))//没有加热,不应该有电流 { if (checkMode != CHECK_MODE.CHECK_ZERO) //第1次 { checkMode = CHECK_MODE.CHECK_ZERO; counter = 0; } //先等待3秒,3秒后再判断 counter++; if (counter > 5) { counter = 0; if (HasElectricity)//有电流,有问题 { ShortCircuit = true; } else { ShortCircuit = false; } } } else { if (checkMode != CHECK_MODE.CHECK_NOZERO) //第1次 { checkMode = CHECK_MODE.CHECK_NOZERO; counter = 0; } if (HasElectricity) { counter = 0; PowerOff = false; } else { counter++; if (counter > 7)//连续7秒,都没有一秒有电流,没有上电 { PowerOff = true; counter = 0; } } } } bool GetCheckIdx_2_loop(int grougIdx_start, int startIdx) { for (int i = grougIdx_start; i < groupBads.Count(); i++) { if(groupBads[i].GetCheckIdx(startIdx)) { groupIdx = i; return true; } startIdx = 0; } return false; } /// <summary> /// 加热棒检测周期 /// </summary> void OnPoll_Check() { switch (CheckStep) { case 0://刚按了开始,清空,检查应该没电流才对 { if (counter == 0) { mHeatCell.ClearPreHeats(); mHeatCell.HeatApply(); counter++; } else if (counter < HEAT_WAIT) { counter++; } else//3秒后 { if (HasElectricity) { ShortCircuit = true;//没输出,也有电流,板烧了 Enable = false;//停止检测 return; } CheckStep++; counter = 0; } }break; case 1://全部加热30% { if (counter == 0) { mHeatCell.ModifyPreHeats(getAllHeat_30(mHeatCell.ChannelCnt)); mHeatCell.HeatApply(); counter++; } else if (counter < HEAT_WAIT) { if (HasElectricity) { //有上电!!! //正式开始 CheckStep++; counter = 0; break; } counter++; } else//3秒内,都没1秒有电,不正常,应该是没上电 { PowerOff = true; Enable = false;//停止检测 return; } }break; case 2://正式开始 { if (counter == 0) { CheckNo = 1; mHeatCell.ModifyPreHeats(getSingleHeat_100(mHeatCell.ChannelCnt, CheckNo - 1)); mHeatCell.HeatApply(); counter = 1; } else if (counter < HEAT_WAIT) { counter++; } else { //3秒后 if (!HasElectricity)//这个位没电流,可能是坏了,还需要2次检查 { Bads[CheckNo - 1] = true; NotifyPropertyChanged(nameof(Bads)); OpenCircuit = true; } if (CheckNo < mHeatCell.ChannelCnt) { CheckNo++; mHeatCell.ModifyPreHeats(getSingleHeat_100(mHeatCell.ChannelCnt, CheckNo - 1)); mHeatCell.HeatApply(); counter = 1; } else { //检查是否2次检测 int cnt = Bads.Count((b) => { return b; }); if (cnt <2) { //没有坏,或只有一条加热棒坏了,没法2次检测 //完成 Enable = false;//停止检测 return; } else { //需要2次检测 CheckStep++; counter = 0; } } } } break; case 3://2次检测 { if (counter == 0)//刚进入!!! { groupIdx = -1; groupBads.Clear(); for (int i = 0; i < Bads.Count(); i++)//分组登记全部坏的加热棒 { int group = i / HeatsOfGroup; if (Bads[i]) { if (groupBads.Count() == 0) groupBads.Add(new GroupBad() { group = group }); else { if (groupBads.Last().group != group) { groupBads.Add(new GroupBad() { group = group }); } } groupBads.Last().Add(i); } } if(!GetCheckIdx_2_loop(0, 0)) { //没有两条同一组,测试结束 Enable = false;//停止检测 return; } var groupBad = groupBads[groupIdx]; CheckNo = groupBad.HeatIdx1+1;//当前检测的位置,现在没用!!! mHeatCell.ModifyPreHeats(getSingleHeat_100(mHeatCell.ChannelCnt, groupBad.HeatIdx0, groupBad.HeatIdx1)); mHeatCell.HeatApply(); counter = 1; } else if (counter < HEAT_WAIT)//3秒延时 { counter++; } else//3秒后 { var groupBad = groupBads[groupIdx]; if (!HasElectricity)//没电流,肯定是坏了 { if (!groupBad.HasGood)//还没找到好的加热棒 { //继续 if (!GetCheckIdx_2_loop(groupIdx, groupBad.NextCheckIdx)) { //没有两条同一组,测试结束 Enable = false;//停止检测 return; } } else { //checkIdx1是坏的 groupBad.PushToHasCheck(); //获取下一个需要测试的 if(!groupBad.GetNextIdx()) { //这个分组已经查完,下一个分组 groupIdx++; if (!GetCheckIdx_2_loop(groupIdx, 0)) { //没有两条同一组,测试结束 Enable = false;//停止检测 return; } } } } else { //刚才测量的是好的!!!!!只是电流不够的加热棒 groupBad.MarkGoodIdx(); //找到好的加热棒了,这个组的加热棒全部测试一次 groupBad.PushToHasCheck(); Bads[groupBad.HeatIdx0] = false;//清除坏的记录 Bads[groupBad.HeatIdx1] = false; NotifyPropertyChanged(nameof(Bads)); OpenCircuit = Bads.Any(b => b); //获取下一个需要测试的 if(!groupBad.GetNextIdx()) { //这个分组已经查完,下一个分组 groupIdx++; if (!GetCheckIdx_2_loop(groupIdx, 0)) { //没有两条同一组,测试结束 Enable = false;//停止检测 return; } } } groupBad = groupBads[groupIdx]; CheckNo = groupBad.HeatIdx1 + 1; mHeatCell.ModifyPreHeats(getSingleHeat_100(mHeatCell.ChannelCnt, groupBad.HeatIdx0, groupBad.HeatIdx1)); mHeatCell.HeatApply(); counter = 1; } }break; } } int[] getSingleHeat_100(int channelcnt, params int[] index) { int[] heats = new int[channelcnt]; Array.Clear(heats, 0, heats.Count()); foreach(int i in index) heats[i] = 100; return heats; } int[] getSingleHeat_100(int channelcnt, int index) { int[] heats = new int[channelcnt]; Array.Clear(heats, 0, heats.Count()); heats[index] = 100; return heats; } int[] getAllHeat_30(int channelcnt) { int[] heats = new int[channelcnt]; for (int i = 0; i < heats.Count(); i++) { heats[i] = 30; } return heats; } #region INotifyPropertyChanged 成员 public event PropertyChangedEventHandler PropertyChanged; protected void NotifyPropertyChanged(string propertyname) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname)); } #endregion } }