闵立的开源项目

PROJECT GUIDE / 03 — INTERNET RADIO

BOX-2 网络收音机

从连接 Wi-Fi 到收听网络电台,完成一台中文收音机。了解电台目录、实体按键、定时关机与常见网络问题。

项目概览

把 ATK-DNESP32S3-BOX2-WIFI 变成一台独立网络收音机:连接 Wi-Fi,加载中国地区的 MP3 电台,用实体按键切台和调整音量。设备同时显示中文台名、天气、日期、时间与电量,支持定时关机和翻面熄屏。

本教程针对 feat/standalone-internet-radio 分支,按提交 c732659 核对。仓库 README 仍保留第一版说明;以下按键、缓存、界面和采样率均以该提交的源码为准。分支后续更新可能改变行为。

  • 从 Radio Browser 获取最多 1000 个中国地区 MP3 电台,查询按票数排序,并请求过滤已标记失效的电台和重复项。
  • 将电台目录保存在板载 Flash;运行时使用 PSRAM 缓冲,电台位置和音量可在重启后恢复。
  • 支持 HTTP / HTTPS MP3 直播流,通过 ES8389 输出单声道 48 kHz 音频。
  • 无需 TF / SD 卡;播放需要持续联网。

依据:电台与缓存实现主程序与按键逻辑

准备硬件与开发环境

项目要求
开发板ATK-DNESP32S3-BOX2-WIFI,ESP32-S3 N16R8:16 MB Flash、8 MB OPI PSRAM。工程使用该板的屏幕、音频和按键引脚,其他 ESP32-S3 板不能直接照搬。
连接与供电一根支持数据传输的 USB 线,以及稳定供电。确认板载扬声器已正确连接。
网络可访问互联网的 2.4 GHz Wi-Fi,准备好 SSID 和密码。ESP32-S3 不连接仅开放 5 GHz 的网络。
电脑本教程使用 Windows 与 PowerShell;确保电脑能下载 Git 仓库和 ESP-IDF 组件。
工具链Git 与 ESP-IDF 6.0.2。工程依赖明确锁定此版本。

先按 ESP-IDF 6.0.2 官方入门文档安装环境。Windows 可使用 ESP-IDF 安装管理器 EIM,在自定义安装中选择 v6.0.2,安装 ESP32-S3 所需工具链。

安装完成后,在 EIM 中选择 6.0.2 并打开 IDF 终端,或使用对应的 PowerShell 快捷方式。之后的命令都在这个已激活环境的终端中执行:

idf.py --version
git --version

第一条应显示 ESP-IDF v6.0.2。若提示找不到 idf.py,先重新打开对应版本的 IDF 终端。项目路径请避开空格;下面使用 C:\esp

依据:依赖版本硬件默认配置Windows 环境激活与构建说明

下载收音机分支

在 ESP-IDF PowerShell 终端中创建工作目录,然后将指定分支克隆到 esp32-box2-radio

New-Item -ItemType Directory -Force -Path C:\esp | Out-Null
Set-Location C:\esp
git clone --branch feat/standalone-internet-radio --single-branch https://github.com/mlpre/esp32_box2.git esp32-box2-radio
Set-Location .\esp32-box2-radio

确认当前分支与提交:

git branch --show-current
git rev-parse --short HEAD

分支名应为 feat/standalone-internet-radio。若要完整复现本文核对的版本,可执行以下可选命令;它会切换到该固定提交:

git switch --detach c732659ebd64ec701d7b9adf8df815ac40653cee

接着设置目标芯片:

idf.py set-target esp32s3

设置目标放在填写 Wi-Fi 之前,因为 set-target 会重新初始化已有构建与配置。此步骤只需在首次配置或确实更换目标时执行。

配置 Wi-Fi

在项目根目录打开配置菜单:

idf.py menuconfig

在主菜单进入 BOX2 Internet Radio,分别填写以下两项。它们直接位于该菜单下:

完整菜单路径填写内容
BOX2 Internet Radio / Wi-Fi SSIDWi-Fi 的完整名称,大小写和空格应与路由器设置一致。
BOX2 Internet Radio / Wi-Fi passwordWi-Fi 密码;只有无密码的开放网络才留空。

保存配置到默认的 sdkconfig 并退出菜单。此工程通过编译配置读取 Wi-Fi;修改后需要重新编译和烧录。配置会进入本地 sdkconfig 和固件,分享文件前请检查是否包含自己的网络信息。

