直接说结论:这轮我用BT2106C做了一个Auracast蓝牙广播模块的接收方案,从画板到调通、从实验室到户外实测,整个过程踩了不少坑,也拿到了一手数据。今天这篇就把它完整拆开讲:为什么选 BT2106C、Auracast 接收端到底要解决哪些问题、硬件和软件怎么配合、实际效果到什么水平,以及你在复刻时最容易栽的坑。
如果你是做音频产品、IoT 网关、助听辅听、博物馆导览、会议室同传这类方向的工程师,这篇可以直接当开发参考。就算你只是对蓝牙广播音频好奇,看完也能明白 Auracast 和传统蓝牙耳机是完全不同的玩法。
1. 项目背景:Auracast 到底解决什么问题
1.1 为什么突然要折腾“广播音频”
传统蓝牙音频是“一对一”的,手机连耳机、电视连音箱,一条链路占住以后别人就听不到。但在很多真实场景里,大家需要的是“一人发声、多人收听”,或者“多个设备同时播放同一路音频”——最典型的是健身房里的电视、酒吧里的球赛、机场登机口、会议室同传、博物馆讲解。用传统蓝牙去做这些场景,要么配对繁琐,要么接入人数受限,要么声音只能从扬声器外放,干扰严重。
Auracast 就是奔着这个痛点来的。它是蓝牙技术联盟基于 LE Audio 推出的广播音频功能,核心思路是把音频从“连接”变成“广播”:发射端持续广播音频数据包,接收端像收音机一样“搜台”并锁定收听。不需要配对,不需要授权,甚至不需要知道发射端是谁,只要扫描到、选一下、同步上来,就能开始听。
所以这个项目的定位很清晰:做一个 Auracast 广播音频接收模块,输入是外部发射端(比如手机、电视、专用麦克风、音频网关)发出的 BIS 广播流,输出是 I2S 或模拟音频,直接接耳机、功放或者后端 DSP 处理。这样一颗模块就能塞进各种产品里,让它们秒变 Auracast 接收器。
1.2 为什么是 BT2106C 这颗芯片
选型的时候其实对比了好几颗方案,包括一些手机同款的高端 SoC,也有低端 BLE SoC 自己写协议栈。最后定 BT2106C,主要看中三点。
第一是原生支持 LE Audio 和 Auracast。这颗芯片在设计之初就把 LE Audio 相关的链路层和上层 profile 做了硬件和固件层面的支持,不需要我从零去啃 BIS/ CIS 同步逻辑。第二是性价比和外围成本。它内置了足够用的 RAM/Flash,单芯片能跑协议栈加应用代码,外围一颗晶振、一颗 Flash(如果不够用)加音频编解码电路就行。第三是功耗表现。广播接收场景很多是便携设备,BT2106C 的接收电流控制得比较好,实测后面细说。
当然,选它也有代价:它不像手机上那颗 SoC 那样有一整套成熟的开源协议栈和平板级的应用生态,很多细节要对着芯片手册和 SDK 去抠。但你如果是做产品而不是做平台,BT2106C 这种“够用且便宜”的思路更实际。
1.3 模块最终形态和影响范围
我这轮做出来的是 20mm x 28mm 左右的小板,核心是 BT2106C,外围带了天线匹配、DC-DC、I2S 输出接口和一个调试串口。板上预留了按键和 LED 接口,方便做搜台/切台和状态指示。
效果上,环境安静的会议室里能稳定收 10 米内发射端的广播;开阔场地拉距能到 50 米左右(手机做发射端时,手机本身的发射功率也限制了一部分);同一个区域内能扫到多个广播源并锁定其中一个收听,切台延迟大概 1 秒上下。
影响范围往大了说,这颗模块可以直接用于:电视伴侣(把电视的 Auracast 广播变成耳机能收)、多语种同传接收器、酒吧/健身房多电视同步收听、助听辅听类产品、博物馆导览标签、会议系统同传接收端。它本质上是给传统音频接收类产品加了一种新的“输入源”,而且这种输入源不需要配对、可以一对多,产品形态一下就灵活了。
2. 硬件设计:模块选型与板级要点
2.1 模块选型:买现成模块还是自己画板
BT2106C 市面上有几种拿货方式:一种是买芯片自己画最小系统板,另一种是买第三方封装好的邮票孔模块。如果你目标是快速验证功能,强烈建议先买现成模块,把协议栈、工具链和音频链路跑通,再决定要不要自己画板。自己从零画板会遇到天线匹配、晶振布局、电源纹波、Flash 选型一堆问题,中间任何一个出问题都会让你误以为是协议栈的 bug,排查起来非常痛苦。
我这轮其实是先买了一颗模块验证,然后自己画了第二版板子。两版对比下来,模块方案在 2.4G 频段的射频表现确实更省心,因为厂商已经把天线匹配和板层做了调优;自己画板则必须严格照着参考设计抄,天线区域的净空和地铜处理一点都不能马虎。
2.2 最小系统的关键外围
BT2106C 的最小系统并不复杂,但有几个细节会影响稳定性和音频质量:
- 电源:芯片的射频部分对电源纹波比较敏感。我用了一颗低噪声 LDO 给射频模拟供电,DC-DC 只给数字部分用。实测如果共用一颗纹波大的 DC-DC,接收灵敏度会掉几个 dB,广播包误码率明显升高。
- 晶振:必须用 32MHz 晶振,匹配电容按芯片手册来,尽量靠近芯片引脚。不要省这颗匹配电容,位置和容值不对会导致频率偏差过大,表现就是搜台不稳定、锁不住广播。
- 音频输出:BT2106C 的原生音频接口通常是 I2S/PCM,接外部 DAC 或 Codec 出模拟信号。我这版选了 ES8311,因为它功耗低、自带耳机功放,而且芯片手册里有现成驱动可以抄。如果你只是要验证,I2S 接一块 MAX98357A 小板也行,但要注意 MAX98357A 的增益默认比较大,容易爆音。
- 天线:首选板载 PCB 天线或陶瓷天线。天线区域净空必须按模块厂商的参考设计来,底下不能走地铜和无关走线。如果塞进金属外壳,天线外侧要留至少 5mm 空间,否则谐振频率直接偏掉。
2.3 从模块到“能用”的音频通路
很多人以为芯片输出 I2S 再接个 DAC 就行,实际不是。Auracast 广播音频的采样率、位深、声道数和普通音频文件不一样,尤其是 LC3 编解码后的输出参数,要和你选的 DAC 驱动严格匹配,否则会出现“有数据但没声音”或者“声音像马达一样”。
我在这版板上把 I2S 主从模式、采样率(最常见是 48kHz,但广播源也可能是 32kHz/44.1kHz)、声道映射做成了运行时可配置,而不是硬编码。这样调试时不同发射端都能适配。另外,ES8311 的 I2C 地址需要根据芯片引脚电平确认,我做板时跳线留错了,第一版只能飞线改地址,这种低级但耗时的坑大家引以为戒。
2.4 焊接和生产的几个经验
如果你准备批量做,注意三点:第一,BT2106C 这类 QFN 封装对焊接温度敏感,建议用钢网+回流焊,手焊时温度不要超过 350 度,每个脚停留不要超过 3 秒,否则芯片容易内部损伤,症状是偶尔死机或搜不到台。第二,天线匹配的 π 型网络预留位置一定要留,即使参考设计说“直连即可”,实际不同批次天线或外壳变化时,可能需要调匹配。第三,Flash 颗粒尽量选厂商 SDK 里兼容列表内的型号,有些国产 Flash 的时序参数在低功耗唤醒后会有偶发读取异常,表现就是升级失败或配置丢失。
3. 软件开发:Auracast 接收端的实现细节
3.1 SDK 与工具链搭建
BT2106C 的 SDK 拿到手以后,第一步不是写代码,而是把编译环境和下载工具跑通。我用的是厂商提供 GCC 工具链加命令行编译,IDE 可选 VS Code,不建议刚上来用复杂 IDE,否则配环境的时间比写代码还多。
SDK 里通常有现成的 LE Audio 例程,重点找这几个:BIS 接收(Broadcast Isochronous Stream Receiver)、PA sync(Periodic Advertising Synchronization)、BIG sync(Broadcast Isochronous Group synchronization)。Auracast 接收端本质上就是:先扫描到 Periodic Advertising,然后同步到对应的 BIG,再从 BIG 里选取一路或多路 BIS 解出音频。SDK 例程一般会给出整套回调流程,你要做的是把它接对。
编译流程大致是:
source envsetup.sh make bt2106c_auracast_rx_defconfig make -j8注意不同 SDK 版本的配置项名称差异很大,如果找不到auracast相关 defconfig,就去例程目录里找broadcast_receiver或le_audio_rx,本质是同一个东西。
3.2 Auracast 接收器状态机拆解
整个接收流程我总结成四步状态机:
- 扫描阶段:芯片进入扫描模式,监听 2.4G 上的周期性广播。Auracast 用的是 Periodic Advertising,它和普通 BLE 广播的区别是:普通广播是每次广播间隔发一包,周期性广播是在一个固定的时间序列里发一系列包,接收端可以预知下一次发包时间,从而降低功耗。
- 同步阶段:收到 Periodic Advertising 后,芯片发起 PA sync,也就是和发射端的时基对齐。这个阶段最关键的是时基校准,如果本地晶振偏差大或环境多径严重,会反复同步失败。
- BIG 同步阶段:PA sync 成功后,协议栈会解析出 BIG 的参数,包括 BIS 数量、信道映射、帧间隔、加密信息等,然后开始同步 BIG。BIG 是真正的音频数据通道。
- 音频输出阶段:BIG 同步上后,LC3 解码器开始工作,解码后的 PCM 数据通过 I2S 送给外部 DAC。这一步要保证 I2S 的时钟和广播源采样率一致,或者做采样率转换,否则会出现音调偏高/偏低或卡顿。
这四步里,前两步是“能不能搜到”,后两步是“能不能听”,开发时分开验证会省很多事。
3.3 关键配置项与参数
在 SDK 的例程配置里,有几个参数直接决定体验:
- 扫描窗口和扫描间隔:扫描窗口越大越容易发现广播,但功耗越高。实测用 200ms 扫描窗口、400ms 扫描间隔在室内能稳定发现广播源,功耗和灵敏度比较均衡。如果搜不到台,先把扫描窗口调到最大试试。
- PA sync 超时:默认值可能只有几秒。如果发射端广播间隔较长(比如 100ms 以上),超时设置太短会导致刚发现就掉线。我一般设 10 秒以上。
- BIS 通道数:Auracast 可以广播多路 BIS,比如一路中文、一路英文、一路环境音。接收端要支持选择某一路,并在代码里显式配置要解码的 BIS 索引。
- 加密和广播 ID:Auracast 广播可以带 PIN 码保护,也可以公开。商用场景建议带加密,接收端需要实现输入 PIN 的 UI 逻辑;验证阶段可以先不加密,减少变量。
下面是我在 SDK 里改过的一段伪代码结构,方便理解:
static void rx_event_handler(le_audio_rx_evt_t *evt) { switch (evt->type) { case LE_AUDIO_RX_EVT_PA_FOUND: /* 发现周期性广播,保存 isochronous info */ le_audio_rx_sync_big(evt->big_info); break; case LE_AUDIO_RX_EVT_BIG_SYNCED: /* BIG 同步成功,启动 LC3 解码并配置 I2S */ audio_start_stream(evt->bisco_params); break; case LE_AUDIO_RX_EVT_AUDIO_DATA: /* 解码后的 PCM 数据发送到 I2S */ i2s_write(evt->pcm_buf, evt->pcm_len); break; case LE_AUDIO_RX_EVT_SYNC_LOST: /* 同步丢失,重新进入扫描 */ le_audio_rx_start_scan(); break; } }3.4 功耗调优的实测数据
广播接收和传统蓝牙连接有个本质区别:它不需要持续双向通信,所以可以设计得很省电。我在两版固件里对比过功耗:
| 模式 | 电流 | 说明 |
|---|---|---|
| 深睡眠(无扫描) | 约 12 uA | 待机,等待按键触发 |
| 周期扫描(发现阶段) | 约 1.8 mA | 扫描窗口 200ms / 间隔 400ms |
| 同步接收 + LC3 解码 + I2S 输出 | 约 6-8 mA | ES8311 功耗另计 |
| 同步接收 + 模拟输出(内置 DAC 版本) | 约 5 mA | 省掉外置 DAC 功耗 |
如果你是做助听器或便携导览设备,6-8 mA 的整机电流基本可以接受;如果是纽扣电池设备,还想更低,可以考虑在扫描阶段用更长扫描间隔,但会牺牲发现速度。这一点要根据产品形态取舍。
4. 实操过程:从点灯到跑通 Auracast
4.1 第一阶段:点亮最小系统
拿到板子之后先别急着调蓝牙。先把电源、串口、LED、按键全部点一遍,确保最小系统稳定。我常用的检查顺序是:
- 上电后串口有没有 Boot log,确认芯片启动。
- 用示波器/万用表确认 LDO 输出电压和晶振起振波形。
- 跑一个 LED Blink 程序,确认 Flash 读写和时钟配置正常。
- 如果 SDK 支持 AT 命令或基础 BLE Beacon 例程,先跑一个,确认射频链路能发包。
这个阶段最容易出的问题就是晶振不起振和 Flash 初始化失败。晶振不起振多半是匹配电容问题,Flash 初始化失败大概率是 SDK 的 Flash 配置和实际颗粒不一致,去board.h里改选中型号就行。
4.2 第二阶段:先实现“非 Auracast”的音频回环
直接调 Auracast 有个麻烦:你不知道搜不到信号是射频问题、协议栈问题,还是发射端根本没有发广播。所以我建议在跑 Auracast 之前,先把音频链路打通。
最简单的办法是让芯片自己产生一段正弦波或提示音,通过 I2S 输出到 DAC,用耳机听有没有声音。这段通了,说明 I2S 配置、DAC 驱动、电源和耳机通路都没问题。然后再把你的手机或电脑开一个标准 BLE Audio 连接(如果支持)测试正常连接音频,确认协议栈和 Codec 都没问题。
我实际踩过的一个坑是:I2S 声道配置成了单声道,但 LC3 解码器默认输出立体声,结果声音只有一边响,而且音量减半。后来看数据手册才发现广播音频的声道映射有几种,必须在 I2S 配置里对应匹配。
4.3 第三阶段:用工程模式验证 Auracast 搜索
很多 BT2106C SDK 会带一个工程调试模式,可以把扫描结果直接打印到串口。我拿到后第一件事就是开启这个模式,然后打开手机上的 Auracast 发射端 App(比如厂商提供的演示 App,或者支持 Auracast 发射的麦克风/电视),看串口能不能打印出广播信息。
串口输出大致长这样:
[PA] adv addr: 0x123456789ABC [PA] adv sid: 0x01 [PA] bis count: 2 [PA] sample rate: 48000 [PA] frame duration: 10000 us [PA] protection: none [BIG] sync start... [BIG] sync success! bis index: 0 [AUDIO] stream started, pcm 48000 Hz看到BIG sync success就说明协议栈层面的链路已经通了。如果一直停在PA扫描到但BIG sync失败,先检查发射端是不是只发 PA 没发 BIG(有些 App 有开关),再检查本地时钟配置。
4.4 第四阶段:集成到具体产品逻辑
协议栈通了以后,剩下的就是产品逻辑:按键搜台、自动选择信号最强的广播源、记住上次收听频道、PIN 码输入界面等。这些功能不复杂,但要花时间打磨交互。
我这版做了一个很简单的逻辑:开机自动扫描,按一下按键切到下一个广播源,LED 用不同颜色显示“空闲/已锁定/信号弱”。实际体验中,自动切到信号最强广播源这个功能非常实用,因为室内多个广播源共存时,用户其实不知道自己想听哪个名称,按信号选往往是最符合直觉的。
5. 实际效果:距离、音质、稳定性和兼容性
5.1 距离测试:开阔地和室内穿墙
Auracast 接收距离主要取决于发射端功率、接收端灵敏度、天线效率、环境多径。我用同一颗模块、同一部安卓手机做发射端,分别测了开阔地和室内的表现。
先说开阔地:手机放在 1.2 米高的三脚架上,接收模块手持,保持天线朝向一致。距离 20 米以内音频完全不断,30 米开始偶发短暂卡顿,50 米能勉强锁定但已经不适合实际使用。注意手机本身发射功率有限,如果用固定式 Auracast 网关(部分开发板有 PA 增益设置),距离还能更远。
室内穿墙就现实多了:同一房间内稳定,隔一堵砖墙还能听清,隔两堵墙基本无法同步。这和 2.4G 频段穿墙衰减快的特点相符,做产品时要预判用户场景,如果是隔房间收听的场景,需要做中继或有线扩展,不能指望单点覆盖。
5.2 音质与延迟
LC3 编解码在中等码率下音质远好于传统 SBC,实测听感接近甚至超过普通 AAC 蓝牙耳机的水平。我用 48kHz/16bit 的 LC3 配置,听语言类内容非常清晰,音乐类的低频和高频也没有明显压缩感。当然,最终音质还取决于你后端 DAC 和耳机/喇叭的质量。
延迟方面,Auracast 广播接收天然有缓冲延迟,因为要抵抗射频抖动。实测从发射端画面发声到接收端耳机出声,延迟大约在 100-200ms 之间,看发射端的帧间隔和接收端的缓冲策略。如果你做的是电视伴侣,200ms 延迟看新闻联播没问题,但打游戏或看口型会明显不同步。这时候要尽量用短帧间隔(比如 10ms 帧)并降低接收端缓冲,但要承担更多丢包风险。
5.3 多广播源共存的表现
我在办公室同时开了 3 个 Auracast 发射端(两个手机 App、一个开发板网关),间隔 5 米左右放置。接收端扫描时能列出 3 个源,锁定其中一个监听时,其他源的信号不会干扰当前收听,只在信道上引发一些底噪上升。这和传统蓝牙被附近设备干扰就断连的表现完全不同,广播机制的天然优势。
不过有一点要提醒:如果多个广播源用了一样的广播名称和一样的加密配置,接收端无法区分它们,用户会看到“同名广播”。做产品时最好让设备名带上默认前缀或序号,方便用户识别。
5.4 收发设备的兼容性实测
我实测过的发射端包括:
| 发射端类型 | 系统/版本 | 表现 |
|---|---|---|
| 演示 App(BT SIG 参考) | Android 12 + LE Audio 扩展 | 正常 |
| 厂商定制 Auracast 网关 | 自研固件 | 正常 |
| 手机系统级 Auracast 发射 | Android 13 部分机型 | 有兼容问题,机型差异大 |
| 电视内置 Auracast 发射 | 新出电视型号 | 需升级到最新固件 |
| 麦克风/音频网关 | 专业音频设备 | 正常,但配置界面通常复杂 |
如果你要做的是通用接收端,一定要准备至少 2-3 种不同发射端做交叉测试。我发现有些发射端的 BIG 参数配置不规范(比如 BIS 数量为 0 但实际发了数据),接收端如果按标准解析就会失败,必须加容错逻辑。
6. 常见问题与排查技巧实录
6.1 搜不到任何广播源
这是开发中最常见的卡点,排查顺序别乱:
- 确认发射端真的在发广播。用手机 BLE 扫描工具抓包,看有没有 Period Advertising。如果没有,发射端问题,换设备或换 App。
- 确认接收端进入了扫描状态。看串口 log 有没有周期扫描调度输出。
- 确认天线没脱落或虚焊。如果天线区域手碰到信号会有明显变化,多半是匹配或净空问题。
- 确认设备地址过滤没开。有些例程默认带 MAC 过滤,会把你自己的广播过滤掉。
- 确认扫描参数不是太保守。把扫描窗口调满,扫 10 秒以上再说。
6.2 能搜到广播但BIG sync一直失败
能搜到广播说明射频链路正常,问题大概率在同步参数。优先排查:
- 本地晶振偏差太大。用频谱仪或参考信号对比,如果偏差超过 20ppm,BIG 同步会反复失败。
- PA sync 超时设太短。广播间隔长的情况下,同步过程需要多个周期才能完成。
- 发射端没有实际发送 BIG 数据。有些 App 的“开始广播”按钮只开了 PA,BIG 要再点一层。用抓包工具确认 BIG 是否真实存在。
6.3 声音断续或音调异常
声音断续先别赖信号,可能是音频通路的问题。检查 I2S 的 DMA buffer 是否足够大,如果太小,瞬间射频抖动就会导致 underrun,表现为每几百毫秒断一下。音调偏高或偏低则是采样率不匹配,确认 LC3 解码输出的采样率配置和 I2S 实际时钟一致。
还有一种情况:用了省电模式导致射频接收窗口太小,同步上以后误码率偏高,音频解码器纠正不了就静音。这种调整接收窗口为连续接收即可,代价是功耗上升。
6.4 功耗异常高
如果实测电流和预期差很多,看看是不是进入了扫描空转模式。比如你在没有广播源的空旷环境下,扫描功耗可能一直在 1.8mA 水平,看似不高,但如果产品一直扫,电池也会很快耗尽。实现上应该做“扫描一段时间没结果就退回报文模式”,等用户按键再唤醒扫描,这才能控制待机功耗。
6.5 烧录和调试的坑
BT2106C 的烧录接口我用的是 SWD,但有个细节:芯片进入低功耗模式后,通过 SWD 连上会概率失败,必须先通过按键或复位把芯片唤醒再烧录。调试软件断点也别在蓝牙中断处理函数里打太多,因为射频时序是硬实时的,断下太久会导致协议栈状态错乱,表现为复位后连不上或搜不到台。
7. 产品化落地:认证、天线设计与产测
如果你准备拿这个模块做产品,以下几件事越早规划越好。
蓝牙 SIG 认证是绕不开的。Auracast 是蓝牙 5.2+ 的特性,你的产品如果要打蓝牙 logo,需要购买声明 ID(Declaration ID)和 QDID,并通过相关测试。如果直接买的是模组,很多模组厂商已经把认证做掉了,你只需要做最终产品认证即可。这里特别提醒:如果是自己画板,射频部分不能随意动,动了认证就要重来。天线设计也要注意,同一个芯片,不同天线的谐振点和辐射效率差异很大。我用 PCB 天线做了一个版本,又用陶瓷天线做了一个版本,同样距离下陶瓷天线在贴近人体时掉信号更明显,而 PCB 天线在开阔地表现略好。具体选型要看你的产品外壳和用户握持方式。
量产阶段一定要写产测固件。产测固件不应该跑完整 Auracast 接收,而是进入一种固定模式:上电后持续扫描指定广播源,并把信号强度和工作状态通过串口/蓝牙打印出来,产线测试人员只需要看 PASS/FAIL。另外,天线匹配网络的 π 型电阻,有些厂商会要求用 0 欧直连,有些要用几 pF 电容,批次不同可能要微调,这个在产测中可以用信号强度一致性来监测。
最后是软件 OTA 升级策略。Auracast 的规范还在演进,芯片 SDK 更新频繁,如果你产品不支持 OTA,后期修复 bug 就非常痛苦。BT2106C 的 OTA 分区要提前规划好,预留一个 bootloader 加双备份 app 区,不然发出去的设备收不回来,维护成本极高。
8. 一些个人体会
这次开发做下来,我最大的感受是:Auracast 并不是“新蓝牙”,而是“广播思维”。做传统蓝牙音频,你习惯为每一个连接建立一条稳定的管道;做 Auracast,你面对的是一个“开放信道”,发射端根本不知道你在听,也不会为你做重传。这套机制带来的省电和一对多是实打实的,但也逼着你在抗丢包、缓冲策略和用户体验上多花心思。
后期如果想继续扩展,可以考虑两个方向:一是加音频后处理,在接收端做降噪、EQ 或语音增强,让这颗模块直接能用在助听类产品上;二是加网络回传,把 Auracast 广播内容通过 Wi-Fi 转成手机可听的流,做一个“广播音频网关”。这些扩展都会在这颗模块的基础上长出新的产品形态,目前看市场需求是实打实的。
最后分享一个开发细节:在调 I2S 和 DAC 时,别一上来就用耳机听,先接一个逻辑分析仪看 I2S 的 LRCK 和 BCLK 波形,确认时序正确再上耳机。这一步能帮你把“没有声音”的问题从硬件问题里快速分离出来,省下大量排查时间。