语音控制单片机(python做的上位机控制arduino)

最近看了垃圾分类很多人做,身为学电子出身的我,也想试试。那首先怎么实现分类呢? 搞摄像头识别。。。。感觉有点难度,还要算法,慢慢研究,然后灵机一动就想到语音控制,我的想法是我说这个垃圾的名称,然后下位机就能识别出垃圾的种类。比如我说,鸡蛋壳,下位机就能识别到
这是干垃圾,就打开相应的垃圾桶,好的说干就干。赶紧上某宝,搜一下语音模块,额 感觉有点贵啊。还要一个一个词条一个词条的录入(其实还是因为贵)。这个方案被我果断否定。
某宝上的语音模块

第二个方案,毕业之后自学了python,百度的语音识别还是很好用的(主要是免费),于是就有个第二个方案,python使用百度语音识别,识别出说得话,获取到语音文本后,爬虫访问垃圾查询网址得到垃圾种类,得到垃圾种类,串口发送给单片机进行处理。
视频链接 https://www.bilibili.com/video/av79334315/

先上效果视频

智能垃圾分类Python上位机+arduino下位机

还有源代码
https://download.csdn.net/download/qq_31366371/12033572
代码文件目录下dist\get_main\get_main.exe 可以直接运行测试

代码功能有很多可以优化的地方:
语音唤醒功能试了很多方案:snowboy,pocketsphinx(这个库貌似智能安装在python3.6环境下,我用的又是python3.7)
爬虫解析数据的程序中也设计得不合理,在运行中一旦程序出错,程序会强制退出。

下面就贴出主要程序:
首先先在百度AI上注册账号,在控制台创建语音技术应用如下图
百度AI控制台
创建完成。
安装使用Python SDK有如下方式:
如果已安装pip,执行pip install baidu-aip即可。
安装库文件。
测试一下 成功识别后打印出{'corpus_no': '6769193090787399379', 'err_msg': 'success.', 'err_no': 0, 'result': ['你好'], 'sn': '875945441651576075584'}

from aip import AipSpeech
""" 你的 APPID AK SK """
APP_ID = '你创建的语音识别应用里有'
API_KEY = '你创建的语音识别应用里有'
SECRET_KEY = '你创建的语音识别应用里有'
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
def get_file_content(filePath):
     with open(filePath, 'rb') as fp:
        return fp.read()
ser = client.asr(get_file_content(r'./1.wav'), 'wav', 16000, {'dev_pid': 1536,}) #注意你的音频文件的采样率一定要是16K的
print(ser)

好的我们先在能进行语音识别了,接下来需要我们通过python进行录音把需要百度AI处理的语音说出来这就需要到python的另一个库
安装库文件在cmd控制面板下输入pip install pyaudio 、pip install wave
安装完成后编辑录音的程序,按1开始录音,按2停止录音,把保存的wav文件用百度语音进行识别就可以得到一个语音文本。

——————————这是代码块———————————————


import pyaudio
import time
import threading
import wave
 
class Recorder():
    def __init__(self, chunk=1024, channels=1, rate=16000):
        self.CHUNK = chunk
        self.FORMAT = pyaudio.paInt16
        self.CHANNELS = channels
        self.RATE = rate
        self._running = True
        self._frames = []
    def start(self):
        threading._start_new_thread(self.__recording, ())
    def __recording(self):
        self._running = True
        self._frames = []
        p = pyaudio.PyAudio()
        stream = p.open(format=self.FORMAT,
                        channels=self.CHANNELS,
                        rate=self.RATE,
                        input=True,
                        frames_per_buffer=self.CHUNK)
        while(self._running):
            data = stream.read(self.CHUNK)
            self._frames.append(data)
 
        stream.stop_stream()
        stream.close()
        p.terminate()
 
    def stop(self):
        self._running = False
 
    def save(self, filename):
        
        p = pyaudio.PyAudio()
        if not filename.endswith(".wav"):
            filename = filename + ".wav"
        wf = wave.open(filename, 'wb')
        wf.setnchannels(self.CHANNELS)
        wf.setsampwidth(p.get_sample_size(self.FORMAT))
        wf.setframerate(self.RATE)
        wf.writeframes(b''.join(self._frames))
        wf.close()
        print("Saved")
 
