树莓派打造智能语音控制系统(附最终代码)

本系统采用的树莓派为3B+

1、语音识别系统在实际应用中的意义:

(1)为人们提供高效,便利的居住环境。
(2)摆脱以往必须手动操作的麻烦,通过语音就能达到控制相关设备的目的。
(3)智能语音对话:通过语音和机器人对话,询问想要知道的相关信息,节省自己手动搜索的时间。

2、系统方案设计

2.1 系统的整体结构

系统的整体结构如图2-1所示。

图2-1 系统整体结构图

本智能语音控制系统采用电器设备+树莓派+百度语音接口来实现,分为应用层、逻辑层和处理层。其中电气设备作为应用层,负责系统的处理结果显现出来。树莓派作为逻辑层,处理业务逻辑上的问题,其中包括对处理层返回的识别后的语音信号进行存储,以及采取相应的操作。百度语音接口作为处理层,对树莓派所录的语音信号进行识别,将识别后的语音信号再次返回给树莓派。

2.2 系统的硬件整体架构

本系统中我们的电气设备直接连接树莓派的GPIO口,具体的连线如图2-2所示。

图2-2 系统整体硬件架构图

2.3 系统的软件整体架构

智能语音控制系统的软件整体架构主要分为以下四部分:
语音信号的采集:通过树莓派自带的录音功能来采集语音信号,并保存。
语音信号的识别:通过python调用百度语音接口,识别采集的语音信号,将识别后的语音信号以wav文件的格式存储于树莓派中。
语音机器人的回复:读取存放识别语音信号的wav文件,调用图灵机器人接口,实现机器人智能回复。
电器设备的控制:电器设备的控制其实说到底就是对树莓派GPIO的控制,其中对风扇驱动的控制主要通过python实现,而led灯的控制主要通过C语言来实现。

3、系统设计与实现

3.1系统总体需求概述

从智能语音控制系统的使用者这个角度出发,我们应该尽量避免使用者去直接接触到我们这个系统的内部设计,而是应该提供简单的接口来供用户使用。本系统为智能语音系统,所以在功能的建设上应该具备以下三方面的需求:
(1)对于智能语音对话模块,我们通过百度AI开放平台的语音识别接口和图灵机器人来实现对话的功能,只要能采集到使用者的语音信号,系统就会去调用相应的接口来给予适当的回复。
(2)对于智能语音控制灯泡开关模块,系统会去识别用户下达的语音指令,并将其转换成相应的操作,达到控制灯泡开关的目的。
(3)对于语音控制风扇开关以及风扇档位模块,系统同样会去识别用户下达的语音指令,达到控制风扇开关以及调整风扇档位的目的。

3.2智能语音识别模块的具体实现

3.2.1语音信号的采集

本系统采用树莓派自带的录音arecord来录音,通过以下指令既可以启动树莓派的录音功能:

arecord -D "plughw:1" -f S16_LE -r 16000 -d 3 wav文件。

其中-D后面所带的为设备名、-f后面所带的为采样格式、-r后面所带的为采样频率。因为百度语音接口所要求的采样频率为16000或者8000,所以在本系统中我们采用了16000的采样频率。后面所带wav文件是我们录音所存储的文件。

3.2.2百度AI语音接口的调用

首先要使用百度AI语音接口,要先去百度AI平台申请语音识别账号,申请成功会得到API Key和Secret Key,如图3-1所示。后续我们在python代码中需要填入这两个key,如下所示:

body = { “grant_type”:“”, “id” :”API Key”, “secret”:”Secret Key”, }。

这样我们的程序就可以调用到百度语音接口了。

图3-1 AppID和API Key

3.2.3智能语音识别的实现

智能语音识别提交的数据格式如Data所示:

Data = { “format” : “wav”, “rate” : 16000, “channel” : 1, “cuid” : “”, “token” : tok, “speech” : wav_data, “len” : wav_length }。

format为提交录音文件的格式,在这里为wav。rate为采样速率,在这里为16000,要和录音的采样速率等同。token为上小节调用百度语音接口所返回的内容。speech和len则为录音文件的内容以及长度。在这里使用urllib2这个库(树莓派自带,只需要导入即可)来进行网络的交互,只需要把Data提交到相应的url路径。就可以得到从接口返回的识别后的语音数据。

