• esp32 --》 pc录音传输

esp32 —》 websocket —》 电脑服务器 —》 保存wav

目标:

你说一句:

“你好”

电脑生成:

test.wav

能正常播放。

这个阶段练:

WiFi
TCP/WebSocket
PCM格式
wav封装

你之前已经学了 socket,这一步正好串起来。


ASR : automatic speech recognition : 自动语音识别 ===》 语音转文字

可以使用:

Whisper
FunASR
百度语音
科大讯飞

ESP32 不适合跑大型 ASR。

ESP32负责:

采集 + 上传

电脑/服务器负责:

AI计算

  1. 核心作用
    把麦克风采集到的 PCM 人声音频,通过算法 / 云端模型翻译成可读文字。
    你的硬件链路完整流程:
    INMP441 拾音 → I2S 读取 PCM 音频 → ASR 模型处理 → 输出汉字 / 文本
  2. 两种主流使用方式(ESP32 设备)
    ① 云端 ASR(最常用)
    设备只负责采集 PCM 音频,通过 WiFi 把音频上传到服务器,云端大模型做识别,再把文字下发给 ESP32。
    例:百度语音、阿里云 ASR、腾讯云语音识别。
    优点:识别准确率极高,支持方言、长句子;
    缺点:必须联网,依赖网络。
    ② 本地离线 ASR(嵌入式专用)
    模型轻量化后直接烧录进 ESP32S3 芯片,不用 WiFi,本地实时识别。
    例:ESP-SR(乐鑫官方离线语音识别库),可识别自定义唤醒词、简单指令(开灯、关灯、播放音乐)。
    优点:断网可用、响应快、无流量;
    缺点:词汇量有限,只能识别预设短句,复杂长句识别差。

在这里插入图片描述


第3步:接入大模型

流程:

语音
|
ASR
|
“今天北京天气怎么样”
|
LLM
|
“北京今天晴天…”

这里可以接:

GPT
DeepSeek
Claude
通义

小智类似方案也是 ESP32 作为终端,通过网络连接 LLM


第4步:TTS语音合成

LLM返回:

北京今天晴,温度25度

变成:

audio.wav

例如:

Edge TTS
Azure TTS
百度TTS

然后:

服务器

ESP32

MAX98357A

声音


第5步:做成实时对话

最终:

    WiFi
      |

±---------------+
| ESP32-S3 |
| |
| INMP441 |
| MAX98357A |
| |
±---------------+
|
|
WebSocket
|
|
±---------------+
| Python Server |
| |
| ASR |
| LLM |
| TTS |
±---------------+
你现在最适合的项目路线

根据你目前水平(已经会 ESP-IDF、FreeRTOS、I2S、WiFi、TCP),我建议:

第一阶段(3天)

完成:

ESP32录音

WiFi发送

PC保存wav


先 TCP/WebSocket 传 PCM
接 Whisper/FunASR 做 ASR
接大模型
TTS返回音频
最后加 MQTT 控制设备


在这里插入图片描述

#include "wifi_manager.h"

#include "esp_event.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_wifi.h"
#include "esp_wifi_default.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "lwip/ip4_addr.h"

#define MAX_CONNECT_RETRY 10
static int sta_connect_cnt = 0;// 重连的次数
#define TAG "wifi_manager"

// 当前sta连接状态
static bool is_sta_connected = false;

static p_wifi_state_cb wifi_callback = NULL;
/***
 *wifi连接 或 工作的 时候,,有很多事件,,通过回调函数通知
 *STA参数
 *
 **/

/**
 *@param1 : 用户自定义的参数
 *@param2 : 事件类型  wifi 还是 ip
 *@param3 :
 *@param4 : 事件数据
 *
 */
static  void event_handler(void* event_handler_arg,
                                    esp_event_base_t event_base,
                                    int32_t event_id,
                                    void* event_data) {
    if (event_base == WIFI_EVENT) {
        switch (event_id) {
            case WIFI_EVENT_STA_START:
                // sta启动了,,触发这个事件
                // 启动wifi连接
                printf("wifi start...");
                esp_wifi_connect();
                break;
            case WIFI_EVENT_STA_DISCONNECTED:

                wifi_event_sta_disconnected_t *reason = event_data;
                ESP_LOGI(TAG,"disconnected reason %d",reason->reason);

                if (is_sta_connected) {
                    is_sta_connected = false;
                    // 连接成功,,, 连接中失败
                    if (wifi_callback) {
                        wifi_callback(WIFI_STATE_DISCONNECTED);
                    }
                }


                if (sta_connect_cnt < MAX_CONNECT_RETRY) {
                    esp_wifi_connect();
                    sta_connect_cnt++;
                    printf("retry count is %d\n",sta_connect_cnt);
                }
                break;
            case WIFI_EVENT_STA_CONNECTED:
                // 连接成功
                ESP_LOGI(TAG,"connected to ap");
                break;
            default:
                break;

        }

    }else if (event_base == IP_EVENT) {

        if (event_id == IP_EVENT_STA_GOT_IP) {
            // 获取到ip
            ESP_LOGI(TAG,"got ip:%s",ip4addr_ntoa(event_data));
            is_sta_connected = true;
            if (wifi_callback) {
                wifi_callback(WIFI_STATE_CONNECTED);
            }
        }
    }
}

