因爲項目需要,要在上位機界面實時顯示室內溫度,上位機採用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();
}