3.3智能语音对话模块的具体实现

3.3.1图灵机器人服务平台的调用

关于智能语音对话模块的实现,我们在基于语音识别的基础上,增加了一个图灵机器人接口的使用。图灵机器人是一个免费的开放平台,这个平台为广大开发群众以及企业合作伙伴提供一系列智能语义处理的服务。话不多说,我们来看具体实现。
首先要使用这个平台,我们需要去图灵机器人官网注册一个账号,注册后我们就可以申请机器人,同时得到一个apikey,如图3-2所示。通过这个apikey我们就可以去请求调用到图灵机器人服务平台。

图3-2 图灵机器人的apikey

3.3.2智能语音回复的实现

我们通过在python代码中加入这个apikey。请求的数据格式如下所示:
body = {"key":Tuling_API_KEY,"info":words.encode("utf-8")}。
其中,key填写的就是所申请到的机器人的apikey,info就是通过百度语音接口识别后的语音数据。 r = requests.post(url,data=body,verify=True),其中的url为图灵机器人接口的路径,r为图灵机器人返回的语音数据。
因为后续还需要根据识别后的语音数据来执行一些相应的操作以及通过音箱播放图灵机器人所返回的语音信息,所以在这里需要额外多加一步,对语音数据进行合成。同样是利用百度AI语音合成接口来实现。
音箱播放图灵机器人的回复是通过mpg123来实现的。mpg123为音频解码的软件,通过它可以对音频进行解码,同时调用驱动来播放音频。上述调用语音合成接口后会返回一个url = “http://tsn.baidu.com/text2audio?tex=“+tex+”&lan=zh&cuid=”+cuid+”&ctp=1&tok=”+tok+”&per=3” 。有了这个url,就可以通过os.system(‘mpg123 “%s”’%url)这个指令,来使树莓派播放合成后的音频。下面一些功能模块也会用到mpg123来播放一些相应的音频。

3.4语音控制led灯模块的具体实现

3.4.1 语音识别具体操作指令部分的实现

语音控制led灯模块是基于智能语音识别的基础上来实现的。主要分为三个步骤:
(1) 通过录音功能,将语音指令记录于wav文件中。
(2) 读取wav文件,调用语音识别接口进行识别,并用一个info字段记录识别后的语音信号。
(3) 在python代码中对info字段进行比对,如若info字段中存在例如“开灯”、“关灯”等字段,即执行相应的操作。

3.4.2控制led灯的具体实现

本系统中控制led灯是采用了WiringPi这个函数库来实现的。WiringPi是树莓派的GPIO控制库函数,其本身采用C语言或者C++来开发,可以嵌入到其他函数中,如python或者PHP中。在本系统中,我们通过控制WiringPi模式下树莓派的4号引脚来实现控制led灯的开关。当识别到开灯指令,运行./light on指令给予4号引脚高电平,led灯亮,当识别到关灯指令,运行./light off给予4号引脚低电平,led灯灭。注意一个事项:在执行light文件时候,我们需要给他一个执行的权限,因为linux系统中对于文件权限的管控比较严格,我们可以用以下命令chmod u+x light来给灯泡脚本一个执行的权限。

3.5 语音控制风扇驱动模块的具体实现

3.5.1 语音识别各种控制指令的实现

语音识别各种控制指令同上述。只是在其中加入了其他一些控制指令,当识别到如“风扇一档”这样的指令,可以改变风扇的转速。

3.5.2 L298N模块的介绍

改变风扇转速是基于PWM技术,在这里我们采用L298N电机驱动板模块来帮助我们实现这个功能,L298N电机驱动模块的外观及连线方式如图3-3所示。

图3-3 L298N电机驱动模块的外观以及接口连线介绍

3.5.3控制电机转速的实现

