上位機開發經驗教訓總結


--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.操作一些標志位的操作,盡量放到一個線程中,多個線程同時操作變量容易產生奇怪的錯誤


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM