本篇文章主要讲一下在树莓派4b中,如何安装、配置QT,并以超声波测距为例,演示如何通过在QT中用c++编程控制超声波测距模块以及相关的接线方法。我会尽可能做到详细。
本篇文章适合没有QT使用经验的同学(比如我),大神肯定是不屑于讲这些具体操作的。此外,树莓派的一些操作,对于使用Linux也有一定参考意义。
1.安装并配置QT
(1)在命令行中输入以下命令:
sudo apt-get updatesudo apt-get upgradesudo apt-get install qt5-defaultsudo apt-get install qtcreator
会耗费一些时间,安装成功后如下图所示:
(2)打开QT creator,点击工具->选项,在Kits选择编译器,点击添加
(3)分别添加c和c++
要注意ABI的选择。
(4)在构建套件(Kits)中,选择刚才添加好的编译器
我的树莓派是不需要每次使用QT都这样配置的,只需要第一次使用时配置。
2.树莓派接线
我的树莓派增加了面包板,在没有接入其他元件时,如下图所示:
我分别将5v和GND引到了'+'和‘-’两列(黄线),这样'+'一列都为5v, '-'一列都为GND。白线为我接的风扇散热,可以不用管。
超声波测距模块共有4个引脚,如下图:
把vcc接到5v上,GND接到GND上,Trig和Echo分别接到gpio17和gpio18上。
至此,线已经接完了,也就是说硬件部分已经完成。理论上讲,这时候才能开机,因为按操作规范来讲,接线必须断电操作。
3.QT编程
用QT编写c++程序我会主要讲到empty qmake project和QT Widgets Application两种方式。具体可以参考《Qt Creator快速入门第3版》霍亚飞编著的第2章内容,网上应该有电子版资源,我这里由于版权问题就不提供了。
我先把源码贴出来
#include #include #include using namespace std;#define Trig 0#define Echo 1void ultrainit(){
wiringPiSetup(); pinMode(Echo,INPUT); pinMode(Trig,OUTPUT); digitalWrite(Trig,LOW);}float disMeasure(){
struct timeval tv1; struct timeval tv2; long time1,time2; float dis=0; digitalWrite(Trig,HIGH); delayMicroseconds(10); digitalWrite(Trig,LOW); while(digitalRead(Echo)==0); gettimeofday(&tv1,nullptr); while(digitalRead(Echo)==1); gettimeofday(&tv2,nullptr); time1=tv1.tv_sec*1000000+tv1.tv_usec; time2=tv2.tv_sec*1000000+tv2.tv_usec; dis=static_cast(time2-time1)/1000000*34000/2; return dis;}int main(void){
float dis=0; if(wiringPiSetup()==-1) {
cout<<"setup failed!"<
方式1:empty qmake project
打开QTcreator,新建项目->其他项目->empty qmake project->choose
Location中设置项目名称,存储位置,点击下一步进入Kits,如果已经按照之前的方法配置过了,直接点下一步就行了。进入summary点击完成。
这是构建好的项目
然后右击项目名(sample),add new
在c++中选择c++ source file,在Location中把名称改为main.cpp,点击下一步进入summary,点击完成。
设置完成后的目录:
双击main.cpp,进行编辑,这就和使用vs一样了,直接把源码复制进去就行了。
点击锤子图标进行构建,相当于vs的生成。点击后会弹出提示框,点击save all就行。
不出意外的话,应该出错了,错误如图所示,存在未定义的引用。
这个问题我从网上查了很久才解决的。解决方法是,在.pro文件的第一行,添加以下代码:
LIBS += -L/usr/local/include -lwiringPi
再次构建,应该显示构建成功。点击运行。
方式2:QT Widgets Application
创建新项目,Application->QT Widgets Application
然后和之前一样一直点击下一步,直到完成。生成的项目目录如下图所示。
首先为了成功构建我们还是要修改.pro文件,修改完成后,双击mainwindow.cpp进行编辑。它里面已经存在代码模板了。把源码中的子函数等内容写在MainWindow::MainWindow之前。主函数内容写在ui->setupUi之后,当然要删掉return。
具体代码如下:
#include "mainwindow.h"#include "ui_mainwindow.h"#include "wiringPi.h"#include #include using namespace std;#define Trig 0#define Echo 1void ultrainit(){
wiringPiSetup(); pinMode(Echo,INPUT); pinMode(Trig,OUTPUT); digitalWrite(Trig,LOW);}float disMeasure(){
struct timeval tv1; struct timeval tv2; long time1,time2; float dis=0; digitalWrite(Trig,HIGH); delayMicroseconds(10); digitalWrite(Trig,LOW); while(digitalRead(Echo)==0); gettimeofday(&tv1,nullptr); while(digitalRead(Echo)==1); gettimeofday(&tv2,nullptr); time1=tv1.tv_sec*1000000+tv1.tv_usec; time2=tv2.tv_sec*1000000+tv2.tv_usec; dis=static_cast(time2-time1)/1000000*34000/2; return dis;}MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){
ui->setupUi(this); float dis; if(wiringPiSetup()==-1) {
cout<<"setup failed!"<
构建后就可以运行了。
4.程序中gpio接口的控制
在接线时,我们将Trig接在了gpio17,Echo接在了gpio18。因此在源码中对Trig和Echo的编号进行了指定。
#define Trig 0#define Echo 1
0和1指的是gpio17和gpio18对应的wiring Pi编码,其中17和18是PCM编码,PCM与wiring Pi的对应关系如下:
举例来说,如果我们接线时将Trig接在gpio27(wiring Pi对应2),将Echo接在gpio22(wiring Pi对应3),那我们就要以以下方式声明:
#define Trig 2#define Echo 3