stm32mp157开发板FS-MP1A是华清远见自主研发的一款高品质、高性价比的Linux+单片机二合一的嵌入式教学级开发板。开发板搭载ST的STM32MP157高性能微处理器,集成2个Cortex-A7核和1个Cortex-M4 核,A7核上可以跑Linux操作系统,M4核上可以跑FreeRTOS、RT-Thread等实时操作系统。开发板搭配仿真器、显示屏、摄像头、资源扩展板等丰富的扩展模块,可拓展物联网、人工智能等相关技术学习,还可以拓展丰富的项目实战,非常贴合企业当下开发需求,是一款嵌入式Linux入门进阶必备开发板!

可学习技术:嵌入式Linux应用/系统/驱动开发、ARM裸机开发、Qt界面编程、STM32单片机、FreeRTOS、人工智能机器视觉等。其中ARM Cortex-A7裸机开发课程是华清远见独有特色课程,可关注:​https://www.bilibili.com/video/BV1Xe4y1i7vm/​,持续更新中。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板

可实战项目:14个Linux+Qt综合项目案例,6个MP1A物联网拓展项目

关注公众号“华清远见在线实验室”,回复“mp157项目”,即可领取项目配套文档及源码。

Linux+Qt综合项目案例:华清远见stm32mp157开发板优势特色部分,包括音乐播放器、智慧家庭、智能工业电表、智能出行助手、智能猫眼、环境监测、智能安防、智能语音识别等10余个项目案例,涉及家居、医疗、农业多种应用方向,在案例中使用了多种物联网和嵌入式技术,包括OT开发、linux应用开发、linux驱动开发、物联网云端接入、MQTT协议、json字符串等知识点。

基于Linux+Qt的智能出行助手项目

项目功能简介:

1、 调用百度 AI 开发平台 API 进行语音识别,进行语音控制传感器的联动,实现智能语音识别平台的功能。

2、 调用天气生活指数 API,获取不同城市每天的运动指数、 舒适度指数、化妆指数等等。

3、 调用百度地图 api,显示不同城市的地图。

4、 实现智能闹钟,定时提醒。

开发平台:

华清远见stm32mp157开发板豪华套餐(开发板+仿真器+五寸屏+摄像头+资源扩展板+tf卡+读卡器)

项目实战:

Qt 开发环境搭建

主机开发环境说明

1) 本文档主要介绍 linux 环境下的 Qt 程序开发;

2) 主机 Qt 版本为 5.14.1;

主机 Qt 环境搭建及使用

Qt Creator 安装

将 qt-creator-opensource-linux-x86_64-4.10.1.run(Qt 实验源码\工具软件) 复制到 ubuntu 主机中,可以采用共享文件夹的方式也可以使用 tfp方式将文 件存入家目录下的 Downloads 目录。我们需要在终端中赋予安装程序可执行的权限

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_02

我们可以使用图形化的文件管理器来查看

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_03

双击“qt-creator-opensource-linux-x86_64-4.10.1.run”图标运行安装程序。出现如下界面:

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_04

等待程序验证完成后点击“Next”

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_05

这里我们需要登录或者注册一个账号,如果我们之前已经注册过直接登录就可以。如果没有注册过则需要新注册有一个账号后登录。这里笔者已经注册过账号,所以直接登录。 登录成功后出现如下界面,点击 Next

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_06

这里选择安装路径

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_07

可以直接默认,Next

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_08

这路选择安装的组件,直接默认即可

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_09

这里我们需要同意用户协议

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_10

这个界面告诉我们安装完成后需要占用的空间。点击”Install”按钮后开始安装。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_11

安装完成后出现如下界面

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_12

点击“Finish”按钮后将弹出 Qt Creator 主界面

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_13

点击“Cancel”按钮后即可正常使用

Qt5.14.1 安装

复制到 qt-opensource-linux-x64-5.14.1.run(Qt 实验源码\工具软件)到 ubuntu 主机中,可以采用共享文件夹的方式也可以使用 tfp 方式将文件存入家目录下的 Downloads 目录。进入所在文件夹,先给执行权限

输入命令

chmod +x ./qt-opensource-linux-x64-5.14.1.run

安装在命令行输入

./qt-opensource-linux-x64-5.14.1.run

会有可视化引导安装,一直 next 就行了

在选择安装组件的时候要是不知道选择那些就全选了 大概有 4 个 G 左右

下载 gcc 和 g++

sudo apt-get install gcc g++

下载 cmake

sudo apt-get install cmake

下载链接库

sudo apt-get install libgl1-mesa-dev libglu1-mesa-dev

Qt Creator 配置

1)配置 GCC

运行 QtCreator 后,依次点击"Tool"->"Options",出现选项对话框,在左侧点击"Kits",右 边选择"Compilers"标签。 检查有没有下图标注的 C++和 C ,般按上面步骤执行后都会有

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_14

