模板网站 建设 方法,东莞人才招聘网官网,哈尔滨工程研究生招生信息网,外贸网站推广渠道1. 前言
围绕ESP32S3 Sense接入语音识别MiniMax模型对话展开#xff0c;首先串口输入“1”字符#xff0c;随后麦克风采集2s声音数据#xff0c;对接百度在线语音识别#xff0c;将返回文本结果丢入MiniMax模型#xff0c;进而返回第二次结果文本#xff0c;实现语言对话…1. 前言
围绕ESP32S3 Sense接入语音识别MiniMax模型对话展开首先串口输入“1”字符随后麦克风采集2s声音数据对接百度在线语音识别将返回文本结果丢入MiniMax模型进而返回第二次结果文本实现语言对话文本效果。以上一共有两次调用后期只需加入tts模块就可完整对话。
讲解视频
1.1 语音接入
百度在线语音接入教程 【ESP32S3 Sense接入百度在线语音识别】 使用Seeed XIAO ESP32S3 Sense开发板接入百度智能云实现在线语音识别。自带麦克风模块用做语音输入通过串口发送字符“1”来控制数据的采集和上传。 1.2 大模型接入
国产大模型接入分享如下 【ESP32接入国产大模型之MiniMax】 【ESP32接入语言大模型之智谱清言】 【ESP32接入国产大模型之文心一言】 【ESP32接入语言大模型之通义千问】
下面是不标准测评推荐使用MiniMax大模型参考而已 MM智能助理是一款由MiniMax自研的没有调用其他产品的接口的大型语言模型。MiniMax是一家中国科技公司一直致力于进行大模型相关的研究。 |模型| 响应时间|内容质量|免费token次数|地址| |–|–|–|–|–| | MiniMax | 3s | 8分|500万|https://www.minimaxi.com/| | 智谱清言 | 7s | 8分|300万|https://open.bigmodel.cn/| |文心一言 | 10s | 9分|500万|https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Nlks5zkzu| | 通义千问 | 8s | 8分|800万|https://tongyi.aliyun.com/qianwen/| 这一次还是采用Arduino编程就会轻松许多开发。这样就可以把sttchat大模型装进口袋啦接下来就只差tts播报啦 2. 先决条件
在继续此项目之前请确保检查以下先决条件。
我们将使用 Arduino IDE 对 ESP32/ESP8266 开发板进行编程因此在继续本教程之前请确保已在 Arduino IDE 中安装这些开发板。
2.1 环境配置
Arduino IDE下载并安装 Arduino IDEESP32 开发板库在 Arduino IDE 中添加 ESP32 支持 参考博客【esp32c3配置arduino IDE教程】 为安装过程留出一些时间具体时间可能因您的互联网连接而异。
2.2 所需零件
要学习本教程您需要1个 ESP32 开发板马克风或者ESP32 Sense建议使用后者笔者发现同样的代码后者可以轻松调用ESP32不行可能板子坏了。 3. 核心代码
提供两种硬件测试
ESP32S3 SenseESP32 max9814麦克风模块用做语音输入一个按键来控制数据的采集和上传
3.1 ESP32S3 Sense ESP32S3 Sense自带麦克风直接烧录 Arduino代码如下
#include Arduino.h
#include base64.h
#include WiFi.h
#include HTTPClient.h
#include cJSON.h
#include I2S.h
#include ArduinoJson.h
#define data_len 16000
// #define key 4 //端口0
// #define ADC 2 //端口39
// #define led 15 //端口2HTTPClient http_client;
// 1. Replace with your network credentials
const char* ssid J09 502;
const char* password qwertyuiop111;
// 2. Check your Aduio port
const int buttonPin 1; // the number of the pushbutton pin
const int ledPin 21; // the number of the LED pin
hw_timer_t* timer NULL;
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,所以得计算好,避免出现越界// 3. Replace with your MiniMax API key
const char* apiKey eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJHcm91cE5hbWUiOiIyMzQ1dm9yIiwiVXNlck5hbWUiOiIyMzQ1dm9yIiwiQWNjb3VudCI6IiIsIlN1YmjE3NTk0ODIxODAxMDAxNzAyMDgiLCJQI6IjE3NTk0ODIxODAwOTU5NzU5MDQiLCJQYWdlTmFtZSI6IiIsIk1haWwiOiIiLCJDcmVhdGVUaW1lIjoiMjAyNC0wMy0xNiAxMzoyNDoxOCIsImlzcyI6Im1pbmltYXgifQ.WlEj8Nk0j_WOMXZE9SbIC8sHpwJ6R6Pi8Spl5mahJsW3-Jsz7Ev53sGGz3v__Bd5dDkt7o9-Y8BOW0WZq2ImaN7Rof7YNtYnYnvPNDyGx23_xRqq5co9P5UkC3ciYEcIch2SUZ5QPkXR-sMUPzhdowSYvfdu1N25kdKJ8GE_63NfCnsdDVt8mv0wQSSweJK0yf_C8a8ADdB1uF4vg_WKMDjHlvzERsoNZgX6FYtr-bee85rIyu4U-OrbUvEpR1FLPXa7lTlx65QvhVIYGbIKde7ERIT_7QLOQoVFvPz0gX-H6V7UlmSRgRy4LK_R9mvV5TqCy3v90WK_AFuwEhPXcg;
HTTPClient http;
String token_key String(Bearer ) apiKey;
// Send request to MiniMax API
String inputText 你好minimax;
String apiUrl https://api.minimax.chat/v1/text/chatcompletion_v2;
int httpResponseCode;
String response,question,answer;
DynamicJsonDocument jsonDoc(1024);uint32_t num 0;
portMUX_TYPE timerMux portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR onTimer() {// Increment the counter and set the time of ISRportENTER_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);
}String getGPTAnswer(String inputText) {http.begin(apiUrl);http.addHeader(Content-Type, application/json);http.addHeader(Authorization, token_key);String payload {\model\:\abab5.5s-chat\,\messages\:[{\role\: \system\,\content\: \你是鹏鹏的生活助手机器人要求下面的回答严格控制在256字符以内。\},{\role\: \user\,\content\: \ inputText \}]};httpResponseCode http.POST(payload);if (httpResponseCode 200) {response http.getString();http.end();Serial.println(response);// Parse JSON responsedeserializeJson(jsonDoc, response);String outputText jsonDoc[choices][0][message][content];return outputText;// Serial.println(outputText);} else {http.end();Serial.printf(Error %i \n, httpResponseCode);return error;}
}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 sampleI2S.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);Serial.println(WiFi.localIP());http.setTimeout(10000);// gain_token();timer timerBegin(0, 80, true); // 80M的时钟 80分频 1MtimerAlarmWrite(timer, 125, true); // 1M 计125个数进中断 8KtimerAttachInterrupt(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);// time1micros();while (!adc_complete_flag) //等待采集完成{ets_delay_us(10);}// time2micros()-time1;timerStop(timer);adc_complete_flag 0; //清标志digitalWrite(ledPin, LOW);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.8f6143793af76e02f5e191.2592000.1713789066.282335-57722200\,); //token 这里需要修改成自己申请到的tokenstrcat(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_apihttp_client.addHeader(Content-Type, application/json);httpCode http_client.POST(data_json);if (httpCode 200) {if (httpCode HTTP_CODE_OK) {response http_client.getString();http_client.end();Serial.println(response);// Parse JSON response// DynamicJsonDocument jsonDoc(512);deserializeJson(jsonDoc, response);String question jsonDoc[result][0];// 访问result数组并获取其第一个元// 输出结果Serial.println(\n Input:question);answer getGPTAnswer(question);Serial.println(Answer: answer);Serial.println(Enter a prompt:);} 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);
}
用于实现一个通过 I2S 接口采集音频信号并将其发送到百度语音识别 API 进行语音识别然后将识别出的文本通过 MiniMax API 获取 AI 回答的功能。以下是代码的主要结构和功能说明 引入必要的库文件包括 Arduino.h、base64.h、WiFi.h、HTTPClient.h、cJSON.h、I2S.h 和 ArduinoJson.h这些库分别提供了基本的 Arduino 功能、Base64 编解码、Wi-Fi 连接、HTTP 客户端操作、JSON 数据处理和 I2S 音频接口驱动。 定义了一些全局变量如 Wi-Fi 的 SSID 和密码以及与音频采集和处理相关的变量如 ADC 数据缓冲区、录音标志位、完成标志位、JSON 格式数据缓冲区还有 MiniMax API 的密钥apiKey。
修改Wi-Fi 的 SSID 和密码
// 1. Replace with your network credentials
const char* ssid J09 502;
const char* password qwertyuiop111;修改MiniMax API 的密钥apiKey
// 3. Replace with your MiniMax API key
const char* apiKey eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJHcm91cE5hbWUiOiIyMzQ1dm9yIiwiVXNlck5hbWUiOiIyMzQ1dm9yIiwiQWNjb3VudCI6IiIsIlN1YmjE3NTk0ODIxODAxMDAxNzAyMDgiLCJQI6IjE3NTk0ODIxODAwOTU5NzU5MDQiLCJQYWdlTmFtZSI6IiIsIk1haWwiOiIiLCJDcmVhdGVUaW1lIjoiMjAyNC0wMy0xNiAxMzoyNDoxOCIsImlzcyI6Im1pbmltYXgifQ.WlEj8Nk0j_WOMXZE9SbIC8sHpwJ6R6Pi8Spl5mahJsW3-Jsz7Ev53sGGz3v__Bd5dDkt7o9-Y8BOW0WZq2ImaN7Rof7YNtYnYnvPNDyGx23_xRqq5co9P5UkC3ciYEcIch2SUZ5QPkXR-sMUPzhdowSYvfdu1N25kdKJ8GE_63NfCnsdDVt8mv0wQSSweJK0yf_C8a8ADdB1uF4vg_WKMDjHlvzERsoNZgX6FYtr-bee85rIyu4U-OrbUvEpR1FLPXa7lTlx65QvhVIYGbIKde7ERIT_7QLOQoVFvPz0gX-H6V7UlmSRgRy4LK_R9mvV5TqCy3v90WK_AFuwEhPXcg;修改百度api
strcat(data_json, \token\:\24.8f6143793af76e02f5e191.2592000.1713789066.282335-57722200\,); //token 这里需要修改成自己申请到的token定义了一个 HTTPClient 实例 http_client用于向 API 发送请求。 函数 getGPTAnswer() 负责调用 MiniMax API并传入用户输入文本以获取 AI 的回答。 onTimer() 函数是一个中断服务程序每当定时器触发时会读取 I2S 接口上的音频数据并存入缓冲区 adc_data 中。当缓冲区满或者录音结束时会设置完成标志。 setup() 函数负责初始化串口通信、配置 I2S 接口、连接 Wi-Fi并设置定时器和中断。 loop() 函数是 Arduino 主循环函数在循环中检查是否有按键输入这里未实际使用。如果有特定输入开始音频采集过程并在采集完成后将音频数据转换为 Base64 编码构建一个 JSON 请求体然后通过 HTTP POST 方式发送到百度语音识别 API。收到识别结果后调用 getGPTAnswer() 函数获取 AI 回答并打印在控制台上。
3.2 ESP32 max9814
ESP32 max9814麦克风模块用做语音输入一个按键来控制数据的采集和上传
4. 上传验证
如果提示Compilation error: ArduinoJson.h: No such file or directory 直接在库管理安装Arduinojson库
打开串口监视器注意右下角选择换行符选择115200波特率输入你想问的问题他就可以回答你
4.1 对话测试 串口发送“1”开始录音然后返回对话结果以上是两次连续对话效果
4.2 报错
如果返回error 大家对照列表查询错误代码结合提示排查解决
5. 总结
现在我们在本教程中您学习了如何使用ESP32S3 Sense接入语音识别MiniMax模型对话。从而实现对外部世界进行感知充分认识这个有机与无机的环境后期会持续分享esp32跑freertos实用案列科学地合理地进行创作和发挥效益然后为人类社会发展贡献一点微薄之力。
如果你有任何问题可以通过下面的二维码加入鹏鹏小分队期待与你思维的碰撞