C#自定義串列埠通訊類的實現
阿新 • • 發佈:2019-02-11
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.IO.Ports;
- using System.Threading;
- namespace CommPort
- {
- enum optype
- {
- Continues,
- Orders
- }
- /// <summary>
- /// 串列埠操作類
- /// </summary>
- public class CommOp
- {
- private SerialPort commport ;
- List<byte> list = new List<byte>();
- /// <summary>
- /// 設定標示位,防止close時存在I/O操作
- /// </summary>
- bool sign = false;
- /// <summary>
- /// 自定義串列埠操作類建構函式
- /// </summary>
- /// <param name="sp"></param>
- public CommOp(SerialPort sp)
- {
- this.commport = sp;
- }
- public CommOp()
- {
- }
- /// <summary>
- /// 連續方式獲得磅秤資料,注意磅秤裝置應該標定為"連續方式"
- /// </summary>
- /// <returns></returns>
- public string GetContinueData()
- {
- string strReceive = "";
- if (sign)
- {
- byte firstbyte = Convert.ToByte(commport.ReadByte());
- //判斷第一個位元組是否是起始位:16進位制的0x02
- if (firstbyte == 0x02)
- {
- //定義接收資料長度
- int bytesRead = 10;
- //資料接收位元組陣列
- byte[] bytesData = new byte[bytesRead];
- //接收位元組
- byte byteData;
- for (int i = 0; i <= bytesRead - 1; i++)
- {
- try
- {
- if (commport.IsOpen)
- {
- byteData = Convert.ToByte(commport.ReadByte());
- //判斷資料結束位元組
- if (byteData == 0x03)
- {
- break;
- }
- bytesData[i] = byteData;
- }
- }
- catch (Exception ex)
- {
- throw new Exception(ex.Message);
- }
- }
- //將位元組陣列轉換成字串
- strReceive = System.Text.Encoding.Default.GetString(bytesData);
- }
- }
- return GetWeightData(strReceive, optype.Continues);
- }
- /// <summary>
- /// 通過上位機指令方式(由通訊協議獲得,如:02 41 42 30 33 03)獲取磅秤資料,注意磅秤裝置應該標定為"指令方式".
- /// </summary>
- /// <returns></returns>
- public string GetDataByOrder(byte[] byts)
- {
- string strReceive = "";
- if (sign)
- {
- //傳送讀取指令
- commport.Write(byts, 0, byts.Length);
- //等待資料進入緩衝區
- Thread.Sleep(500);
- //接收緩衝區中資料的位元組數
- int int_Len = commport.BytesToRead;
- //接收資料
- byte[] bytes = new byte[int_Len];
- commport.Read(bytes, 0, int_Len);
- //將資料存入字串緩衝區中
- if (int_Len >= 12)
- {
- for (int i = 0; i < bytes.Length; i++)
- {
- list.Add(bytes[i]);
- }
- strReceive = System.Text.Encoding.Default.GetString(list.ToArray());
- list.Clear();
- }
- }
- return GetWeightData(strReceive, optype.Orders);
- }
- /// <summary>
- /// 根據通訊協定分析傳輸資料(如,有效資料位,小數點位等)
- /// </summary>
- /// <param name="data"></param>
- /// <returns></returns>
- private string GetWeightData(string data,optype type)
- {
- double d = 0;
- switch (type)
- {
- case optype.Orders:
- d = Convert.ToDouble(data.Substring(4, 6)) / Math.Pow(10, Convert.ToDouble(data.Substring(10, 1)));
- break;
- case optype.Continues:
- d = Convert.ToDouble(data.Substring(1, 6)) / Math.Pow(10, Convert.ToDouble(data.Substring(7, 1)));
- break;
- }
- return d.ToString().PadLeft(7,'0');
- }
- /// <summary>
- /// 開啟序列介面
- /// </summary>
- public void Open()
- {
- try
- {
- if (!commport.IsOpen)
- {
- commport.Open();//開啟串列埠方法
- Thread.Sleep(1500);
- sign = true;
- }
- }//丟擲異常
- catch (Exception ex)
- {
- throw new Exception(ex.Message);
- }
- }
- /// <summary>
- /// 關閉序列介面
- /// </summary>
- public void Close()
- {
- try
- {
- if (commport.IsOpen)
- {
- sign = false;
- Thread.Sleep(1500);
- commport.DiscardInBuffer();
- commport.Close();
- }
- }
- catch (Exception ex)
- {
- throw new Exception(ex.Message);
- }
- }
- }
- }
這裡採用了兩種方式進去讀取:
1.連續方式:只要磅秤顯示有資料,資料就會源源不斷的拋入緩衝區,電腦則可以在此時進行讀取並分析。通常可以採用serialPort的DataReceived事件處理。
優點:實時性好。
缺點:資料過多,分析效果不太好。
2.指令方式:聯機電腦傳送讀取指令給磅秤,磅秤則傳送相應的資料資訊到緩衝區(沒有其他資訊),我們可以獲取並分析。
優點:資料單一,分析容易
缺點:需要手動更新獲取資料(可以結合Timer元件實現實時更新資料的效果)。