点击右侧"Add"按钮,弹出下拉列表后,选择"GCC"的"C"

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_15

填写信息如下,"Name"为"Auto-GCC","Compiler path"点击旁边的"Browse.."按钮选择编译器的路径,例子中的路径是 “/usr/bin/gcc”

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_16

2)配置 G++

点击右侧"Add"按钮,弹出下拉列表后,选择"GCC"的"C++",下面的文本框填写"Name" 为"Auto-G++","Compiler path"点击旁边的"Browse.."按钮选择编译器的路径,例子中的路径是" /usr/bin/g++"。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_17

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_18

填写完成后,点击"Apply"。

3)配置 qmake

选择"Qt Versions"标签,如果有下面红框中的文本,可以跳过下面步骤

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_19

如果没有,在右侧点击"Add..."

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_20

会弹出 qmake 路径选择对话框,这里以"/home/linux/Qt5.14.1/5.14.1/gcc_64/bin/qmake"为例子。 选择”qmake”文件后,点击"Open"按钮

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_21

"Version name"改为" Qt %{Qt:Version} GCC"。然后点击"Apply"按钮。

4)配置 Kits

点击左侧"Kits",右侧选择"Kits"标签。检查有没有下图红框选中的文本,如果有可以跳过下面步骤

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_22

然后没有,点击 Add:

在弹出的对话框中"Name"为"Desktop","Device Type"选择"Desktop"选项, "Sysroot"选择目标设备的系统目录,"Compiler"选择之前配置的名称"Auto-GCC"和"Auto-G++","Qt version"选择之前配 置的名称"Qt 5.14.1GCC",其它默认即可,最后点击"Apply"和"OK"按钮。

Qt Creator 新建工程

注意:工程路径最好不要包含中文、特殊字符、空格等。

我们可以新建一个“qt”文件夹,该文件夹用作我们以后存放源代码。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_23

打开 Qt Creator,在欢迎页面点击 “New”按钮,来新建一个工程。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_24

在出现的新建项目窗口中,我们选则“Application”->“Qt Widgets Application”,然后点击右下方“Choose…”按钮,来创建一个桌面 Qt 应用。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_25

我们在这里设置项目介绍和源码位置,我们这里创建一个名为“HelloWorld”的示例项目,设置完成之后点击 next

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_26

直接点击 next

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_27

随后进行细节设置,主要设置要创建的源码文件的基本类信息,包括类名等。这里我们可以根据自己的项目特点进行设置。需要说明的一点就是基类的选择,这里基类有 QMainWindow、QWidget、QDialog 三种,它们的不同之处如下:

QMainWindow 类提供一个带有菜单条,工具条和一个状态条的主应用程序窗口。主窗口通常提供一个大的中央窗口部件,以及周围菜单,工具条,和一个状态栏。QMainWindow 窗口经常被继承,使得封装中央部件,菜单,工具条,状态栏等都变得很容易,当用户点击它的时候,相应的槽就会被调用;

QWidget 类是所有用户界面对象的基类,窗口部件是用户界面的一个基本单元,它从窗口系统接收鼠标,键盘和其他消息,并在屏幕上绘制自己。一个窗口部件可以被他的父窗口或者是其他窗口挡住一部分;

QDialog 类是对话框窗口的基类,对话框窗口主要用于短期任务和用户进行短期通讯的顶级窗口,QDialog 可以是模态对话框或者是非模态对话框。QDialog 支持扩展并带有返回值,他们可以带有默认值;我们在这里选择 QDialog 类即可,点击 next 完成类信息设置。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_28

直接点击 next 按钮即可。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_29

然后进行工具选择,该页面可以选择我们创建的工程可以使用的工具,选择想要使用的编译器模块,例如下图 。点击 next

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_30

最后我们设置汇总信息,如果不需要版本控制等功能,直接点击完成finish 即可。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_31

随后我们就进入到了主界面,这时候 Qt 已经帮我们做好了一些准备工作,包括创建了一些文件,写好了一些前置代码等等。

我们可以点击左边 protect 栏,来查看我们的编译选项。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_32

我们可以在左下角选择编译 Debug 版或者 Release 版,即调试版或发行版。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_33

左下角绿色剪头是编译并运行,锤子是仅编译,我们可以直接点击绿色小箭头将我们导入的工程编译并运行起来。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_34

点击运行按钮后,我们可以看到 HelloWorld 窗口运行起来了。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_35

导入工程

我们可以将已存在的 Qt 程序项目直接打开,这里以上一章节的HelloWorld 程序为例。首先我们确定源码存在的位置,如 HelloWorld 程序源码在 /home/linux/qt/helloworld 路径下

点击欢迎页面的“Open” 按钮可以打开已有的工程

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_36

