C# 之 串口数据侦听的实现

  当需要编程操纵硬件时会遇到过这样的问题,就是通过串口来接收硬件发来的数据,或是通过串口向硬件发送某种格式的命令。在C#平台上,可以通过 System.IO.Ports 命名空间下的SerialPort 类来实现。

  下面是我做过的一个简单的示例,首先获取本机关联的串行端口列表,然后获取配置文件中配置的COM端口,检查是否在本机串行端口列表中,若在列表中则进一步实例化串口对象,并为串口对象指定数据接收事件来实现监听,示例代码如下:

using System.IO.Ports;
namespace SerialTest
{
  public class SerialTest
  {
       #region 串口监听

        private SerialPort serialPort = null;
        /// <summary>
        /// 开启串口监听
        /// </summary>
        private void StartSerialPortMonitor()
        {
            List<string> comList = GetComlist(false); //首先获取本机关联的串行端口列表
       if (comList.Count == 0)
            {
                DialogForm.Show("提示信息", "当前设备不存在串行端口!");
                System.Environment.Exit(0); //彻底退出应用程序   
            }
            else
            {
                string targetCOMPort = ConfigurationManager.AppSettings["COMPort"].ToString();
                //判断串口列表中是否存在目标串行端口
                if (!comList.Contains(targetCOMPort))
                {
                    DialogForm.Show("提示信息", "当前设备不存在配置的串行端口!");
                    System.Environment.Exit(0); //彻底退出应用程序   
                }

                serialPort = new SerialPort();

                //设置参数
                serialPort.PortName = ConfigurationManager.AppSettings["COMPort"].ToString(); //通信端口
                serialPort.BaudRate = Int32.Parse(ConfigurationManager.AppSettings["BaudRate"].ToString()); //串行波特率
                serialPort.DataBits = 8; //每个字节的标准数据位长度
                serialPort.StopBits = StopBits.One; //设置每个字节的标准停止位数
                serialPort.Parity = Parity.None; //设置奇偶校验检查协议
                serialPort.ReadTimeout = 3000; //单位毫秒
                serialPort.WriteTimeout = 3000; //单位毫秒
                //串口控件成员变量,字面意思为接收字节阀值,
                //串口对象在收到这样长度的数据之后会触发事件处理函数
                //一般都设为1
                serialPort.ReceivedBytesThreshold = 1;
                serialPort.DataReceived += new SerialDataReceivedEventHandler(CommDataReceived); //设置数据接收事件(监听)

                try
                {
                    serialPort.Open(); //打开串口
                }
                catch (Exception ex)
                {
                    DialogForm.Show("提示信息", "串行端口打开失败!具体原因:" + ex.Message);
                    System.Environment.Exit(0); //彻底退出应用程序   
                }
            }
        }

        /// <summary>
        /// 串口数据处理函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void CommDataReceived(Object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                //Comm.BytesToRead中为要读入的字节长度
                int len = serialPort.BytesToRead;
                Byte[] readBuffer = new Byte[len];
                serialPort.Read(readBuffer, 0, len); //将数据读入缓存
                //处理readBuffer中的数据,自定义处理过程
                string msg = encoding.GetString(readBuffer, 0, len); //获取出入库产品编号
                DialogForm.Show("接收到的信息", msg);
            }
            catch(Exception ex)
            {
                DialogForm.Show("提示信息", "接收返回消息异常!具体原因:" + ex.Message);
            }
        }

        /// <summary>
        /// 关闭串口
        /// </summary>
        private void Stop()
        {
            serialPort.Close();
        }

        /// <summary>
        /// 获取本机串口列表
        /// </summary>
        /// <param name="isUseReg"></param>
        /// <returns></returns>
        private List<string> GetComlist(bool isUseReg)
        {
            List<string> list = new List<string>();
            try
            {
                if (isUseReg)
                {
                    RegistryKey RootKey = Registry.LocalMachine;
                    RegistryKey Comkey = RootKey.OpenSubKey(@"HARDWARE\DEVICEMAP\SERIALCOMM");

                    String[] ComNames = Comkey.GetValueNames();

                    foreach (String ComNamekey in ComNames)
                    {
                        string TemS = Comkey.GetValue(ComNamekey).ToString();
                        list.Add(TemS);
                    }
                }
                else
                {
                    foreach (string com in SerialPort.GetPortNames())  //自动获取串行口名称  
                        list.Add(com);
                }
            }
            catch
            {
                DialogForm.Show("提示信息", "串行端口检查异常!");
                System.Environment.Exit(0); //彻底退出应用程序   
            }
            return list;
        }  

        #endregion 串口监听
  }
}
时间: 2024-10-06 14:57:04

