1. 立项背景:Auracast广播到底解决什么问题
很多做蓝牙音频开发的朋友,一听到Auracast第一反应是"这不就是个新蓝牙协议吗",其实这个理解不够准确。Auracast不是简单的版本升级,它是蓝牙SIG在LE Audio框架下推出的一套全新广播音频机制,核心变化在于:音频传输不再走"配对-连接-传输"这条传统链路,而是改成了"广播-收听"的单向模式。
我做这个BT2106C项目的出发点,是接了客户一个需求——要做一款面向商场大屏、机场候机厅这类场景的音频广播发射端设备。传统的做法大家都很熟:蓝牙接收端设备(功放、耳机)用A2DP连接过来,把音频推过去。但问题是,A2DP协议栈要求一对一连接,一台发射设备只能服务一个接收设备,再多就得用昂贵的多点模块或者牺牲稳定性。客户要的却是"一个发射端,同时覆盖几十上百个收听者",而且理想状态下这些收听者不需要任何配对操作,走过来就能听到。
这需求乍一听像FM广播的蓝牙版,但FM的音频质量和频道管理能力太弱,而且手机端没法原生支持FM接收。Auracast正好补齐了这个缺口:它基于BLE的同步广播通道(isochronous channel),发射端把音频流编码成LC3格式,以广播数据包的形式周期性发送,接收端(手机、耳机、专用接收模块)扫描到广播组后直接同步收听,不需要配对、不需要PIN码、没有连接数上限。
这就是我最终选BT2106C做这个项目的根本原因。这颗芯片属于中科蓝讯新一代支持LE Audio方案的蓝牙SoC,片内集成RISC-V核心和完整的蓝牙基带射频,对Auracast广播的支持是原生级的,不是靠协议栈软件硬凑。相比用通用蓝牙芯片外加协议栈授权这样的方案,使用专用SoC能把BOM成本压得很低,功耗表现也更好。
2. 硬件设计要点:模块整体布局、天线与关键引脚处理
BT2106C以模块形式做进产品里,硬件设计上的坑其实比想象中多。当初我一开始图省事直接用参考设计画板,第一版打样回来发现广播距离完全达不到预期,排查到最后才发现问题出在天线净空和电源纹波上。这次把整理过的设计要点写出来供参考。
2.1 最小系统的搭建思路
BT2106C模块本身已经集成了晶振、PMU电源管理和射频匹配网络,所以外部需要的外围器件不多。我的最小系统构成如下:
- 电源:VDDBAT输入3.7V锂电池,经过片内LDO稳压到各路核心电压,外部只需在电源引脚附近放置10uF+100nF的组合去耦电容
- 复位电路:NRST引脚接10k下拉电阻和100nF电容到地,防止上电瞬间误触发复位
- 音频输入:因为是广播发射端,音频源通常是模拟线路输入或I2S数字输入,我选用了I2S直连方案,省去模拟前端,信噪比也更高
- 天线部分:PCB板载天线设计在板边,净空区长度至少10mm,天线下方所有层做挖空处理
2.2 天线布板的实际测试复盘
我第一版设计犯了一个低级错误:为了把板子尺寸压缩到极限,把天线净空区砍到了7mm,同时在天线正下方走了一根电源线。实测结果就是频率偏了,发射功率虽然能到+8dBm,但实际测得的广播距离只有空旷地20米出头。后来重新改版,把净空区加回12mm,电源线绕行避开天线正下方,同样条件下距离拉到了35米以上。
这里有个建议供参考:如果你对射频走线不够有把握,直接用模块厂家提供的参考PCB布局,不要自创。模块这类的射频性能非常依赖PCB寄生参数,天线的匹配网络哪怕偏差0.5pF,驻波比都可能恶化到2.0以上,直接影响辐射效率。
2.3 I2S音频输入注意事项
既然走数字音频链路,I2S的时序匹配就很关键。我用的是主模式,MCU作为I2S master输出BCLK和LRCK,BT2106C作为slave接收。之前遇到过一个问题:LRCK的占空比不够精准,导致左声道偶尔串音到右声道,波形上看其实就是边沿抖动。后来在LRCK线上加了一颗22Ω串联电阻抑制振铃,问题就消失了。
另外,I2S输入的参考电压域要和模块的数字IO电压匹配,BT2106C的IO电压是3.3V,如果MCU也是3.3V就直连,但如果是1.8V的MCU,就需要做电平转换或选用开漏模式配上拉,否则会损伤芯片。
3. 固件开发的关键动作:从SDK配置到广播参数调优
固件这块是整个项目最花时间的部分。BT2106C的SDK基于RISC-V架构,工具链用的是平头哥系列编译器,开发调试思路和ARM体系完全不同,刚开始上手时我也花了不少时间适应。
3.1 SDK环境搭建和编译流程
SDK包解压后,目录结构大致是app、drivers、stack放在核心目录中,使用scons脚本构建。环境建议用Ubuntu 18.04/20.04的64位系统,Windows下用WSL也可以,但直接原生Linux体验最稳。
编译流程很简单,修改应用层代码,在根目录执行构建命令,就能生成烧录用的bin文件。烧录通过串口直接下载到芯片即可。注意Windows下需要安装USB转串口驱动,Ubuntu下一般免驱。
这里提个建议,开发期间建议开两个终端,一个跑编译,一个跑串口日志监控。BT2106C的串口日志输出功能很实用,尤其调试协议栈状态机时,没有日志基本没法干活。
3.2 广播参数配置的核心代码逻辑
Auracast广播模式配置,在SDK里其实就是配置"是否启用广播"以及对应的广播参数。关键代码如下:
// 广播组配置示例 app_auracast_config_t auracast_cfg = { .adv_enable = true, .adv_interval = 100, // 广播间隔,单位ms .adv_phy = ADV_PHY_CODED, // 使用LE Coded PHY,延长距离 .bis_num = 1, // 广播流数量 .audio_channel = 2, // 双声道 .lc3_bitrate = 96000, // 96kbps .sync_timeout = 3000, // 同步超时时间,单位ms .adv_tx_power = 8, // 发射功率,单位dBm }; auracast_init(&auracast_cfg);这段配置里有几个点比较关键:
第一是PHY的选择。BLE有两种长距离PHY,LE Coded PHY在相同发射功率下距离能提升约2倍,但代价是数据速率下降到125kbps或500kbps。做广播音频时,如果只广播单声道LC3 64kbps,LE Coded 500kbps模式完全够用,而且距离更远。如果你的应用场景是近距离舞蹈教室这类,用2M PHY可以提高空中传输效率,降低时延。
第二是LC3码率的选择。LC3在96kbps时主观音质已经和A2DP的SBC 328kbps相当甚至更好,这是LC3编码效率高带来的直接效果。但我测试中发现,在信号边缘地带,码率越高的广播流越容易出现断音。所以如果接收端距离较远,建议把码率砍到64kbps,代价是高频细腻度稍有下降,但换来的是更稳定的接收。
第三是广播间隔。广播间隔越短,接收端同步越快,但功耗越高。100ms的间隔在大多数场景下都合适,如果你做的是固定供电设备完全无所谓,但如果是电池供电的便携广播器,建议把间隔调到150ms,功耗能降不少。
3.3 广播名称和元数据配置
Auracast有个特点,接收端要发现并识别广播源,靠的是广播包的元数据,而不是像经典蓝牙那样配对搜索设备名。这个元数据里最重要的就是广播名(Broadcast Name),用户手机上打开蓝牙设置里的"音频广播"功能时,看到的列表项,对应的就是这个字段。
配置方法是在广播数据包里填入广播ID和名称:
// 广播元数据配置 auracast_meta_t meta = { .broadcast_id = "MALL-INFO", .broadcast_name = "商场公共广播-1F", .language = "zh-CN", .public_group = true, }; auracast_set_metadata(&meta);这里有个细节容易踩坑:广播名用来做展示,广播ID才实际参与接收端的同步识别。同一个广播组下可以包含多个广播流(比如多语言音轨),每个流用BIS index区分。如果你要做多语言广播,就需要在配置里开多个BIS,每个BIS对应一种语言,接收端在界面上选择要听哪一路。
4. 实测表现与数据:距离、音质、功耗到底怎么样
实测是我这次开发最花时间的环节,因为广播音频的接收表现受环境影响比传统蓝牙连接大得多。构建场景后,我分别在空旷户外、商场大厅和有遮挡的办公区做了三轮测试,把关键数据整理出来。
4.1 接收距离的实测数据
测试场景分为三种,接收设备用的是普通手机,开启蓝牙设置里的Auracast广播接收功能(Android系统版本为13以上,具体机型有差异),结果如下:
| 测试环境 | 连接模式对比 | 实测距离 |
|---|---|---|
| 空旷户外 | A2DP连接模式 | 约20m(手机与模块直接连接) |
| 空旷户外 | Auracast广播模式 | 约35m(可稳定收听,再远开始断续) |
| 商场大厅 | Auracast广播模式 | 约15-20m(受货架遮挡影响) |
| 办公区隔墙 | Auracast广播模式 | 约8m(穿一面混凝土墙) |
空旷环境下广播模式能比A2DP远将近一倍,主要原因是A2DP要求双向链路稳定,回传通道一旦丢包就整体降级;而广播是单向的,接收端只要偶尔收到几个完整的数据包就能解码出连续音频,容错性明显更好。
但我必须强调,这些数据是在+8dBm发射功率、LE Coded PHY下测得的,实际产品里如果天线匹配不好或板子结构变化,距离会缩水很多。建议留出至少30%的余量来设计你的产品使用距离。
4.2 音频延时和音质
用延迟测试仪实测从I2S输入到手机出声,整体延迟在80-100ms之间。这个延迟不包含网络传输,就是纯本地链路延迟,对于广播场景完全够用。它不像游戏耳机那样对延迟敏感,你不可能用Auracast打音游——这本来就不是它的定位场景。
音质方面,我盲测对比了LC3 96kbps单声道广播和传统SBC 328kbps立体声A2DP。听流行音乐时,两者差异很小;但听古典乐的弦乐群部分,LC3的高频滚降比SBC略明显一些。不过听语音广播和商场背景音乐,LC3完全胜任,甚至因为LC3的瞬态响应更好,人声的清晰度反而比SBC更好。
4.3 功耗实测数据
功耗项目:
| 工作状态 | 电流消耗 |
|---|---|
| 广播发射中(100ms间隔,LC3 96kbps) | 约36mA @ 3.7V |
| 广播发射中(150ms间隔,LC3 64kbps) | 约28mA @ 3.7V |
| 待机(无广播) | 约15uA |
| 深度睡眠 | 约5uA |
如果用2000mAh的锂电池供电,广播模式下理论工作时间有55小时,这在便携广播设备里算是很不错的成绩。当然,实际整机功耗还要算上音频输入前级和其他外围的消耗,我这边纯模块数据供参考。
5. 开发中最难啃的几块骨头:问题定位与解决过程
这部分挑三个印象最深的坑来说,每一个都花了超过一天才定位到根因。
5.1 手机扫描不到广播源的问题
刚把广播功能跑通时,用手机测试,发现广播列表一直是空的。这个状态看起来像是广播压根没有发出,但我用频谱仪在板端检测却能看到2.4GHz频段有明显能量辐射,说明射频链路是有动作的。
排查链路是这样的:
第一步,抓串口日志,确认协议栈的状态机是否进入broadcasting状态。日志确实显示已进入广播模式,所以SDK层面的逻辑没跑错。
第二步,用8通道的蓝牙协议分析仪抓空中包。抓包结果显示,模块发出的广播包类型和预期不符——包里面携带的广播信息结构有问题,接收端的手机按照标准流程解析后直接丢弃了这个广播包。
第三步,仔细核对SDK版本的API定义,发现老版本的SDK里,设置广播元数据的函数需要在广播启动之后调用,而我是在启动之前调用的。这导致广播已经按默认空参数发出去了,元数据没有挂到广播包上,手机自然识别不了。
解决办法:调整API调用顺序,在启动广播前完成配置。顺便提一句,SDK版本差异在这个领域很常见,每次拿到新版本SDK第一件事就是读更新日志和API变更记录,很多"玄学"问题其实是API变更导致的。
5.2 接收端声音断断续续
第二阶段测试时,手机能搜到广播源了,也能连上,但声音每隔几秒就卡顿一次。刚开始怀疑是距离太远信号弱,但把手机拿到模块旁边1米内还是卡,这就排除了射频信号问题。
继续排查:
- 检查I2S输入是否异常:用示波器看BCLK/LRCK波形,正常
- 检查音频源本身是否卡顿:把同一路I2S接到别的设备测试,正常
- 检查SDK里的缓存区设置:发现音频缓冲区的深度配置为默认值,但我在配置广播参数时改了编解码器的码率,没同步调整缓冲区大小
问题根源就在这里。LC3编码器的处理延迟和缓冲区深度是有配合关系的,当时我把码率从64kbps调到96kbps,但缓冲区还保持原来较小值,导致编码器和缓冲区不匹配,出现周期性欠载,音频流中断。
解决方法是把缓冲区深度增加到原来的1.5倍,卡顿就消失了。这个教训是:改任何编解码参数之前,先检查缓冲区配置是否仍然匹配,不要指望SDK自动帮你适配。
5.3 充电状态下广播距离急剧缩短
这个坑挺有意思,排查过程如下。产品做了USB供电功能,固件里也理所当然地把VUSB检测作为USB在线供电切换的判断条件。结果实测发现,插上USB供电后广播距离从30米骤降到10米,拔出USB就恢复正常。
一开始以为是电源纹波问题,但示波器测量USB供电时模块电源引脚,纹波确实比电池供电时大,但也就增加了50mV左右,不至于让射频性能恶化这么多。后来用频谱仪直接看辐射波形,发现USB线缆本身变成了一个中继天线,辐射了较高强度的杂散信号,干扰了板载天线的正常辐射。
处理方案有几个,我采用了两条腿走路的方法:在USB接口上增加共模电感过滤线缆上的高频杂散,同时在模块天线附近增加接地铜柱,阻断USB线缆耦合路径。改版后,USB供电和电池供电的广播距离差异缩小到3米以内,基本可接受。
6. 应用场景的扩展空间与产品化建议
硬件调试和功能验证都做完之后,我回头梳理了这个方案在产品化层面的价值,因为BT2106C本身的应用潜力其实不止于单一广播发射功能。
6.1 场景扩展:一台设备多种工作模式
在实际开发中我们最后做了一个配置开关,让设备可以三档切换:
- 广播模式:Auracast广播,面向所有接收端
- 传统蓝牙模式:A2DP连接,一对一
- 混合模式:A2DP和Auracast同时工作
混合模式在BLE 5.x规范下是可行的,因为A2DP走BR/EDR链路,而Auracast走LE链路,两者互不干扰。这个设计最大的好处是一台设备向兼容A2DP的旧耳机提供传统连接之外,也能给支持Auracast的新设备广播音频。做兼容性的价值在过渡期非常明显,消费者手上的设备大概率新旧混杂。
6.2 产品化时需要额外考虑的问题
从开发板到量产产品中间有几个容易忽略的点:
天线一致性:量产外壳如果用金属材质或者电镀工艺,对天线影响非常大。建议外壳方案确定后先打样做有源天线测试,不要等开模了再测。
认证测试:蓝牙音频广播设备出口海外要过蓝牙SIG认证,产品需要申请Auracast相关认证档案。国内上市则要做无线电型号核准。这部分建议提前规划时间,认证周期比想象中长。
固件OTA升级:广播设备的固件升级没法和传统蓝牙设备一样通过已连接的手机推送。我给产品加了USB本地升级通道,用PC端工具通过串口或者USB口刷写固件。后期如果需要远程升级,可以考虑加一个额外的BLE长连接通道专门跑OTA数据。
散热设计:虽然36mA的功耗发热不大,但如果设备集成在密闭外壳里,又长期8dBm持续发射,推荐在模块底下铺铜散热。
7. 开发周期总结和关键技术点复盘
整个项目从拿到SDK到功能稳定,我前后花了大概六周时间。时间分布如下:硬件设计打样约一周半,SDK熟悉和环境搭建约一周,广播功能调通约两周,稳定性和兼容性测试占了一周半。
这里做一次关键复盘:
第一,选型阶段要充分评估SDK成熟度。BT2106C这类国产方案有一个共同问题,文档不如国外大厂全面,遇到问题主要靠官方FAE和社区讨论。如果团队没有强Debug能力,建议把评估时间拉长一点,前期先用官方开发板把核心链路验证了再画PCB。
第二,Auracast的验收标准要尽早和客户对齐。在开发过程中我遇到过一个很实际的问题,客户认为"手机搜索不到广播源"就是产品故障,但实际上部分手机系统需要在设置里打开广播接收功能,不同品牌手机对Auracast的支持程度和入口位置差异很大。因此在产品说明书里清晰说明兼容设备范围和启用条件是必要的。
第三,Buffer配置和编解码器参数相关性很强,SDK改了任何音频相关的配置都要重新做全链路测试。
第四,做广播音频开发最好配备一个蓝牙协议分析仪,单纯靠串口日志很多问题定位不了。我这次通过抓包定位到的广播包元数据问题,如果没有分析仪,可能还要多花两三天时间。
最后分享一个技巧:开发调试时可以用另一台支持Auracast的手机充当"参考接收端",专门用于快速验证广播参数修改后的效果。对比不同型号手机的接收表现,能帮你快速发现兼容性问题,比只看自己的测试设备要全面得多。