控制电机转速的软件实现主要采用了python。p = GPIO.PWM(32,50)通过这条指令设置树莓派GPIO引脚中32引脚为输出,PWM的频率为50hz。p.start(0)这个指令让信号开始输出。最后是改变转速的指令p.ChangeDutyCycle(N),通过改变N来改变其占空比(N的取值在0-100之间),就可以达到控制转速的目的,占空比越大,电机的转速越快。
在本系统中,我们只控制一个电机的转速,所以在这里只使用了L298N电机驱动模块IN1这个引脚。树莓派32GPIO口发出PWM信号,连接到L298N电机驱动模块的IN1引脚,既可以达到控制电机转速的目的,L298N电机驱动模块与树莓派连线图如3-5所示。

图3-5 L298N电机驱动模块与树莓派的连线图

4 调试

4.1 语音唤醒功能的调试

本设计的程序运行之后,首先会停留在第一个录音环节,为时2秒,如图4-1所示。其功能作用为语音唤醒,就是在每次你下达语音指令之前,需要说一声“你好”来唤醒系统,然后才可以继续下达语音指令。唤醒系统后系统会播报“我来啦”的语音,屏幕上也会显示“我来啦”字样,如图4-2所示。


4-1 语音唤醒录音

4-2 语音唤醒成功显示

经多次测试发现,正常情况下语音唤醒功能都能较好的实现,但同时也存在特殊情况,主要发生在系统没有录到音时,因为我给语音唤醒的录音时间为2秒,在这两秒内如果没有录到音就会出现问题。所以给的解决方法是对语音唤醒这个函数进行递归调用,如果第一次没有录到音,程序就会重新调用语音唤醒这个函数,无限循环,直到录到音为止。

4.2 语音控制调试

设计中所用到的语音控制指令如下表所示:

指令 功能
打开灯 Led灯打开
关掉灯 Led灯关闭
打开风扇 驱动电机开始转动
风扇二档 驱动电机加快转速
关掉风扇 驱动电机停止转动

在经历多次测试后发现,一般情况下系统的的控制功能和对话功能都能够较好的实现,互不干扰。但是存在一些特殊情况,比如说你下达的是控制命令,但是系统却启用了对话功能,控制功能没有生效。经过对系统进行重重排查,将原因归结于录音设备的问题,比如说你“打开灯”但是系统并没有收集到这个完整的指令,可能录音到的为“打”或者“打开”,系统判定你没有说出完整的控制指令,因此就会调用对话功能来对此次录音到的信息来做一个回复。针对这种情况,因为本系统采取的录音设备质量比较一般,所以目前无法很好的去解决。