找到我们刚才解压好的源码,选择“helloworld.pro”文件并点击打开

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_37

接下来我们就可以进入到代码编辑界面了。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_38

左上角是项目栏,点击项目名称左边的小箭头可以展开项目目录

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_39

我们可以点击左边项目栏,来查看我们的编译选项。需注意的是构建设置中的路径应与工程路径处于同级目录下。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_40

我们可以在左下角选择编译 Debug 版或者 Release 版,即调试版或发行版。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_41

左下角绿色剪头是编译并运行,锤子是仅编译,我们可以直接点击绿色小箭头将我们导入的工程编译并运行起来

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_42

点击运行按钮后,我们可以看到 HelloWorld 窗口运行起来了。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_43

文件说明

通过上面两个章节,我们学习到了 Qt 程序的新建与导入的方法,也知道了Qt 会帮我们做一些基础工作,比如帮我们建立了一些文件,那么这些文件都是干什么用的呢?我们以HelloWorld 程序来说明一下。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_44

以“.pro”为后缀名的文件,为 Qt 的项目管理文件,存储项目设置的文件;

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_45

“Qt += core gui”表示项目中加入 core gui 模块。core gui 是 Qt 用于GUI 设计的类库模块,如果创建的是控制台(console)应用程序,就不需要添加 core gui。

Qt 类库以模块的形式组织各种功能的类,根据项目涉及的功能需求,在项目中添加适当的类库模块支持。例如,如果项目中使用到了涉及数据库操作的类就需要用到 sql(数据库)模块,在 pro 文件中需要在后面加上 sql:

1 Qt += core gui sql

“greaterThan(QT_MAJOR_VERSION, 4): QT += widgets”,这是个条件执行语句,表示当 Qt 主版本大于 4 时,才加入 widgets 模块。“TARGET = HelloWorld”表示生成的目标可执行文件的名称,即编译后生成的可执行文件是 HelloWorld.exe。

“TEMPLATE = app”表示项目使用的模板是 app,是一般的应用程序。

后面的 SOURCES、HEADERS、FORMS 记录了项目中包含的源程序文件、头文件和窗体文件(.ui 文件)的名称。这些文件列表是 Qt Creator 自动添加到项目管理文件里面的,用户不需要手动修改。当添加一个文件到项目,或从项目里删除一个文件时,项目管理文件里的条目会自动修改。

文件夹“Header”中,存放的是所设计的窗体类的头文件;

文件夹“Sources”中,存放着源码文件。main.cpp 是实现 main()函数的程序文件,HelloWorld.cpp 是 widget.h 里定义类的实现文件。C++中,任何窗体或界面组件都是用类封装的,一个类一般有一个头文件(.h 文件)和一个源程序文件(.cpp 文件);

文件夹“Forms”中,存放着界面设计文件,“.ui”文件是一个 XML 格式存储的窗体上的元件及其布局的文件,双击项目文件目录树中的文件 ui,会打开一个集成在 Qt Creator 中的 Qt Designer 对窗体进行可视化设计;

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_46

UI 设计器有以下一些功能区域:

组件面板:窗口左侧是界面设计组件面板,分为多个组,如 Layouts、Buttons、Display Widgets 等,界面设计的常见组件都可以在组件面板里找到。

中间主要区域是待设计的窗体。如果要将某个组件放置到窗体上时,从组件面板上拖放一个组件到窗体上即可。

Signals 和 Slots 编辑器与 Action 编辑器是位于待设计窗体下方的两个编辑器。Signals 和 Slots 编辑器用于可视化地进行信号与槽的关联,Action 编辑器用于可视化设计 Action。

布局和界面设计工具栏:窗口上方的一个工具栏,工具栏上的按钮主要实现布局和界面设计。

对象浏览器(Object Inspector):窗口右上方是 Object Inspector,用树状视图显示窗体上各组件之间的布局包含关系,视图有两列,显示每个组件的对象名称(ObjectName)和类名称。

属性编辑器(Property Editor):窗口右下方是属性编辑器,是界面设计时最常用到的编辑器。属性编辑器显示某个选中的组件或窗体的各种属性及其取值,可以在属性编辑器里修改这些属性的值。属性编辑器的内容分为两列,左侧为属性的名称,右侧为属性的值。属性又分为多个组,实际上表示了类的继承关系,位于下方的类属性组继承自位于上方的类属性组;如果我们需要新建资源文件、源码文件等,可以在项目文件夹出点击鼠标右键,选择 Add New;如果我们有新的文件需要添加,可以在项目文件夹出点击鼠标右键,选择 Add Existing Files。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_47

帮助文档

