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

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

 

/// <summary>
/// 保持读取开关
/// </summary>
bool  _keepReading;

/// <summary>
/// 检测频率【检测等待时间,毫秒】【按行读取,可以不用】
/// </summary>
int  _jcpl =  1 ;

/// <summary>
/// 串口
/// </summary>
SerialPort _sp =  new  SerialPort();

/// <summary>
/// 字符串队列【.NET Framework 4.0以上】
/// </summary>
ConcurrentQueue< string > _cq =  new  ConcurrentQueue< string >();

/// <summary>
/// 字节数据队列
/// </summary>
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

 

/// <summary>
/// 串口读取方法
/// </summary>
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

 

/// <summary>
/// 数据解析
/// </summary>
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的参数配置和资源释放,就先不写了。这个一般情况下都会。

点赞
收藏

评论区

加载中...

相关推荐

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

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java将前端的json数组字符串转换为列表

记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang

皕杰报表(关于日期时间时分秒显示不出来)

在使用皕杰报表设计器时,数据据里面是日期型,但当你web预览时候,发现有日期时间类型的数据时分秒显示不出来,只有年月日能显示出来,时分秒显示为0:00:00。1.可以使用tochar解决,数据集用selecttochar(flowdate,"yyyyMMddHH:mm:ss")fromtablename2.也可以把数据库日期类型date改成timestamp

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