【ESP32S3 Sense接入百度在线语音识别】

这篇具有很好参考价值的文章主要介绍了【ESP32S3 Sense接入百度在线语音识别】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

视频地址:

ESP32S3 Sense接入百度在线语音识别

目前这是我使用的ESP32S3官方硬件👍👍👍(小小的身材有大大的力量)只需要35元加摄像头麦克风79元,后期我会整理相关专栏进行Arduino系统学习😘😘😘。有需要可以购买xiao开发板💕💕💕,SeeedXIAO ESP32S3 Sense硬件购买地址:https://s.click.taobao.com/lekazrt
语音识别接入,arduino学习,百度,语音识别,Seeed xiao,ESP32S3

1. 前言

语音识别接入,arduino学习,百度,语音识别,Seeed xiao,ESP32S3

使用Seeed XIAO ESP32S3 Sense开发板接入百度智能云实现在线语音识别。自带麦克风模块用做语音输入,通过串口发送字符“1”来控制数据的采集和上传。
语音识别接入,arduino学习,百度,语音识别,Seeed xiao,ESP32S3

步骤概括   
(1) 在百度云控制端选择“语音识别”并创建应用获取API Key和Secret Key获取token   
(2)采集音频数据,将数据打包成规定的格式,POST发送到请求API
(3) 接收返回的识别数据

2. 操作流程

2.1 创建语音识别应用

登录百度云账号,选择语音识别
  官网地址:https://ai.baidu.com/tech/speech
语音识别接入,arduino学习,百度,语音识别,Seeed xiao,ESP32S3
新用户可以直接领取资源,也可付费接入,创建应用。
语音识别接入,arduino学习,百度,语音识别,Seeed xiao,ESP32S3
根据创建应用生成的API Key和Secret Key来获取token,创建好应用,点管理应用,会有API Key和Secret Key,如下图应用创建成功
语音识别接入,arduino学习,百度,语音识别,Seeed xiao,ESP32S3

2.2 API秘钥创建

点击在线调试
语音识别接入,arduino学习,百度,语音识别,Seeed xiao,ESP32S3
按照如下顺序选择
语音识别接入,arduino学习,百度,语音识别,Seeed xiao,ESP32S3

有了API Key和Secret Key就可以得到token,下面附上ESP32进行get请求得到token的代码

语音识别接入,arduino学习,百度,语音识别,Seeed xiao,ESP32S3

access_token对应的值就是可用的token了,每次申请的token有效期为30天,过期需要重新申请,可以申请多个。不用每次都调用获取token的程序,申请一个可以用30天,定时更新就可以吧。

3. JSON语音接入

采集数据,POST发送到请求API数据上传 POST 方式有 2 种:JSON 格式和RAW 格式。
语音识别接入,arduino学习,百度,语音识别,Seeed xiao,ESP32S3

3.1 JSON格式

这里介绍使用使用JSON格式上传的方式,下图为JSON格式上传的一些必要的参数说明
语音识别接入,arduino学习,百度,语音识别,Seeed xiao,ESP32S3

3.2 ESP32S3 Sense接入代码

图中对数据类型和内容说的很明确了,只需要按照这个格式打包好数据然后发送就行,下面是ESP32的具体实现代码。

#include <Arduino.h>
#include "base64.h"
#include "WiFi.h"
#include "HTTPClient.h"
#include "cJSON.h"
#include <I2S.h>
#include <ArduinoJson.h>

// #define key 4             //端口0
// #define ADC 2             //端口39
// #define led 15            //端口2
const int buttonPin = 1;  // the number of the pushbutton pin
const int ledPin = 21;    // the number of the LED pin
HTTPClient http_client;
// 1. Replace with your network credentials
const char* ssid = "J09 502";
const char* password = "qwertyuiop111";
hw_timer_t* timer = NULL;

#define data_len 16000
uint16_t adc_data[data_len];  //16000个数据,8K采样率,即2秒,录音时间为2秒,想要实现更长时间的语音识别,就要改这个数组大小
                              //和下面data_json数组的大小,改大一些。