SSID 留空时,程序仍能启动,但不会初始化 Wi-Fi 或开始网络播放;串口日志会提示进入 BOX2 Internet Radio 配置。

字段名称依据 Kconfig.projbuild,启动行为依据 main.c

编译、烧录与查看日志

首先编译固件。首次构建会准备工程依赖,耗时取决于网络和电脑性能:

idf.py build

构建成功后,用 USB 数据线连接开发板,在 Windows 设备管理器的“端口(COM 和 LPT)”中查看实际端口。也可以在 PowerShell 中列出可用串口:

[System.IO.Ports.SerialPort]::GetPortNames()

下面的 COM7 仅为示例,执行前请替换为你的开发板实际串口:

idf.py -p COM7 flash monitor

该命令会烧录构建产物并打开串口监视器。退出监视器按 Ctrl + ]。以后只查看运行日志,可以单独运行:

idf.py -p COM7 monitor

工程使用自定义分区,应用分区容量为 6 MB。使用 idf.py flash 可自动采用正确地址,无需手动组合烧录参数。主要产物如下:

文件烧录地址
build/bootloader/bootloader.bin0x0
build/partition_table/partition-table.bin0x8000
build/esp32_box2.bin0x10000

另有 radio_cache 数据分区,起始地址 0x610000、大小 0x50000,用于保存电台目录。固件的实际大小以本次构建输出为准。

依据:分区表官方烧录与监视器说明

首次开机与正常运行

  1. 连接 Wi-Fi。串口出现 Wi-Fi connected, IP=... 表示已取得 IP 地址。
  2. 准备电台目录。首次运行没有有效缓存时,设备会向 Radio Browser 请求目录,界面台名区域显示“正在更新电台”。数量由服务端当时的数据决定,最多 1000 个。
  3. 开始播放。获得有效目录后,设备连接电台并预缓冲音频;出现台名并听到声音后,即可使用实体按键操作。
  4. 同步时间和天气。联网后通过 SNTP 校时,按 UTC+8 显示时间。天气根据公网 IP 定位城市,再请求天气服务;成功后显示天气图标、城市和温度。

后续启动会优先读取 Flash 中的电台目录,恢复已保存的电台位置和音量。缓存的是电台地址列表,声音仍需实时从网络获取。需要刷新电台时,长按第 1 个按键约 2 秒。

当前界面的顶部是音量、时间和电量,中间是天气、日期与中文台名,底部是按键功能图标。它不显示 IP 地址、采样率或接收字节数;连接与解码问题请查看串口日志。

无有效目录时,下载失败后等待约 5 秒重试。已有目录时,手动更新失败会保留原目录。电台播放出错后通常等待约 2.5 秒重连,同一选择连续失败两次会自动切到下一台。

依据:目录、恢复与重连逻辑当前屏幕布局

按键、定时与翻面熄屏

面对屏幕,四个实体按键从左到右对应源码中的 Q、L、M、R。下表按照物理顺序排列:

位置 / 标识短按长按
第 1 个 / Q切到上一个电台,松开后执行。按住约 2 秒更新在线电台目录。
第 2 个 / L音量增加 10 个百分点;到 100% 后,再按回到 0%。无独立长按功能。
第 3 个 / M循环选择定时关机时间,松开后执行。按住约 2 秒,再松开,关机并进入深睡;按第 3 个键唤醒。
第 4 个 / R切到下一个电台。无独立长按功能。

定时顺序:关闭、5、10、20、30、60、90、120 分钟,之后回到关闭。每次选定新的时间都会重新计时;屏幕显示所选择的时长,并非逐分钟倒计时。

更新电台:更新期间播放会中断,成功后保存新目录并从新目录的第一个电台开始播放。若更新失败且已有有效缓存,则继续使用旧目录。

翻面熄屏:屏幕朝下稳定放置约 0.5 秒后会关闭背光,翻回后恢复显示,音频继续播放。该功能依赖板载运动传感器;传感器不可用时,程序保留亮屏运行。

依据:按键、防抖、定时及休眠实现

更换 Wi-Fi 与更新配置

路由器名称或密码变化后,回到同一个项目目录,重新配置并烧录即可。以下串口仍以 COM7 为例:

Set-Location C:\esp\esp32-box2-radio
idf.py menuconfig
idf.py build
idf.py -p COM7 flash monitor

BOX2 Internet Radio 中修改 SSID 和密码,保存后再执行后两条命令。此时不需要重复运行 set-target。普通固件烧录不主动清除 NVS 和电台缓存分区,因此保存的台序与音量通常可以继续使用。

