核桃派
直播中

大饭米粒

3年用户 7经验值
擅长:嵌入式技术 控制/MCU RF/无线
私信 关注

【核桃派ZeroW开发板体验连载】打造智能音箱,一个简化版的“小爱同学”

开始

首先感谢发烧友william hill官网 提供的试用机会,本次将使用核桃派打造一个智能音箱项目,本帖将记录整个过程。

收到核桃派开发套件后是散件拆开之后进行简单组合,组合可随意搭配,只是【重点】是注意主板【底部不要接触到底面】,除了附带的散热片加在H616主控之外,最好把另外两个RAM内存颗粒和WIFI蓝牙模组也加一个散热片(可选)
开箱.png

系统加载需要一张预先拷贝操作系统的内存卡,内存卡容量最好是16G以上

系统镜像

镜像下载

注意如果是复刻项目的话,需要下载这个镜像,保持环境一致
镜像.png

镜像烧录

镜像下载之后推荐使用balenaEtcher进行烧录,下载地址:https://etcher.balena.io/#download-etcher

下载之后安装打开,balenaEtcher界面非常友好,没有多余的选项,将内存卡使用读卡器插入电脑之后打开balenaEtcher,根据引导(每次点击只有一个按钮)选择上一步下载的镜像进行烧录
烧录.png

将烧录好的内存卡插入主控板接入电源即可正常开机,注意一定不要带电插拔SD卡!

系统简单部署

注意主板通电之前,找一个支持HDMI接口的显示屏使用数据线和主板连接之后再通电,正常情况下你会看到如下所示的桌面
系统桌面.png

如上图所示,先在F处系统托盘连接好WIFI(以太网最好),然后在E处启动栏打开终端,执行如下命令开启VNC

set-vnc enable

此时使用sudo ifconfig查看wlan0网卡获取到的IP地址或者可以直接进路由查看主机名为WalnutPi的IP地址,开启VNC成功之后重启开发板移除HDMI了,直接接一个电源线。

开始开发

使用QT绘制界面

本来想直接用C++配合QT的GUI来制作程序,但是发现系统镜像中已内置好了Python11.2和PyQt5,那么本次源代码直接用Python来编写,通过中间件PyQT来调用QT的GUI库。

目前开发环境为Pycharm+Python3.11.2+PyQT5,对的没错直接在电脑上进行开发,只要环境一样是可以的。

相信看到这里的同学们对于下载安装Pycharm和python环境已经熟练掌握,以及通过pip install pyqt5安装pyqt5库等,安装过程不再赘述。

绘制待机界面

由于本次项目涉及3.5寸显示屏,此次绘制图形界面像素尺寸为320X480,以下是简单设计的待机页面,作为系统开机首次加载页和长时间无操作后默认跳转页

待机.png
上图为填充了相关字符内容的成品图,实际上用到的是这样的图片,这个是原图。
待机2.png

其内容是通过代码实时修改的。
此时打开Qt设计师就可以简单的绘制一些占位文本和图片,通过QT的style样式可以很快实现和原效果图一致的界面
占位.png

有同学已经注意到右上角有天气数据,等会会讲到python调用天气接口把数据显示到QT界面中,右上角的天气图标来源自心知天气提供的图标,保存在QT的QRC资源文件中。
将简单绘制好的待机UI通过安装pyqt5获得的pyuic5工具,将ui文件转为py文件待用,同样将资源文件qrc使用pyrcc5工具转换为py文件,此时你会得到这几个文件
转换.png

心知天气是一个提供气象服务的平台,该平台可提供免费的天气查询服务,此时Python通过requests库进行GET请求访问心知天气的API,获取天气实况
文档地址为https://seniverse.yuque.com/hyper_data/api_v3/nyiu3t

整合待机界面代码

以下是本次项目的目录结构

.venv //虚拟环境包
ui
   0.png
   1.png
    ....
   standby.py
   voice_rc.py
test.py

其中standby.py为本次待机界面的UI代码,voice_rc.py为整个项目的资源文件,最外层的test.py为本次项目入口文件

【test.py】代码

# -*- coding: utf-8 -*-

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import Qt
from ui.MainPage import Ui_MainPage
from ui.Standby import *
from ui.voice_rc import *
from string import Template
import datetime
import requests

class StandbyWindow(QMainWindow, Ui_Standby):
    week_list = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]
    weather_uri = "https://api.seniverse.com/v3/weather/now.json?key=ibmerkwkfqbsvhhf&location=ip&language=zh-Hans&unit=c"
    def __init__(self, parent=None):
        super(StandbyWindow, self).__init__(parent)
        self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
        self.setWindowTitle('')
        self.setupUi(self)
        self.retranslateUi(self)

    def retranslateUi(self, Standby):
        _translate = QtCore.QCoreApplication.translate
        now = datetime.datetime.now()
        self.data.setText(_translate("Standby",now.strftime("%Y-%m-%d")))
        self.time_label.setText(_translate("Standby",now.strftime("%H:%M")))
        self.week.setText(_translate("Standby",self.week_list[now.weekday()]))
        responses = requests.get(self.weather_uri).json()
        code = responses['results'][0]['now']['code']
        self.tianqi.setText(_translate("Standby", responses['results'][0]['now']['text']))
        self.wendu_3.setText(_translate("Standby", responses['results'][0]['location']['name']))
        self.wendu.setText(_translate("Standby", responses['results'][0]['now']['temperature']))
        template = Template("QLabel#weather_ico{"
                                       "    background-image: url(:/weather/$code.png);"
                                       "    background-repeat: no-repeat;"
                                       "    background-position: center;"
                                       "    background-attachment: fixed;"
                                       "    background-size: cover;"
                                       "    color:rgb(255,255,255)"
                                       "}")
        self.weather_ico.setStyleSheet(template.substitute(code=code))

class MyMainWindow(QMainWindow, Ui_MainPage):
    def __init__(self, parent=None):
        super(MyMainWindow, self).__init__(parent)
        self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
        self.setWindowTitle('')
        self.setupUi(self)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    my_win = StandbyWindow()
    my_win.show()
    sys.exit(app.exec())

UI文件和资源文件代码行数较多,以附件形式展示,可自行下载查看。

*附件:ui.zip
一切准备就绪之后,将Python代码放在核桃派中进行运行
待机运行结果.png

通过VNC远程连接可以看到,已经正常显示出UI界面,Python获取的实时时间信息已显示在QT界面中,以及右上角通过天气API接口请求的天气数据也已正常显示。

目前本帖记录到待机画面的制作,下一步将启用3.5寸显示屏展示QT界面,由于扩展板音频仅能播放音频,下面将尝试使用USB麦克风采集音频进行离线语音实时识别,进一步开发智能音箱的功能。

更多回帖

发帖
×
20
完善资料,
赚取积分