接收串口数据
首先我们需要在Qt项目中对串口模块的使用做出相关的配置。(配置详情可参考Qt实现简单串口编辑器)然后制定相关的信号与槽函数来接收串口向我们发来的数据。
//定义信号接收槽(用于接收PSD向计算机发来的数据)**************************************************************************
connect(&mSerialPort,&QSerialPort::readyRead,
[=]()
{
//接收到PSD发送来的一条数据
QByteArray temp = mSerialPort.readAll().toHex();
info.append(temp);
if(info.length() == 36){
//检查校验和
if(checkRight(info)){
//处理数据
qDebug() << "success data";
QString x = hexstrtoflo1(info,1);
QString y = hexstrtoflo1(info,2);
tableShow(x,y);
}else{
//抛弃数据
qDebug() << "worse data";
QString x = hexstrtoflo1(info,1);
QString y = hexstrtoflo1(info,2);
tableShow(x,y);
}
}
});
- 由于串口向我们发送的为字节数据,所以我们需要使用QByteArray对数据进行接收。(QSerialPort::toHex()就是将数据以16进制转换接收),需要注意的是:串口并不会一次性发送整条数据,它可能将帧头,数据,校验位等信息分多次发送。所以我们需要进行判断,当数据量达到协议规定后方定义为一条完整的数据(当然可以根据帧头针尾来判断是否为一条合格的数据)。
- 拿到数据后我们需要根据协议设计来检查校验和,以此判断数据是否存在偏差。根据判断的返回值来决定存储数据还是抛弃数据。
- **hexstrtoflo1()**函数是用来从收到的数据中提取有用的数据信息。
接下来我们将详细描述如何提取信息,并进行转化存储。
首先我们应了解QByteArray::at()函数,用来提取相应位的数据以便于解析。
QString checkStr = "";
for(int i = 16;i < 24;i=i+2){
checkStr += QString(infodata.at(i))+QString(infodata.at(i+1));
}
我们每次取出一个字节,按协议内容依次循环取出所有字节数据并拼接为字符串。例如:需提取4字节数据,并将它们转化为浮点数进行展示。
unsigned char byteArray[4];
unsigned char *pf;
unsigned char i; //计数器
unsigned char j; //计数器
for(i = 0,j = 0;i < 8;i = i+2,j++){
QString str = checkStr.mid(i,2);
bool checkok;
int checkval=str.toInt(&checkok,16);//以16进制数读入
pf =(unsigned char*)&checkval; /*unsigned char型指针取得浮点数的首地址*/
byteArray[j]=*pf; /*使用unsigned char型指针从低地址一个字节一个字节取出*/
}
float x = *((float*)byteArray);
qDebug("\n%f ",x);
我们需要将字符串中的每一个字节剥离出来,想办法将其依次存入无符号字节数组当中。首先以16进制读取为int类型(占用4字节),将其地址赋值为(unsigned char*)类型的pf,指针类型决定指针长度,赋值完成之后便可刚好取到checkval数据中四字节的首字节,也就是我们的真正的数据字节,再将他们依次读入无符号字节数组当中去进行存储。这样便可将以字符串表示的四字节转为数组进行存储。
拿到数据之后,我们仅需强制转换,便可以得到这些字节所对应的浮点数。
float x = *((float*)byteArray);
printf("\n%f ",x);