講解視頻:
ESP32S3 AI助手使用MiniMax大模型生產(chǎn)工具1
1. 前言
大家好,今天的教程將圍繞如何實(shí)現(xiàn)精準(zhǔn)的語(yǔ)音播報(bào)功能展開(kāi),我們用到了ESP32S3 Sense接入語(yǔ)音識(shí)別+MiniMax模型對(duì)話+SNR9816TTS模塊。
目前這是我使用的ESP32S3官方硬件??????(小小的身材有大大的力量)只需要35元加攝像頭麥克風(fēng)79元,后期我會(huì)整理相關(guān)專(zhuān)欄進(jìn)行Arduino系統(tǒng)學(xué)習(xí)??????。有需要可以購(gòu)買(mǎi)xiao開(kāi)發(fā)板??????,SeeedXIAO ESP32S3 Sense硬件購(gòu)買(mǎi)地址:https://s.click.taobao.com/lekazrt
在后續(xù)的測(cè)試過(guò)程中,我們用到了一款極致實(shí)用的AI工具——海螺AI?。ㄓ袉?wèn)題,找海螺AI)它是MiniMax旗下的一款自研AI平臺(tái),專(zhuān)注于解決實(shí)際問(wèn)題,可以讓你的工作更高效、更便捷!
本博客文本作為輸入海螺AI,生成了以下視頻文案,還是非常不錯(cuò)噠!??????
海螺AI提供了多種實(shí)用功能,能夠滿足多種場(chǎng)景下的需求。比如,你可以用它來(lái)處理圖片和文件、進(jìn)行知識(shí)搜索和問(wèn)答、生成代碼和文案,讓你的工作流更暢通無(wú)阻!
MiniMax是海螺的母公司,MiniMax最近推出了大法師計(jì)劃,為全球大模型初創(chuàng)公司和開(kāi)發(fā)者免費(fèi)提供2000億tokens,以促進(jìn)通用人工智能設(shè)計(jì)開(kāi)發(fā)行業(yè)的發(fā)展。(MiniMax大法師計(jì)劃)
2. 功能模塊概述
首先串口輸入“1”字符,隨后麥克風(fēng)采集2s聲音數(shù)據(jù),對(duì)接百度在線語(yǔ)音識(shí)別,將返回文本結(jié)果丟入MiniMax模型,進(jìn)而返回第二次結(jié)果文本,實(shí)現(xiàn)語(yǔ)言對(duì)話文本效果。經(jīng)過(guò)以上兩次調(diào)用后,載入TTS模塊就可完整對(duì)話,實(shí)現(xiàn)精準(zhǔn)的語(yǔ)音播報(bào)功能。
2.1 語(yǔ)音接入
百度在線語(yǔ)音接入教程:
【ESP32S3 Sense接入百度在線語(yǔ)音識(shí)別】
使用Seeed XIAO ESP32S3 Sense開(kāi)發(fā)板接入百度智能云實(shí)現(xiàn)在線語(yǔ)音識(shí)別。自帶麥克風(fēng)模塊用做語(yǔ)音輸入,通過(guò)串口發(fā)送字符“1”來(lái)控制數(shù)據(jù)的采集和上傳。
2.2 大模型接入
國(guó)產(chǎn)大模型接入分享如下:
【ESP32接入國(guó)產(chǎn)大模型之MiniMax】
【ESP32接入語(yǔ)言大模型之智譜清言】
【ESP32接入國(guó)產(chǎn)大模型之文心一言】
【ESP32接入語(yǔ)言大模型之通義千問(wèn)】
下面是不標(biāo)準(zhǔn)測(cè)評(píng),強(qiáng)烈推薦使用MiniMax大模型
MiniMax是一家中國(guó)科技公司,一直致力于進(jìn)行大模型相關(guān)的研究。近期提出了MINIMAX大法師計(jì)劃,獲取更多的2000億token,為全球 AI大模型領(lǐng)域創(chuàng)業(yè)公司以及優(yōu)秀的個(gè)人開(kāi)發(fā)者提供了豐富的資源。
模型 | 響應(yīng)時(shí)間 | 內(nèi)容質(zhì)量 | 免費(fèi)token次數(shù) | 地址 |
---|---|---|---|---|
MiniMax | 3s | 8分 | 500萬(wàn)+2000億token | https://www.minimaxi.com/ |
智譜清言 | 7s | 8分 | 300萬(wàn) | https://open.bigmodel.cn/ |
文心一言 | 10s | 9分 | 500萬(wàn) | https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Nlks5zkzu |
通義千問(wèn) | 8s | 8分 | 800萬(wàn) | https://tongyi.aliyun.com/qianwen/ |
結(jié)合以上圖表對(duì)比,無(wú)能是回復(fù)文本的質(zhì)量與速度方面,MiniMax是海螺的母公司,是MiniMax開(kāi)展的大法師計(jì)劃領(lǐng)先!??!??????
STT語(yǔ)音接入+大模型Chat接入整合教程見(jiàn):【ESP32S3 Sense接入語(yǔ)音識(shí)別+MiniMax模型對(duì)話】
2.3 TTS模塊接入
SNR9816TTS 是基于獨(dú)家語(yǔ)音合成算法開(kāi)發(fā)的一款高流暢度,高自然度的優(yōu)美人聲語(yǔ)音合成模塊。該模塊方案基于新一代的神經(jīng)網(wǎng)絡(luò)算法,純中文版選取了優(yōu)質(zhì)的女聲發(fā)音人(默認(rèn))和男聲發(fā)音人(指令切換),中英文版只支持女聲發(fā)音人,以滿足各種應(yīng)用場(chǎng)景的合成播報(bào)。
模塊以中文為主,支持?jǐn)?shù)字、英文(純中文版:單個(gè)字母發(fā)音、中英文版:英文單詞發(fā)音),文本編碼支持GB2312。優(yōu)異的合成效果(可懂度、清晰度、自然度、表現(xiàn)力、節(jié)奏/停頓、語(yǔ)速、語(yǔ)調(diào)、音質(zhì)、音色、理解程度)方面有顯著提升。
調(diào)試教程見(jiàn):【Arduino使用SNR9816TTS模塊教程】
3. 先決條件
這一次還是采用Arduino編程就會(huì)輕松許多開(kāi)發(fā)。這樣就可以通過(guò)stt+chat+tts把MiniMax語(yǔ)言大模型裝進(jìn)口袋啦??????
在繼續(xù)此項(xiàng)目之前,請(qǐng)確保檢查以下先決條件。我們將使用 Arduino IDE 對(duì) ESP32/ESP8266 開(kāi)發(fā)板進(jìn)行編程,因此在繼續(xù)本教程之前,請(qǐng)確保已在 Arduino IDE 中安裝這些開(kāi)發(fā)板。此外,為了實(shí)現(xiàn)ESP32C3與SNR9816TTS模塊的串口通信,請(qǐng)確保您已經(jīng)安裝了ESPSoftwareSerial和UTF8ToGB2312庫(kù)。??????
3.1 環(huán)境配置
- Arduino IDE:下載并安裝 Arduino IDE;
- ESP32 開(kāi)發(fā)板庫(kù):在 Arduino IDE 中添加 ESP32 支持;
參考博客:【esp32c3配置arduino IDE教程】
為安裝過(guò)程留出一些時(shí)間,具體時(shí)間可能因您的互聯(lián)網(wǎng)連接而異。
3.2 所需零件
要學(xué)習(xí)本教程,您需要1個(gè)ESP32S3 Sense,建議使用后者,筆者發(fā)現(xiàn)同樣的代碼后者可以輕松調(diào)用,ESP32不行(可能板子壞了)。
名稱(chēng) | 端口 | 功能 | 購(gòu)買(mǎi)地址 |
---|---|---|---|
ESP32S3 Sense | TXGPIO01 RXGPIO02 | 主控 | 官方地址 |
中文版 SNR9816TTS | TXRX RXTX | TTS模塊 | 淘寶地址 |
3.3 硬件連接步驟
-
電源連接:將SNR9816TTS模塊的5V電源引腳連接到ESP32S3的5V輸出端,模塊的GND引腳連接到ESP32C3的GND。
-
串口通信:將SNR9816TTS模塊的RX引腳連接到ESP32S3的GPIO01的TX引腳,模塊的TX引腳連接到Arduino的GPIO02的RX引腳。這里使用軟件串口(SoftwareSerial)庫(kù)模擬額外的串行通信端口。
-
音響:喇叭(第 3、4 引腳)接到對(duì)應(yīng)SPKN和SPKP引腳上,官方喇叭響度有點(diǎn)大,我拆了四六級(jí)聽(tīng)力耳機(jī)喇叭好多啦??????。
4. 核心代碼
下面準(zhǔn)備進(jìn)行了基于ESP32S3 Sense 的硬件測(cè)試,此部分有源碼分享和代碼解析兩部分
4.1 源碼分享
Arduino代碼如下
#include <Arduino.h>
#include "base64.h"
#include <WiFi.h>
#include "HTTPClient.h"
#include "cJSON.h"
#include <I2S.h>
#include <ArduinoJson.h>
#include <SoftwareSerial.h>
#include "UTF8ToGB2312.h"
#define MYPORT_TX 1
#define MYPORT_RX 2
EspSoftwareSerial::UART myPort;
uint8_t voicedata[] = { 0xFD, 0x00, 0x06, 0x01, 0x01, 0x5B, 0x76, 0x31, 0x5D }; //voicedata[7] = 0x31 ~ 0x39
// #define data_len 16000
// #define key 4 //端口0
// #define ADC 2 //端口39
// #define led 15 //端口2
HTTPClient 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;
const int adc_data_len = 8000 * 3;
const int data_json_len = adc_data_len * 3;
uint16_t *adc_data;
char *data_json;
// uint16_t adc_data[data_len]; //16000個(gè)數(shù)據(jù),8K采樣率,即2秒,錄音時(shí)間為2秒,想要實(shí)現(xiàn)更長(zhǎng)時(shí)間的語(yǔ)音識(shí)別,就要改這個(gè)數(shù)組大小
// char data_json[json_len]; //用于儲(chǔ)存json格式的數(shù)據(jù),大一點(diǎn),JSON編碼后數(shù)據(jù)字節(jié)數(shù)變成原來(lái)的4/3,所以得計(jì)算好,避免出現(xiàn)越界
//和下面data_json數(shù)組的大小,改大一些。
uint8_t adc_start_flag = 0; //開(kāi)始標(biāo)志
uint8_t adc_complete_flag = 0; //完成標(biāo)志
// 3. Replace with your MiniMax API key
const char *apiKey = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJHcm91cE5hbWUiOiIyMzQ1dm9yIiwiVXNlck5hbWUiOiIyMzQ1dm9yIiwiQWN.WlEj8Nk0j_WOMXZE9SbIC8sHpwJ6R6Pi8Spl5mahJsW3-Jsz7Ev53sGGz3v__Bd5dDkt7o9-Y8BOW0WZq2ImaN7Rof7YNtYnYnvPNDyGx23_xRqq5co9P5UkC3ciYEcIch2SUZ5QPkXR-sMUPzhdowSYvfdu1N25kdKJ8GE_63NfCnsdDVt8mv0wQSSweJK0yf_C8a8ADdB1uF4vg_WKMDjHlvzERsoNZgX6FYtr-bee85rIyu4U-OrbUvEpR1FLPXa7lTlx65QvhVIYGbIKde7ERIT_7QLOQoVFvPz0gX-H6V7UlmSRgRy4LK_R9mvV5TqCy3v90WK_AFuwEhPXcg";
// 3. Replace with your baidu voice detect token
String token = "24.8f6143793af71.2592000.1713789066.282335-57722200";
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 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 >= adc_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\": \"你是鵬鵬的生活助手機(jī)器人,要求下面的回答嚴(yán)格控制在256字符以內(nèi)。\"},{\"role\": \"user\",\"content\": \"" + inputText + "\"}]}";
httpResponseCode = http.POST(payload);
if (httpResponseCode == 200) {
response = http.getString();
http.end();
Serial.println(response);
// Parse JSON response
deserializeJson(jsonDoc, response);
String outputText = jsonDoc["choices"][0]["message"]["content"];
return outputText;
// Serial.println(outputText);
} else {
http.end();
Serial.printf("Error %i \n", httpResponseCode);
speech("語(yǔ)言大模型故障,請(qǐng)檢查api是否失效");
return "<error>";
}
}
void speech(String data) {
//0--空閑 1--繁忙 2--異常
// while (workstate() > 0) {
// if (workstate() == 1) Serial.println("tts busy");
// if (workstate() == 2) Serial.println("tts wrong");
// }
String utf8_str = data;
String gb2312_str = GB.get(utf8_str);
unsigned char head[gb2312_str.length() + 6];
// 定義無(wú)符號(hào)字符類(lèi)型數(shù)組,將 GB2312 編碼的字符串復(fù)制到數(shù)組中
unsigned char gb2312_data[gb2312_str.length() + 1];
memset(gb2312_data, 0, sizeof(gb2312_data));
strncpy((char *)gb2312_data, gb2312_str.c_str(), gb2312_str.length());
// head byte
head[0] = 0xFD;
// length bytes
unsigned int dat_len = gb2312_str.length() + 3;
head[1] = dat_len >> 8;
head[2] = dat_len;
// cmd byte
head[3] = 0x01;
// para byte
head[4] = 0x01;
// send each character individually
for (int i = 0; i < gb2312_str.length(); i++) {
head[i + 5] = gb2312_data[i];
}
// 計(jì)算異或值并添加到數(shù)組,額這個(gè)是syn那個(gè)芯片的例程,這個(gè)異或計(jì)算有沒(méi)有用我懶得改了。反正代碼能跑。
head[gb2312_str.length() + 5] = head[0];
for (int i = 1; i < gb2312_str.length() + 5; i++) {
head[gb2312_str.length() + 5] ^= head[i];
}
// 發(fā)送字符數(shù)組到串口
for (int j = 0; j < gb2312_str.length() + 6; j++) {
myPort.write(head[j]);
}
delay(gb2312_str.length() * 100);
// Serial.println(data);
}
// 查詢tts合成工作狀態(tài) 返回1表示繁忙 0表示空閑
int workstate() {
unsigned char head[4] = { 0xFD, 0x00, 0x01, 0x21 };
// 發(fā)送字符數(shù)組到串口
for (int j = 0; j < 4; j++) {
myPort.write(head[j]);
}
// 等待myPort的返回
while (myPort.available() < 1) {
// 可以在這里加入一些延時(shí),以防止過(guò)快地查詢
delay(150);
}
// 讀取并處理返回的數(shù)據(jù)
byte response = myPort.read();
// 返回相應(yīng)的狀態(tài)值
if (response == 0x4E) {
// 繁忙
return 1;
} else if (response == 0x4F) {
// 空閑
return 0;
} else {
// 未知狀態(tài),可以根據(jù)需要進(jìn)行處理
return 2;
}
}
void setup() {
//Serial.begin(921600);
Serial.begin(115200);
adc_data = (uint16_t *)ps_malloc(adc_data_len * sizeof(uint16_t)); //ps_malloc 指使用片外PSRAM內(nèi)存
if (!adc_data) {
Serial.println("Failed to allocate memory for adc_data");
}
data_json = (char *)ps_malloc(data_json_len * sizeof(char)); // 根據(jù)需要調(diào)整大小
if (!data_json) {
Serial.println("Failed to allocate memory for data_json");
}
myPort.begin(115200, SWSERIAL_8N1, MYPORT_RX, MYPORT_TX, false);
delay(1000);
if (!myPort) { // If the object did not initialize, then its configuration is invalid
Serial.println("Invalid EspSoftwareSerial pin configuration, check config");
while (1) { // Don't continue with invalid configuration
delay(1000);
}
}
speech("系統(tǒng)開(kāi)機(jī)");
delay(1500);
for (int i = 0; i < sizeof(voicedata) / sizeof(voicedata[0]); i++) {
myPort.write(voicedata[i]);
}
delay(1000);
speech("系統(tǒng)音量以調(diào)小");
// 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");
Serial.println(WiFi.localIP());
http.setTimeout(4000);
http_client.setTimeout(4000);
// gain_token();
timer = timerBegin(0, 80, true); // 80M的時(shí)鐘 80分頻 1M
timerAlarmWrite(timer, 125, true); // 1M 計(jì)125個(gè)數(shù)進(jìn)中斷 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");
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; //清標(biāo)志
digitalWrite(ledPin, LOW);
// memset(data_json, '\0', strlen(data_json)); //將數(shù)組清空
memset(data_json, '\0', data_json_len * sizeof(char));
strcat(data_json, "{");
strcat(data_json, "\"format\":\"pcm\",");
strcat(data_json, "\"rate\":16000,");
strcat(data_json, "\"dev_pid\":1537,");
strcat(data_json, "\"channel\":1,");
strcat(data_json, "\"cuid\":\"666666\",");
strcat(data_json, "\"token\":\"");
strcat(data_json, token.c_str());
strcat(data_json, "\",");
sprintf(data_json + strlen(data_json), "\"len\":%d,", adc_data_len * 2);
strcat(data_json, "\"speech\":\"");
strcat(data_json, base64::encode((uint8_t *)adc_data, adc_data_len * sizeof(uint16_t)).c_str());
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) {
response = http_client.getString();
http_client.end();
Serial.print(response);
// Parse JSON response
// DynamicJsonDocument jsonDoc(512);
deserializeJson(jsonDoc, response);
String question = jsonDoc["result"][0];
// 訪問(wèn)"result"數(shù)組,并獲取其第一個(gè)元
// 輸出結(jié)果
Serial.println("Input:" + question);
answer = getGPTAnswer(question);
speech(answer);
Serial.println("Answer: " + answer);
// Serial.println("Enter a prompt:");
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http_client.errorToString(httpCode).c_str());
speech("語(yǔ)音識(shí)別在線故障,請(qǐng)檢查api是否失效");
}
}
// while (!digitalRead(buttonPin))
// ;
Serial.println("Recognition complete\r\n");
}
}
vTaskDelay(1);
}
4.2 代碼解析
用于實(shí)現(xiàn)一個(gè)通過(guò) I2S 接口采集音頻信號(hào)并將其發(fā)送到百度語(yǔ)音識(shí)別 API 進(jìn)行語(yǔ)音識(shí)別,然后將識(shí)別出的文本通過(guò) MiniMax API 獲取 AI 回答的功能。以下是代碼的主要結(jié)構(gòu)和功能說(shuō)明:
-
引入必要的庫(kù)文件,包括
① Arduino.h:包含Arduino核心庫(kù),提供了基本的Arduino函數(shù)和結(jié)構(gòu)
② base64.h:引入一個(gè)用于Base64編碼和解碼的庫(kù)
③ WiFi.h:用于連接WiFi網(wǎng)絡(luò)的庫(kù)
④ HTTPClient.h:用于Arduino上進(jìn)行HTTP請(qǐng)求的庫(kù)
⑤ cJSON.h:用于處理JSON數(shù)據(jù)的庫(kù)
⑥ I2S.h:I2S(Inter-IC Sound)庫(kù),用于在Arduino上進(jìn)行音頻處理
⑦ ArduinoJson.h:ArduinoJson庫(kù),用于解析和生成JSON數(shù)據(jù)
⑧ SoftwareSerial.h:軟串口庫(kù),用于模擬多個(gè)串口
⑨ UTF8ToGB2312.h:一個(gè)自定義的UTF-8到GB2312編碼的轉(zhuǎn)換庫(kù)
然后,定義了一些必要的常量和變量。 -
定義了一些全局變量,如 Wi-Fi 的 SSID 和密碼,以及與音頻采集和處理相關(guān)的變量,如 ADC 數(shù)據(jù)緩沖區(qū)、錄音標(biāo)志位、完成標(biāo)志位、JSON 格式數(shù)據(jù)緩沖區(qū),還有 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.eyJHcm91cE5hbWUiOiIyMzQ1dm9yIiwiVXNlck5hbWUiOiIyMzQ1d6Im1pbmltYXgifQ.WlEj8Nk0j_WOMXZE9SbIC8sHpwJ6R6Pi8Spl5mahJsW3-Jsz7Ev53sGGz3v__Bd5dDkt7o9-Y8BOW0WZq2ImaN7Rof7YNtYnYnvPNDyGx23_xRqq5co9P5UkC3ciYEcIch2SUZ5QPkXR-sMUPzhdowSYvfdu1N25kdKJ8GE_63NfCnsdDVt8mv0wQSSweJK0yf_C8a8ADdB1uF4vg_WKMDjHlvzERsoNZgX6FYtr-bee85rIyu4U-OrbUvEpR1FLPXa7lTlx65QvhVIYGbIKde7ERIT_7QLOQoVFvPz0gX-H6V7UlmSRgRy4LK_R9mvV5TqCy3v90WK_AFuwEhPXcg";
修改百度api
strcat(data_json, "\"token\":\"24.8f6143791.2592000.1713789066.282335-57722200\","); //token 這里需要修改成自己申請(qǐng)到的token
-
定義了一個(gè) HTTPClient 實(shí)例 http_client,用于向 API 發(fā)送請(qǐng)求。
-
構(gòu)建函數(shù) getGPTAnswer() ,用于向一個(gè)預(yù)先定義的API發(fā)送HTTP POST請(qǐng)求,以獲取對(duì)特定輸入文本的GPT模型生成的響應(yīng)。
-
構(gòu)建函數(shù) speech() ,用于將輸入的文本數(shù)據(jù)轉(zhuǎn)換為語(yǔ)音,并通過(guò)串口與語(yǔ)音合成模塊進(jìn)行通信,實(shí)現(xiàn)語(yǔ)音合成的功能。
-
構(gòu)建函數(shù) workstate(),用于查詢語(yǔ)音合成模塊的工作狀態(tài),并返回相應(yīng)的狀態(tài)值。
-
setup()函數(shù),它在程序開(kāi)始時(shí)被調(diào)用,用于初始化設(shè)置和準(zhǔn)備工作。具體來(lái)說(shuō),該函數(shù)會(huì)初始化系統(tǒng)各個(gè)部分的設(shè)置,包括串口通信、內(nèi)存分配、軟件串口、語(yǔ)音提示、GPIO設(shè)置、I2S音頻初始化、Wi-Fi連接和定時(shí)器初始化。
-
loop()函數(shù),它在程序運(yùn)行過(guò)程中會(huì)一直執(zhí)行,用于處理主要的邏輯流程。具體來(lái)說(shuō),它主要負(fù)責(zé)監(jiān)聽(tīng)串口輸入,控制語(yǔ)音識(shí)別的啟動(dòng)、停止和結(jié)果處理,與百度語(yǔ)音識(shí)別API的交互,以及延時(shí)等待。
5. 上傳驗(yàn)證
如果提示Compilation error: ArduinoJson.h: No such file or directory
直接在庫(kù)管理安裝Arduinojson
庫(kù)
打開(kāi)串口監(jiān)視器,注意右下角選擇換行符,選擇115200波特率,輸入你想問(wèn)的問(wèn)題,他就可以回答你
5.1 對(duì)話測(cè)試
代碼優(yōu)化后可以減少動(dòng)態(tài)內(nèi)存使用:3s語(yǔ)言輸入,2s識(shí)別,5s交互播報(bào)
串口發(fā)送“1”,開(kāi)始錄音,然后返回對(duì)話結(jié)果,進(jìn)行TTS語(yǔ)音播報(bào)??????
5.2 報(bào)錯(cuò)
- 如果返回error ,大家對(duì)照列表查詢錯(cuò)誤代碼,結(jié)合提示排查解決
2. 如果第一次可以二次自動(dòng)重啟,可以配置下載程序運(yùn)行在core0
- 百度在線語(yǔ)音識(shí)別錯(cuò)誤碼自查表
6. 總結(jié)
博主強(qiáng)烈推薦大家使用??????海螺AI并且加入大法師計(jì)劃,支持國(guó)產(chǎn)!它是一款由MiniMax自研的,沒(méi)有調(diào)用其他產(chǎn)品的接口的大型語(yǔ)言模型。作為一個(gè)強(qiáng)有力的生產(chǎn)力工具,無(wú)論是大學(xué)生還是職場(chǎng)人,海螺AI都能成為你的得力助手。??????
- 對(duì)于大學(xué)生,它可以幫助你提升論文寫(xiě)作的效率,解放你的創(chuàng)作靈感;在求職面試中,它能夠?yàn)槟闾峁┴S富的資料和實(shí)用的建議,讓你輕松應(yīng)對(duì)各種挑戰(zhàn)。??????
- 而對(duì)于職場(chǎng)人來(lái)說(shuō),海螺AI更是一個(gè)不可或缺的生產(chǎn)力工具,能夠幫助你高效處理工作任務(wù),提升工作效率,節(jié)省寶貴的時(shí)間。??????
??????現(xiàn)在,我們?cè)诒窘坛讨?,您學(xué)習(xí)了如何使用ESP32S3 Sense接入語(yǔ)音識(shí)別+MiniMax模型+TTS模塊實(shí)現(xiàn)語(yǔ)音播報(bào)功能。??????從而實(shí)現(xiàn)對(duì)外部世界進(jìn)行感知,充分認(rèn)識(shí)這個(gè)有機(jī)與無(wú)機(jī)的環(huán)境,后期會(huì)持續(xù)分享esp32跑freertos實(shí)用案列??????科學(xué)地合理地進(jìn)行創(chuàng)作和發(fā)揮效益,然后為人類(lèi)社會(huì)發(fā)展貢獻(xiàn)一點(diǎn)微薄之力。??????文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-848620.html
如果你有任何問(wèn)題,可以通過(guò)下面的二維碼加入鵬鵬小分隊(duì),期待與你思維的碰撞??????文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-848620.html
到了這里,關(guān)于【ESP32S3 Sense接入語(yǔ)音識(shí)別+MiniMax模型+TTS模塊語(yǔ)音播報(bào)】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!