语音操作esp8266(基于micropython)

准备

在科大讯飞官网下载Android MSC(SDK)

此图像的alt属性为空;文件名为image-1.png

在下载好的SDK中把libs内的文件复制到工程的libs目录下

此图像的alt属性为空;文件名为image-2.png

gson2.8.5下载链接:https://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.5/gson-2.8.5.jar

右键libs中的jar包,选择add as library

此图像的alt属性为空;文件名为image-4.png

将SDK中的assets复制到main目录下

此图像的alt属性为空;文件名为image-3.png

固件

http://www.micropython.org/resources/firmware/esp8266-20191220-v1.12.bin

代码

esp8266(micropython)

from machine import Pin
import dht,time,network
from socket import *

global wendu,shidu
#初始化相关模块
led = Pin(2,Pin.OUT,value=1)#灯
#创建DTH11对象
d = dht.DHT11(Pin(5)) #传感器连接到引脚14
time.sleep(1)   #首次+启动停顿1秒让传感器稳定

def WIFI_Connect():
    wlan = network.WLAN(network.STA_IF) #STA模式 
    wlan.active(True)                   #激活接口
    #配置单片机ip 掩码等
    start_time=time.time()              #记录时间做超时判断
    if not wlan.isconnected():
        wlan.connect('wifi名字', 'wifi密码') #WIFI账号密码
        while not wlan.isconnected():
            #超时判断,15秒没连接成功判定为超时
            if time.time()-start_time > 50 :
                print('WIFI Connected Timeout!')
                break

    if wlan.isconnected():
        #串口打印信息
        print('network information:', wlan.ifconfig())
        return True
    else:
        return False
 
def dht_get():
    d.measure()         #温湿度采集
    wendu = d.temperature()
    shidu = d.humidity()
    HOST = ''  # 主机号为空白表示可以使用任何可用的地址。
    PORT = 8998  # 端口号
    BUFSIZ = 1024  # 接收数据缓冲大小
    ADDR = (HOST, PORT)

    tcpSerSock = socket(AF_INET, SOCK_STREAM)  # 创建TCP服务器套接字
    tcpSerSock.bind(ADDR)  # 套接字与地址绑定
    tcpSerSock.listen(5)  # 监听连接,同时连接请求的最大数目

    while True:
        print('等待客户端的连接...')
        tcpCliSock, addr = tcpSerSock.accept()  # 接收客户端连接请求
        print('取得连接:', addr)
        
        while True:
            data = tcpCliSock.recv(BUFSIZ)  # 连续接收指定字节的数据,接收到的是字节数组
            if not data:  # 如果数据空白,则表示客户端退出,所以退出接收
                break
            tcpCliSock.send(('温度为%s湿度为%s'%(wendu,shidu)).encode())
            #发送消息
            print(data.decode().strip())
            #接收到的消息
            if(data.decode().strip() == 'on'):
              led.value(0)
            elif(data.decode().strip() == 'off'):
              led.value(1)
        tcpCliSock.close()  # 关闭与客户端的连接
    tcpSerSock.close()  # 关闭服务器socket
   
if WIFI_Connect():
    dht_get()
   

Android Studio

MainActivity.java