uint8_t adc_start_flag = 0;     //开始标志
uint8_t adc_complete_flag = 0;  //完成标志


char data_json[45000];  //用于储存json格式的数据,大一点,JSON编码后数据字节数变成原来的4/3,所以得计算好,避免出现越界


void IRAM_ATTR onTimer();
void gain_token(void);
void setup() {

  //Serial.begin(921600);
  Serial.begin(115200);
  // pinMode(ADC, ANALOG);
  // pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  // start I2S at 16 kHz with 16-bits per sample
  I2S.setAllPins(-1, 42, 41, -1, -1);
  if (!I2S.begin(PDM_MONO_MODE, 16000, 16)) {
    Serial.println("Failed to initialize I2S!");
    while (1)
      ;  // do nothing
  }
  uint8_t count = 0;
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    count++;
    if (count >= 75) {
      Serial.printf("\r\n-- wifi connect fail! --");
      break;
    }
    vTaskDelay(200);
  }
  Serial.printf("\r\n-- wifi connect success! --\r\n");

  // gain_token();

  timer = timerBegin(0, 80, true);    //  80M的时钟 80分频 1M
  timerAlarmWrite(timer, 125, true);  //  1M  计125个数进中断  8K
  timerAttachInterrupt(timer, &onTimer, true);
  timerAlarmEnable(timer);
  timerStop(timer);  //先暂停
}


uint32_t time1, time2;
void loop() {

  if (Serial.available() > 0)  //按键按下
  {
    if (Serial.read() == '1') {
      Serial.printf("Start recognition\r\n\r\n");
      digitalWrite(ledPin, HIGH);
      adc_start_flag = 1;
      timerStart(timer);

      // time1=micros();
      while (!adc_complete_flag)  //等待采集完成
      {
        ets_delay_us(10);
      }
      // time2=micros()-time1;

      timerStop(timer);
      adc_complete_flag = 0;  //清标志

      digitalWrite(ledPin, LOW);

      // Serial.printf("time:%d\r\n",time2);  //打印花费时间


      memset(data_json, '\0', strlen(data_json));  //将数组清空
      strcat(data_json, "{");
      strcat(data_json, "\"format\":\"pcm\",");
      strcat(data_json, "\"rate\":16000,");                                                                        //采样率    如果采样率改变了,记得修改该值,只有16000、8000两个固定采样率
      strcat(data_json, "\"dev_pid\":1537,");                                                                      //中文普通话
      strcat(data_json, "\"channel\":1,");                                                                         //单声道
      strcat(data_json, "\"cuid\":\"666666\",");                                                                   //识别码    随便打几个字符,但最好唯一
      strcat(data_json, "\"token\":\"24.8f6133335e191.2592000.1713789066.282335-57722200\",");  //token	这里需要修改成自己申请到的token
      strcat(data_json, "\"len\":32000,");                                                                         //数据长度  如果传输的数据长度改变了,记得修改该值,该值是ADC采集的数据字节数,不是base64编码后的长度
      strcat(data_json, "\"speech\":\"");
      strcat(data_json, base64::encode((uint8_t*)adc_data, sizeof(adc_data)).c_str());  //base64编码数据
      strcat(data_json, "\"");
      strcat(data_json, "}");
      // Serial.println(data_json);


      int httpCode;
      http_client.setTimeout(5000);
      http_client.begin("http://vop.baidu.com/server_api");  //https://vop.baidu.com/pro_api
      http_client.addHeader("Content-Type", "application/json");
      httpCode = http_client.POST(data_json);

      if (httpCode == 200) {
        if (httpCode == HTTP_CODE_OK) {
          String response = http_client.getString();
          http_client.end();
          Serial.println(response);
          // Parse JSON response
          DynamicJsonDocument jsonDoc(512);
          deserializeJson(jsonDoc, response);
          String outputText = jsonDoc["result"][0];
          // 访问"result"数组,并获取其第一个元
          // 输出结果
          Serial.println(outputText);

        } else {
          Serial.printf("[HTTP] GET... failed, error: %s\n", http_client.errorToString(httpCode).c_str());
        }
      }
      // while (!digitalRead(buttonPin))
      //   ;
      Serial.printf("Recognition complete\r\n");
    }
  }
  vTaskDelay(1);
}