Qt 的帮助文档是伴随我们学习 Qt 开发的好伙伴。在 Qt 开发过程中,我们会面临图形接口使用的问题,它不像 C 语言那样就那么几个函数接口,图形接口的接口数量可以用海量来形容,常用的我们可能能记住,其它的就没有必要去记了,用到什么就去帮助文档查看用法是比较方便的。我们可以按 F1 按键,或通过上方导航栏的“help->contects”来进入帮助文档。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_48

上方的前进后退按钮方便我们查看文档,如返回到上一步,返回到下一步。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_49

我们可以通过帮助文档来查看以下几个部分:类使用的相关介绍;查看相关类的使用介绍,我们可以先进入到帮助文档,然后在左上角选择“Search”。笔者这里以 QWidget 类为例,输入我们想要查找的类的名字,然后双击查找结果来查看说明。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_50

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_51

也可以先将鼠标移动到想要查询的类的位置,如图所示,将鼠标移动至“QWidget”处,然后按“F1”键,即可跳转到相应的帮助文档。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_52

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_53

我们可以通过再按一次“F1”键来全窗口查看帮助文档,按“Esc”键可以退出。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_54

部分常用的成员元素包括以下几项:

公有成员函数:操作部件属性的相关函数;

公有槽函数:Qt 类中已经定义好的槽函数,直接可与信号相连接;

信号:软中断,如按下按钮触发 pressed() 信号等;

保护成员函数:通常事件所对应的虚函数放在此处;

事件:常用事件,如操作鼠标触发的鼠标事件;

滚动鼠标滚轮,向下即可看到“Qwdget Class”类的相关说明了。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_55

部分常用的成员元素包括以下几项:

公有成员函数:操作部件属性的相关函数;

公有槽函数:Qt 类中已经定义好的槽函数,直接可与信号相连接;

信号:软中断,如按下按钮触发 pressed() 信号等;

保护成员函数:通常事件所对应的虚函数放在此处;

事件:常用事件,如操作鼠标触发的鼠标事件;

滚动鼠标滚轮,向下即可看到“Qwdget Class”类的相关说明了。

1) 查看所用的部件的相应成员函数。

我们可以查找到该类所用部件的相应成员函数的使用方法、功能、参数、返回值等等,我们以“按钮”控件,即“QPushButton Class”类为例,我们通过索引搜索的方式,来找到这个类

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_56

我们可以通过点击“Public Functions” 来查看“QPushButton”这个类中的成员函数。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_57

这里以“QPushButton(const QString &text, QWidget *parent =Q_NULLPTR)”为例,我们点击函数名字可以进入到函数详情中。我们可以看到相应的描述为:以“text”为显示内容,以“parent”为父对象,构造一个push 按钮。“text”“parent”为函数参数,由于是构造函数,所以此函数没有返回值。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_58

还有一些函数是继承自其它类的,例如“Public Functions”中有 21 个继承自“QAbstractButton”类的函数,我们点击“QAbstractButton”即可查看。击“QAbstractButton”即可查看

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_59

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_60

同样我们可以点击相应的函数进入查看详情。如查看“void setText(const QString &text)”。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_61

2) 查看所用的部件的信号。

我们这里还是以“PushButton”为例,我们点击“Public Slots”。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_62

可以看到“PushButton”本身有一个“void showMenu()”的信号,并且有很多继承自其他类的信号。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_63

一般来说我们用的“PushButton”的信号,最多的是用到其继承自基类“QAbstractButton”中的几个信号,分别是点击(按下后抬起)、按压(单按下)、释放(单抬起)等

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_64

我们可以点击相应信号查看详情

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_65

3) 查看所用的部件的事件(所对应的虚函数如何编写)。部件常用事件主要在 “QWidget”中声明,选择“Events”即可查看相关说明。

每个事件都对应着事件函数。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_66

点击事件函数可查看详情

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_67

实验步骤

语音识别模块

录音

在 pro 文件添加

QT += network

QT += multimedia

在 mainwindow.h 头文件添加下面定义

void RecorderStart(QString fileName);//开始录音

void RecorderEnd();//结束录音并转换格式

QFile *outFile;//录音时的变量

QAudioInput *my_audio;//录音时的变量

QAudioFormat audioFormat;//录音时的变量

Mainwindow.cpp 录音函数实现:

void MainWindow::RecorderStart(QString fileName)

