1. 程式人生 > >C#自定義串列埠通訊類的實現

C#自定義串列埠通訊類的實現

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.IO.Ports;
  5. using System.Threading;
  6. namespace CommPort
  7. {
  8.     enum optype
  9.     {
  10.         Continues,
  11.         Orders
  12.     }
  13.     /// <summary> 
  14.     /// 串列埠操作類 
  15.     /// </summary> 
  16.     public class CommOp
  17.     {
  18.         private  SerialPort commport ;
  19.         List<byte> list = new List<byte>();
  20.         /// <summary> 
  21.         /// 設定標示位,防止close時存在I/O操作 
  22.         /// </summary> 
  23.         bool sign = false;
  24.         /// <summary> 
  25.         /// 自定義串列埠操作類建構函式 
  26.         /// </summary> 
  27.         /// <param name="sp"></param> 
  28.         public CommOp(SerialPort sp)
  29.         {
  30.             this.commport = sp;
  31.         }
  32.         public CommOp()
  33.         { 
  34.         }
  35.         /// <summary> 
  36.         /// 連續方式獲得磅秤資料,注意磅秤裝置應該標定為"連續方式" 
  37.         /// </summary> 
  38.         /// <returns></returns> 
  39.         public string GetContinueData()
  40.         {
  41.             string strReceive = "";
  42.             if (sign)
  43.             {
  44.                 byte firstbyte = Convert.ToByte(commport.ReadByte());
  45.                 //判斷第一個位元組是否是起始位:16進位制的0x02  
  46.                 if (firstbyte == 0x02)
  47.                 {
  48.                     //定義接收資料長度  
  49.                     int bytesRead = 10;
  50.                     //資料接收位元組陣列  
  51.                     byte[] bytesData = new byte[bytesRead];
  52.                     //接收位元組  
  53.                     byte byteData;
  54.                     for (int i = 0; i <= bytesRead - 1; i++)
  55.                     {
  56.                         try
  57.                         {
  58.                             if (commport.IsOpen)
  59.                             {
  60.                                 byteData = Convert.ToByte(commport.ReadByte());
  61.                                 //判斷資料結束位元組  
  62.                                 if (byteData == 0x03)
  63.                                 {
  64.                                     break;
  65.                                 }
  66.                                 bytesData[i] = byteData;
  67.                             }
  68.                         }
  69.                         catch (Exception ex)
  70.                         {
  71.                             throw new Exception(ex.Message);
  72.                         }
  73.                     }
  74.                     //將位元組陣列轉換成字串  
  75.                     strReceive = System.Text.Encoding.Default.GetString(bytesData);
  76.                 }
  77.             }
  78.             return GetWeightData(strReceive, optype.Continues);
  79.         }
  80.         /// <summary> 
  81.         /// 通過上位機指令方式(由通訊協議獲得,如:02 41 42 30 33 03)獲取磅秤資料,注意磅秤裝置應該標定為"指令方式". 
  82.         /// </summary> 
  83.         /// <returns></returns> 
  84.         public string GetDataByOrder(byte[] byts)
  85.         {
  86.             string strReceive = "";
  87.             if (sign)
  88.             {   
  89.                 //傳送讀取指令 
  90.                 commport.Write(byts, 0, byts.Length);
  91.                 //等待資料進入緩衝區 
  92.                 Thread.Sleep(500); 
  93.                 //接收緩衝區中資料的位元組數  
  94.                 int int_Len = commport.BytesToRead;
  95.                 //接收資料  
  96.                 byte[] bytes = new byte[int_Len];
  97.                 commport.Read(bytes, 0, int_Len);
  98.                 //將資料存入字串緩衝區中  
  99.                 if (int_Len >= 12)
  100.                 {
  101.                     for (int i = 0; i < bytes.Length; i++)
  102.                     {
  103.                         list.Add(bytes[i]);
  104.                     }
  105.                     strReceive = System.Text.Encoding.Default.GetString(list.ToArray());
  106.                     list.Clear();
  107.                 }
  108.             }
  109.             return GetWeightData(strReceive, optype.Orders);
  110.         }
  111.         /// <summary> 
  112.         /// 根據通訊協定分析傳輸資料(如,有效資料位,小數點位等) 
  113.         /// </summary> 
  114.         /// <param name="data"></param> 
  115.         /// <returns></returns> 
  116.         private string GetWeightData(string data,optype type)
  117.         {
  118.             double d = 0;
  119.             switch (type)
  120.             {
  121.                 case optype.Orders:
  122.                     d = Convert.ToDouble(data.Substring(4, 6)) / Math.Pow(10, Convert.ToDouble(data.Substring(10, 1)));
  123.                     break;
  124.                 case optype.Continues:
  125.                     d = Convert.ToDouble(data.Substring(1, 6)) / Math.Pow(10, Convert.ToDouble(data.Substring(7, 1)));
  126.                     break;
  127.             }
  128.           return d.ToString().PadLeft(7,'0');
  129.         }
  130.         /// <summary> 
  131.         /// 開啟序列介面 
  132.         /// </summary> 
  133.         public void Open()
  134.         {
  135.             try
  136.             {
  137.                 if (!commport.IsOpen)
  138.                 {
  139.                     commport.Open();//開啟串列埠方法  
  140.                     Thread.Sleep(1500);
  141.                     sign = true;
  142.                 }
  143.             }//丟擲異常  
  144.             catch (Exception ex)
  145.             {
  146.                 throw new Exception(ex.Message);
  147.             }
  148.         }
  149.         /// <summary> 
  150.         /// 關閉序列介面 
  151.         /// </summary> 
  152.         public void Close()
  153.         {
  154.             try
  155.             {
  156.                 if (commport.IsOpen)
  157.                 {
  158.                     sign = false;
  159.                     Thread.Sleep(1500);
  160.                     commport.DiscardInBuffer();
  161.                     commport.Close();
  162.                 }
  163.             }
  164.             catch (Exception ex)
  165.             {
  166.                 throw new Exception(ex.Message);
  167.             }
  168.         }
  169.     }
  170. }

這裡採用了兩種方式進去讀取:

1.連續方式:只要磅秤顯示有資料,資料就會源源不斷的拋入緩衝區,電腦則可以在此時進行讀取並分析。通常可以採用serialPort的DataReceived事件處理。

   優點:實時性好。

   缺點:資料過多,分析效果不太好。

2.指令方式:聯機電腦傳送讀取指令給磅秤,磅秤則傳送相應的資料資訊到緩衝區(沒有其他資訊),我們可以獲取並分析。

    優點:資料單一,分析容易

     缺點:需要手動更新獲取資料(可以結合Timer元件實現實時更新資料的效果)。