uint32_t num = 0;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR onTimer() {
  // Increment the counter and set the time of ISR
  portENTER_CRITICAL_ISR(&timerMux);
  if (adc_start_flag == 1) {
    //Serial.println("");
    // adc_data[num] = analogRead(ADC);
    adc_data[num] = I2S.read();
    num++;
    if (num >= data_len) {
      adc_complete_flag = 1;
      adc_start_flag = 0;
      num = 0;
      //Serial.println(Complete_flag);
    }
  }
  portEXIT_CRITICAL_ISR(&timerMux);
}



// void gain_token(void)  //获取token
// {
//   int httpCode;
//   //注意,要把下面网址中的your_apikey和your_secretkey替换成自己的API Key和Secret Key
//   http_client.begin("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=your_apikey&client_secret=your_secretkey");
//   httpCode = http_client.GET();
//   if (httpCode > 0) {
//     if (httpCode == HTTP_CODE_OK) {
//       String payload = http_client.getString();
//       Serial.println(payload);
//     }
//   } else {
//     Serial.printf("[HTTP] GET... failed, error: %s\n", http_client.errorToString(httpCode).c_str());
//   }
//   http_client.end();
// }

3.3 ESP32接入代码

使用ESP32接入百度智能云实现在线语音识别,max9814麦克风模块用做语音输入,一个按键来控制数据的采集和上传

#include <Arduino.h>
#include "base64.h"
#include "WiFi.h"
#include "HTTPClient.h"
#include "cJSON.h"



#define key 4       //端口0
#define ADC 2      //端口39
#define led 15       //端口2

HTTPClient http_client;

hw_timer_t * timer = NULL;

#define data_len 16000
uint16_t adc_data[data_len];    //16000个数据,8K采样率,即2秒,录音时间为2秒,想要实现更长时间的语音识别,就要改这个数组大小
                                //和下面data_json数组的大小,改大一些。

uint8_t adc_start_flag=0;       //开始标志
uint8_t adc_complete_flag=0;    //完成标志


char data_json[45000];  //用于储存json格式的数据,大一点,JSON编码后数据字节数变成原来的4/3,所以得计算好,避免出现越界


void IRAM_ATTR onTimer();
void gain_token(void);
void setup() {

    //Serial.begin(921600);
    Serial.begin(115200);
    pinMode(ADC,ANALOG);     
    pinMode(key,INPUT_PULLUP);
    pinMode(led,OUTPUT);      
    
    uint8_t count=0;
    WiFi.disconnect(true);
    WiFi.begin("1111110","88888888");//填写自己的wifi账号密码
    while (WiFi.status() != WL_CONNECTED) 
    {
        Serial.print(".");
        count++;
        if(count>=75){
            Serial.printf("\r\n-- wifi connect fail! --");
            break;
        }
        vTaskDelay(200);
    }
    Serial.printf("\r\n-- wifi connect success! --\r\n");
    
    // gain_token();

    timer = timerBegin(0, 80, true);    //  80M的时钟 80分频 1M
    timerAlarmWrite(timer, 125, true);  //  1M  计125个数进中断  8K
    timerAttachInterrupt(timer, &onTimer, true);
    timerAlarmEnable(timer);
    timerStop(timer);   //先暂停
}


