上位机开发经验教训总结

--20191118更新程序,程序调整为使用状态机的方式实现

public void CircleMain()
        {
            while(true)
            {
                Thread.Sleep(100);

                #region 超时管理定时器计数
                if (delay100Ms < int.MaxValue)
                {
                    delay100Ms++;
                }
                #endregion

                #region 数据采集及变量映射

                var result = ModbusPlc.ReadDiscrete("0", 7);
                if (!result.IsSuccess)
                {
                    eSystemStatus = E_system_status.Error;
                    continue;
                }
                bool[] mappingResult = result.Content;
                bReset = mappingResult[0];
                bStop = mappingResult[1];
                bBeforePrintSensor = mappingResult[2];
                bPrintSensor = mappingResult[3];
                bAfterPrintSensor = mappingResult[4];
                bBeforeSingal = mappingResult[5];
                bAfterSingal = mappingResult[6];
                #endregion

                #region 急停按钮
                if (bStop==false)
                {
                    eSystemStatus = E_system_status.Error;
                }
                #endregion

                #region 状态机

                switch (eSystemStatus)
                {
                    case E_system_status.Idle:
                        //开始前打印位置有产品,需要取出
                        if (bPrintSensor)
                        {
                           eSystemStatus = E_system_status.Error;
                           statusMsg = "开始前打印位置有产品,需要取出后才能运行!";
                        }
                        else
                        {
                            ModbusPlc.WriteCoil(FeedProductAddress, true);  //前道要板命令
                            eSystemStatus = E_system_status.Feed;
                        }
                        break;
                    case E_system_status.Feed:
                        
                        if (bBeforePrintSensor)
                        {
                            ModbusPlc.WriteCoil(MoveBeltAddress, true);
                            ModbusPlc.WriteCoil(FeedProductAddress, false);
                            ModbusPlc.WriteCoil(PrintPosCylinderAddress, true);
                            eSystemStatus = E_system_status.Stable;
                            delay100Ms = 0;
                        }
                        break;
                    case E_system_status.Stable:
                        //5S后还没有运行到打印位置,可能卡板或者传感器失效
                        if (delay100Ms > 30)
                        {
                            eSystemStatus = E_system_status.Error;
                            statusMsg = "3S后还没有运行到打印位置,可能卡板或者传感器失效";
                        }
                        if (bPrintSensor)
                        {
                            eSystemStatus = E_system_status.Ready;
                            //正式喷码前触发一次喷印
                            TcpPrinter.SendData(new byte[] { 0x94, 0x00, 0x00, 0x94 });
                            delay100Ms = 0;
                        }
                        break;
                    case E_system_status.Ready:
                        if (delay100Ms > 10)
                        {
                            ModbusPlc.WriteCoil(MoveBeltAddress, false);
                            eSystemStatus = E_system_status.Printing;
                            statusMsg = "开始打印......";
                            //TcpClient.SendData(_startPrint);
                            
                        }
                        break;

                    case E_system_status.Printing:

                        if (nRouteIndex < routeList.Count)
                        {
                            if (ePrintStep == EPrintStep.PrintIdle)
                            {
                                SendPrintPoint(impossiblePointList, false);
                                MoveNextPoint(routeList[nRouteIndex].startX, routeList[nRouteIndex].startY, routeList[nRouteIndex].Angle);
                                ePrintStep = EPrintStep.SendStartPoint;
                                bMoveDone = false;
                            }
                            else if (ePrintStep == EPrintStep.SendStartPoint)
                            {
                                GetStatusOfRtexController();
                                if (bMoveDone)
                                {
                                    ePrintStep = EPrintStep.MoveDoneStartPoint;
                                }
                            }
                            else if (ePrintStep == EPrintStep.MoveDoneStartPoint)
                            {
                                ePrintStep = EPrintStep.SendEndPoint;
                                SendPrinterData(routeList[nRouteIndex]);
                                SendPrintPoint(routeList[nRouteIndex].printPointList, true);
                                MoveNextPoint(routeList[nRouteIndex].endX, routeList[nRouteIndex].endY, routeList[nRouteIndex].Angle);
                                bMoveDone = false;
                            }
                            else if (ePrintStep == EPrintStep.SendEndPoint)
                            {
                                GetStatusOfRtexController();
                                if (bMoveDone)
                                {
                                    ePrintStep = EPrintStep.PrintIdle;
                                    nRouteIndex++;
                                }
                            }
                        }
                        else
                        {
                            eSystemStatus = E_system_status.PrintPreEnd;
                            nRouteIndex = 0;
                        }
                        break;
                    case E_system_status.PrintPreEnd:
                        if (bAfterSingal)
                        {
                            MoveToHome();
                            ModbusPlc.WriteCoil(PrintPosCylinderAddress, false);  //气缸下降
                            ModbusPlc.WriteCoil(MoveBeltAddress, true);  //输送带启动
                            eSystemStatus = E_system_status.PrintEnd;
                            delay100Ms = 0;
                        }
                        break;
                    case E_system_status.PrintEnd:
                        //卡板或者传感器失效
                        if (delay100Ms > 50)
                        {
                            eSystemStatus = E_system_status.Error;
                            statusMsg = "输出卡板或者后端传感器失效";
                        }
                        if (!bAfterSingal)
                        {
                            ModbusPlc.WriteCoil(MoveBeltAddress, false);
                            eSystemStatus = E_system_status.Idle;
                            statusMsg = "打印完成,设备等待打印";
                        }
                        
                        break;
                    case E_system_status.Error:
                        ModbusPlc.WriteCoil(RedLampAddress, true);
                        ModbusPlc.WriteCoil(GreenLampAddress, false);
                        ModbusPlc.WriteCoil(AlarmBeepAddress, true);
                        if(bReset)
                        {
                            ModbusPlc.WriteCoil(RedLampAddress, false);
                            ModbusPlc.WriteCoil(GreenLampAddress, true);
                            ModbusPlc.WriteCoil(AlarmBeepAddress, false);
                            eSystemStatus = E_system_status.Idle;
                            statusMsg = "已复位";
                        }

                        break;
                    default:
                        break;
                }

                #endregion

                #region 显示状态


                Action<string> actionDisplayStatus = (msg) =>
                {
                    this.lblStatus.Text = msg;
                };
                Invoke(actionDisplayStatus, statusMsg + " " + ePrintStep.ToString());

                #endregion
            }
        }

 

 

总结下面几点

1.与下位机的连接尽量保持长连接,每次用到的时候去连接的话,过一段时间速度明显下降,什么问题并没有找到

2.C#中的BitConverter 类可以非常方便的在字节与其他类型之间进行转换

3.周期性操作使用while循环,避免使用timer定时器

4.操作一些标志位的操作,尽量放到一个线程中,多个线程同时操作变量容易产生奇怪的错误

posted @ 2019-11-05 14:17  shenjuncaci  阅读(1189)  评论(6编辑  收藏  举报