{

QAudioDeviceInfo device = QAudioDeviceInfo::defaultInputDevice();

if(device.isNull())

{

QMessageBox::warning(NULL,"QAudioDeviceInfo","录音设备不存

在");

return;

}

// 设置通道数

audioFormat.setChannelCount(1);

// 设置编码

audioFormat.setCodec("audio/pcm");

// 设置采样频率

audioFormat.setSampleRate(16000);

// 设置位深

audioFormat.setSampleSize(16);

// 判断设备是否支持该格式

if(!device.isFormatSupported(audioFormat)){ //当前使用设备是否支持

audioFormat = device.nearestFormat(audioFormat); //转换为最接近格

}

// 创建录音对象

my_audio = new QAudioInput(audioFormat,this);

outFile = new QFile;

outFile->setFileName(fileName); //语音原始文件

outFile->open(QIODevice::WriteOnly);

// 开始录音

my_audio->start(outFile);

}

结束录音函数实现

/**********************

* 结束录音并转换格式

**********************/

void MainWindow::RecorderEnd()

{

// 结束录音

my_audio->stop();

outFile->close();

delete outFile;

outFile =NULL;

delete my_audio;

my_audio = NULL;

}

点击释放按钮槽函数

右键按钮,转到槽,选择 pressed 和 released 点击 ok。会在 mainwindow.cpp生成 on_pushButton_video_pressed()和 on_pushButton_video_released()槽函数。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_68

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_69

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_70

在两个槽函数分别实现如上图所示

申请百度 AI 开发平台语音识别应用

语音识别是利用百度的 API 在线识别。所以需要申请项目 ID。

进入百度的 API 平台:​​https://ai.baidu.com/​

在产品服务下选择语音识别:

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_71

点击立即使用:

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_72

申请账号点击登录:

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_73

点击创建应用:

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_74

输入应用名称、应用描述,点击立即创建:

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_75

点击返回应用列表:

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_76

获取 AppID、API Key 和 Secret Key

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_77

我们记住其中的 API Key 和 Secret Key,下面会用到。

HTTP 请求类实现

我们录好的音频文件需要通过 HTTPS 协议上传到百度 AI 开发平台进行语音识别,之后 AI 平台会返回给我们识别的结果。

http 类只需要封装一个方法

bool post_sync(QString url,QMap<QString,QString>header,QByteArray

requestData,QByteArray &replyData);

使用这个方法去 URL 发送请求会收到 URL 的返回值。

http.h

#ifndef HTTP_H

#define HTTP_H

#include <QObject>

#include <QMap>

#include <QNetworkAccessManager>

#include <QNetworkRequest>

#include <QNetworkReply>

#include <QEventLoop>

#include <QDebug>

class Http : public QObject

{

Q_OBJECT

public:

explicit Http(QObject *parent = nullptr);

bool post_sync(QString url,QMap<QString,QString>header,QByteArray

requestData,QByteArray &replyData);

};

#endif // HTTP_H

http.cpp

这个方法的第一个参数是 post 方法发送请求的 URL,第二个参数是请求的方法头,第三个参数是请求的数据,第四个参数是返回的数据。

这里要说的是必须要设置 openssl 签名配置,否则在 ARM 上会报错。

bool Http::post_sync(QString url,QMap<QString,QString>header,QByteArray

requestData,QByteArray &replyData)

{

// 发送请求的对象

QNetworkAccessManager manager;

// 请求 对象

QNetworkRequest request;

request.setUrl(url);

QMapIterator<QString,QString> it(header);

while (it.hasNext()) {

it.next();

request.setRawHeader(it.key().toLatin1() ,it.value().toLatin1());

}

//设置 openssl 签名配置,否则在 ARM 上会报错

QSslConfiguration conf = request.sslConfiguration();

conf.setPeerVerifyMode(QSslSocket::VerifyNone);

#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))

conf.setProtocol(QSsl::TlsV1_0);

#else

conf.setProtocol(QSsl::TlsV1);

#endif

request.setSslConfiguration(conf);

QNetworkReply *reply = manager.post(request,requestData);

QEventLoop l;

//一旦服务器返回,reply 会发出信号

connect(reply,&QNetworkReply::finished,&l,&QEventLoop::quit);

l.exec();

if(reply != nullptr && reply->error() == QNetworkReply::NoError)

{

replyData = reply->readAll();

return true;

}

else

{

qDebug()<<"request error!";

return false;

}

}

发送请求

这里需要向两个 URL 发送两个请求,第一个请求是把我们 4.2.3 创建应用得到的 API Key 和 Secret Key 组合成一个 URL 获取 access_token,第二个请求是把音频文件发送请求到语音识别的 URL 才能返回语音识别的结果。

我们新建一个类 Speech

Speech.h

这里我们把 API Key 和 Secret Key 作为参数传到 const QString baiduTokenUrl 里面去。把主机名和获取的 access_token 做为参数传入 const QString baiduSpeechUrl。

#include <QObject>

#include <QJsonDocument>

#include <QJsonParseError>

#include <QJsonObject>

#include <QJsonValue>

#include <QJsonArray>

#include <QFile>

#include "http.h"

#include <QHostInfo>

// 获取 Access Token

const QString baiduTokenUrl =

"​​https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=​

%1&client_secret=%2&";

const QString client_id = "我们创建应用的 API Key";

const QString client_secret = "我们创建应用的 Secret Key";

// 语音识别 url

const QString baiduSpeechUrl =

"​​https://vop.baidu.com/server_api?dev_pid=1537&cuid=%1&token=%2";​

class Speech:public QObject

{

Q_OBJECT

public:

Speech();

QString speechIdentify(QString fileName);

private:

QString getJsonValue(QByteArray ba,QString key);

};

#endif // SPEECH_H

Speech.cpp

QString Speech::speechIdentify(QString fileName)

{

// 获取 Access Token

QString tokenUrl =QString(baiduTokenUrl).arg(client_id).arg(client_secret);

Http my_http;

QMap<QString,QString>header;

header.insert(QString("Content-Type"),QString("audio/pcm;rate=16000"));

QByteArray requestData;//请求内容

QByteArray replyData;//url 返回内容

qDebug()<<tokenUrl;

bool result = my_http.post_sync(tokenUrl,header,requestData,replyData);

if(result) {

QString key = "access_token";

QString accessToken =getJsonValue(replyData,key);

qDebug()<<accessToken;

// 语音识别

QString speechUrl =

QString(baiduSpeechUrl).arg(QHostInfo::localHostName()).arg(accessToken);

QFile file;

file.setFileName(fileName);

file.open(QIODevice::ReadOnly);

requestData = file.readAll();

file.close();

replyData.clear();

// 再次发起请求

result = my_http.post_sync(speechUrl,header,requestData,replyData);

if(result) {

QString key = "result";

QString retText =getJsonValue(replyData,key);

qDebug()<<retText;

return retText;

}

else{

return NULL;

}

}

else {

return "error";

}

}

解析返回的数据

返回的数据是这种 Json 类型的,我们只需要获取里边 result 的值就能得到

我们想要的结果了。

{"err_no":0,"err_msg":"success.","corpus_no":"15984125203285346378","sn":"

481D633F-73BA-726F-49EF-8659ACCC2F3D","result":["北京天气"]}

QString Speech::getJsonValue(QByteArray ba,QString key)

{

QJsonParseError parseError;

QJsonDocument jsondocument =

QJsonDocument::fromJson(ba,&parseError);

if(parseError.error ==QJsonParseError::NoError)

{

if(jsondocument.isObject())

{

QJsonObject jsonObject = jsondocument.object();

if(jsonObject.contains(key)){

QJsonValue jsonvalue = jsonObject.value(key);

if(jsonvalue.isString())

return jsonvalue.toString();

else if(jsonvalue.isArray()){

QJsonArray arr = jsonvalue.toArray();

QJsonValue val =arr.at(0);

return val.toString();

}

}

}

}

return "";

}

MainWindow 类调用函数

我们在释放按钮的槽函数里添加以下代码

void MainWindow::on_pushButton_video_released()

{

ui->pushButton_video->setText("按住说话");

RecorderEnd();

Speech my_speech;

QString text =my_speech.speechIdentify("./1.pcm");

ui->textEdit->append(text);

audioCtrl(text);

}

语音控制设备联动

代码如下

void MainWindow::audioCtrl(QString text)

{

if(text == "开灯。")

{

system("echo 1 >/sys/class/leds/user1/brightness");

system("echo 1 >/sys/class/leds/user2/brightness");

system("echo 1 >/sys/class/leds/user3/brightness");

ui->textEdit_2->setText("灯已打开");

}

else if(text == "关灯。")

{

system("echo 0 >/sys/class/leds/user1/brightness");

system("echo 0 >/sys/class/leds/user2/brightness");

system("echo 0 >/sys/class/leds/user3/brightness");

ui->textEdit_2->setText("灯已关闭");

}

else if(text == "报警。")

{

int fd;

struct input_event event;

struct timeval time;

fd = open("/dev/input/by-path/platform-beeper-event", O_RDWR);

event.type = EV_SND;

event.code = SND_TONE;

event.value = 1000;

time.tv_sec = 1;

time.tv_usec = 0;

event.time = time;

write(fd, &event, sizeof(struct input_event));

ui->textEdit_2->setText("蜂鸣器已报警");

}

else if(text == "关闭。")

{

int fd;

struct input_event event;

struct timeval time;

fd = open("/dev/input/by-path/platform-beeper-event", O_RDWR);

event.type = EV_SND;

event.code = SND_TONE;

event.value = 0;

time.tv_sec = 0;

time.tv_usec = 0;

event.time = time;

write(fd, &event, sizeof(struct input_event));

ui->textEdit_2->setText("蜂鸣器报警已关闭");

}

else if(text == "关风扇。")

{

unsigned char arg;

Ioctl(EXIT_FAN,&arg);

ui->textEdit_2->setText("风扇已关闭");

}

else if(text == "开风扇。")

{

unsigned char arg;

Ioctl(EXIT_FAN,&arg);

Ioctl(INIT_FAN,&arg);

Ioctl(FAN_UP,&arg);

ui->textEdit_2->setText("风扇已打开");

}

else if(text == "温度。")

{

QString tem = temCollect();

ui->textEdit_2->setText(QString(" 此 时 温 度

为:").append(tem).append("'C"));

}

else if(text == "湿度。")

{

QString hum = humCollect();

ui->textEdit_2->setText(QString(" 此时湿度

为:").append(hum).append("%"));

}

}

智慧生活模块

创建 API 应用

浏览器进入 ​https://dev.qweather.com/;注册账号并登陆,点击进入控制台

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_78

进入控制台后,点击应用管理。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_79

点击创建应用,选择免费开发板

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_80

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_81

填写天气数据应用名称后选择 WebAPI,自定义天气数据应用名称。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_82

完成上述操作后,把 key 复制下来,后边代码需要用到。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_83

Get方法获取 API 的 JOSN 数据

我们将 key 填写到下面的 URL 里面,使用 get 方法就能从 API 爬虫下JOSN 数据来了

你的 KEY其中请求参数

Location:需要查询地区的 LocationID 或以英文逗号分隔的经度,纬度坐标(十进制),LocationID 可通过城市搜索服务获取。例如 locatinotallow=101010100

Key:用户认证 key,即上面获取到的 key。

Type:生活指数的类型 ID,包括洗车指数、穿衣指数、钓鱼指数等。可以一次性获取多个类型的生活指数,多个类型用英文,分割。例如 type=3,5。具体生活指数的 ID 和等级参考生活指数常量。各项生活指数并非适用于所有城市。

所以我们以参数的形式将城市的 LocationID 填入 URL 就能获取不同城市的生活指标。

具体代码参考下面:

//get 方法获取信息

void LifeWidget::sendQuest(QString cityStr)

{

QString key = "您申请的 key";

QString quest_url =

"​​https://devapi.qweather.com/v7/indices/1d?type=0&locatinotallow=%1&key=%2";​

quest_url = quest_url.arg(cityStr).arg(key);

QNetworkRequest quest;

quest.setUrl(QUrl(quest_url));

//设置 openssl 签名配置,否则在 ARM 上会报错

QSslConfiguration conf = quest.sslConfiguration();

conf.setPeerVerifyMode(QSslSocket::VerifyNone);

#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))

conf.setProtocol(QSsl::TlsV1_0);

#else

conf.setProtocol(QSsl::TlsV1);

#endif

quest.setSslConfiguration(conf);

manager->get(quest); /*发送 get 网络请求*/

}

//数据接收槽函数

void LifeWidget::replyFinished(QNetworkReply *reply)

{

replyall = reply->readAll();

reply->deleteLater(); //销毁请求对象

}

void LifeWidget::init_networt_life()

{

manager = new QNetworkAccessManager(this);

connect(manager, SIGNAL(finished(QNetworkReply*)), this,

SLOT(replyFinished(QNetworkReply*)));//关联信号和槽

}

解析 JOSN 数据

{

"code": "200",

"updateTime": "2021-02-06T16:36+08:00",

"fxLink": "​​http://hfx.link/2ax2",​

"daily": [

{

"date": "2021-02-06",

"type": "2",

"name": "洗车指数",

"level": "2",

"category": "较适宜",

"text": "较适宜洗车,未来一天无雨,风力较小,擦洗一新的汽车至少

能保持一天。"

},

{

"date": "2021-02-06",

"type": "1",

"name": "运动指数",

"level": "3",

"category": "较不宜",

"text": "天气较好,但考虑天气寒冷,推荐您进行室内运动,户外运动

时请注意保暖并做好准备活动。"

}

],

"refer": {

"sources": [

"Weather China"

],

"license": [

"commercial license"

]

}

}

我们通过 get 方法获取到的 JOSN 数据如上所示。只需要解析 key 为 daily的值即可。其中 daily 的值是一个数组类型的数据,只需要取出我们需要的即可。

void DetaInfo::setInfo(QString info,int type)

{

qDebug()<<"setINfo";

QJsonParseError err;

QJsonDocument json_recv = QJsonDocument::fromJson(info.toUtf8(),

&err);//解析 json 对象

if (!json_recv.isNull())

{

QJsonObject object = json_recv.object();

if (object.contains("daily"))

{

QJsonValue value = object.value("daily"); // 获取指定 key 对

应的 value

if (value.isArray())

{

QJsonObject today_life = value.toArray().at(type).toObject();

QString category = today_life.value("category").toString();

QString text = today_life.value("text").toString();

ui->label_category->setText(category);

ui->label_text->setText(text);

}

}

}

}

出行地图模块

申请百度地图 API 秘钥

进入百度地图官网 ​https://lbsyun.baidu.com/

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_84

点击进入控制台

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_85

这里需要登录百度账号,扫码或者输入用户名密码登录即可。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_86

登录成功后点击应用管理下的我的应用。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_87

点击创建应用

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_88

自定义应用名称后,应用类型选择浏览器端,在白名单输入框输入*

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_89

这里就是我们需要的 AK 秘钥。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_90

map.html

复制百度地图 API 源码。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_91

新建 map.html

将上面 API 的源码复制到吗 map.html

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_92

将代码里面的红框里的您的秘钥替换刚才申请的 AK 即可。

在 map.html 文件添加方法

添加函数,通过 QT 程序传参来改变地图路线的起点,途经点,终点。

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_93

QT端实现

这里使用了 webkit 模块,在 pro 文件中添加 QT += webkit webkitwidgets

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_语音识别_94

具体代码如下

void MainWindow::mapinit()

{

QWebSettings *settings = QWebSettings::globalSettings();

settings->setAttribute(QWebSettings::PluginsEnabled, true);//允许插件

settings->setAttribute(QWebSettings::JavascriptEnabled, true);//JavaScript

settings->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);//

settings->setAttribute(QWebSettings::JavascriptCanOpenWindows, true);

settings->setFontFamily(QWebSettings::FixedFont,"幼圆");

ui->webView->setStyle(new CustomStyle());

ui->webView->load(QUrl("qrc:/map.html"));

connect(ui->webView->page()->mainFrame(),

SIGNAL(javaScriptWindowObjectCleared()), this,

SLOT(populateJavaScriptWindowObject()));

}

void MainWindow::populateJavaScriptWindowObject()

{

ui->webView->page()->mainFrame()->addToJavaScriptWindowObject("Myweb

kit", this);

}

void MainWindow::onBtnCallJSClicked()

{

QString strVal = QString("callfromqt(要传的参数);"));

ui->webView->page()->mainFrame()->evaluateJavaScript(strVal);

}

智能闹钟模块

开启线程,检测时间

这里设置了四个闹钟,即在线程类里边设置了四个全局变量(闹钟时间)。当前时间戳等于设置的时间戳后设置蜂鸣器响起。

void TimeAlarmClock::run()

{

while (1) {

QDateTime time = QDateTime::currentDateTime(); //获取当前时间

uint timeT = time.toTime_t(); //将当前时间转为时间戳

// qDebug()<<timeT<<alarm_clocktime1;

if(alarm_clocktime1==timeT){

beep_on();

// qDebug()<<"open";

}else{

}

if(alarm_clocktime2==timeT){

beep_on();

}else{

}

if(alarm_clocktime3==timeT){

beep_on();

}else{

}

if(alarm_clocktime4==timeT){

beep_on();

}else{

}

}

}

void TimeAlarmClock::beep_on()

{

int fd;

struct input_event event;

struct timeval time;

fd = open("/dev/input/by-path/platform-beeper-event", O_RDWR);

event.type = EV_SND;

event.code = SND_TONE;

event.value = 1000;

time.tv_sec = 1;

time.tv_usec = 0;

event.time = time;

write(fd, &event, sizeof(struct input_event));

close(fd);

}

提交闹钟时间

使用 QdateTimeEdit 设置闹钟时间,点击按钮后,将闹钟时间设置到线程中的全局变量中

void MainWindow::on_time_btn1_clicked()

{

if(ui->time_btn1->text()==" "){

ui->time_btn1->setText("\n");

timeAlarmClock.alarm_clocktime1 =

ui->dateTimeEdit_1->dateTime().toTime_t();

}else{

ui->time_btn1->setText(" ");

timeAlarmClock.alarm_clocktime1 = 0;

}

}

实验源码

源码路径【11-出行助手\实验源码\04-Aivideo】

注意事项

1.在开发板运行时,需要导入中文字库,否则会因为识别不了中文。

将【11-出行助手\工具软件\wqy-zenhei-0.9.47-nightlybuild.tar.gz 或wqy-zenhei-0.8.38-1.tar.gz】复制到 ubuntu 下。并使用 scp 命令将文件拷贝到开发板的 usr/share/fonts 目录下,使用 tar 命令解压后即可

linux@ubuntu:~$ scp wqy-zenhei-0.8.38-1.tar.gz

​​root@192.168.10.128​​:/usr/share/fonts/

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_95

2.如果使用 mipi 五寸屏运行此项目,需要进行屏幕旋转以适应屏幕,具体步骤如下:

在/etc/profile.d/qt-eglfs.sh 添加环境变量如下

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_Qt_96

学生毕业设计选题linux+qt嵌入式物联网智能出行助手项目基于stm32mp157开发板_开发板_97

下面变量的 event0 设备需要填实际的触摸屏设备

这里即填 event0

export QT_QPA_EGLFS_ROTATION=90

export QT_QPA_EGLFS_NO_LIBINPUT=1

export

QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/event0:rotate=90