uint32_t time1,time2;
void loop() {
    
    if(digitalRead(key)==0) //按键按下
    {
        Serial.printf("Start recognition\r\n\r\n");
        digitalWrite(led,HIGH);
        adc_start_flag=1;
        timerStart(timer);

        // time1=micros();
        while(!adc_complete_flag)  //等待采集完成
        {
            ets_delay_us(10);
        }
        // time2=micros()-time1;

        timerStop(timer);
        adc_complete_flag=0;        //清标志

        digitalWrite(led,LOW);

        // Serial.printf("time:%d\r\n",time2);  //打印花费时间
        
        
        memset(data_json,'\0',strlen(data_json));   //将数组清空
        strcat(data_json,"{");
        strcat(data_json,"\"format\":\"pcm\",");
        strcat(data_json,"\"rate\":8000,");         //采样率    如果采样率改变了,记得修改该值,只有16000、8000两个固定采样率
        strcat(data_json,"\"dev_pid\":1537,");      //中文普通话
        strcat(data_json,"\"channel\":1,");         //单声道
        strcat(data_json,"\"cuid\":\"666666\",");   //识别码    随便打几个字符,但最好唯一
        strcat(data_json,"\"token\":\"24.c640024cd1355e\",");  //token	这里需要修改成自己申请到的token
        strcat(data_json,"\"len\":32000,");         //数据长度  如果传输的数据长度改变了,记得修改该值,该值是ADC采集的数据字节数,不是base64编码后的长度
        strcat(data_json,"\"speech\":\"");
        strcat(data_json,base64::encode((uint8_t *)adc_data,sizeof(adc_data)).c_str());     //base64编码数据
        strcat(data_json,"\"");
        strcat(data_json,"}");
        // Serial.println(data_json);
        

        int httpCode;
        http_client.begin("http://vop.baidu.com/server_api");         //https://vop.baidu.com/pro_api
        http_client.addHeader("Content-Type","application/json");
        httpCode = http_client.POST(data_json);

        if(httpCode == 200) {
            if(httpCode == HTTP_CODE_OK) {
                String payload = http_client.getString();
                Serial.println(payload);
            }
        }
        else {
            Serial.printf("[HTTP] GET... failed, error: %s\n", http_client.errorToString(httpCode).c_str());
        }
        http_client.end();

        while (!digitalRead(key));
        Serial.printf("Recognition complete\r\n");
    }
}


uint32_t num=0;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR onTimer(){
  // Increment the counter and set the time of ISR
    portENTER_CRITICAL_ISR(&timerMux);
    if(adc_start_flag==1)
    {
        //Serial.println("");
        adc_data[num]=analogRead(ADC);
        num++;
        if(num>=data_len)
        {
            adc_complete_flag=1;
            adc_start_flag=0;
            num=0;
            //Serial.println(Complete_flag);
        }
    }
    portEXIT_CRITICAL_ISR(&timerMux);
}



void gain_token(void)   //获取token
{
    int httpCode;
    //注意,要把下面网址中的your_apikey和your_secretkey替换成自己的API Key和Secret Key
    http_client.begin("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=your_apikey&client_secret=your_secretkey");
    httpCode = http_client.GET();
    if(httpCode > 0) {
        if(httpCode == HTTP_CODE_OK) {
            String payload = http_client.getString();
            Serial.println(payload);
        }
    }
    else {
        Serial.printf("[HTTP] GET... failed, error: %s\n", http_client.errorToString(httpCode).c_str());
    }
    http_client.end();
}

上面代码是将数据拼接成要求的JSON的格式并通过POST的方式发送到请求API,并接收打印返回的数据消息。使用的定时器设置成8K频率定时采集音频数据,上面代码中并未展示,后面会附上完整代码。
  ESP32是有JSON库的,在 “cJSON.h” 头文件中,但是我没有用,因为我发现数据太长时不知道为啥会出现莫名其妙的错误,也没深究,就使用函数strcat()将数据拼接成规定的格式,好使,就是写的时候麻烦一些,但问题不大。
  POST发送数据有一个固定头部:Content-Type:application/json,POST前需要设置一下。

4. 接收数据

参考以下烧录配置,
语音识别接入,arduino学习,百度,语音识别,Seeed xiao,ESP32S3

