Qt+Raspberry pi 3B+ 读取ds18b20温度传感器的值

因为项目需要,要在上位机界面实时显示室内温度,上位机采用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();

}

猜你喜欢

转载自blog.csdn.net/qq_37273544/article/details/88116760