Qt串口通信接收数据不完整的解决方法

版权声明:本文为灿哥哥http://blog.youkuaiyun.com/caoshangpa原创文章,转载请标明出处。 https://blog.youkuaiyun.com/caoshangpa/article/details/50915005
在使用串口接收数据时,当数据量大的时候会出现数据接收不完整的情况。因为串口数据获取函数readAll()由readyRead()信号触发,但readyRead()信号在串口读到起始标志时立即发送,并不保证一定是当前所发数据的起始部分。因此串口通信双方在通信前应制定好通信协议,规定好数据的起始和结束标志,串口当读到完整的起始和结束标志之后,才认定读完一条完整的数据。

本例中用串口定时发送当前时间,用"#"表示数据的结尾,定时时间为0毫秒,即能发多快就发多快。
//发送
void Widget::slotSendData()
{
    QByteArray temp;
    temp.append(getCurrentTime());
    temp.append("#");
    serialPort->write(temp);
}

//接收
void Widget::slotReadData()
{
    QByteArray temp = serialPort->readAll();
 
    if(!temp.isEmpty())
    {
        byteArray.append(temp);
        if(byteArray.contains("#"))
        {
            ui->textEditReceive->setText(byteArray.split('#').at(0));
            byteArray = byteArray.right(byteArray.length()-byteArray.indexOf('#')-1);
        }
    }
}

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

代码如下所示:

void Widget::slotSendData()
{
    matrix.rotate(90);
    QPixmap tempPixmap = pixmap.transformed(matrix);
    QBuffer buffer;
    tempPixmap.save(&buffer,"jpg");
    ui->labelImage->setPixmap(tempPixmap);
 
    char *data=(char*)buffer.data().data();
    int dataLength=buffer.data().length();
    //打印图片大小
    qDebug()<<"Image Size:"<<dataLength;
    int standPacketSize=120;
    int packetSize=0;
    int packetNum=ceil(dataLength/120.0);
 
    if(dataLength>120)
    {
        for(int i=0;i<packetNum;i++)
        {
            if(standPacketSize*(i+1)<dataLength)
            {
                packetSize=standPacketSize;
            }
            else
            {
                packetSize=dataLength-standPacketSize*i;
 
            }
 
            serialPort->write(data,packetSize);
            data=data+packetSize;
        }
    }
 
    serialPort->write("###",3);
}

运行效果如下图所示:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值