package com.example.esp8266;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.EditText;
import com.google.gson.Gson;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.SynthesizerListener;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    private Socket socke;
    private PrintWriter pw;
    private String data;
    private String Recognition_txt;

    //所需申请的权限
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.INTERNET,
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.ACCESS_NETWORK_STATE,
            Manifest.permission.ACCESS_WIFI_STATE,
            Manifest.permission.CHANGE_NETWORK_STATE,
            Manifest.permission.READ_PHONE_STATE,
            Manifest.permission.READ_CONTACTS,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.CAMERA
    };
    public static class AudioUtils {
        private static AudioUtils audioUtils;
        private SpeechSynthesizer mySynthesizer;
        public AudioUtils(){

        }

        public static AudioUtils getInstance() {
            if (audioUtils == null) {
                synchronized (AudioUtils.class) {
                    if (audioUtils == null) {
                        audioUtils = new AudioUtils();
                    }
                }
            }
            return audioUtils;
        }

        private InitListener myInitListener = new InitListener() { @Override public void onInit(int code) {  } };

        public void init(Context context) {
            mySynthesizer = SpeechSynthesizer.createSynthesizer(context, myInitListener);
            mySynthesizer.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan");
            //发音人xiaoyan
            mySynthesizer.setParameter(SpeechConstant.SPEED,"50");
            //语速50
            mySynthesizer.setParameter(SpeechConstant.PITCH, "50");
            //语调50
            mySynthesizer.setParameter(SpeechConstant.VOLUME, "100");
            //音量100
        }

        public void speakText(String content){
            int code =mySynthesizer.startSpeaking(content,new SynthesizerListener(){

                @Override
                public void onSpeakBegin() {

                }

                @Override
                public void onBufferProgress(int i, int i1, int i2, String s) {

                }

                @Override
                public void onSpeakPaused() {

                }

                @Override
                public void onSpeakResumed() {

                }

                @Override
                public void onSpeakProgress(int i, int i1, int i2) {

                }

                @Override
                public void onCompleted(SpeechError speechError) {

                }

                @Override
                public void onEvent(int i, int i1, int i2, Bundle bundle) {

                }
            });
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        applypermission();
        // 将“xxxxxx”替换成您申请的APPID,申请地址:http://www.xfyun.cn
        // 请勿在“=”与appid之间添加任何空字符或者转义符
        SpeechUtility.createUtility(this, SpeechConstant.APPID +"=xxxxxx");

        final Handler handler = new Handler(){
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                if(msg.what==1){

                }
            }
        };


        new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        Socket sk = null;
                        while(true) {
                            try {
                                // 读Sock里面的数据
                                InputStream s = socke.getInputStream();
                                byte[] buf = new byte[1024];
                                int len = 0;
                                while ((len = s.read(buf)) != -1) {
                                    data = new String(buf, 0, len);
                                    handler.sendEmptyMessage(1);
                                }
                                Thread.sleep(1000);
                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }

                        }
                    }
                }).start();
    }

    //建立socket连接
    Thread connection = new Thread(new Runnable() {
        @Override
        public void run() {
            final EditText editext1 = (EditText) findViewById(R.id.edittext1);
            final EditText editext2 = (EditText) findViewById(R.id.edittext2);
            try {
                socke = new Socket(editext1.getText().toString(),Integer.valueOf(editext2.getText().toString()));
                pw = new PrintWriter(socke.getOutputStream(),true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

    public void run(View view){
        connection.start();
    }

    //定义判断权限申请的函数,在onCreat中调用就行
    public void applypermission(){
        if(Build.VERSION.SDK_INT>=23){
            boolean needapply=false;
            for(int i=0;i<PERMISSIONS_STORAGE.length;i++){
                int chechpermission= ContextCompat.checkSelfPermission(getApplicationContext(),
                        PERMISSIONS_STORAGE[i]);
                if(chechpermission!= PackageManager.PERMISSION_GRANTED){
                    needapply=true;
                }
            }
            if(needapply){
                ActivityCompat.requestPermissions(MainActivity.this,PERMISSIONS_STORAGE,1);
            }
        }
    }
    public class Recognition{
        /**
         *@TODO 科大讯飞语音听写
         * linowl 2020.09.11
         */
        public void initSpeech(final Context context) {
            //1.创建RecognizerDialog对象
            RecognizerDialog mDialog = new RecognizerDialog(context, null);
            //识别器定义
            //2.设置accent、language等参数
            mDialog.setParameter(SpeechConstant.DOMAIN,"iat");
            //应用领域  iat:日常用语   medical:医疗
            mDialog.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
            //语言 zh_cn:中文 en_us:英文 ja_jp:日语 ko_kr:韩语 ru-ru:俄语 fr_fr:法语 es_es:西班牙语
            mDialog.setParameter(SpeechConstant.ACCENT, "mandarin");
            //方言  默认mandarin
            //3.设置回调接口
            mDialog.setListener(new RecognizerDialogListener() {
                @Override
                public void onResult(RecognizerResult recognizerResult, boolean isLast) {
                    if (!isLast) {
                        //解析语音
                        String result = parseVoice(recognizerResult.getResultString());
                        voiceif(result);

                    }
                }

                @Override
                public void onError(SpeechError speechError) {

                }
            });
            //4.显示dialog,接收语音输入
            mDialog.show();
        }
    }
    /**
     * 解析语音json
     */
    public String parseVoice(String resultString) {
        Gson gson = new Gson();
        Voice voiceBean = gson.fromJson(resultString, Voice.class);

        StringBuffer sb = new StringBuffer();
        ArrayList<Voice.WSBean> ws = voiceBean.ws;
        for (Voice.WSBean wsBean : ws) {
            String word = wsBean.cw.get(0).w;
            sb.append(word);
        }
        return sb.toString();
    }
    /**
     * 语音实体类
     */
    public class Voice {

        public ArrayList<WSBean> ws;

        public class WSBean {
            public ArrayList<CWBean> cw;
        }

        public class CWBean {
            public String w;
        }
    }

    //调用use类的initSpeech函数
    public void Recognition(View view){
        new Recognition().initSpeech(this);
    }

    public void send_msg(String send_txt){
        pw.println(send_txt);
    }

    public void voiceif(String speek_txt){//在服务器读取esp8266的数据

        if (speek_txt.equals("当前状态")){//判断语音识别的信息
            try {
                AudioUtils.getInstance().init(this); //初始化语音对象
                AudioUtils.getInstance().speakText(data); //播放语音
            }catch (Exception e){
                e.printStackTrace();
            }
        }else if(speek_txt.equals("开灯")){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    send_msg("on");
                }
            }).start();
        }else if(speek_txt.equals("关灯")){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    send_msg("off");
                }
            }).start();
        }
    }

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/edittext1"
        android:layout_width="210dp"
        android:layout_height="40dp"
        android:layout_marginTop="28dp"
        android:hint="IP地址"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/edittext2"
        android:layout_width="210dp"
        android:layout_height="40dp"
        android:layout_marginTop="20dp"
        android:hint="端口号"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/edittext1" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="28dp"
        android:onClick="run"
        android:text="连接"
        app:layout_constraintEnd_toEndOf="@+id/edittext2"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="@+id/edittext2"
        app:layout_constraintTop_toBottomOf="@+id/edittext2" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="Recognition"
        android:text="识别"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button" />


</androidx.constraintlayout.widget.ConstraintLayout>

在AndroidManifest.xml添加权限

<!--连接网络权限,用于执行云端语音能力 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!--获取手机录音机使用权限,听写、识别、语义理解需要用到此权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!--读取网络信息状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--获取当前wifi状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--允许程序改变网络连接状态 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!--读取手机信息权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!--读取联系人权限,上传联系人需要用到此权限 -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<!--外存储写权限,构建语法需要用到此权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--外存储读权限,构建语法需要用到此权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!--手机定位信息,用来为语义等功能提供定位,提供更精准的服务-->
<!--定位信息是敏感信息,可通过Setting.setLocationEnable(false)关闭定位请求 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--如需使用人脸识别,还要添加:摄相头权限,拍照需要用到 -->
<uses-permission android:name="android.permission.CAMERA" />

build.gradle

此图像的alt属性为空;文件名为image-5.png

注意

单片机作为服务器,图中红色框住的为ip地址,IP地址和端口要和服务器设置的一样。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