旧电话机“智”变:用ESP32-S3和小智AI打造复古智能电话

一台落满灰尘的旧式电话机,经过适度改造后,可以成为一台基于 ESP32-S3 的语音交互设备。这个项目保留电话机的外观和听筒结构,在内部加入 I2S 数字麦克风、I2S 功放模块和小智 AI 软件:拿起听筒后开始对话,放下听筒后结束交互。

项目同时涉及 ESP-IDF 环境搭建、小智 AI 源码编译、GPIO 配置、I2S 音频驱动和旧设备内部改造,适合具备一定嵌入式开发基础的创客。需要提前说明的是,项目能否稳定运行取决于硬件接线、供电、WiFi 连接以及小智 AI 服务端配置,并不是完成烧录后即可在所有设备上直接复现。

旧电话机“智”变:用ESP32-S3和小智AI打造复古智能电话图7

硬件组成

组件型号或规格数量作用
主控板ESP32-S3-DevKitC-1,Flash 不低于 8MB,PSRAM 不低于 2MB1负责运算、联网和外设控制
I2S 麦克风INMP441 或其他 I2S 数字麦克风1采集语音
I2S 功放模块MAX983571放大数字音频信号
扬声器8Ω、3W,或电话原装喇叭1播放语音回复
旧式电话机任意带听筒的款式1作为项目外壳和交互载体
导线、铜条若干用于内部连接和摘机检测
USB 数据线Type-C1供电与烧录

ESP32-S3-DevKitC-1 的 Flash 和 PSRAM 容量需要与项目配置相匹配。原项目要求至少具备 2MB PSRAM,并建议使用更大容量的 PSRAM;如果使用 2MB PSRAM,需要同步检查软件配置。

电话机内部改造

处理听筒和扬声器

拆开电话机底盖后,先确认原有电路板、听筒线路以及摘机检测结构,再决定拆除哪些部件。原项目保留听筒中的四根线,其中两根原本连接麦克风,另外两根连接听筒扬声器。

拆开听筒,取下原装碳精麦克风,将 INMP441 等 I2S 麦克风模块安装到原麦克风位置。由于不同电话机的内部空间和固定方式并不相同,安装时需要避免麦克风被外壳挤压,并尽量减少导线松动。

电话机原有的外放喇叭可以继续使用,由 MAX98357 功放模块驱动。听筒中的小型扬声器在本方案中不再参与播放,语音主要通过电话机外放喇叭输出。

利用摘机开关检测状态

电话机内部通常有由听筒压下的弹片或铜片,用于接通和断开电话线路。改造时,可以将这组机械结构作为摘机检测开关:

  • 铜条一端连接 ESP32-S3 的 GPIO_NUM_8
  • 另一端连接 GND
  • GPIO 配置为输入,并启用内部上拉电阻。

在当前接线方式下:

  • 听筒放下时,铜片接触,GPIO 被拉到低电平;
  • 听筒拿起时,铜片分离,GPIO 通过内部上拉变为高电平。

软件据此区分“挂机”和“摘机”。由于不同电话机的弹片结构可能相反,实际装配后应先用串口日志或调试方式确认电平变化,再决定软件中的有效电平和事件映射。

硬件接线

本项目采用以下 GPIO 分配方案。引脚可以在 config.h 中调整,但修改后必须同时检查软件配置和实际接线,避免多个外设使用同一个 GPIO。

旧电话机“智”变:用ESP32-S3和小智AI打造复古智能电话图5

旧电话机“智”变:用ESP32-S3和小智AI打造复古智能电话图6

I2S 麦克风接线

以 INMP441 为例:

  • WSGPIO_NUM_4,字选择信号
  • SCKGPIO_NUM_5,时钟信号
  • DINGPIO_NUM_6,数据输入
  • L/RGND,选择左声道
  • VDD3.3V
  • GNDGND

供电和地线不能接反,否则可能损坏麦克风模块。原项目说明中提到部分连接可不接,但这不应理解为可以省略模块的正常供电。实际接线前,应以所用 INMP441 模块的引脚定义和电源要求为准。

旧电话机“智”变:用ESP32-S3和小智AI打造复古智能电话图2

I2S 功放接线

以 MAX98357 为例:

  • BCLKGPIO_NUM_15,位时钟
  • LRCGPIO_NUM_16,左右声道时钟
  • DINGPIO_NUM_7,音频数据输入
  • GAINGND,较低增益
  • SD3.3V,使能功放
  • VIN3.3V5V
  • GNDGND

GAIN 的具体效果取决于模块设计和供电条件。如果音量过大或过小,可以尝试调整该引脚,但应先确认模块的电气规格。功放的电源和地线需要连接可靠,隐藏在元件下方的焊点尤其要检查是否存在虚焊或短路。

旧电话机“智”变:用ESP32-S3和小智AI打造复古智能电话图3

