C# SerialPort串口接收 丢数据 数据不完整的解决方法

Stella981
• 阅读 1413

C# SerialPort的 DataReceived事件,可能是存在问题,使用时,数据丢失,造成数据不完整。

解决方法思路:

使用独立线程读取数据,把串口缓冲区的数据,读取到程序中。抛开DataReceived事件。

使用其它线程获取“串口中读取的数据”再进行解析。

客户程序由被动触发,改为主动获取。

相关变量、对象

 C# Code 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

 

/// 


/// 保持读取开关
/// 

bool  _keepReading;

/// 


/// 检测频率【检测等待时间,毫秒】【按行读取,可以不用】
/// 

int  _jcpl =  1 ;

/// 


/// 串口
/// 

SerialPort _sp =  new  SerialPort();

/// 


/// 字符串队列【.NET Framework 4.0以上】
/// 

ConcurrentQueue< string > _cq =  new  ConcurrentQueue< string >();

/// 


/// 字节数据队列
/// 

ConcurrentQueue< byte []> _cqBZ =  new  ConcurrentQueue< byte []>();

串口读取方法【ViewCommStatus,自定义方法,串口读取状态输出】

 C# Code 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

 

/// 


/// 串口读取方法
/// 

void  SerialPortRead()
{
     while  (_keepReading)
    {
         if  (_jcpl >  0 ) //按行读取可以省略
{
            Thread.Sleep(_jcpl);
        } if  (_sp ==  null )
        {
            ViewCommStatus( false ,  "串口对象未实例化!" );
            Thread.Sleep( 3000 ); //3秒后重新检测
continue ;
        }
         if  (!_sp.IsOpen)
        {
            ViewCommStatus( false ,  "串口未打开" );
            Thread.Sleep( 3000 );
             continue ;
        }

         try { #region  按行读取
             string  buffer = _sp.ReadLine();
             if  (! string .IsNullOrEmpty(buffer)) //可以不加判断,允许添加null值,数据解析时,再做判断。
{
                _cq.Enqueue(buffer);
            } #endregion //#region 字节读取
//byte[] readBuffer = new byte[_sp.ReadBufferSize + 1];
//int count = _sp.Read(readBuffer, 0, _sp.ReadBufferSize);
//if (count != 0)
//{
//    _cqBZ.Enqueue(readBuffer);
//}
//#endregion
ViewCommStatus( true ,  "串口通信正常" );
        }
         catch  (TimeoutException) //注意超时时间的定义
{
            ViewCommStatus( false ,  "串口读取超时!" );
        }
         catch  (Exception ex) //排除隐患后可以去掉。
{
            ViewCommStatus( false ,  "串口读取异常:"  + ex.Message);
        }

    }
}

 数据解析方法

 C# Code 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

 

/// 


/// 数据解析
/// 

void  DataAnalysis()
{
     while  ( true )
    {
        Thread.Sleep( 10 );

         if  (_cq.IsEmpty)
        {
             continue ;
        }

         #region  按行读取
         for  ( int  i =  0 ; i < _cq.Count; i++)
        {
             string  strTmp =  "" ;
            _cq.TryDequeue( out  strTmp);
             //解析strTmp
//解析strTmp
//解析strTmp
} #endregion #region  按字节读取
         //StringBuilder sb = new StringBuilder();
//for (int i = 0; i < _cq.Count; i++)
//{
//    byte[] bt = null;
//    _cqBZ.TryDequeue(out bt);
//    string strTmp = System.Text.Encoding.ASCII.GetString(bt);
//    sb.Append(strTmp);
//}
////解析sb
////解析sb
////解析sb
#endregion }

}

调用示例

 C# Code 

1
2
3
4
5
6
7
8
9
10
11

 

void  StartRead()
{
    _keepReading =  true ;

    Thread trdRead =  new  Thread(SerialPortRead);
    trdRead.Start();

    Thread trdDataAnalysis =  new  Thread(DataAnalysis);
    trdDataAnalysis.Start();
}

SerialPort的参数配置和资源释放,就先不写了。这个一般情况下都会。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Java修道之路,问鼎巅峰,我辈代码修仙法力齐天
<center<fontcolor00FF7Fsize5face"黑体"代码尽头谁为峰,一见秃头道成空。</font<center<fontcolor00FF00size5face"黑体"编程修真路破折,一步一劫渡飞升。</font众所周知,编程修真有八大境界:1.Javase练气筑基2.数据库结丹3.web前端元婴4.Jav
皕杰报表(关于日期时间时分秒显示不出来)
在使用皕杰报表设计器时,数据据里面是日期型,但当你web预览时候,发现有日期时间类型的数据时分秒显示不出来,只有年月日能显示出来,时分秒显示为0:00:00。1.可以使用tochar解决,数据集用selecttochar(flowdate,"yyyyMMddHH:mm:ss")fromtablename2.也可以把数据库日期类型date改成timestamp
Stella981 Stella981
3年前
JS 苹果手机日期显示NaN问题
问题描述newDate("2019122910:30:00")在IOS下显示为NaN原因分析带的日期IOS下存在兼容问题解决方法字符串替换letdateStr"2019122910:30:00";datedateStr.repl
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这