//使用如下代码记得修正缩进问题,python格式要求
系统程序如下:
代码1
# coding: utf-8
import RPi.GPIO as GPIO
import numpy as np
from datetime import datetime
import wave
import time
import urllib, urllib2, pycurl
import base64
import json
import sys
import requests
import os
import yuyinhecheng
import tulin
import yuyinshibietoken = yuyinshibie.get_access_token()
def yuyinhx():os.system('arecord -D "plughw:1" -f S16_LE -r 16000 -d 3 /home/pi/Desktop/yyhx.wav')meg =yuyinshibie.asr_main("/home/pi/Desktop/yyhx.wav",token)if any(['好'.encode("utf-8") in meg,'你'.encode("utf-8")in meg,"你好".encode("utf-8")in meg,"您".encode("utf-8")in meg]):f=open('/home/pi/Desktop/yyhx.wav','wb')f.close()url="http://tsn.baidu.com/text2audio?tex=我来啦&lan=zh&cuid=B8-27-EB-BA-24-14&ctp=1&tok="+token+"&per=3"os.system('mpg123 "%s"'%url)global flagflag = Trueelse:time.sleep(3)yuyinhx()
​​
def controllPwm(speed):#atexit.register(GPIO.cleanup)os.system('cd /home/pi/Desktop&&./start on')​#这句应该可以不要servopin = 32                      #用到树莓派哪个口GPIO.setmode(GPIO.BOARD)​      #设置模式GPIO.setup(servopin, GPIO.OUT, initial=False) #设置32为输出p = GPIO.PWM(servopin,50) #50HZ #设置32为PWM 频率50Hzp.start(0)p.ChangeDutyCycle(speed)time.sleep(0.02)
def controlldevices():switch = Truewhile switch:yuyinhx()if flag:while True:os.system('sudo arecord -D "plughw:1" -f S16_LE -r 16000 -d 3 /home/pi/Desktop/pwm.wav')info =yuyinshibie.asr_main("/home/pi/Desktop/pwm.wav",token)if '打开风扇'.encode("utf-8") in info:url = "http://tsn.baidu.com/text2audio?tex=正在为您开风扇&lan=zh&cuid=B8-27-EB-BA-24-14&ctp=1&tok="+token+"&per=3"os.system('mpg123 "%s"'%url)os.system('cd /home/pi/Desktop&&./start on')servopin = 32GPIO.setmode(GPIO.BOARD)GPIO.setup(servopin,GPIO.OUT,initial=False)p = GPIO.PWM(servopin,50)p.start(0)p.ChangeDutyCycle(50) break​​​​             elif '二档'.encode("utf-8") in info:url = "http://tsn.baidu.com/text2audio?tex=正在开风扇一档&lan=zh&cuid=B8-27-EB-BA-24-14&ctp=1&tok="+token+"&per=3"os.system('mpg123 "%s"'%url)os.system('cd /home/pi/Desktop&&./start on')servopin = 32GPIO.setmode(GPIO.BOARD)GPIO.setup(servopin,GPIO.OUT,initial=False)p = GPIO.PWM(servopin,50)p.start(0)p.ChangeDutyCycle(100)breakelif '关掉风扇'.encode("utf-8") in info:url = "http://tsn.baidu.com/text2audio?tex=正在为您关风扇&lan=zh&cuid=B8-27-EB-BA-24-14&ctp=1&tok="+token+"&per=3"os.system('mpg123 "%s"'%url)os.system('cd /home/pi/Desktop&&./start off')servopin = 32GPIO.setmode(GPIO.BOARD)GPIO.setup(servopin,GPIO.OUT,initial=False)p = GPIO.PWM(servopin,50)p.start(0)p.ChangeDutyCycle(0)break
​​​​
​​​​        elif '打开灯'.encode("utf-8") in info:url = "http://tsn.baidu.com/text2audio?tex=正在为您开灯&lan=zh&cuid=B8-27-EB-BA-24-14&ctp=1&tok="+token+"&per=3"os.system('mpg123 "%s"'%url)os.system('cd /home/pi/Desktop&&./light on')breakelif '关掉灯'.encode("utf-8") in info:url = "http://tsn.baidu.com/text2audio?tex=正在为您关灯&lan=zh&cuid=B8-27-EB-BA-24-14&ctp=1&tok="+token+"&per=3"os.system('mpg123 "%s"'%url)time.sleep(0.5)os.system('cd /home/pi/Desktop&&./light off')break
​​​​
​​​​elif info is not None:if'风扇'.encode("utf-8") not in info:if '灯'.encode("utf-8") not in info:if'二档'.encode("utf-8")not in info:tex = tulin.Tuling(info)
​​​​​           if any(['那就换个方式看看'.encode("utf-8") in tex , '扫码出现问题了吗'.encode("utf-8")in tex,'是失效了吗'.encode("utf-8")in tex,'有没有联网呀'.encode("utf-8")in tex,'不会是假的吧'.encode("utf-8")in tex]):url="http://tsn.baidu.com/text2audio?tex=请语音输入指令&lan=zh&cuid=B8-27-EB-BA-24-14&ctp=1&tok="+token+"&per=3"os.system('mpg123 "%s"'%url)continue
​​​​​​​​else:​url = yuyinhecheng.yuyinhecheng_api(tok,tex)os.system('mpg123 "%s"'%url)time.sleep(0.5)
​​​​​                     break​​​​else:url = "http://tsn.baidu.com/text2audio?tex=请语音输入指令&lan=zh&cuid=B8-27-EB-BA-24-14&ctp=1&tok="+token+"&per=3"os.system('mpg123 "%s"'%url)continue
​​​​​
​​​​​
​​​​
if __name__ == '__main__':
controlldevices()代码2:
# coding: utf-8
import sys
import json
import urllib2
import base64
import requests
reload(sys)
sys.setdefaultencoding(“utf-8”)
def get_access_token():
url = “https://openapi.baidu.com/oauth/2.0/token”
body = {
“grant_type”:”client_credentials”,
“client_id” :”此处填写自己的client_id”,
“client_secret”:”此处填写自己的client_secret”,
}
r = requests.post(url,data=body,verify=True)
respond = json.loads(r.text)
return respond["access_token"]
def yuyinshibie_api(audio_data,token):
speech_data = base64.b64encode(audio_data).decode(“utf-8”)
speech_length = len(audio_data)
post_data = {
“format” : “wav”,
“rate” : 16000,
“channel” : 1,
“cuid” : “B8-27-EB-BA-24-14”,
“token” : token,
“speech” : speech_data,
“len” : speech_length
}
url = "http://vop.baidu.com/server_api"
json_data = json.dumps(post_data).encode("utf-8")
json_length = len(json_data)
#print(json_data)req = urllib2.Request(url, data=json_data)
req.add_header("Content-Type", "application/json")
req.add_header("Content-Length", json_length)#print("asr start request\n")
resp = urllib2.urlopen(req)
#print("asr finish request\n")
resp = resp.read()
resp_data = json.loads(resp.decode("utf-8"))
if resp_data["err_no"] == 0:return resp_data["result"]
else:print(resp_data)return None
def asr_main(filename,tok):
try:
f = open(filename, “rb”)
audio_data = f.read()
f.close()
resp = yuyinshibie_api(audio_data,tok)
return resp[0]
except Exception,e:
print “e:”,e
return “识别失败”.encode(“utf-8”)代码3:
# coding: utf-8import requests
import json
import sys
reload(sys)
sys.setdefaultencoding("utf-8")def Tuling(words):Tuling_API_KEY = "此处填写自己的Turling KEY"body = {"key":Tuling_API_KEY,"info":words.encode("utf-8")}url = "http://www.tuling123.com/openapi/api"r = requests.post(url,data=body,verify=True)if r:date = json.loads(r.text)print date["text"]return date["text"]else:return None代码4:
# coding: utf-8
import sys
import urllib2
import json
import os
import yuyinshibie
reload(sys)
sys.setdefaultencoding(“utf-8”)
def yuyinhecheng_api(tok,tex):
cuid = “B8-27-EB-BA-24-14”
spd = “4”
url = “http://tsn.baidu.com/text2audio?tex=“+tex+”&lan=zh&cuid=”+cuid+”&ctp=1&tok=”+tok+”&per=3”
#print url
#response = requests.get(url)
#date = response.read()
return url
def tts_main(filename,words,tok):
voice_date = yuyinhecheng_api(tok,words)
f = open(filename,"wb")
f.write(voice_date)
f.close()代码5:
//脚本light的内容
#!/bin/bash
if [ $# > 1 ]
then
/usr/local/bin/gpio mode 4 outif [[ "$1" = "on" ]]then
/usr/local/bin/gpio write 4 onfiif [[ "$1" = "off" ]]then
/usr/local/bin/gpio write 4 offfi
fi//给灯泡脚本权限
chmod u+x light//测试灯泡亮
1 ./light on
2 ./light off

树莓派打造智能语音控制系统相关推荐

  1. 树莓派蓝牙ble gattlib c语言,树莓派构建智能家居控制系统 篇三:花花草草智能监测仪接入树莓派Domoticz...

    树莓派构建智能家居控制系统 篇三:花花草草智能监测仪接入树莓派Domoticz 2017-05-22 19:30:08 35点赞 410收藏 31评论 作为工科男,实在对花花草草没太多感觉.家里阳台养 ...

  2. Python语言打造智能语音助手——附完整源码

    Python语言打造智能语音助手--附完整源码 随着智能家居.智能办公等领域的逐渐兴起,实现语音控制与交互已成为了一种趋势.而Python语言是一门极具魅力的编程语言,其强大的库.简洁的语法以及易于学 ...

  3. 用机智云和ShineBlink打造智能语音控制版宠物屋

    自从养了宠物后,才知道养宠物和养娃一样都要费时费力,但是现在大家都忙于生计早出晚归,为了更好的照顾到宠物,我们利用机智云物联网开发平台.ShineBlink开发板.传感器.语音控制模块.Wi-Fi模块 ...

  4. 【小白教程】基于树莓派的智能语音助手-python

    [完整教程零基础]基于树莓派的智能语音助手-python 树莓派3b+.python3系统自带.百度语音识别与合成.调用图灵机器人(热词唤醒失败,可用snowboy) 1.Windows系统下[下载+ ...

  5. 树莓派打造智能家居(二):MQTT搭建和测试

    1.MQTT是什么 1.1概念 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式 ...

  6. python开发闹钟_「玩转树莓派」为女朋友打造一款智能语音闹钟

    前言 最近在做智慧工厂相关的工作,多多少少了解了一点物联网相关的技术.于是心血来潮,寻思自己可以做点什么,恰巧之前听说过一些树莓派的传闻,于是就有了这么一款闹钟. 需要说明的是,在看这篇文章之前,你至 ...

  7. 「玩转树莓派」为女朋友打造一款智能语音闹钟

    前言 最近在做智慧工厂相关的工作,多多少少了解了一点物联网相关的技术.于是心血来潮,寻思自己可以做点什么,恰巧之前听说过一些树莓派的传闻,于是就有了这么一款闹钟. 需要说明的是,在看这篇文章之前,你至 ...

  8. python语音唤醒_Python实战教程:为女朋友打造一款智能语音闹钟

    Python实战教程:为女朋友打造一款智能语音闹钟 前言 最近学了一些物联网相关的技术,有点心血来潮,寻思自己可以做点什么,恰巧之前听说过一些树莓派的传闻,就想着做一款智能点的闹钟. 需要说明的是,在 ...

  9. python语音唤醒_用Python为女朋友打造一款智能语音闹钟

    image 前言 最近在做智慧工厂相关的工作,多多少少了解了一点物联网相关的技术.于是心血来潮,寻思自己可以做点什么,恰巧之前听说过一些树莓派的传闻,于是就有了这么一款闹钟. 需要说明的是,在看这篇文 ...

  10. python做一个闹钟_【玩转Python】为女朋友打造一款智能语音闹钟

    在看这篇文章之前,你至少应该是一个会装操作系统的程序猿,懂点 Linux,会些 Python,最主要的是你得有一个女朋友.当然没有也没关系,相信看完这篇文章,你也尝试做了这么一款闹钟,说不定..... ...

最新文章

  1. 谁是AI行业最受关注的人?未来图灵发布《AI明星企业家热搜榜》
  2. 一次搞定OpenCV源码及扩展模块的编译与环境配置
  3. samtools常用命令详解
  4. R语言分类算法之线性判别分析(Linear Discriminant Analysis)
  5. 经典小程序源码及其下载地址
  6. pdf转jpg的在线与用转换器的转换方法
  7. 正则表达式-验证手机号与邮箱
  8. 猩猩艾艾吸烟_艾艾在墙上谁是最公平的
  9. 论文阅读 “Adaptive Tool Path Planning Strategy for Freeform Surface Machining using Point Cloud Article”
  10. PS从入门到精通第4节——祖传抠图技法
  11. iOS Code Signing 学习笔记转写
  12. Redis启动和停止(Ubuntu)
  13. square enix服务器维护,Square Enix解决《最终幻想14》的服务器问题
  14. Carmichael function[卡迈克尔函数相关性质]
  15. 什么是三层交换机?二层交换与三层交换和路由有什么区别?
  16. 使用deconvblind估计PSF
  17. 马化腾同款的效率神器 搜狗录音翻译笔京东首批已断货
  18. BlockChain:2020年7月10日世界人工智能大会WAIC《链智未来 赋能产业区块链主题论坛》(三)
  19. python股票趋势线_如何计算股票图表的趋势线
  20. Burpsuite抓取app数据包

热门文章

  1. 专转本-矩阵的初等变换与线性方程组
  2. Win10 使用 Virtual Box 安装 Ubuntu 虚拟机
  3. 阿里P7大牛手把手教你!java全栈工程师证书
  4. Android地图轨迹抽稀、动态绘制
  5. linux服务器搭建开源蝉道10步走
  6. 如何用es6 set实现交差并集
  7. 七年级画图计算机教案,信息技术画图软件学习教案
  8. API文档自动生成工具
  9. [UE4]委托代理:单播委托,多播委托,动态单播委托,动态多播委托,事件
  10. C#事件和委托的区别