自定义串口通信类的实现(SerialPort)

  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.     ///  
  14.     /// 串口操作类 
  15.     ///  
  16.     public class CommOp
  17.     {
  18.         private  SerialPort commport ;
  19.         List<byte> list = new List<byte>();
  20.         ///  
  21.         /// 设置标示位,防止close时存在I/O操作 
  22.         ///  
  23.         bool sign = false;
  24.         ///  
  25.         /// 自定义串口操作类构造函数 
  26.         ///  
  27.         ///  
  28.         public CommOp(SerialPort sp)
  29.         {
  30.             this.commport = sp;
  31.         }
  32.         public CommOp()
  33.         { 
  34.         }
  35.         ///  
  36.         /// 连续方式获得磅秤数据,注意磅秤设备应该标定为"连续方式" 
  37.         ///  
  38.         ///  
  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.         }
  81.         ///  
  82.         /// 通过上位机指令方式(由通讯协议获得,如:02 41 42 30 33 03)获取磅秤数据,注意磅秤设备应该标定为"指令方式". 
  83.         ///  
  84.         ///  
  85.         public string GetDataByOrder(byte[] byts)
  86.         {
  87.             string strReceive = "";
  88.             if (sign)
  89.             {   
  90.                 //发送读取指令 
  91.                 commport.Write(byts, 0, byts.Length);
  92.                 //等待数据进入缓冲区 
  93.                 Thread.Sleep(500); 
  94.                 //接收缓冲区中数据的字节数  
  95.                 int int_Len = commport.BytesToRead;
  96.                 //接收数据  
  97.                 byte[] bytes = new byte[int_Len];
  98.                 commport.Read(bytes, 0, int_Len);
  99.                 //将数据存入字符串缓冲区中  
  100.                 if (int_Len >= 12)
  101.                 {
  102.                     for (int i = 0; i < bytes.Length; i++)
  103.                     {
  104.                         list.Add(bytes[i]);
  105.                     }
  106.                     strReceive = System.Text.Encoding.Default.GetString(list.ToArray());
  107.                     list.Clear();
  108.                 }
  109.             }
  110.             return GetWeightData(strReceive, optype.Orders);
  111.         }
  112.         ///  
  113.         /// 根据通讯协定分析传输数据(如,有效数据位,小数点位等) 
  114.         ///  
  115.         ///  
  116.         ///  
  117.         private string GetWeightData(string data,optype type)
  118.         {
  119.             
  120.             double d = 0;
  121.             switch (type)
  122.             {
  123.                 case optype.Orders:
  124.                     d = Convert.ToDouble(data.Substring(4, 6)) / Math.Pow(10, Convert.ToDouble(data.Substring(10, 1)));
  125.                     break;
  126.                 case optype.Continues:
  127.                     d = Convert.ToDouble(data.Substring(1, 6)) / Math.Pow(10, Convert.ToDouble(data.Substring(7, 1)));
  128.                     break;
  129.             }
  130.           return d.ToString().PadLeft(7,'0');
  131.         }
  132.         ///  
  133.         /// 打开串行接口 
  134.         ///  
  135.         public void Open()
  136.         {
  137.            
  138.             try
  139.             {
  140.                 if (!commport.IsOpen)
  141.                 {
  142.                     commport.Open();//打开串口方法  
  143.                     Thread.Sleep(1500);
  144.                     sign = true;
  145.                 }
  146.             }//抛出异常  
  147.             catch (Exception ex)
  148.             {
  149.                 throw new Exception(ex.Message);
  150.             }
  151.         }
  152.         ///  
  153.         /// 关闭串行接口 
  154.         ///  
  155.         public void Close()
  156.         {
  157.             try
  158.             {
  159.                 if (commport.IsOpen)
  160.                 {
  161.                     sign = false;
  162.                     Thread.Sleep(1500);
  163.                     commport.DiscardInBuffer();
  164.                     commport.Close();
  165.                 }
  166.             }
  167.             catch (Exception ex)
  168.             {
  169.                 throw new Exception(ex.Message);
  170.             }
  171.         }
  172.     }
  173. }

这里采用了两种方式进去读取:

1.连续方式:只要磅秤显示有数据,数据就会源源不断的抛入缓冲区,电脑则可以在此时进行读取并分析。通常可以采用serialPort的DataReceived事件处理。

   优点:实时性好。

   缺点:数据过多,分析效果不太好。

2.指令方式:联机电脑发送读取指令给磅秤,磅秤则发送相应的数据信息到缓冲区(没有其他信息),我们可以获取并分析。

    优点:数据单一,分析容易

     缺点:需要手动更新获取数据(可以结合Timer组件实现实时更新数据的效果)。

 

你可能感兴趣的:(自定义串口通信类的实现(SerialPort))