• Qt串口通信接收数据不完整的解决方法(传输图片)


        在使用串口接收数据时,当数据量大的时候会出现数据接收不完整的情况。因为串口数据获取函数readAll()由readyRead()信号触发,但readyRead()信号在串口读到起始标志时立即发送,并不保证一定是当前所发数据的起始部分。因此串口通信双方在通信前应制定好通信协议,规定好数据的起始和结束标志,串口当读到完整的起始和结束标志之后,才认定读完一条完整的数据。

        本例中用串口定时发送当前时间,用"#"表示数据的结尾,定时时间为0毫秒,即能发多快就发多快。

    //发送

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:18px;">void Widget::slotSendData()  
    2. {  
    3.     QByteArray temp;  
    4.     temp.append(getCurrentTime());  
    5.     temp.append("#");  
    6.     serialPort->write(temp);  
    7. }</span>  

    //接收

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:18px;">void Widget::slotReadData()  
    2. {  
    3.     QByteArray temp = serialPort->readAll();  
    4.   
    5.     if(!temp.isEmpty())  
    6.     {  
    7.         byteArray.append(temp);  
    8.         if(byteArray.contains("#"))  
    9.         {  
    10.             ui->textEditReceive->setText(byteArray.split('#').at(0));  
    11.             byteArray = byteArray.right(byteArray.length()-byteArray.indexOf('#')-1);  
    12.         }  
    13.     }  
    14. }</span>  

    源码链接:http://download.csdn.net/detail/caoshangpa/9464700

    ===============2016.10.14更新==============

    补充一个通过串口传输图片的例子,这里假设波特率为9600,那么一秒钟就能传输9600/8=1200字节。代码中将定时器设置为1秒,所以选择的图片应该小于1200字节。这里为了演示如何完整接收数据,将图片按照指定大小分段发送,在每段之后紧接着发送字符串“###”。

    代码如下所示:

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. void Widget::slotSendData()  
    2. {  
    3.     matrix.rotate(90);  
    4.     QPixmap tempPixmap = pixmap.transformed(matrix);  
    5.     QBuffer buffer;  
    6.     tempPixmap.save(&buffer,"jpg");  
    7.     ui->labelImage->setPixmap(tempPixmap);  
    8.   
    9.     char *data=(char*)buffer.data().data();  
    10.     int dataLength=buffer.data().length();  
    11.     //打印图片大小  
    12.     qDebug()<<"Image Size:"<<dataLength;  
    13.     int standPacketSize=120;  
    14.     int packetSize=0;  
    15.     int packetNum=ceil(dataLength/120.0);  
    16.   
    17.     if(dataLength>120)  
    18.     {  
    19.         for(int i=0;i<packetNum;i++)  
    20.         {  
    21.             if(standPacketSize*(i+1)<dataLength)  
    22.             {  
    23.                 packetSize=standPacketSize;  
    24.             }  
    25.             else  
    26.             {  
    27.                 packetSize=dataLength-standPacketSize*i;  
    28.   
    29.             }  
    30.   
    31.             serialPort->write(data,packetSize);  
    32.             data=data+packetSize;  
    33.         }  
    34.     }  
    35.   
    36.     serialPort->write("###",3);  
    37. }  

    运行效果如下图所示:

    操作顺序1——》2——》3,左边的实例就会加载目录中的1.JPG并发送给右边的实例,图片每秒钟旋转90°。

    源码链接:http://download.csdn.net/detail/caoshangpa/9653821

    http://blog.csdn.net/caoshangpa/article/details/50915005

  • 相关阅读:
    设置Linux环境的欢迎登陆信息
    负载均衡实现之随机数
    数据库连接池原理分析及模拟实现
    SpringBoot入门 (十四) Security安全控制
    SpringBoot入门 (十三) WebSocket使用
    SpringBoot入门 (十二) 定时任务
    SpringBoot入门 (十一) 数据校验
    SpringBoot入门 (十) 发送邮件
    SpringBoot入门 (九) MQ使用
    SpringBoot入门 (八) Cache使用
  • 原文地址:https://www.cnblogs.com/findumars/p/5979344.html
Copyright © 2020-2023  润新知