2017-07-04 58 views
0

我正在使用C#中的串行端口功能與一個硬件進行通信。一切都寫入串行端口,並且串行端口始終處於連接狀態。串行端口數據接收事件處理程序可靠性

由於某些原因,串行端口數據接收處理程序並不總是讀取數據(每8次中有1次,它無法讀取任何內容或調用事件函數本身)。在另一邊一切都很好。我只接收從串口爲1,2,3一個字母等

這裏是我的代碼:

串行設置:

//Create new serial port 
    SerialPort SerPort = new SerialPort("COM4"); 

    private void SetupSerial() 
    { 
     SerPort.BaudRate = 9600; 
     SerPort.Parity = Parity.None; 
     SerPort.StopBits = StopBits.One; 
     SerPort.DataBits = 8; 
     SerPort.Handshake = Handshake.None; 
     SerPort.ReadTimeout = 4000; 
     SerPort.WriteTimeout = 6000; 
     SerPort.Open(); 
     SerPort.DataReceived += new SerialDataReceivedEventHandler(HandleSerialData); 

     lblStatus.Text = "Successfully connected to COM port with no errors!"; 

    } 

我寫串行功能:

 private void WriteToSerial(string data) 
    { 
     byte[] MyMessage = Encoding.UTF8.GetBytes(data); 
     SerPort.Write(MyMessage, 0, MyMessage.Length); 

     string time = "[" + DateTime.Now.ToString("HH:mm") + "]"; 

     bool debug = chkDebug.Checked; 
     if (debug) f.DebugText = time + " Wrote bytes to serial: " + data; 
    } 

我收到事件功能:

//Called everytime serial data is recieved 
    private void HandleSerialData(object sender, SerialDataReceivedEventArgs e) 
    { 
     try 
     { 
      //Store recieved data in variable 
      SerialPort sp = (SerialPort)sender; 
      string data = sp.ReadExisting().ToString(); 

      bool debug = chkDebug.Checked; 

      string time = "[" + DateTime.Now.ToString("HH:mm") + "]"; 
      if(debug) f.DebugText = time + " Recieved serial data: " + data; 

      switch (data) 
      { 
       case "1": 
       //If Battery is already on 
       if(Battery1[0] == "ON") 
       { 
        Battery1[0] = "OFF"; //ON or OFF 
        Battery1[2] = DateTime.Now.ToString("h:mm tt"); //End time 
        WriteLogFile("1"); 
        lblST1.Text = "n/a"; 
        lblET1.Text = "n/a"; 
        if (debug) f.DebugText = time + " Battery 1 testing switched OFF."; 
       } 
       else 
       { 
        Battery1[0] = "ON"; //ON or OFF 
        Battery1[1] = DateTime.Now.ToString("h:mm tt"); //Start time 
        Battery1[5] = DateTime.Now.ToString("d/MM/yyyy"); //Start date 
        plcRespond = true; 
        lblST1.Text = Battery1[1]; 
         if (debug) f.DebugText = time + " Battery 1 testing switched ON."; 
       } 
       break; 

       case "2": 
       //If Battery is already on 
       if (Battery2[0] == "ON") 
       { 
        Battery2[0] = "OFF"; 
        Battery2[2] = DateTime.Now.ToString("h:mm tt"); //End time 
        WriteLogFile("2"); 
        lblST2.Text = "n/a"; 
        lblET2.Text = "n/a"; 
         if (debug) f.DebugText = time + " Battery 2 testing switched OFF."; 
       } 
       else 
       { 
        Battery2[0] = "ON"; //ON or OFF 
        Battery2[1] = DateTime.Now.ToString("h:mm tt"); //Start time 
        Battery2[5] = DateTime.Now.ToString("d/MM/yyyy"); //Start date 
        plcRespond = true; 
        lblST2.Text = Battery2[1]; 
         if (debug) f.DebugText = time + " Battery 2 testing switched ON."; 
       } 
       break; 

       case "3": 
       //If Battery is already on 
       if (Battery3[0] == "ON") 
       { 
        Battery3[0] = "OFF"; //ON or OFF 
        Battery3[2] = DateTime.Now.ToString("h:mm tt"); //End time 
        WriteLogFile("3"); 
        lblST3.Text = "n/a"; 
        lblET3.Text = "n/a"; 
         if (debug) f.DebugText = time + " Battery 3 testing switched OFF."; 
       } 
       else 
       { 
        Battery3[0] = "ON"; //ON or OFF 
        Battery3[1] = DateTime.Now.ToString("h:mm tt"); //Start time 
        Battery3[5] = DateTime.Now.ToString("d/MM/yyyy"); //Start date 
        plcRespond = true; 
        lblST3.Text = Battery3[1]; 
         if (debug) f.DebugText = time + " Battery 3 testing switched ON."; 
       } 
       break; 

       case "4": 
       //If Battery is already on 
       if (Battery4[0] == "ON") 
       { 
        Battery4[0] = "OFF"; //ON or OFF 
        Battery4[2] = DateTime.Now.ToString("h:mm tt"); //End time 
        WriteLogFile("4"); 
        lblST4.Text = "n/a"; 
        lblET4.Text = "n/a"; 
         if (debug) f.DebugText = time + " Battery 4 testing switched OFF."; 
       } 
       else 
       { 
        Battery4[0] = "ON"; //ON or OFF 
        Battery4[1] = DateTime.Now.ToString("h:mm tt"); //Start time 
        Battery4[5] = DateTime.Now.ToString("d/MM/yyyy"); //Start date 
        plcRespond = true; 
        lblST4.Text = Battery4[1]; 
         if (debug) f.DebugText = time + " Battery 4 testing switched ON."; 
       } 
       break; 

       case "5": 
       //If Battery is already on 
       if (Battery5[0] == "ON") 
       { 
        Battery5[0] = "OFF"; //ON or OFF 
        Battery5[2] = DateTime.Now.ToString("h:mm tt"); //End time 
        WriteLogFile("5"); 
        lblST5.Text = "n/a"; 
        lblET5.Text = "n/a"; 
         if (debug) f.DebugText = time + " Battery 5 testing switched OFF."; 
        } 
       else 
       { 
        Battery5[0] = "ON"; //ON or OFF 
        Battery5[1] = DateTime.Now.ToString("h:mm tt"); //Start time 
        Battery5[5] = DateTime.Now.ToString("d/MM/yyyy"); //Start date 
        plcRespond = true; 
        lblST5.Text = Battery5[1]; 
         if (debug) f.DebugText = time + " Battery 5 testing switched ON."; 
       } 
       break; 

       case "6": 
       //If Battery is already on 
       if (Battery6[0] == "ON") 
       { 
        Battery6[0] = "OFF"; //ON or OFF 
        Battery6[2] = DateTime.Now.ToString("h:mm tt"); //End time 
        WriteLogFile("6"); 
        lblST6.Text = "n/a"; 
        lblET6.Text = "n/a"; 
         if (debug) f.DebugText = time + " Battery 6 testing switched OFF."; 
       } 
       else 
       { 
        Battery6[0] = "ON"; //ON or OFF 
        Battery6[1] = DateTime.Now.ToString("h:mm tt"); //Start time 
        Battery6[5] = DateTime.Now.ToString("d/MM/yyyy"); //Start date 
        plcRespond = true; 
        lblST6.Text = Battery6[1]; 
         if (debug) f.DebugText = time + " Battery 6 testing switched ON."; 
       } 
       break; 
      } 

      SerPort.DiscardInBuffer(); 
      SerPort.DiscardOutBuffer(); 

     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Error recieving COM data! " + ex.Message); 
     } 
    } 

有沒有更好的方式讀取不使用ReadExisting的串行數據?或者使用更可靠的功能?

回答

0

我以前用ReadExisting有問題。如果在讀取緩衝區時有更多數據到達,我不知道在ReadExisting中會發生什麼。

在串口甚至處理程序中我使用下面的代碼。由於它決定了首先讀取的長度,因此在下一次函數調用期間將讀取到達的新數據,以便可以在數據發送的速率下清空緩衝區。

private void HandleSerialData(object sender, SerialDataReceivedEventArgs e) 
{ 
    int lengthToRead = sp.BytesToRead; 
    byte[] rxBytes = new byte[lengthToRead]; 
    sp.Read(rxBytes, 0, lengthToRead); 
    functionThatInterpratesData(rxBytes); 
} 

,這也具有可重複使用的好處,因爲你的字節數組轉換爲字符串或不過你有單獨編碼它。

我會創建一個函數將字節數組轉換爲字符串(大量的例子),另一個處理case語句。

+1

乾杯。我已經用你提供給我的方式。它目前似乎工作正常,並沒有錯過任何讀取。我會稍微回過頭來讓你知道。 – Zack

+0

你是怎麼過的? – MikeS159