none
使用C#的元件SerialPort進行通訊,常出現回覆訊息長度不正確的情形。求助通訊方面的高手。 RRS feed

  • 問題

  • Hi, 各位通訊方面的高手。

    先描述我的問題。

    我用C#寫了一支程式,透過Com Port與機台溝通。使用C#的SerialPort元件。

    並且為了紀錄方面,我會將收到的訊息轉成10進位Int並且寫入Log。

    但常會出現回覆訊息不正確的情形。

    舉例來說 : 收到回覆的訊息長度應該為2,轉成Int為6213,但常出現回覆的訊息長度為3,轉成Int為621363。

    想請各位通訊的高手幫我開惑。感謝。

    這是我用來使用RS232通訊的Class

    using System;
    using System.Collections.Generic;
    using System.IO.Ports;
    using System.Text;
    using System.Threading;
    
    using log4net;
    using log4net.Config;
    
    namespace Lib_OvenEap.Lib_RS232
    {
        public class Uti_RS232
        {
            private static readonly ILog mLog = LogManager.GetLogger(typeof(Uti_RS232));
            public delegate void Rs232EventHandler(object sender, Uti_RS232_MsgEventArg e);
            public event Rs232EventHandler Receive;
            private SerialPort mComPort;
    
            private byte[] mBigenByte;
            private byte[] mEndByte;
    
            public Uti_RS232()
            {
                mBigenByte = StringToByteArray("");
                mEndByte = StringToByteArray("\r");
            }
    
            public bool Open(string portname, int baudrate, Parity parity, int databit, StopBits stopbit)
            {
                try
                {
                    if (mComPort != null)
                        if (mComPort.IsOpen) mComPort.Close();
    
                    mComPort = new SerialPort(portname, baudrate, parity, databit, stopbit);
                    mComPort.WriteTimeout = 5000;
                    mComPort.ReadTimeout = 5000;
                    mComPort.Handshake = Handshake.None;
                    mComPort.Open();                
                    Thread.Sleep(1000);
                    mComPort.DataReceived += new SerialDataReceivedEventHandler(MsgReceive);
                    return true;
                }
                catch (Exception ex)
                {
                    mLog.Error("[Lib_RS232] [Uti_RS232] [Open] [Reason : " + ex.Message + "]");
                    return false;
                }
            }
    
            public void Close()
            {
                if (mComPort != null && mComPort.IsOpen)
                {
                    mComPort.Close();
                }
            }
    
            public void SendStrMsg(string Msg)
            {
                byte[] MsgByte = StringToByteArray(Msg);
                int MsgLength = mBigenByte.Length + MsgByte.Length + mEndByte.Length;
                byte[] BufferByte = new byte[MsgLength];
                try
                {
                    if (mBigenByte.Length > 0)
                        Buffer.BlockCopy(mBigenByte, 0, BufferByte, 0, mBigenByte.Length);
    
                    Buffer.BlockCopy(MsgByte, 0, BufferByte, mBigenByte.Length, MsgByte.Length);
                    Buffer.BlockCopy(mEndByte, 0, BufferByte, mBigenByte.Length + MsgByte.Length, mEndByte.Length);                
                    mComPort.Write(BufferByte, 0, MsgLength);                                
                }
                catch (Exception ex) { mLog.Error("[Lib_RS232] [Uti_RS232] [SendStrMsg] [Reason : " + ex.Message + "]"); }
            }
    
            public void SendCharMsg(char[] charmsg)
            {
                try { mComPort.Write(charmsg, 0, charmsg.Length); }            
                catch (Exception ex) { mLog.Error("[Lib_RS232] [Uti_RS232] [SendCharMsg] [Reason : " + ex.Message + "]"); }
            }
    
            private void MsgReceive(object sender, SerialDataReceivedEventArgs e)
            {
                try
                {
                    Thread.Sleep(1000);                
                    int Cnt = mComPort.BytesToRead;
                    char[] MsgCharArr = new char[Cnt];
                    mComPort.Read(MsgCharArr, 0, Cnt);
                    string Msg = new string(MsgCharArr);
                    List<string> MsgToHexArr = new List<string>();
                    List<string> MsgToIntArr = new List<string>();
                    for (int i = 0; i < MsgCharArr.Length; i++)
                    {
                        int CharArrToInt = (int)MsgCharArr[i];
                        MsgToHexArr.Add(String.Format("{0:X}", CharArrToInt));
                        MsgToIntArr.Add(CharArrToInt.ToString());
                    }
                    string MsgToHex = string.Empty;
                    for (int j = 0; j < MsgToHexArr.Count; j++)
                    {
                        MsgToHex = MsgToHex + MsgToHexArr[j];
                    }
    
                    string MsgToInt = string.Empty;
                    for (int k = 0; k < MsgToIntArr.Count; k++)
                    {
                        MsgToInt = MsgToInt + MsgToIntArr[k];
                    }
    
                    //byte[] MsgByteArr = new byte[Cnt];
                    //mComPort.Read(MsgByteArr, 0, Cnt);
                    //string Msg = "";// new string(MsgByteArr);
                    //List<string> MsgToHexArr = new List<string>();
                    //List<string> MsgToIntArr = new List<string>();
                    //string MsgToHex = string.Empty;
                    //for (int j = 0; j < MsgToHexArr.Count; j++)
                    //{
                    //    MsgToHex = MsgToHex + MsgToHexArr[j];
                    //}
    
                    //string MsgToInt = string.Empty;
                    //for (int k = 0; k < MsgToIntArr.Count; k++)
                    //{
                    //    MsgToInt = MsgToInt + MsgToIntArr[k];
                    //}
    
                    mLog.Info("Message Received : [" + Msg + "], Convert to Hex : [" + MsgToHex + "], Convert to Int : [" + MsgToInt + "]");
    
                    Uti_RS232_MsgEventArg MsgEventArg = new Uti_RS232_MsgEventArg(MsgToInt);
                    Receive(this, MsgEventArg);
                }
                catch (Exception ex) { mLog.Error("[Lib_RS232] [Uti_RS232] [MsgReceive] [Reason : " + ex.Message + "]"); }
            }
    
            private static byte[] StringToByteArray(string str)
            {
                ASCIIEncoding Encoding = new ASCIIEncoding();
                return (Encoding.GetBytes(str));
            }
        }
    }
    

    這是主程式與RS232通訊共用訊息的Class

    using System;
    
    namespace Lib_OvenEap.Lib_RS232
    {
        public class Uti_RS232_MsgEventArg : EventArgs
        {
            private string mMsg;
    
            public Uti_RS232_MsgEventArg(string msg) { mMsg = msg; }       
    
            public string Msg
            {
                get { return mMsg; }
                set { mMsg = value; }
            }
        }
    }

    這是主程式的Class

    using System;
    using System.IO.Ports;
    using System.Threading;
    
    using log4net;
    
    using Lib_OvenEap.Lib_Common;
    using Lib_OvenEap.Lib_MsgHandler;
    using Lib_OvenEap.Lib_Parameter;
    using Lib_OvenEap.Lib_RS232;
    using Lib_OvenEap.Properties;
    
    namespace Lib_OVNC001
    {
        public class MainProcessEqp
        {
            private static readonly ILog mLog = LogManager.GetLogger(typeof(MainProcessEqp));
            private static Uti_RS232 mComPort = new Uti_RS232();
            
            private int mMsgReSendTimes = 0;
            private int mMsgReSendLimit = 0;
            public int mMsgReSendInterval = 10 * 1000;
            private static Timer mTimerMsgReSend = null;
            private readonly object mLockTimerMsgReSend = new object();        
    
            public enum ProcessState
            {
                StandBy,
                ChkAllStatus,
                ChkEqpStatus,
                ChkPdl,
                ChkLightOn,
                ChkLightOff,
                ChkProgram,
                ChkStart,
            }
    
            public enum PdlState
            {
                StandBy,
                ReadySetGroup,
                ReadySetTempForWait,
                ReadySetTemp,
                ReadySetTime,
                ReadySetPower,
                ReadySetAlarm,
                ReadySetEndSegment,
    
                ReadySelectFan1,
                ReadySetSegmentForFan1Start,
                ReadySetSegmentForFan1End,
                ReadySetTimeForFan1Start,
                ReadySetTimeForFan1End,
    
                ReadySelectFan2,
                ReadySetSegmentForFan2Start,
                ReadySetSegmentForFan2End,
                ReadySetTimeForFan2Start,
                ReadySetTimeForFan2End,
    
                FinishPDL,
            }
    
            public enum EqpState
            {
                Run,
                Idle,
                Disconnect,
            }
    
            public struct ProcessInfo
            {
                public bool IsChkEqpStatusSuccees;
                public bool IsChkEqpStatusFinish;
                public EqpState Status;
                public string ChkEqpStatusErrorMsg;
    
                public bool IsPdlFinish;
                public bool IsPdlSucceed;
                public string PdlErrorMsg;
    
                public bool IsLightChangeFinish;
                public bool IsLightChangeSucceed;
                public string LightChangeErrorMsg;
    
                public bool IsConfirmProgramFinish;
                public bool IsConfirmProgramSucceed;
                public string ConfirmProgramErrorMsg;
    
                public bool IsStartFinish;
                public bool IsStartSucceed;
                public string StartErrorMsg;
    
                //public Dictionary<string, Para_Eqp.RcpParameter> RcpList;
                public PdlState CurrentPdlState;
                public ProcessState CurrentProcessState;
            }
            public ProcessInfo mProcessInfo;
            private Para_Eqp mEqpObj = null;
            private string mDevice = "", mPort = "";        
            private int mRcpSegment = 1, mFan2EndTime = 0;
    
            public delegate void LogEventHandler(Object sender, LogEventArgs e);
            public event LogEventHandler LogToMainForm;
    
            public MainProcessEqp()
            {
                mProcessInfo.IsChkEqpStatusSuccees = false;
                mProcessInfo.IsChkEqpStatusFinish = false;
                mProcessInfo.Status = EqpState.Disconnect;
                mProcessInfo.ChkEqpStatusErrorMsg = "";
    
                mProcessInfo.IsPdlFinish = false;
                mProcessInfo.IsPdlSucceed = false;
                mProcessInfo.PdlErrorMsg = "";
    
                mProcessInfo.IsLightChangeFinish = false;
                mProcessInfo.IsLightChangeSucceed = false;
    
                mProcessInfo.IsStartFinish = false;
                mProcessInfo.IsStartSucceed = false;
                mProcessInfo.StartErrorMsg = "";
                mProcessInfo.CurrentPdlState = PdlState.StandBy;
                mProcessInfo.CurrentProcessState = ProcessState.StandBy;
                
                mTimerMsgReSend = new Timer(new TimerCallback(MsgReSendTrigger), null, Timeout.Infinite, Timeout.Infinite);
                mComPort.Receive += new Uti_RS232.Rs232EventHandler(RS232_Receive);
            }
    
            public bool OpenComPort(Para_Eqp eqpobj, string device, string port)
            {
                try
                {
                    mComPort.Open(port, 9600, Parity.None, 8, StopBits.One);
                    OnLogToMainForm(new LogEventArgs(Resource.MsgOpenComPortScceed + " [EQP = " + eqpobj.EQPID + "] [Device = " + device + "] [Port = " + port + "]"));
                    mLog.Info(Resource.MsgOpenComPortScceed + " [EQP = " + eqpobj.EQPID + "] [Device = " + device + "] [Port = " + port + "]");
                    return true;
                }
                catch (Exception ex)
                {
                    OnLogToMainForm(new LogEventArgs(Resource.MsgOpenComPortFailed + " [EQP = " + eqpobj.EQPID + "] [Device = " + device + "] [Port = " + port + "]"));
                    mLog.Error("[Lib_OVNC001] [MainProcessEqp] [OpenComPort] [Reason : " + ex.Message + "] [EQP = " + eqpobj.EQPID + "] [Device = " + device + "] [Port = " + port + "]");
                    return false;
                }
            }
    
            public bool CloseComPort(Para_Eqp eqpobj, string device, string port)
            {
                try
                {
                    mComPort.Close();
                    OnLogToMainForm(new LogEventArgs(Resource.MsgCloseComPortSucceed + " [EQP = " + eqpobj.EQPID + "] [Device = " + device + "] [Port = " + port + "]"));
                    mLog.Info(Resource.MsgCloseComPortSucceed + " [EQP = " + eqpobj.EQPID + "] [Device = " + device + "] [Port = " + port + "]");
                    return true;
                }
                catch (Exception ex)
                {
                    OnLogToMainForm(new LogEventArgs(Resource.MsgCloseComPortFail + " [EQP = " + eqpobj.EQPID + "] [Device = " + device + "] [Port = " + port + "]"));
                    mLog.Error("[Lib_OVNC001] [MainProcessEqp] [CloseComPort] [Reason : " + ex.Message + "] [EQP = " + eqpobj.EQPID + "] [Device = " + device + "] [Port = " + port + "]");
                    return false;
                }
            }
    
            public bool SendStrCmd(Para_Eqp eqpobj, string device, string port, string cmd)
            {
                try
                {
                    mEqpObj = eqpobj;
                    mDevice = device;
                    mPort = port;
                    mLog.Info(Resource.MsgSendComPortCmdSucceed + " [EQP = " + eqpobj.EQPID + "] [Device = " + device + "] [Port = " + port + "] [CMD = " + cmd + "]");
                    OnLogToMainForm(new LogEventArgs("Timer for Re-Send Message Start..."));
                    mLog.Info("Timer for Re-Send Message Start...");
                    mTimerMsgReSend.Change(mMsgReSendInterval, mMsgReSendInterval);
                    mComPort.SendStrMsg(cmd);                                
                    return true;
                }
                catch (Exception ex)
                {
                    OnLogToMainForm(new LogEventArgs(Resource.MsgSendComPortCmdFailed + " [EQP = " + eqpobj.EQPID + "] [Device = " + device + "] [Port = " + port + "] [CMD = " + cmd + "]"));
                    mLog.Error("[Lib_OVNC001] [MainProcessEqp] [SendStrCmd] [Reason : " + ex.Message + "] [EQP = " + eqpobj.EQPID + "] [Device = " + device + "] [Port = " + port + "] [CMD = " + cmd + "]");
                    return false;
                }
            }
    
            public bool SendCharCmd(Para_Eqp eqpobj, char[] charcmd, bool pdl, string device, string port)
            {
                try
                {
                    mEqpObj = eqpobj;
                    mDevice = device;
                    mPort = port;
                    if (pdl)
                        mLog.Info(Resource.MsgPdl + " [EQP = " + eqpobj.EQPID + "] [Device = " + device + "] [Port = " + port + "] [CMD = " + Uti_Common.CharArrToString(charcmd) + "]");
                    else
                        mLog.Info(Resource.MsgSendComPortCmdSucceed + " [EQP = " + eqpobj.EQPID + "] [Device = " + device + "] [Port = " + port + "] [CMD = " + Uti_Common.CharArrToString(charcmd) + "]");
                    mComPort.SendCharMsg(charcmd);
                    OnLogToMainForm(new LogEventArgs("Timer for Re-Send Message Start..."));
                    mLog.Info("Timer for Re-Send Message Start...");
                    mTimerMsgReSend.Change(mMsgReSendInterval, mMsgReSendInterval);
                    return true;
                }
                catch (Exception ex)
                {
                    mLog.Error("[Lib_OVNC001] [MainProcessEqp] [SendCharCmd] [Reason : " + ex.Message + "]");
                    return false;
                }
            }
    
            private void RS232_Receive(object sender, Uti_RS232_MsgEventArg e)
            {
                try
                {                
                    mLog.Info(Resource.MsgReceiveComPortCmdSucceed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "] [CMD = " + e.Msg + "]");
                    OnLogToMainForm(new LogEventArgs("Timer for Re-Send Message Close..."));
                    mLog.Info("Timer for Re-Send Message Close...");
                    mTimerMsgReSend.Change(Timeout.Infinite, Timeout.Infinite);                
                    this.RS232_CmdHandle(e.Msg);
                }
                catch (Exception ex) { mLog.Error("[Lib_OVNC001] [MainProcessEqp] [RS232_Receive] [Reason : " + ex.Message + "]"); }
            }
    
            private void RS232_CmdHandle(string cmd)
            {            
                try
                {
                    switch (cmd)
                    {
                        case "3348484849484813":                        
                            mProcessInfo.Status = EqpState.Run;
                            mProcessInfo.IsChkEqpStatusFinish = true;
                            break;
    
                        case "3348484850484813":                        
                            mProcessInfo.Status = EqpState.Idle;
                            mProcessInfo.IsChkEqpStatusFinish = true;
                            break;
    
                        case "6":
                            mProcessInfo.IsPdlSucceed = true;
                            Para_Eqp.RcpParameter RcpPara = mEqpObj.RECIPELIST[mRcpSegment.ToString()];
                            switch (mProcessInfo.CurrentPdlState)
                            {
                                case PdlState.ReadySetTempForWait:
                                    if (!SendCharCmd(mEqpObj, MsgGenerate_RS232.SetTemperatureForWait(Convert.ToInt32(mEqpObj.ADEVICEID)), true, mDevice, mPort))
                                    {
                                        mProcessInfo.PdlErrorMsg = Resource.MsgSendComPortCmdFailed;
                                        mProcessInfo.IsPdlSucceed = false;
                                    }
                                    else mProcessInfo.CurrentPdlState = PdlState.ReadySetTemp;
                                    break;
    
                                case PdlState.ReadySetTemp:
                                    if (!SendCharCmd(mEqpObj, MsgGenerate_RS232.SetTemperatureBySegment(Convert.ToInt32(mEqpObj.ADEVICEID), Convert.ToInt32(RcpPara.SEGMENT_FOR_TEMPERATURE), RcpPara.TEMPERATURE), true, mDevice, mPort))
                                    {
                                        mProcessInfo.PdlErrorMsg = Resource.MsgSendComPortCmdFailed;
                                        mProcessInfo.IsPdlSucceed = false;
                                    }
                                    else mProcessInfo.CurrentPdlState = PdlState.ReadySetTime;
                                    break;
    
                                case PdlState.ReadySetTime:
                                    if (!SendCharCmd(mEqpObj, MsgGenerate_RS232.SetTimeBySegment(Convert.ToInt32(mEqpObj.ADEVICEID), Convert.ToInt32(RcpPara.SEGMENT_FOR_RCPTIME), RcpPara.RCPTIME), true, mDevice, mPort))
                                    {
                                        mProcessInfo.PdlErrorMsg = Resource.MsgSendComPortCmdFailed;
                                        mProcessInfo.IsPdlSucceed = false;
                                    }
                                    else mProcessInfo.CurrentPdlState = PdlState.ReadySetPower;
                                    break;
    
                                case PdlState.ReadySetPower:
                                    if (!SendCharCmd(mEqpObj, MsgGenerate_RS232.SetPowerBySegment(Convert.ToInt32(mEqpObj.ADEVICEID), Convert.ToInt32(RcpPara.SEGMENT_FOR_POWER), RcpPara.POWER), true, mDevice, mPort))
                                    {
                                        mProcessInfo.PdlErrorMsg = Resource.MsgSendComPortCmdFailed;
                                        mProcessInfo.IsPdlSucceed = false;
                                    }
                                    else mProcessInfo.CurrentPdlState = PdlState.ReadySetAlarm;
                                    break;
    
                                case PdlState.ReadySetAlarm:
                                    if (!SendCharCmd(mEqpObj, MsgGenerate_RS232.SetAlarmBySegment(Convert.ToInt32(mEqpObj.ADEVICEID), Convert.ToInt32(RcpPara.SEGMENT_FOR_ALARM), RcpPara.ALARM), true, mDevice, mPort))
                                    {
                                        mProcessInfo.PdlErrorMsg = Resource.MsgSendComPortCmdFailed;
                                        mProcessInfo.IsPdlSucceed = false;
                                    }
                                    else
                                    {
                                        if (mRcpSegment >= mEqpObj.RECIPELIST.Keys.Count)
                                        {
                                            mRcpSegment = 1;
                                            mProcessInfo.CurrentPdlState = PdlState.ReadySetEndSegment;
                                            mFan2EndTime = RcpPara.RCPTIME;
                                        }
                                        else
                                        {
                                            mRcpSegment++;
                                            mProcessInfo.CurrentPdlState = PdlState.ReadySetTemp;
                                        }
                                    }
                                    break;
    
                                case PdlState.ReadySetEndSegment:
                                    if (!SendCharCmd(mEqpObj, MsgGenerate_RS232.SetEndSegment(Convert.ToInt32(mEqpObj.ADEVICEID), mEqpObj.RECIPELIST.Keys.Count), true, mDevice, mPort))
                                    {
                                        mProcessInfo.PdlErrorMsg = Resource.MsgSendComPortCmdFailed;
                                        mProcessInfo.IsPdlSucceed = false;
                                    }
                                    else mProcessInfo.CurrentPdlState = PdlState.ReadySelectFan1;                                
                                    break;
    
                                case PdlState.ReadySelectFan1:
                                    if (!SendCharCmd(mEqpObj, MsgGenerate_RS232.SelecteFan(Convert.ToInt32(mEqpObj.ADEVICEID), 1, 1), true, mDevice, mPort))
                                    {
                                        mProcessInfo.PdlErrorMsg = Resource.MsgSendComPortCmdFailed;
                                        mProcessInfo.IsPdlSucceed = false;
                                    }
                                    else mProcessInfo.CurrentPdlState = PdlState.ReadySetSegmentForFan1Start;
                                    break;
    
                                case PdlState.ReadySetSegmentForFan1Start:
                                    if (!SendCharCmd(mEqpObj, MsgGenerate_RS232.SetSegmentForFan(Convert.ToInt32(mEqpObj.ADEVICEID), 1, "SO", mEqpObj.RECIPELIST.Keys.Count, 1), true, mDevice, mPort))
                                    {
                                        mProcessInfo.PdlErrorMsg = Resource.MsgSendComPortCmdFailed;
                                        mProcessInfo.IsPdlSucceed = false;
                                    }
                                    else mProcessInfo.CurrentPdlState = PdlState.ReadySetSegmentForFan1End;
                                    break;
    
                                case PdlState.ReadySetSegmentForFan1End:
                                    if (!SendCharCmd(mEqpObj, MsgGenerate_RS232.SetSegmentForFan(Convert.ToInt32(mEqpObj.ADEVICEID), 1, "SF", mEqpObj.RECIPELIST.Keys.Count, 1), true, mDevice, mPort))
                                    {
                                        mProcessInfo.PdlErrorMsg = Resource.MsgSendComPortCmdFailed;
                                        mProcessInfo.IsPdlSucceed = false;
                                    }
                                    else mProcessInfo.CurrentPdlState = PdlState.ReadySetTimeForFan1Start;
                                    break;
    
                                case PdlState.ReadySetTimeForFan1Start:
                                    if (!SendCharCmd(mEqpObj, MsgGenerate_RS232.SetTimeForFan(Convert.ToInt32(mEqpObj.ADEVICEID), 1, 1, "TO", 0), true, mDevice, mPort))
                                    {
                                        mProcessInfo.PdlErrorMsg = Resource.MsgSendComPortCmdFailed;
                                        mProcessInfo.IsPdlSucceed = false;
                                    }
                                    else mProcessInfo.CurrentPdlState = PdlState.ReadySetTimeForFan1End;
                                    break;
    
                                case PdlState.ReadySetTimeForFan1End:
                                    if (!SendCharCmd(mEqpObj, MsgGenerate_RS232.SetTimeForFan(Convert.ToInt32(mEqpObj.ADEVICEID), 1, 1, "TF", 0), true, mDevice, mPort))
                                    {
                                        mProcessInfo.PdlErrorMsg = Resource.MsgSendComPortCmdFailed;
                                        mProcessInfo.IsPdlSucceed = false;
                                    }
                                    else mProcessInfo.CurrentPdlState = PdlState.ReadySelectFan2;
                                    break;
    
                                case PdlState.ReadySelectFan2:
                                    if (!SendCharCmd(mEqpObj, MsgGenerate_RS232.SelecteFan(Convert.ToInt32(mEqpObj.ADEVICEID), 2, 2), true, mDevice, mPort))
                                    {
                                        mProcessInfo.PdlErrorMsg = Resource.MsgSendComPortCmdFailed;
                                        mProcessInfo.IsPdlSucceed = false;
                                    }
                                    else mProcessInfo.CurrentPdlState = PdlState.ReadySetSegmentForFan2Start;
                                    break;
    
                                case PdlState.ReadySetSegmentForFan2Start:
                                    if (!SendCharCmd(mEqpObj, MsgGenerate_RS232.SetSegmentForFan(Convert.ToInt32(mEqpObj.ADEVICEID), 2, "SO", mEqpObj.RECIPELIST.Keys.Count, 2), true, mDevice, mPort))
                                    {
                                        mProcessInfo.PdlErrorMsg = Resource.MsgSendComPortCmdFailed;
                                        mProcessInfo.IsPdlSucceed = false;
                                    }
                                    else mProcessInfo.CurrentPdlState = PdlState.ReadySetSegmentForFan2End;
                                    break;
    
                                case PdlState.ReadySetSegmentForFan2End:
                                    if (!SendCharCmd(mEqpObj, MsgGenerate_RS232.SetSegmentForFan(Convert.ToInt32(mEqpObj.ADEVICEID), 2, "SF", mEqpObj.RECIPELIST.Keys.Count, 2), true, mDevice, mPort))
                                    {
                                        mProcessInfo.PdlErrorMsg = Resource.MsgSendComPortCmdFailed;
                                        mProcessInfo.IsPdlSucceed = false;
                                    }
                                    else mProcessInfo.CurrentPdlState = PdlState.ReadySetTimeForFan2Start;
                                    break;
    
                                case PdlState.ReadySetTimeForFan2Start:
                                    if (!SendCharCmd(mEqpObj, MsgGenerate_RS232.SetTimeForFan(Convert.ToInt32(mEqpObj.ADEVICEID), 2, 2, "TO", 0), true, mDevice, mPort))
                                    {
                                        mProcessInfo.PdlErrorMsg = Resource.MsgSendComPortCmdFailed;
                                        mProcessInfo.IsPdlSucceed = false;
                                    }
                                    else mProcessInfo.CurrentPdlState = PdlState.ReadySetTimeForFan2End;
                                    break;
    
                                case PdlState.ReadySetTimeForFan2End:
                                    if (!SendCharCmd(mEqpObj, MsgGenerate_RS232.SetTimeForFan(Convert.ToInt32(mEqpObj.ADEVICEID), 2, 2, "TF", mFan2EndTime + 30), true, mDevice, mPort))
                                    {
                                        mProcessInfo.PdlErrorMsg = Resource.MsgSendComPortCmdFailed;
                                        mProcessInfo.IsPdlSucceed = false;
                                    }
                                    else mProcessInfo.CurrentPdlState = PdlState.FinishPDL;
                                    break;
                            }
    
                            if (mProcessInfo.IsPdlSucceed)
                            {
                                if (mProcessInfo.CurrentPdlState == PdlState.FinishPDL) mProcessInfo.IsPdlFinish = true;
                            }
                            else
                            {
                                if (mProcessInfo.PdlErrorMsg == Resource.MsgSendComPortCmdFailed)
                                    mLog.Info(Resource.MsgSendComPortCmdFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                mProcessInfo.IsPdlFinish = true;
                            }
                            break;
    
                        case "21":
                            switch (mProcessInfo.CurrentPdlState)
                            {
                                case PdlState.ReadySetTempForWait:
                                    mLog.Info(Resource.MsgSetGroupFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    mProcessInfo.PdlErrorMsg = Resource.MsgSetGroupFailed;
                                    break;
    
                                case PdlState.ReadySetTemp:
                                    mLog.Info(Resource.MsgSetTempForWaitFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    mProcessInfo.PdlErrorMsg = Resource.MsgSetTempForWaitFailed;
                                    break;
    
                                case PdlState.ReadySetTime:
                                    mLog.Info(Resource.MsgSetTemperatureBySegmentFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    mProcessInfo.PdlErrorMsg = Resource.MsgSetTemperatureBySegmentFailed;
                                    break;
    
                                case PdlState.ReadySetPower:
                                    mLog.Info(Resource.MsgSetTimeBySegmentFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    mProcessInfo.PdlErrorMsg = Resource.MsgSetTimeBySegmentFailed;
                                    break;
    
                                case PdlState.ReadySetAlarm:
                                    mLog.Info(Resource.MsgSetPowerBySegmentFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    mProcessInfo.PdlErrorMsg = Resource.MsgSetPowerBySegmentFailed;
                                    break;
    
                                case PdlState.ReadySetEndSegment:
                                    mLog.Info(Resource.MsgSetAlarmBySegmentFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    mProcessInfo.PdlErrorMsg = Resource.MsgSetAlarmBySegmentFailed;
                                    break;
    
                                case PdlState.ReadySelectFan1:
                                    mLog.Info(Resource.MsgSetEndSegmentFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    mProcessInfo.PdlErrorMsg = Resource.MsgSetEndSegmentFailed;
                                    break;
    
                                case PdlState.ReadySetSegmentForFan1Start:
                                    mLog.Info(Resource.MsgSelecteFan1Failed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    mProcessInfo.PdlErrorMsg = Resource.MsgSelecteFan1Failed;
                                    break;
    
                                case PdlState.ReadySetSegmentForFan1End:
                                    mLog.Info(Resource.MsgSetSegmentForFan1StartFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    mProcessInfo.PdlErrorMsg = Resource.MsgSetSegmentForFan1StartFailed;
                                    break;
    
                                case PdlState.ReadySetTimeForFan1Start:
                                    mLog.Info(Resource.MsgSetSegmentForFan1EndFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    mProcessInfo.PdlErrorMsg = Resource.MsgSetSegmentForFan1EndFailed;
                                    break;
    
                                case PdlState.ReadySetTimeForFan1End:
                                    mLog.Info(Resource.MsgSetTimeForFan1StartFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    mProcessInfo.PdlErrorMsg = Resource.MsgSetTimeForFan1StartFailed;
                                    break;
    
                                case PdlState.ReadySelectFan2:
                                    mLog.Info(Resource.MsgSetTimeForFan1EndFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    mProcessInfo.PdlErrorMsg = Resource.MsgSetTimeForFan1EndFailed;
                                    break;
    
                                case PdlState.ReadySetSegmentForFan2Start:
                                    mLog.Info(Resource.MsgSelecteFan2Failed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    mProcessInfo.PdlErrorMsg = Resource.MsgSelecteFan2Failed;
                                    break;
    
                                case PdlState.ReadySetSegmentForFan2End:
                                    mLog.Info(Resource.MsgSetSegmentForFan2StartFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    mProcessInfo.PdlErrorMsg = Resource.MsgSetSegmentForFan2StartFailed;
                                    break;
    
                                case PdlState.ReadySetTimeForFan2Start:
                                    mLog.Info(Resource.MsgSetSegmentForFan2EndFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    mProcessInfo.PdlErrorMsg = Resource.MsgSetSegmentForFan2EndFailed;
                                    break;
    
                                case PdlState.ReadySetTimeForFan2End:
                                    mLog.Info(Resource.MsgSetTimeForFan2StartFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    mProcessInfo.PdlErrorMsg = Resource.MsgSetTimeForFan2StartFailed;
                                    break;
    
                                case PdlState.FinishPDL:
                                    mLog.Info(Resource.MsgSetTimeForFan2EndFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    mProcessInfo.PdlErrorMsg = Resource.MsgSetTimeForFan2EndFailed;
                                    break;
                            }
                            mProcessInfo.IsPdlFinish = true;
                            break;
    
                        case "6213":
                            switch (mProcessInfo.CurrentProcessState)
                            {
                                case ProcessState.ChkLightOff:                                
                                    mProcessInfo.IsLightChangeSucceed = true;
                                    mProcessInfo.IsLightChangeFinish = true;
                                    break;
    
                                case ProcessState.ChkLightOn:
                                    goto case ProcessState.ChkLightOff;                                
    
                                case ProcessState.ChkStart:                                
                                    mProcessInfo.IsStartSucceed = true;
                                    mProcessInfo.IsStartFinish = true;
                                    break;
                            }
                            break;
    
                        case "UndefinedCom":
                            OnLogToMainForm(new LogEventArgs(Resource.MsgUndefinedComPortCmd + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]"));
                            mLog.Info(Resource.MsgUndefinedComPortCmd + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                            switch (mProcessInfo.CurrentProcessState)
                            {
                                case ProcessState.ChkAllStatus:
                                    goto case ProcessState.ChkEqpStatus;
    
                                case ProcessState.ChkEqpStatus:
                                    mProcessInfo.ChkEqpStatusErrorMsg = Resource.MsgUndefinedComPortCmd;
                                    mProcessInfo.Status = EqpState.Disconnect;
                                    mProcessInfo.IsChkEqpStatusFinish = true;
                                    break;
    
                                case ProcessState.ChkPdl:
                                    mProcessInfo.PdlErrorMsg = Resource.MsgUndefinedComPortCmd;
                                    mProcessInfo.IsPdlSucceed = false;
                                    mProcessInfo.IsPdlFinish = true;
                                    break;
    
                                case ProcessState.ChkLightOff:
                                    mProcessInfo.LightChangeErrorMsg = Resource.MsgUndefinedComPortCmd;
                                    mProcessInfo.IsLightChangeSucceed = false;
                                    mProcessInfo.IsLightChangeFinish = true;
                                    break;
    
                                case ProcessState.ChkLightOn:
                                    goto case ProcessState.ChkLightOff;                                
                                
                                case ProcessState.ChkProgram:
                                    mProcessInfo.ConfirmProgramErrorMsg = Resource.MsgUndefinedComPortCmd;
                                    mProcessInfo.IsConfirmProgramSucceed = false;
                                    mProcessInfo.IsConfirmProgramFinish = true;
                                    break;
    
                                case ProcessState.ChkStart:
                                    mProcessInfo.StartErrorMsg = Resource.MsgUndefinedComPortCmd;
                                    mProcessInfo.IsStartSucceed = false;
                                    mProcessInfo.IsStartFinish = true;
                                    break;
                            }
                            break;
    
                        default:
                            if (cmd.Length >= 17)
                            {
                                if (cmd.Substring(0, 13).ToString() == "2808348484848")
                                {
                                    if (cmd.Substring(13, 4) == "4954")
                                    {
                                        mProcessInfo.IsConfirmProgramSucceed = true;
                                        mProcessInfo.IsConfirmProgramFinish = true;
                                        break;
                                    }
                                    else
                                    {
                                        mProcessInfo.IsConfirmProgramSucceed = false;
                                        mProcessInfo.IsConfirmProgramFinish = true;
                                        break;
                                    }
                                }
                                else goto case "UndefinedCom";
                            }
                            else
                            {
                                if (cmd.Substring(0, 1) == "6") goto case "6";
                                else goto case "UndefinedCom";
                            }
                    }                
                }
                catch (Exception ex) { mLog.Error("[Lib_OVNC001] [MainProcessEqp] [RS232_CmdHandle] [Reason : " + ex.Message + "]"); }
            }
    
            protected virtual void OnLogToMainForm(LogEventArgs e) { LogToMainForm(this, e); }        
    
            private void MsgReSendTrigger(object obj)
            {
                try
                {
                    lock (mLockTimerMsgReSend)
                    {
                        mMsgReSendTimes++;
                    }
                    
                    mTimerMsgReSend.Change(Timeout.Infinite, Timeout.Infinite);
                    OnLogToMainForm(new LogEventArgs("Timer for Re-Send Message Close..."));
                    mLog.Info("Timer for Re-Send Message Close...");
                    //if (mMsgReSendTimes > mMsgReSendLimit)
                    //{
                    //    OnLogToMainForm(new LogEventArgs("Timer for Re-Send Message Close..."));
                    //    mLog.Info("Timer for Re-Send Message Close...");                                        
                    //}
                    //else
    
                    if (mMsgReSendTimes <= mMsgReSendLimit)
                    {
                        if (mProcessInfo.CurrentProcessState != ProcessState.ChkPdl && mProcessInfo.CurrentProcessState != ProcessState.ChkStart) //要重覆下的指令太多,所以TimeOut直接回覆失敗,不Retry
                        {
                            OnLogToMainForm(new LogEventArgs("Timer for Re-Send Msg : " + mMsgReSendTimes + ". [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]"));
                            mLog.Info("Timer for Re-Send Msg : " + mMsgReSendTimes + ". [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                            CloseComPort(mEqpObj, mDevice, mPort);
                            OpenComPort(mEqpObj, mDevice, mPort);
    
                            //OnLogToMainForm(new LogEventArgs("Timer for Re-Send Message Close..."));
                            //mLog.Info("Timer for Re-Send Message Close...");
                            //mTimerMsgReSend.Change(Timeout.Infinite, Timeout.Infinite);
                        }
                        //else
                        //{
                        //    OnLogToMainForm(new LogEventArgs("Timer for Re-Send Msg : " + mMsgReSendTimes + ". [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]"));
                        //    mLog.Info("Timer for Re-Send Msg : " + mMsgReSendTimes + ". [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                        //    CloseComPort(mEqpObj, mDevice, mPort);
                        //    OpenComPort(mEqpObj, mDevice, mPort);
                        //}
                    }
    
                    switch (mProcessInfo.CurrentProcessState)
                    {
                        case ProcessState.ChkAllStatus:
                            if (mMsgReSendTimes > mMsgReSendLimit)
                            {
                                mMsgReSendTimes = 0;
                                mProcessInfo.ChkEqpStatusErrorMsg = "Msg Reply Time-Out";
                                mProcessInfo.Status = EqpState.Disconnect;
                                mProcessInfo.IsChkEqpStatusFinish = true;
                            }
                            else
                            {
                                if (!SendStrCmd(mEqpObj, mDevice, mPort, "$0" + mDevice + "6"))
                                {
                                    mLog.Info(Resource.MsgSendComPortCmdFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    OnLogToMainForm(new LogEventArgs("Timer for Re-Send Message Close..."));
                                    mLog.Info("Timer for Re-Send Message Close...");
                                    mTimerMsgReSend.Change(Timeout.Infinite, Timeout.Infinite);
                                    mProcessInfo.ChkEqpStatusErrorMsg = Resource.MsgSendComPortCmdFailed;
                                    mProcessInfo.Status = EqpState.Disconnect;
                                    mProcessInfo.IsChkEqpStatusFinish = true;
                                }
                            }
                            break;
    
                        case ProcessState.ChkEqpStatus:
                            if (mMsgReSendTimes > mMsgReSendLimit)
                            {
                                mMsgReSendTimes = 0;
                                mProcessInfo.ChkEqpStatusErrorMsg = "Msg Reply Time-Out";
                                mProcessInfo.Status = EqpState.Disconnect;
                                mProcessInfo.IsChkEqpStatusFinish = true;
                            }
                            else
                            {
                                if (!SendStrCmd(mEqpObj, mDevice, mPort, "$0" + mDevice + "6"))
                                {
                                    mLog.Info(Resource.MsgSendComPortCmdFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    OnLogToMainForm(new LogEventArgs("Timer for Re-Send Message Close..."));
                                    mLog.Info("Timer for Re-Send Message Close...");
                                    mTimerMsgReSend.Change(Timeout.Infinite, Timeout.Infinite);
                                    mProcessInfo.ChkEqpStatusErrorMsg = Resource.MsgSendComPortCmdFailed;
                                    mProcessInfo.Status = EqpState.Disconnect;
                                    mProcessInfo.IsChkEqpStatusFinish = true;
                                }
                            }
                            break;
    
                        case ProcessState.ChkPdl:
                            mMsgReSendTimes = 0;
                            mProcessInfo.PdlErrorMsg = "Msg Reply Time-Out";
                            mProcessInfo.IsPdlSucceed = false;
                            mProcessInfo.IsPdlFinish = true;
                            break;
    
                        case ProcessState.ChkLightOff:
                            if (mMsgReSendTimes > mMsgReSendLimit)
                            {
                                mMsgReSendTimes = 0;
                                mProcessInfo.LightChangeErrorMsg = "Msg Reply Time-Out";
                                mProcessInfo.IsLightChangeSucceed = false;
                                mProcessInfo.IsLightChangeFinish = true;
                            }
                            else
                            {
                                if (!SendStrCmd(mEqpObj, mDevice, mPort, "$0" + mDevice + "6"))
                                {
                                    mLog.Info(Resource.MsgSendComPortCmdFailed + " [EQP = " + mEqpObj.EQPID + "] [Device = " + mDevice + "] [Port = " + mPort + "]");
                                    OnLogToMainForm(new LogEventArgs("Timer for Re-Send Message Close..."));
                                    mLog.Info("Timer for Re-Send Message Close...");
                                    mTimerMsgReSend.Change(Timeout.Infinite, Timeout.Infinite);
                                    mProcessInfo.LightChangeErrorMsg = Resource.MsgSendComPortCmdFailed;
                                    mProcessInfo.IsLightChangeSucceed = false;
                                    mProcessInfo.IsChkEqpStatusFinish = true;
                                }
                            }
                            break;
    
                        case ProcessState.ChkLightOn:
                            goto case ProcessState.ChkLightOff;
    
                        case ProcessState.ChkProgram:
                            mMsgReSendTimes = 0;
                            mProcessInfo.ConfirmProgramErrorMsg = "Msg Reply Time-Out";
                            mProcessInfo.IsConfirmProgramSucceed = false;
                            mProcessInfo.IsConfirmProgramFinish = true;
                            break;
    
                        case ProcessState.ChkStart:
                            mMsgReSendTimes = 0;
                            mProcessInfo.StartErrorMsg = "Msg Reply Time-Out";
                            mProcessInfo.IsStartSucceed = false;
                            mProcessInfo.IsStartFinish = true;
                            break;
                    }
                }
                catch (Exception ex) { mLog.Error("[Lib_OVNC001] [MainProcessEqp] [MsgReSend] [Reason : " + ex.Message + "]"); }
            }
        }
    }
    

    主要的問題發生在主程式裡面RS232_CmdHandle的這個Function,會收到沒有定義的訊息。

    這個問題已經困擾我很久了,還請各位高手幫忙。

    讓我可以真正找出問題的原因並解決問題。

    感謝。

    2014年10月23日 上午 08:33

所有回覆

  • 請確定 機器送出的訊息 是 2個byte 還是2個 char
    長度2 是 單純的 data length 還是 total length


    以下為簽名檔,如果你愛拉椅子坐那就是你的問題。
    先查MSDN文件庫
    再用GOOGLE搜尋
    才到論壇來發問

    這是論壇不是技術支援中心
    沒有人得無償解答你的問題

    在標題或文章註明很急
    不會增加網友回覆速度

    2014年10月23日 上午 09:12
  • Hi, Alex

    依照我程式的寫法。如下

    mComPort.DataReceived += new SerialDataReceivedEventHandler(MsgReceive);

    機器回覆訊息,我就會收到。

    所以長度應該就是total length

    至於回覆的是byte還是char,我不是很確定。

    我有爬過文,C#的SerialPort收到訊息不正確的情形好像很常見。

    但我用BCB完全沒有這個問題。

    想請教,我這樣的寫法有問題嗎?

    我可以怎麼樣改進?

    問題發生真正的原因是什麼?

    感謝。


    2014年10月23日 上午 09:27
  • (1) 我注意到你用了 DataReceived Event 要小心一件事就是當你送了第一個request 之後, 有可能設備還沒回應完成, 又送第二個 request , 這樣可能就會導致收到兩次連在一起 (而且不一定是完整的) 回應

    (2) 用 Timer 請注意時間間隔要夠長

    (3) 通常這樣個狀況, 要先把條件單純化後測試, 先使用手動按 Button , 慢慢送一次收一次, 花時間去測試這樣的情形會不會出現

    (3-1) 如果手動慢慢做, 還會出現這樣的狀況, 有可能是通訊干擾, 也有可能是某一邊的通訊晶片的頻率有問題 (Baud Rate 不一致, 我見過幾次用錯震盪器導致 BuadRate 變成很奇怪數字的現象)

    (3-2) 如果慢慢測試都正常, 那問題可能出在你的程式碼, 通常一送一回的發送回應寫法我不會用 DataReceived Event, 在我的部落格文章 Serial Port 系列(15) 基本篇 -- 發送回應(一) 有解釋為什麼不要用 DataReceived Event 來做這件事

    (4) 一般我們在對自己的程式沒那麼有信心的時候會借助AccessPort 這個軟體來觀察發送與回應的封包, 建議你也應該下載來用

     


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2014年10月23日 下午 03:27
    版主
  • 1. 使用 AccessPort 同步接收資訊,看看是否是設備送過來的資料問題。

    2. 搜尋 SerialPort MemoryStream ,學習正確接收 SerialPort 位元組

    3. 了解 DataReceived 是多工非同步行為,設想 CPU 競速問題。

    4. 確認環境訊號干擾程度,(所以要配合 1)

    通常接收訊號不正確多半是程式寫錯,把 Windows 程式當 DOS 程式寫。其次是環境噪訊。

    搞通訊的太多人了,不是 .Net 問題。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    2014年10月23日 下午 03:35
  • Hi, Bill

    針對(1),我有考慮這個問題。這是一支與機台連線的程式,而且同一時間只對一個機台下指令,所以發送Request後,如果沒有回覆,不會再發送第二個Request。

    針對(2),我原本有設置一個Resend的Timer,但發現訊息回覆錯誤的頻率變很高,所以後改成Timeout沒有回覆就算了。

    針對(3),我在寫這支程式時,我有先寫一個模擬器,用來測試通訊與指令。單一測試或短時間測試沒有問題。但沒有作壓力測試。真正困擾我的原因在於,機台回復訊息的長度不正確,並不是每一次都發生,而是偶發,導致我沒有辦法確切的找出問題在哪裡。我不確定是我程式寫得不好,還是機台有線路干擾的問題。我擔心我的程式有我所不知道的盲點,所以尋求各位高手的協助。

    針對(3-1),動手慢慢做,不會有這個問題。但就像上面所說,這問題是偶發的,所以我也不確定動手慢慢做,時間拉長會不會出現相同的問題。

    針對(3-2),我後來有注意到你的文章。但我動作有點太慢了。如果現在要改成Send -> Thread Sleep -> Receive的模式,我底層的通訊的程式碼整個都要改寫.....但在這之前,我還是先詢問各位前輩的意見,看是否有其他幫助。

    針對(4),我已經下載。下周會開始使用。

    感謝Bill前輩的回覆。這應該算是我的經驗還不夠,下次如果再寫通訊的時候,我不會再使用DataReceivedEvent,會改用Send -> Thread Sleep -> Receive的模式。希望這樣的經驗,也能給各位做個參考。

    如果還有其他的建議,也希望各位前輩能再給我一點指點。

    感謝。

    2014年10月24日 下午 04:57
  • Hi, 前輩

    針對1,我有注意到這個工作,下周會開始使用。

    針對2,第一次看到SerialPort MemoryStream這個物件,我會Survey一下。

    針對3,前輩,我沒有什麼硬體的背景,比較駑鈍一點,所以您說的CPU競速的問題,我不是很懂。如果您時間允許,是否可以再解釋更詳細一點。

    針對4,我目前懷疑的問題發生的原因有兩的。第一,就是我程式寫得不好(不應該用DataReceivedEvent)。第二,就是線路有干擾。但因為這個問題是偶發,也就是有時候才會發生。所以導致我很難找出問題的真正原因。

    感謝前輩的回覆。我會配合使用AccessPort測試觀察看看。同時Survey SerialPort MemortStream的用法。

    如果前輩還有其他的建議或指教,或我的程式還有沒注意到的地方。都希望前輩不吝指教。

    感謝。

    2014年10月24日 下午 05:07
  • 2. 是說 SerialPort + MemorySteam 如何搭配。廣泛用在接收資料中,用在網路就是 TcpClient + MemoryStream 或是 Socket + MemoryStream

    3. 你就當隨便找兩個人一起跑步,你能確保跑第一道的一定跑贏 10 公尺嗎?一邊接收資料,一邊執行你的程式碼,哪有可能每次程式碼執行的時候,收到的長度都一樣?所以需要 2。

    4. 的部分可以配合 1 ,若 1 監聽沒有,就是程式寫錯。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    2014年10月25日 上午 04:25
  • Hi, 前輩

    關於第2與第3點。

    我思考還有爬了一些文。大致了解您的意思。(但怎麼搭配我還要再想一下)

    這的確是我的程式可以再加強的地方。

    可見我這支程式,可以改進的地方還很多。

    感謝前輩非常寶貴的意見。

    2014年10月25日 下午 06:49
  • 把這篇關於暴衝的部分看一下:

    https://social.msdn.microsoft.com/Forums/zh-TW/c4d187b0-7d8f-4ca0-856f-0f6239774fe4/rs232?forum=232


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    2014年10月26日 上午 01:42