旧电话机“智”变:用ESP32-S3和小智AI打造复古智能电话图4

摘机检测接线

  • 铜条 1 → GPIO_NUM_8
  • 铜条 2 → GND
  • GPIO 启用内部上拉电阻
  • 软件中设置 active_high = false

建议先在不连接其他音频模块的情况下,单独测试摘机开关的高低电平变化。确认听筒拿起和放下时的状态后,再接入完整的软件事件逻辑,可以减少排查难度。

核心软件逻辑

本项目基于开源的 xiaozhi-esp32 项目进行二次开发,摘机检测逻辑放在 compact_wifi_board.cc 中。代码的核心思路是:将电话机的机械弹片当作一个按钮,根据电平变化触发唤醒或退出事件。

// 在构造函数中初始化摘机检测按钮
CompactWifiBoard() :
    boot_button_(BOOT_BUTTON_GPIO),
    touch_button_(TOUCH_BUTTON_GPIO, false, 300, 100)
    // 低电平有效,长按 3 秒触发
{
    InitializeDisplayI2c();
    InitializeSsd1306Display();
    InitializeButtons();
    InitializeTools();
}

// 在 InitializeButtons 中注册事件
void InitializeButtons() {
    // 拿起听筒:唤醒小智
    touch_button_.OnClick([this]() {
        auto& app = Application::GetInstance();
        app.WakeWordInvoke("你好小智");
        GetDisplay()->ShowNotification("正在唤醒...");
    });

    // 放下听筒:退出对话
    touch_button_.OnLongPress([this]() {
        auto& app = Application::GetInstance();
        app.WakeWordInvoke("退出");
        GetDisplay()->ShowNotification("正在退出...");
    });
}

这里有三个参数需要结合实际接线理解:

  • active_high = false:低电平被视为按钮有效状态。由于摘机开关一端接地,听筒放下时对应低电平;
  • long_press_time = 300:长按判定时间为 300ms,即 3 秒,用于避免短暂抖动直接触发退出;
  • OnClickOnLongPress 的具体触发结果,取决于按钮库对“按下”和“释放”的定义,以及电话机弹片的实际电平变化。

在当前逻辑中,听筒放下对应持续低电平,因此触发长按事件并发送“退出”;听筒拿起后电平恢复为高电平,对应释放或点击事件,从而发送“你好小智”。如果实际电话机的开关状态相反,需要调整接线或软件逻辑,不能直接照搬事件映射。

编译与烧录

项目使用 ESP-IDF v5.3 或更高版本开发。进入源码目录后,先设置目标芯片:

cd xiaozhi-esp32
idf.py set-target esp32s3

然后打开项目配置界面:

idf.py menuconfig

Xiaozhi Assistant → Board Type 中选择对应的开发板类型。如果实际使用的 GPIO 与默认配置不同,需要同步修改 GPIO 定义。例如:

#define AUDIO_I2S_MIC_GPIO_WS   GPIO_NUM_4
#define AUDIO_I2S_MIC_GPIO_SCK  GPIO_NUM_5
#define AUDIO_I2S_MIC_GPIO_DIN  GPIO_NUM_6

#define AUDIO_I2S_SPK_GPIO_DOUT GPIO_NUM_7
#define AUDIO_I2S_SPK_GPIO_BCLK GPIO_NUM_15
#define AUDIO_I2S_SPK_GPIO_LRCK GPIO_NUM_16

#define BOOT_BUTTON_GPIO        GPIO_NUM_
#define TOUCH_BUTTON_GPIO       GPIO_NUM_8

完成配置后,执行编译和烧录:

idf.py build
idf.py flash -p [你的串口号]

烧录完成并重新上电后,设备会进入配网模式。使用手机连接名称类似 Xiaozhi-xxxx 的 WiFi 热点,再访问 配置网络。连接成功后,可以通过“你好,小智”测试语音交互。

旧电话机“智”变:用ESP32-S3和小智AI打造复古智能电话图8

旧电话机“智”变:用ESP32-S3和小智AI打造复古智能电话图9

工作原理

语音数据链路

用户说话时,安装在听筒中的 I2S 麦克风负责采集音频,并通过 I2S 总线传给 ESP32-S3。ESP32-S3 再通过 WebSocket 将音频数据发送到小智 AI 云端服务器。

服务端负责语音理解和回复生成,原项目提到可以使用 Qwen、DeepSeek 等大语言模型。生成的语音数据以流式方式返回 ESP32-S3,经 MAX98357 放大后,由电话机外放喇叭播放。

因此,这个项目并不是完全离线的语音设备。它需要稳定的 WiFi 连接,并依赖小智 AI 服务端完成后续处理。网络中断、服务端不可用或音频参数不匹配,都可能导致无法唤醒、回复延迟或没有声音。

摘机检测逻辑