若只是希望获取新电台,在设备上长按 Q 键约 2 秒即可;不需要重新编译。当前配置菜单只提供 Wi-Fi 名称与密码,没有电台地址、天气城市或其他播放格式的设置项。

支持范围与网络要求

项目当前行为
播放格式面向 HTTP / HTTPS MP3 直播流;不提供 AAC、HLS / M3U8、PLS 播放。M3U 用于导入电台目录。
音频输出兼容单声道和双声道 MP3 输入,混合为单声道,经 FIR 重采样后以 48 kHz 输出。
电台目录运行时存放在 PSRAM,并缓存到板载 Flash。电台可用性受公共目录与各电台服务器影响,目录标为可用并不保证实时可播。
离线能力不提供音频下载、TF / SD 卡播放、离线节目或收藏管理。保存的目录不能代替互联网连接。
歌曲信息请求关闭 ICY metadata,未实现歌曲标题解析。
中文显示内置字库覆盖常用中文区域;未覆盖的字符,包括 BMP 之外的扩展汉字,会显示为问号。
切台与等待切台包含连接结束、重新连接和缓冲过程;网络读取超时配置为 5 秒,目录请求超时为 15 秒,因此不能保证瞬间切换。
天气与时间城市由公网 IP 推断,可能与实际位置不同。天气正常时每 10 分钟刷新;定位约每 6 小时刷新。天气缓存可能在启动时先显示上次结果。

网络需要允许访问 de1.api.radio-browser.info 和目录中的各电台地址。天气额外使用 ipwho.isapi.open-meteo.com;校时使用 ntp.aliyun.com。HTTPS 请求使用证书包验证。需要网页认证的公共 Wi-Fi 不适合此固件的直接连接流程。

依据:重采样实现天气服务字库范围

常见问题排查

现象优先检查
找不到 idf.py使用 EIM 打开已安装的 6.0.2 终端,再运行 idf.py --version。普通 PowerShell 通常尚未激活工具链。
版本或依赖解析报错确认是 ESP-IDF 6.0.2,并检查电脑能访问组件下载服务。保留报错中第一个失败原因;不要通过随意升级依赖绕开版本约束。
找不到 COM 口或端口被占用检查 USB 线是否支持数据、连接接口是否正确,在设备管理器重新确认端口。关闭占用串口的终端或监视器。
烧录连接失败核对实际 COM 口、USB 连接和供电。按照开发板说明进入下载模式后重试;也可降低烧录波特率。
无法连接 Wi-Fi确认网络为 2.4 GHz,SSID 与密码正确,并已重新编译烧录。串口反复出现 Wi-Fi disconnected; reconnecting 时,先检查信号和路由器设置。
没有电台或持续更新失败检查 DNS、互联网连接以及 Radio Browser 服务的可达性。没有缓存时会自动重试;已有缓存可先继续收听,稍后再长按 Q 更新。
有台名但没有声音确认音量不是 0%,等待连接与缓冲完成,再换几个电台测试。查看日志中的 HTTP 状态、连接失败或解码错误,并检查扬声器连接。
频繁卡顿或自动切台靠近路由器、检查供电,再测试其他电台。同一电台连续失败两次后自动换台属于当前恢复逻辑。
黑屏但还有声音先把屏幕朝上放置,检查是否触发翻面熄屏。若设备已经关机,按第 3 个按键唤醒。
天气空白、城市不对或时间为 00:00检查天气接口和 SNTP 网络访问。城市来自公网 IP 定位;时间未同步时会显示占位值。天气服务失败不会阻止电台任务运行。
PSRAM 初始化或内存分配失败确认使用 N16R8 硬件,目标为 ESP32-S3,并保留默认的 8 MB OPI PSRAM 配置。

降低烧录速度的示例命令:

idf.py -p COM7 -b 115200 flash monitor

记录问题时,建议保留提交号、idf.py --version 输出,以及从启动到首次报错的串口日志。这样可以区分环境、连接、电台源和板级硬件问题。

源码与参考资料

本文核对的完整提交为 c732659ebd64ec701d7b9adf8df815ac40653cee,提交日期为 2026 年 8 月 26 日。以下源码链接固定到该版本:

本教程经过仓库源码核对,未将第一版 README 的旧构建体积或构建验证结论视为当前提交的实测结果。最终播放效果和电台可用性请在实际设备与网络环境中确认。