C# 通过SerialPort简单调用串口

问题

最近比较经常使用串口进行发送以及传输数据,但是笔者在刚开始接触SerialPort类时,对于Write之后去Read数据的时候,由于设备上面还没有返回数据,读取到的只能是空值。然而,再进行下一次Write操作的时候,可能返回上一次数据和这一次数据。这样使得笔者得到的数据难以保持准确性。

1、解决思路

对于上面的问题,由于数据要实时的进行返回。所以笔者想法就是在Write之后,使用线程等待(Thread.Sleep)去等待数据返回。但是最终等待多久,根据串口传输以及设备返回命令所决定。这个等待的时间是个纠结的事情。笔者就考虑:“可以通过重复相应的次数进行等待,如果等待之后还是没有获取到数据,直接舍去这个数据”。不知道园内有没有更好的解决方案。

2、解决源码

这个插入一个题外话:对于串口的编程,要注意及时的开关,但是笔者要实时获取数据使数据保持一种常开的状态,所以笔者所能想到的就是实现IDisposable接口进行清理。

笔者对于写入与获取数据的核心编码就是在串口数据获取类指定一个内部变量(_isWorking),如果_isWorking 正在工作,就让接下来的Write命令进行等待(等待时长必须长于重复次数的总时长),获取到数据之后,将_isWorking 设置为false。【这里存在一个问题,如果高数据命令情况下,会阻塞!!笔者还未找到好的解决方法】。

好了又扯了这么多,上主要的代码

  /// <summary>
        /// 串口写入数据,并且等待返回值
        /// </summary>
        /// <param name="writeCommandByte">写入命令</param>
        /// <param name="replyData">返回数据</param>
        /// <returns>返回数据偏移位</returns>
        protected int WriteWithReplyData(byte[] writeCommandByte, out byte[] replyData)
        {
            if (writeCommandByte == null)
            {
                throw new ArgumentNullException("writeCommandByte");
            }
            //等待其他发送数据的完成
            var waitTimes = 0;
            while (waitTimes < 4 && _isWorking)
            {
                waitTimes++;
                Thread.Sleep(40);
            }

            //如果超时还是没有等待到,就直接返回
            if (_isWorking)
            {
                replyData = null;
                return 0;
            }
            //开始工作,设置串口工作状态未true
            _isWorking = true;
            _port.Write(writeCommandByte, 0, writeCommandByte.Length);
            replyData = new byte[_port.ReadBufferSize];
            int count = 0;
            var times = 0;
            //等待数据返回,并限制等待时间100ms
            while (times < 5 && count <= 0)
            {
                times++;
                count = _port.Read(replyData, 0, _port.ReadBufferSize);
                if (count <= 0)
                {
                    Thread.Sleep(20);
                }
            }
            //等待得到数据,将工作状态设为false
            _isWorking = false;
            return count;

        }

3、值得考虑

①有没有其他更好的解决方法,解决这个数据等待过程无数据返回或合并数据的返回?

②笔者的解决方式,中间如果命令集密集的话就回存在经常丢数据的情况,有没好的解决方案?

(如果觉得不错请点赞下,有误的话请指出,卤鸽在此感谢)

时间: 2024-12-05 06:04:19

C# 通过SerialPort简单调用串口的相关文章

C#实现简单的串口通信

前言 本着学习研究的态度,用c#语言实现简单的串口通信工具. 一.串口通信原理 串口通信 串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节.尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据.它很简单并且能够实现远距离通信.由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据.其他线用于握手,但不是必须的.串口通信最重要的参数是波特率.数据位.停止位和奇偶校验.对于两个进行通信的

经测试稳定可用的蓝牙链接通信Demo,记录过程中遇到的问题的思考和解决办法,并整理后给出一个Utils类可以简单调用来实现蓝牙功能

说明:这是本人在蓝牙开发过程中遇到过的问题记录和分析,以及解决办法. 在研究过程中,许多的前人给出的解决方案和思路指导对我相当有帮助,但并非都是可采取的解决方法, 经过本人对这些方法的测试和使用过后,给出自己的理解和解决方案,不一定是正确的,但这些方法的确可以解决问题. 如果有人遇到同样的问题,并且看到我的文章解决,那是我的荣幸. !!!!!!但特别需要说明的是,看的越多,不明白的越多,我的看法可能是完全错误的,这些方法只是暂时解决了我的问题, !!!!!!如果有人发现了我的错误,请私信或评论告

利用反射机制,获取类的字段、方法、并实现简单调用

这篇文章是为之后要介绍Android的ICO框架做预备的,所以,如果想最近学习Android的ICO框架的同学,可以稍微看一下. 首先,简单介绍一下Java里面的反射. JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 不知道这样的一段解释,你能否看懂.如果更简单的说,反射就是能够根据你给出类名实例化出一个实实在在的对象.所以,对象的实例

Winform简单调用WebApi

WebAPI  Controllers public class SimuController : ApiController { //EF 5 BIM_GENERALDICTONARY_DBEntities entities=new BIM_GENERALDICTONARY_DBEntities(); // GET api/Simu public IEnumerable<T_BIM_PropityClass> Get() { return entities.T_BIM_PropityClas

AX中API的简单调用

FilePath    folder = "E:\\NewFolder1";    FilePath    filePath;    container   fileInfo;    int         fileHandle;    FileName    _FileName;    ; _FileName = folder;    filePath = _FileName; if (substr(_FileName,strlen(_FileName)-1,1) == '\\') 

Webservice简单调用示例

Webservice简单调用示例 webservice主要是一些站点为我们写好了的方法,供我们调用,当然我们也可以自己去编写自己的webservice,本文主要是通过一个小的实例,去如何调用webservice.下面先给出几个常用的webservice的调用地址. 快递查询接口 http://webservice.36wu.com/ExpressService.asmx ip查询接口 http://webservice.36wu.com/ipService.asmx 天气预报接口 http://

FPGA UART简单的串口接收模块

FPGA UART RX,FPGA设计一个简单的串口接收模块 FPGA UART TX,简单的FPGA串口发送模块

loadrunner做webservice接口之简单调用

今天听大神讲了webservice做接口,我按照他大概讲的意思自己模拟实战了下,可能还有很多不对,一般使用webservice做接口,会使用到soapui,但是用了loadrunner以后发现lr很快捷和简单,如下: 准备webservice测试接口,我用的是天气预报的接口,地址:http://ws.webxml.com.cn/  天气预报接口地址:http://ws.webxml.com.cn/webservices/DomesticAirline.asmx?wsdl,地址可以打开就能看到他的

StreamReader 和 StreamWriter 简单调用

/* ######### ############ ############# ## ########### ### ###### ##### ### ####### #### ### ########## #### #### ########### #### #### ########### ##### ##### ### ######## ##### ##### ### ######## ###### ###### ### ########### ###### ###### #### ###