GPIO_NUM_8 配置为输入,并启用内部上拉电阻。听筒放下时,铜条接触地线,GPIO 为低电平;听筒拿起时,铜条分离,GPIO 被上拉为高电平。

active_high = false 的条件下:

  • 低电平被视为“按下”;
  • 听筒放下,相当于持续按下,达到长按时间后触发 OnLongPress,发送“退出”;
  • 听筒拿起,相当于释放,触发 OnClick,发送“你好小智”。

实际使用时,如果机械触点存在抖动,可能出现重复触发或状态误判。长按判定能够减少一部分误触,但仍建议确保弹片安装牢固、接线长度适当,并在软件和硬件两侧分别确认状态变化。

扩展:让小智整理电脑照片

除了语音问答,这套系统还可以通过后端工具扩展功能。原项目给出的示例是:在小智 AI 后端注册一个文件整理工具,当用户提出整理照片的请求时,由服务端调用该函数处理指定目录中的图片。

工具调用方式

后端 Python 服务支持自定义 Tools。示例函数名为 organize_images,可以根据日期、扩展名或图片尺寸对文件进行分类移动:

# 文件整理工具函数
def organize_images(source_dir, target_base_dir="", mode="date"):
    # ...完整实现见项目源码
    return {"moved": moved_count, "errors": errors}

# 注册为 AI 工具
TOOLS = [
    {
        "type": "function",
        "function": {
            "name": "organize_images",
            "description": "整理指定文件夹中的图片,按日期/扩展名/尺寸分类",
            "parameters": {
                "source_dir": {"type": "string"},
                "mode": {"enum": ["date", "ext", "size"]}
            }
        }
    }
]

示例中提到的文件位置是 mcp-calculator-main/pic.py。这类工具涉及真实文件移动,不能只把语音识别结果直接当作操作指令执行。使用前应明确源目录、目标目录和分类方式,并保留必要的备份;否则一旦路径识别错误或工具参数配置不完整,可能造成文件被移动到不易查找的位置。

功能验证

可以按照以下顺序测试:

  1. 设备上电,确认能够播放初始化提示音;
  2. 拿起听筒,检查屏幕是否显示“正在唤醒…”;
  3. 确认设备是否播报“你好,我在”;
  4. 对着听筒说话,检查外放喇叭能否播放语音回复;
  5. 如果已配置照片整理工具,再测试整理指定文件夹的语音请求;
  6. 放下听筒,确认屏幕显示“正在退出…”并结束对话。

建议先验证摘机检测、麦克风采集和扬声器播放,再测试网络问答,最后测试文件整理等涉及实际操作的扩展功能。这样可以将机械、电气、音频和服务端问题分开定位。

供电与安全注意事项

  • 确认供电方案。 原项目提到使用 3.7V 锂电池供电,同时功放模块的 VIN 可接 3.3V 或 5V。实际装配时应根据所用开发板、功放模块和电池管理方案确认电压范围,不能仅凭外观或接口判断。
  • 检查麦克风电源。 INMP441 的 VDDGND 不能接反,否则可能损坏模块。电源、地线和信号线应分别核对。
  • 谨慎调整功放增益。 GAIN 接地时为较低增益,接 3.3V 时可能获得更高增益。调整后应先低音量测试,避免扬声器过载或出现明显失真。
  • 确认 PSRAM 配置。 项目要求 ESP32-S3 至少具备 2MB PSRAM,并建议使用 8MB。如果使用 2MB PSRAM,需要检查并调整相关配置。
  • 保证网络稳定。 设备需要通过 WiFi 与小智 AI 服务端通信,网络不稳定会影响语音识别、回复速度和播放连续性。
  • 注意焊接安全。 改造过程涉及拆机、焊接和电路连接。上电前应检查是否短路、是否存在裸露焊点,以及功放电源和地线是否连接牢固。
  • 保留原机结构。 如果希望以后恢复电话机原状,拆除原电路板和线路时应记录接线位置,并尽量采用可拆卸连接方式。

旧式电话机在这个项目中并不是简单的外壳,而是同时承担了交互结构、摘机检测和声音输出等功能。ESP32-S3 负责本地控制和联网,I2S 麦克风与功放负责音频输入输出,小智 AI 服务端负责语音交互的后续处理。三者之间任何一环配置不一致,都可能影响最终效果。

按原项目的配置,主控板、麦克风和功放模块的成本约为百元级,但实际花费会受到电话机、电源方案和改造材料的影响。对于创客教育,它可以用来展示旧物改造、GPIO 状态检测、I2S 音频和 AI 服务调用之间的关系;对于有嵌入式基础的开发者,则适合作为一个软硬件结合的练习项目。项目源码基于 xiaozhi-esp32 二次开发,正式制作前应先完成单模块测试,再进行整体装配。

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 共10条

请登录后发表评论