def LuYin():
   
    a = int(input('请输入1开始录音:'))
    if a == 1:           
        rec = Recorder()
        begin = time.time()
        print("Start recording")
        rec.start()
        b = int(input('请输入2停止录音:'))
        if b == 2:
            print("Stop recording")
            rec.stop()
            fina = time.time()
            t = fina - begin
            print('录音时间为%ds'%t)
            rec.save(r"./1.wav")
if __name__ == "__main__":
    LuYin()

爬取垃圾分类网站的信息,具体思路就是使用fiddler抓包,然后在用python构造get请求。

def shibei_LaJi():
    str_utf8=t2u.text2utf8()
    url=r'https://www.smartmll.com/?s='
    url = url + str_utf8[1]  # 构造Ulr参数 
    print(url)
    res1 = requests.get(url,headers=headers,verify=False)  

    #print(res1.text)  #  取网页源码 打印出全部网络数据 用于调试
    with open(r"./douban.txt","w") as f:
            f.write(res1.text)
    txt_op.delblankline(r"./douban.txt",r"./text2.txt")  #将文本中的空行去掉
    Garbage=txt_operation.web_parsing() #获取垃圾种类
    if Garbage =='请输入垃圾':
        playsound('./test.mp3')
    else:
        result  = client.synthesis(str_utf8[0]+"属于"+Garbage, 'zh', 1, {'vol': 5,'per':4,'spd':5})  #调用百度文字转语音
    #识别正确返回语音二进制 错误则返回dict 参照下面错误码
        if not isinstance(result, dict):
            with open('./auido.mp3', 'wb+') as f:
                f.write(result)
        playsound("auido.mp3")
    print (Garbage)
    return Garbage

通过垃圾分类网站得到垃圾种类后在通过串口发送给单片机进行处理

def serial_send():
    Garbage_utf8 = shibei_LaJi()
    s_utf8 =  Garbage_utf8.encode('UTF-8') #垃圾种类的文本转UTF-8格式
    string = str(s_utf8)
    string=string.strip('b')
    #print(string) #去除头字母 '\xe4\xb8\xad\xe5\x9b\xbd
    string = string.strip(r"'") #去除字符串中的首尾的1单引号
    string=string.replace(r'\x','') #把字符串中的/x, 删除
    #string=string.replace(r'\x','\000') 前一个程序中使用 空字符替换/x 造成在串口读取中出现错误

    string= string.upper()
    
    print(type(string))
    ser.write(bytes(string.encode("UTF8")))  #发送识别到的垃圾种类 
    
    time.sleep(2)     #sleep() 与 inWaiting() 最好配对使用
    num=ser.inWaiting()
    uart_data = ser.read(num)
    print(uart_data)
    ser.close()    
    print(string)

arduino程序读取发送来的值,从而实现智能语音识别垃圾种类uart_data == “E58FAFE59B9EE694B6E789A9” 表示垃圾种类的UTF-8编码
https://www.qqxiuzi.cn/bianma/guojima.php 可通过这个网站查询
在这里插入图片描述

char x;//缓存函数
String comdata = "";//字符串函数
String uart_data = "" ;//保存串口接收到的值
int i=0;
void setup() {
  Serial.begin(115200);//打开串口波特率115200
  pinMode(A0, OUTPUT);
  pinMode(A1, OUTPUT);
}
void loop()
{
  if (Serial.available() > 0)//判读是否串口有数据
  {
    String comdata = "";//缓存清零
    while (Serial.available() > 0)//循环串口是否有数据
    {
      x = Serial.read();
      comdata += x;//叠加数据到comdata
      uart_data = comdata;
      delay(2);//延时等待响应
    }
    if (comdata.length() > 0)//如果comdata有数据
    {
      Serial.print(comdata);//打印comdata数据
    }
  }
  if (uart_data == "E58FAFE59B9EE694B6E789A9")  //可回收物
  {
        digitalWrite(A0, HIGH);
  }
  
  if (uart_data == "E5B9B2E59E83E59CBE")  //干垃圾
  {
       digitalWrite(A1, HIGH);       
  }
}
  • 6
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值