串口输入字符“1”,点击按回车键,然后有2s录音时间。等待百度在线语音识别返回,在上一步的代码中实现了接收数据,这里列一下返回的数据。

22:04:58.854 -> Start recognition
22:04:58.854 -> 
22:05:01.558 -> {"corpus_no":"7349559668823131804","err_msg":"success.","err_no":0,"result":["你好。"],"sn":"922395388061711202708"}
22:05:01.558 -> 
22:05:01.558 -> 你好。
22:05:01.558 -> Recognition complete
22:08:46.838 -> Start recognition
22:08:46.838 -> 
22:08:49.809 -> {"corpus_no":"7349560648200206506","err_msg":"success.","err_no":0,"result":["你知道百度吗?"],"sn":"497775464181711202936"}
22:08:49.809 -> 
22:08:49.809 -> 你知道百度吗?
22:08:49.809 -> Recognition complete
22:08:54.218 -> Start recognition
22:08:54.218 -> 
22:08:57.084 -> {"corpus_no":"7349560678205790969","err_msg":"success.","err_no":0,"result":["我喜欢小黄人。"],"sn":"748488478211711202943"}
22:08:57.084 -> 
22:08:57.084 -> 我喜欢小黄人。
22:08:57.084 -> Recognition complete

语音识别接入,arduino学习,百度,语音识别,Seeed xiao,ESP32S3

数据发送成功则会返回正确的识别数据,当然声音信号不好时返回的语音识别也会不准确。

5. 总结

本文使用Seeed XIAO ESP32S3 Sense开发板接入百度智能云实现在线语音识别。自带麦克风模块用做语音输入,通过串口发送字符“1”来控制数据的采集和上传。从而实现对外部世界进行感知,充分认识这个有机与无机的环境,科学地合理地进行创作和发挥效益,然后为人类社会发展贡献一点微薄之力。🤣🤣🤣

  1. 我会持续更新对应专栏博客,非常期待你的三连!!!🎉🎉🎉
  2. 如果鹏鹏有哪里说的不妥,还请大佬多多评论指教!!!👍👍👍
  3. 下面有我的🐧🐧🐧群推广,欢迎志同道合的朋友们加入,期待与你的思维碰撞😘😘😘

参考文献:ESP32接入百度智能云语音识别,实现在线语音识别文章来源地址https://www.toymoban.com/news/detail-846066.html