C# 之 串口数据侦听的实现的相关文章

静动态侦听及报错

今天在玩测试环境的时候,有好几个侦听端口,我就嫌麻烦,他多余的删除了.只留下一个默认的LISTENER,结果发生了错误. 无法连接,我的服务器ip为:192.168.1.2 报错:目标主机不可达, 意思很明显,就是ip问题.我查看了一下本地ip和两个配置侦听的参数,发现ip都没有问题: 我就去用grid用户登录打开侦听配置界面在netmgr里面把listener的实例名改为固定ip地址 然后发现有出现新的错误: 发现目标地址正在使用????我想,那不是废话吗,我服务器ip就是当前配置的ip地址呀

Binding自动侦听

WPF的强大之一就是数据绑定,Binding是数据桥梁,它的两端是分别是源(Source)和目标(Target),一个简单的类的属性值发生变化,会自动反映在UI界面上,这个属性就是Binding的Path路径,那么如何自动反映在UI界面上的呢?其实就是数据源要实现INotifyPropertyChanged接口,其属性的set语句中实现一个PropertyChanged事件,当为Binding设置数据源后,Binding就会自动侦听来自这个接口的PropertyChanged事件 看看下面例子,

WEB页获取串口数据

最近做一个B/S的项目,需要读取电子秤的值,之前一直没做过,也没有经验,于是在网上找到很多  大致分两种 使用ActiveX控件,JS调用MSCOMM32.dll的串口控件对串口进行控制 使用C#语言的控件对串口进行控制,然后使用JS+AJAX与C#进行交互获得串口数据 详情见  使用JS获得串口数据 http://blog.csdn.net/xuing/article/details/6688306    但是小弟用这两种办法都获取到数据 串口配置如下: 1 serialPort1.PortN

怎么配置 Oracle 侦听器来使用SQL操作ST_Geometry

关于这个内容,其实从ArcSDE9.2推出ST_Geometry就让用户感到很有吸引力,而且特别是在ArcSDE9.3之后,用户使用SQL操作ST_geometry越来越多,但是在配置Oracle监听来说总是碰到这样那样的问题,以下就是总结一下配置 Oracle 侦听器来使用SQL操作ST_Geometry . 首先说明一下:如果你的ArcSDE版本是9.2最好不要使用这种方式,因为Bug也是比较多的. 例如:http://support.esri.com/en/knowledgebase/te

VueJs(7)---计算属性和侦听器

计算属性和侦听器 一. 概述 计算属性 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护.例如: <div id="example"> {{ message.split('').reverse().join('') }} </div> 在这个地方,模板不再是简单的声明式逻辑.你必须看一段时间才能意识到,这里是想要显示变量 message 的翻转字符串.当你想要在模板中多次引用此处的翻转字符串时,就会更加难以

Vue.js学习日记(3)——计算属性和侦听器

1.计算属性 模板不仅可以是简单的声明式逻辑,也可以是较为复杂的表达式. <div id="element"> <!--简单声明--> {{message}} <!--复杂表达式,表示变量message的翻转字符串--> {{message.split('').reverse().join('')}} </id> 如果表达式过于复杂,将不利于直接理解.当需要在模板中多次引用message的翻转字符串时,操作也会变得繁琐. 所以,对于任何复

VUE 计算属性 vs 侦听属性

计算属性 vs 侦听属性 Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性.当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 AngularJS.然而,通常更好的做法是使用计算属性而不是命令式的 watch 回调.细想一下这个例子: <div id="demo">{{ fullName }}</div> var vm = new Vue({ el: '#demo', data: { fi

Vue计算属性和侦听器

计算属性 模板内的表达式非常便利,但是在模板中放入太多的逻辑会让模板过重切难以维护.对于任何复杂逻辑都应该使用计算属性. <p>{{ reverseMsg }}</> var vm = new Vue({ el: '#example', data: { message: 'hello' }, computed: { reverseMsg: function() { return this.message } } }) 这里声明一个计算属性reverseMsg.我们提供的函数将作用属

侦听对象 watch

处理依赖,Vue还提供了另外一种处理依赖的方法:侦听对象.再computed属性里面,我们设置需要计算的属性,而在函数里面设置计算这个属性的逻辑,侦听属性采用的则是另外一种机制,把想要侦听的属性名称设置为键,这里就是counter这个键,必须与属性名称相同,这里就是data属性中的counter属性,在函数中指定counter属性变化时需要执行的代码,Vue会自动把属性变化之后的数值传递给该函数,以允许我们对属性变化做出反应,所以这里我也可以通过设置一个全局输出变量来实现,有时可能确实得这样,比