因为项目需要,要在上位机界面实时显示室内温度,上位机采用QT5.5编写,采用DS18B20采集数据,显示在控件lcdNumber上。DS18B20是一个比较常用的温度传感器,采用单总线控制,在linux中,一切都是文件,所以数据采集也是文件的读取。
一、修改配置文件
在/boot/config.txt文件后面添加下面这一句
sudo vi /boot/config.txt
dtoverlay=w1-gpio
这一句就是树莓派添加Device Tree设备,dtoverlay=w1-gpio表示添加单总线设备,也可以写成dtoverlay=w1-gpio,gpioin=4默认管脚为BCM编号4,如果DS18B20接到其他管脚则需要修改这个值,在微雪电子的树莓派扩展板上Pioneer 600扩展板DS18B20默认接到4,故不用修改。
二、查看模块是否启动
重启树莓派使设置生效,运行lsmod命令,如果发现红色方框的两个模块说明模块已启动。
如果没有发现,也可以运行如下命令加载模块
sudo modprobe w1_gpio
sudo modprobe w1_therm
三、 读取温度
如果没有问题,在/sys/bus/w1/devices中发现一个28-XXXX开头的文件夹,这个就是DS18B20的ROM,每个DS18B20都一样,连接多个18B20就会有多个这样的文件,在这个文件夹中再读取w1_slave文件则会返回当前温度值。
这里我们先进去打印一下,看看有哪些数值:
sudo modprobe w1-gpio
sudo modprobe w1-therm
cd /sys/bus/w1/devices
cd 28-00000xxx
cat w1_slave
在返回数据中,第一行最后的YRS表示CRC校验成功,数据有效。第二行最后t=30500表示当前温度为30.5摄氏度。
按照此逻辑,只要反复读取这个文件中的t值即可显示温度。
四:QT界面显示温度
在QT中ui界面拖选一个lcdNumber,然后使用定时器定时去读取数值,显示在这个控件上即可;参照一个大佬的程序:QT+树莓派读取温度,在实际使用中有一点问题,一是显示在lcdNumber上,必须是个字符串,而我想要的是带小数点的温度值。二是涉及到一些数值类型装换,如读到的值是30500,实际要显示为30.5。三是树莓派直接接DS18B20是找不到上面所说的文件的,必须要在DS18B20的VCC和数据引脚之间接一个4.7K的上拉电阻才可以。
五:源程序
.h文件
只是添加一些要用到的包,再声明一个信号函数private slots:void cj();
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QString>
#include <QDir>
#include <QStringList>
#include <QMessageBox>
#include <QTextStream>
#include <QDebug>
#include <QTimer>
#include <QTime>
#inclede <QTextCodec>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void cj();
private:
Ui::MainWindow *ui;
QDebug *Debug;
};
#endif // MAINWINDOW_H
.cpp文件
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::cj()
{
system("sudo modprobe w1-gpio");
system("sudo modprobe w1-therm");
QString tempFile="/sys/bus/w1/devices/";
qDebug() << tempFile;
QString tempData;
//设置ds18b20的文件所在位置
QDir tempPath("/sys/bus/w1/devices/");
//得到所有的文件列表
QStringList fileList=tempPath.entryList();
//遍历所有文件,找到关于ds18b20的文件
int i=0;
while(i<fileList.size())
{
if(fileList.at(i).contains("28-"))
{
tempFile.append(fileList.at(i)); //已经找到了文件
break;
}
i++;
}
tempFile.append("/w1_slave");
qDebug() << tempFile;
QFile file(tempFile);
if(!file.open(QIODevice::ReadOnly|QFile::Text))
{
QMessageBox::information(this,tr("fgbdfgds"),tr("hjggnfghn"));
return;
}
QTextStream in(&file);
//根据存储的文件找到需要的数据
QString str=in.readAll(); //读出所有内容
// qDebug() << str;
tempData=str.mid(str.indexOf('t')+2,3); //定位数据的位置,找到所需要的数据,精度可以达到小数点后三位,本程序只 需一位
float temp = tempData.toFloat(); // 将字符类型转换为float
float temp2 = temp/10; // 将float进行运算得到小数点
QString temp3 = QString::number(temp2,'f',2); // 再将float转换为字符型,2代表小数点后几位
ui->lcdNumber->display(temp3);
file.close();
}