IMX6ULL+QT+485采集
演示视频:
【野火linux】linux嵌入式问询485传感器
接下来记录我的第二个linux+QT的应用,其实原理很简单,打开串口,配置波特率,然后对接485传感器即可。具体流程如下:
由野火的linux板原理图和手册可知,CAN和485是公用的,切换跳线帽即可使能485接口
接着就是QT部分的编程:整体不是太复杂,而且我在代码中做了比较详细的中文注释
代码链接:https://gitee.com/wenzhengclub/Imx6ULL_QT_RS485
接下来主要是针对代码和制作过程中遇到的问题进行分析:
首先是初始化部分,主要是进行串口相关的信息的配置
//打开串口
void Widget::on_open_btn_clicked()
{
update();
sleep(100); //延时100ms
//find_port(); //重新查找com
//初始化串口
serialport->setPortName(ui->com->currentText()); //设置串口名
if(serialport->open(QIODevice::ReadWrite)) //打开串口成功
{
serialport->setBaudRate(ui->baud->currentText().toInt()); //设置波特率
switch(ui->bit->currentIndex()) //设置数据位数
{
case 8:serialport->setDataBits(QSerialPort::Data8);break;
default: break;
}
switch(ui->check_bit->currentIndex()) //设置奇偶校验
{
case 0: serialport->setParity(QSerialPort::NoParity);break;
default: break;
}
switch(ui->stop_bit->currentIndex()) //设置停止位
{
case 1: serialport->setStopBits(QSerialPort::OneStop);break;
case 2: serialport->setStopBits(QSerialPort::TwoStop);break;
default: break;
}
serialport->setFlowControl(QSerialPort::NoFlowControl); //设置流控制
//连接槽函数
QObject::connect(serialport, &QSerialPort::readyRead, this, &Widget::Read_Date);
// 设置控件可否使用
ui->open_btn->setEnabled(false);
ui->close_btn->setEnabled(true);
ui->send_btn->setEnabled(true);
}
else //打开失败提示
{
sleep(100);
QMessageBox::information(this,tr("Erro"),tr("Open the failure"),QMessageBox::Ok);
}
}
然后就是串口到来的数据的解析:
//窗口显示串口传来的数据
void Widget::Read_Date()
{
QByteArray buf;
quint8 outChar4 ;
buf = serialport->readAll();
// 下面是很重要的部分,可以将QT输出的QByteArry拼接为16进制buf
QDataStream out4(&buf,QIODevice::ReadWrite); //将字节数组读入
while(!out4.atEnd())
{
outChar4 = 0;
out4>>outChar4; //每字节填充一次,直到结束
testbuf[msg_flag]=outChar4;
msg_flag++;
//qDebug() << testbuf[wendu_flag];
}
msg_flag =0;
//下面开始计算16进制数据
qint16 tem= (testbuf[3]<<8)+testbuf[4];
qint16 hum = (testbuf[5]<<8)+testbuf[6];
double tem_double = tem/10.00;
double hum_double = hum/10.00;
// qDebug() << tem;
// qDebug() << hum;
//UI界面的显示
ui->temperature_bar->setValue(tem_double);
ui->humidity_bar->setValue(hum_double);
ui->temperature_label->setText(QString::number(tem_double));
ui->humidity_label->setText(QString::number(hum_double));
// qDebug() << buf;
if(!buf.isEmpty()) //将数据显示到文本串口
{
QString str = ui->rev_msg->toPlainText();
// byteArray 转 16进制 注意:这里是转换成了16进制的字符串,并不是可以直接使用的16进制buf
QByteArray temp = buf.toHex();
ui->rev_msg->clear();
ui->rev_msg->append(temp);
}
buf.clear(); //清空缓存区
}
其中最重要的就是这里: QDataStream out4(&buf,QIODevice::ReadWrite); //将字节数组读入
因为我测试发现QT对于16进制buf的处理有一些问题,QT里有一个QByteArray 它用来接收串口数据,然后还有一个函数:toHex()但是它并不能将数据准换为16进制buf,而是转成了16进制的字符串。最终查阅资料发现别人使用的拼接函数,把字节一个一个拼接成c语言常用的16进制buf,接下来就和单片机处理485的方法一致了,解析数据,计算传感器值。