void wifi_manager_init(p_wifi_state_cb cb) {
    // tcp/ip协议的初始化
    ESP_ERROR_CHECK(esp_netif_init());
    // 创建时间循环
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    // 创建sta对象 : 如果要使用sta功能,就要创建一个sta对象,,底层会把这个sta对象绑定到wifi的接口,将相关的wifi STA事件注册到默认的事件循环中
    esp_netif_create_default_wifi_sta();





    // 初始化整个wifi
    wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();

    ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config));


    esp_event_handler_instance_t instance_any_id;
    esp_event_handler_instance_t instance_ip;
    // 事件回调
    esp_event_handler_instance_register(WIFI_EVENT,ESP_EVENT_ANY_ID,event_handler,NULL,&instance_any_id);
    esp_event_handler_instance_register(IP_EVENT,IP_EVENT_STA_GOT_IP,event_handler,NULL,&instance_ip);



    // callback保存


    wifi_callback = cb;


    // //
    // // 设置wifi的工作模式
    // esp_wifi_set_mode(WIFI_MODE_STA);
    //
    //
    // // 设置wifi配置
    // esp_wifi_set_config(WIFI_IF_STA, &wifi_config);

}


void wifi_manager_connect(const char* ssid, const char* password) {

    wifi_config_t wifi_config = {
          .sta = {
            .threshold.authmode = WIFI_AUTH_WPA2_PSK,
              // .ssid =ssid
          }
    };

    /**
     *sprintf : 无长度限制,ssid超长会越界写烂内存
     *snprintf : 有长度保护
     *
     *@param1 : 存放结果的缓冲区
     *@param2 : 缓冲区最大可写入字节数,,, 预留1字节的结束符'\0'
     *@param3 : 格式化字符串
     *@param4 : 可变参数
     **/
    snprintf((char*)wifi_config.sta.ssid,31,"%s",ssid);
    snprintf((char*)wifi_config.sta.password,63,"%s",password);



    // 重连清零
    sta_connect_cnt=0;

    // 判断当前wifi模式是不是STA
    wifi_mode_t mode;
    esp_wifi_get_mode(&mode);
    if (mode != WIFI_MODE_STA) {
        // 停止wifi工作
        esp_wifi_stop();
        // 设置wifi的工作模式
        esp_wifi_set_mode(WIFI_MODE_STA);

    }

    // 设置wifi配置
    esp_wifi_set_config(WIFI_IF_STA, &wifi_config);

    // 启动wifi
    esp_wifi_start();
}

#ifndef __WIFI_MANAGER_H__
#define __WIFI_MANAGER_H__

typedef enum {
    WIFI_STATE_CONNECTED,
    WIFI_STATE_DISCONNECTED,
}WIFI_STATE;

// 指针 p_wifi_state_cb 指向一个函数,,, void:没有返回值 ():没有入参
typedef void(*p_wifi_state_cb)(WIFI_STATE);


void wifi_manager_init(p_wifi_state_cb f);
// 发起连接
void wifi_manager_connect(const char* ssid, const char* password);
#endif
#include <stdio.h>

#include "esp_event.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_wifi.h"
#include "esp_wifi_default.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "wifi_manager.h"

#define TAG "main"
#define default_wifi_ssid "csl"
#define default_wifi_password "12348888"


/**
 * 配网方式
 *
 *
 */
void wifi_state_handler(WIFI_STATE state) {
    if (state == WIFI_STATE_CONNECTED) {
        ESP_LOGI(TAG, "WIFI CONNECTED");
    }
    if (state == WIFI_STATE_DISCONNECTED) {
        ESP_LOGI(TAG, "WIFI DISCONNECTED");
    }
}

void app_main(void)
{

    // wifi信息会默认保存在nvs
    nvs_flash_init();


    wifi_manager_init(wifi_state_handler);


    wifi_manager_connect("csl","12348888");


    while (1) {
        vTaskDelay(pdMS_TO_TICKS(50));
    }

}

idf.py menuconfig

Component config
    └── HTTP Server
          └── Enable WebSocket server support
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