到了这里,关于【ESP32S3 Sense接入百度在线语音识别】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • esp32s3使用多串口

    esp32s3使用多串口

    我按照别人博客中设置串口2,串口打印有问题,因为没有看到esp32s3 多串口,就总结了一下自己的经验 下图为esp32的引脚图 下图为esp32s3的引脚图 ESP32-S3 有三个 UART(通用异步收发器)控制器,即 UART0、UART1、UART2,支持异步通信(RS232 和 RS485)和 IrDA,通信速率可达到 5 Mbps。

    2024年02月04日
    浏览(12)
  • ESP32S3入手体验测试

    ESP32S3入手体验测试

    🔖所入手的型号是 YD-ESP32-S3 N16R8 ,该款和乐鑫官方推出的 ESP32-S3-DevKitC-1 配置差不多。 🎈乐鑫官方介绍:ESP32-S3-DevKitC-1 v1.1 🔰两者采用的模组:ESP32-S3-WROOM-1 和ESP32-S3-WROOM-1U模组对比: 🍁 YD-ESP32-S3 和 ESP32-S3-DevKitC-1 硬件基本信息: 🛠核心模组配置都是可选。两款开发板从原

    2024年02月05日
    浏览(34)
  • ESP32S3系列--SPI主机驱动详解(一)

    ESP32S3系列--SPI主机驱动详解(一)

    SPI是一种串行同步接口,可用于与外围设备进行通信。 ESP32S3自带4个SPI外设,其中SPI0/SPI1内部专用,共用一组信号线,通过一个仲裁器访问外部Flash和PSRAM;SPI2/3各自使用一组独立的信号线;开发者可以使用SPI2/3控制外部SPI从设备(Slave device);其中SPI2作为主设备有6个片选,数据

    2023年04月09日
    浏览(7)
  • 【EPS32S3学习笔记】ESP32+OPENCV+OV2640+LVGL

    【EPS32S3学习笔记】ESP32+OPENCV+OV2640+LVGL

    提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 提示:这里可以添加本文要记录的大概内容: 前面已经完成了ESP32S3+LVGL+OV2640的工

    2024年02月06日
    浏览(9)
  • ESP32S3学习——LEDC LED PWM 控制器

    ESP32S3学习——LEDC LED PWM 控制器

    芯片:esp32s3 开发环境:espidfv4.4 1)LED 控制器 (LEDC) 主要用于控制 LED,也可产生 PWM 信号用于 其他设备 的控制。 该控制器有 8 路通道 ,可以产生独立的波形来驱动 RGB LED 等设备。 LED PWM 控制器可在 无需 CPU 干预 的情况下 自动改变占 空比,实现亮度和颜色渐变(因为这个功能

    2024年02月06日
    浏览(8)
  • ESP32S3 ADC DMA使用记录(坑记录)(大牛欢迎给出建议)

    目前测到三个问题: 一、ADC DMA采样频率sample_freq_hz取值范围611-83333,虽然可以达到83333,但是只能是在while循环里面不停采样才可以,如果想要隔一段时间采样一次则不行,假如隔一段时间使用adc_digi_read_bytes读取40byte数据,结果经常会返回ESP_ERR_INVALID_STATE,且经常读取的数据

    2024年02月11日
    浏览(8)
  • 视频图像处理算法opencv在esp32及esp32s3上面的移植,也可以移植openmv

    视频图像处理算法opencv在esp32及esp32s3上面的移植,也可以移植openmv

    opencv 在 esp32 及 esp32s3 上面的移植 Opencv 简介       OpenCV 是一个基于 Apache2.0 许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在 Linux 、 Windows 、 Android 和 Mac OS 操作系统上,它轻量级而且高效—— 由一系列 C 函数和少量 C++ 类构成,同时提供了 Python 、 R

    2024年02月09日
    浏览(7)
  • ESP32S3使用esp-iot-solution SDK开发USBHID鼠标键盘教程

    ESP32S3使用esp-iot-solution SDK开发USBHID鼠标键盘教程

    ​ 手里最近翻到了一个ESP32S3开发板,于是想做个鼠标键盘玩玩,这是我第二次接触ESP32,上一次18年买的吃灰板子至今没上过电。新找到的S3看手册是支持OTG的,按照官方的教程搭建的WSL+VSCODE环境。然而一切准备就绪发现ESP-IDF里面没有USB-HIDdemo。没有demo怎么玩。于是乎查找资

    2024年02月09日
    浏览(10)
  • ESP32-S3语音唤醒技术,智能机器人应用,物联网技术发展

    ESP32-S3语音唤醒技术,智能机器人应用,物联网技术发展

    随着技术的发展,智能服务正在融入群众的生活。智能机器人的应用,大大提高人们的工作效率,并减少投入的成本。 传感器检测是否有来宾,指纹识别模块可以用来签到,语音识别处理模块可以进行简单的日常提问进行识别并用相应的回答,触摸屏界面实现人机互动,可以

    2024年02月13日
    浏览(17)
  • ESP32 AT指令模式连接百度云天工物接入

    ESP32 AT指令模式连接百度云天工物接入

    ​ ESP32是乐鑫公司的一款 WiFi+蓝牙双模组,通过使用ESP32可以轻松快速的将设备接入物联网云平台。 ​ ESP32模组支持 IDF 开发和 AT 指令开发两种方式。 ​ IDF开发 ,也即直接片上编程进行二次开发,这种方式开发和普通的MCU开发十分相似,底层基于FreeRTOS实时操作系统+LwIP协议

    2024年01月18日
    浏览(11)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包