上个月有个做电动三轮车仪表的朋友找我,说他们新项目要在仪表板上加语音播报,采购那边拿到一份推荐清单,头一行写的就是 WT588F02-8S-C,让他确认能不能用。他给我打电话的第一句话是"这芯片是不是只能放三句话",第二句话是"三语播报是不是要中英粤各来一遍"。这两个问题其实代表了很多人的第一反应:把"三语"理解成三种语言,把语音芯片理解成一个只能按顺序播放的录音盒。真实情况是,这里的"三语"指的是速度、电量、故障这三类信息的语音播报,而 WT588F02-8S-C 这类离线语音芯片能做的事,比"放三句话"要多得多。这篇就把这套方案从选型、硬件、播报逻辑、语料制作到量产测试整条链路捋一遍,给正在做电动车仪表、共享出行终端、电动滑板车这类产品的同行一个可落地的参考。
1. 仪表盘加了语音播报,到底解决了骑行者哪几个真实麻烦
1.1 强光下的仪表基本等于"装饰件"
做过两轮车的人都知道一个尴尬事实:正午太阳直射的时候,LCD 屏的对比度会被环境光完全压过去,骑行者低头看仪表的那零点几秒,几乎读不到有效信息。而低头看屏这个动作本身在时速 25km/h 以上的时候就很危险,按 25km/h 算,低头 1 秒车就往前跑了将近 7 米。所以仪表信息从"视觉通道"分流一部分到"听觉通道",不是因为酷炫,而是因为视觉通道在人车混行的场景里本来就已经被路面、后视镜、行人占满了。
语音播报的价值在三个时刻最明显:一是骑行中需要知道当前速度是否超限;二是快到目的地时想确认还能不能跑回去;三是车辆抖动、异响、突然降速的时候,需要立刻知道是控制器报了故障还是单纯没电。这三件事对应下来,正好就是速度、电量、故障这三类播报内容,也是这套方案被反复提出来的根本原因。
1.2 三类播报对应的是三种完全不同的触发逻辑
很多人一开始会把这三类播报当成同一件事,觉得都是"读一个数然后播出来"。实际做下来会发现,它们的触发模型差别很大。
速度播报是周期性 + 阈值型的。它不是每秒都播,那样会把骑行者烦死;通常是跨越某个速度阈值(比如进入 20km/h、25km/h、30km/h 三个档)时播一次,或者在高速档位下每 30 秒提醒一次。阈值型播报的关键是"迟滞",也就是升档和降档要用不同的阈值,否则速度在 24~26km/h 之间波动时会疯狂重复播报。
电量播报是低频 + 事件型的。开机时播一次当前电量百分比,骑行过程中只在跨过几个关键节点时播,比如从 50% 掉到 30%、从 30% 掉到 15%。这两条线要分开设,因为铅酸电池和锂电池的放电曲线完全不一样,同样是"电压 46V",在铅酸上可能是 60% 电量,在锂电上可能已经接近 20%。
故障播报是即时 + 优先级最高的。控制器一旦通过串口或单线报出故障码,语音必须在几百毫秒内响应,而且要能打断正在播放的内容。这里最容易踩的坑是:故障播报如果被速度播报挤在后面排队,等播完速度再播故障,黄花菜都凉了。
1.3 为什么选离线语音芯片,而不是蓝牙音箱那套方案
有一派做法是在仪表里塞一个蓝牙模块,语音靠手机 App 走 TTS 合成再通过蓝牙推过来。这个方案在演示阶段很漂亮,落到量产就全是问题:用户得装 App、得配对、得保持手机连着,电池本身没电或者手机没电的时候语音功能直接归零;更关键的是,骑行场景对响应延迟极其敏感,蓝牙链路加上手机 TTS 的合成延迟,从"控制器报故障"到"喇叭出声"经常要一秒以上。
离线语音芯片的思路是把音频数据直接存在芯片内部的 Flash 里,MCU 通过一根线或者两根线给个地址,芯片立刻从内部 Flash 取数据送到 PWM 输出。整条链路没有任何无线环节,也没有操作系统调度,响应时间稳定在毫秒级,掉电也不会丢语料。代价是语料必须提前录制和烧录进去,改词就得重新烧,灵活性不如 TTS。但对于速度、电量、故障这三类高度固定的播报内容来说,这个代价完全可以接受——毕竟"电量百分之三十"这种话,一年也不会改一次。
2. WT588F02-8S-C 这颗 SOP-8 封装的小芯片能扛多少活
2.1 先把"三语"这个词的歧义说清楚
前面提到的那个误会值得单独讲一段,因为选型阶段如果理解偏了,Flash 容量会算错,后面全盘皆输。如果"三语"真的指普通话、英语、粤语三种语言,那所有语料要乘以三,包括数字 0 到 9、十、百、千、百分之、剩余、故障、超速、请充电这些词元,一套下来是相当可观的容量。而这里说的三语是"三类播报内容",语料只需要一套普通话就够。
我建议在项目立项文档里就把这个定义写死,别用"三语"这种容易歧义的简称,直接写成"速度播报 / 电量播报 / 故障播报"三路。真要做多语言版本的时候,正确的做法也是在同系列里选 Flash 更大的型号,或者把语料按"普通话版"和"英文版"分成两个烧录版本,按订单分别出货,而不是硬塞进同一颗芯片再想办法压缩采样率。
2.2 封装小、外围少,这是它被仪表板接受的主要原因
仪表板的空间是被成本压到极限的。一块常规两轮车仪表的 PCB 面积本来就不大,上面已经挤了数码管或 LCD 驱动、MCU、DC-DC、按键、蜂鸣器、接插件。语音芯片如果用 SOP-8 这种封装,加上必要的去耦电容和一路 PWM 输出,占的面积非常小,而且不需要额外的 Flash、不需要晶振(这类芯片通常内置振荡),外围元件可以精简到"一颗电容一颗电阻"的量级。
这点对结构件的影响很直接:不需要为语音功能改模具,直接在现有主板上加一块区域就能塞进去。我在一个共享滑板车项目上见过相反的例子,团队一开始选了带独立音频 DAC 的方案,结果因为要加功放、加滤波、加屏蔽罩,PCB 大了将近三分之一,最后结构件重新开模,工期拖了一个多月。所以选型阶段不要只看芯片单价,要把"外围面积"和"结构件改动量"一起算进去。
2.3 控制方式的选择:按键触发、一线串口、两线串口
这类芯片通常提供几种控制方式,各有各的适用面:
| 控制方式 | 接线 | 适用场景 | 注意点 |
|---|---|---|---|
| 按键直接触发 | 每个按键对应一段语音 | 固定提示音、开机音、倒车提示 | 按键数量受引脚数限制,只适合少量固定语料 |
| 一线串口 | 1 根数据线 + 地 | 仪表主控控制,引脚紧张时首选 | 时序对延时敏感,中断里发容易出错 |
| 两线串口 | TX/RX + 地 | 语料多、需要频繁切换地址 | 波特率和帧格式必须与手册一致 |
电动车仪表的典型做法是"按键 + 串口"混用:开机音和几个固定提示走按键触发,速度、电量、故障的播报走串口地址。这样即使主控 MCU 死机了,开机提示音这类基础功能还能靠按键兜底,用户体验不会彻底崩掉。
在线路上我强烈建议给数据线串一颗小阻值电阻(常见 100Ω 到 1kΩ 之间),并且把走线尽量走内层。电机和控制器的线束在仪表附近走的时候,耦合过来的尖峰很容易在数据线上打出误码,串一颗电阻加对地小电容,能挡掉相当一部分。
2.4 3.3V 这件事:为什么它总被单独提出来讨论
最近搜到的一个热词是"语音芯片 3.3V 输出",这个词背后其实是两个不同的问题,很多人混在一起了。
第一个问题是供电电压。这类芯片通常支持一个比较宽的工作电压范围,3.3V 或者 5V 供电都能跑,所以仪表主控如果是 3.3V 系统,可以直接用同一路 3.3V 给语音芯片供电,不需要额外的 LDO。但要注意,芯片工作电压范围宽不代表音质在任何电压下都一样,PWM 输出的驱动能力和音量跟供电电压是正相关的,3.3V 供电时能推出来的响度比 5V 时要低一截。如果喇叭是 8Ω/0.5W 这种,3.3V 供电下音量可能偏小,尤其是装在车头风噪大的位置,用户会听不清。
第二个问题是IO 电平。仪表的 MCU 很多是 3.3V 的,语音芯片如果也在 3.3V 下工作,两边的逻辑电平天然匹配,数据线直连就行,不需要电平转换。但如果语音芯片用 5V 供电,MCU 是 3.3V,就会出现 MCU 输出高电平低于语音芯片识别门限的情况,通信会变得很不稳定,间歇性丢指令。这时候要么把语音芯片也改成 3.3V 供电,要么加电平转换,不要指望"一般都能识别"这种玄学。
还有第三个容易被忽略的点:如果芯片有可用的输出引脚用来驱动外设或者给 MCU 一个状态指示,那个输出的驱动能力通常很弱,只能当信号用,不能直接驱动 LED 或者继电器。我见过有人拿它去驱动一个蜂鸣器,结果声音小得几乎听不见,还怀疑是芯片坏了。
3. 硬件设计:把芯片塞进一块已经被成本和空间挤满的仪表板
3.1 从整车电压到芯片供电的那条链路
两轮车、三轮车的电池组电压通常是 48V、60V 或者 72V,仪表板内部一般先有一级 DC-DC 把电压降到 12V 或者 5V,再往下分。语音芯片的供电可以直接从这一级取,也可以在仪表内部再做一次 3.3V LDO。
这里有个很实际的取舍:如果直接从 12V 用 LDO 降到 3.3V,压差 8.7V,芯片工作电流按几十毫安算,LDO 上的功耗就是几百毫瓦,封装小一点的 LDO 会明显发烫,夏天暴晒下仪表内部温度本来就高,很容易触发热保护。所以我的建议是分级降压:DC-DC 先降到 5V,再从 5V 用 LDO 降到 3.3V。多一颗 LDO 的成本很低,但整机的热设计会舒服很多。
另外要注意供电的上电次序。如果语音芯片和 MCU 共用一路 3.3V,上电时两者同时启动问题不大;但如果 MCU 先启动、语音芯片因为内部 Flash 初始化需要更长时间才准备好,MCU 一开始就发地址指令,芯片是收不到的。稳妥的做法是在 MCU 初始化完成后延时一两百毫秒再发第一条指令,或者在硬件上给语音芯片的供电加一个小的 RC 延时。
3.2 PWM 输出接喇叭的两个致命细节
这类芯片驱动喇叭一般是 PWM 差分输出,也就是有两个输出脚。这里有两个坑,几乎每个新手都会踩一次。
第一个坑:喇叭不能有一端接地。PWM 差分输出是桥接式的,两个脚都要接到喇叭两端,如果把其中一端接到 GND,轻则声音极小、重则完全没有声音,甚至可能因为输出短路而损坏芯片。有些工程师习惯了单端输出的接法,看到两个输出脚就本能地把负极接地,这个错误查起来很费时间,因为芯片不会冒烟,只是"声音不对"。
第二个坑:输出是方波,不是模拟波形。有些便宜的方案为了省滤波电容,直接让 PWM 差分输出推喇叭,靠喇叭自身的电感和人耳的听觉积分来"还原"声音。这个做法在播放语音时勉强能听,但会有明显的"电子音"感和高频毛刺,长时间听会很不舒服。加一个简单的 LC 或者 RC 低通滤波,成本增加很少,听感提升很明显。我在一个项目上做过对比:同一套语料,加滤波前后用同一只 8Ω/1W 喇叭播放,加滤波之后人声的清晰度提升非常直观,尤其是"百分之三十"这种数字连读,之前是糊在一起的。
3.3 喇叭的选型和安装位置比芯片本身更影响最终效果
先给一个参考量级:这类芯片在 3.3V 供电下直接推 8Ω/0.5W 的小喇叭比较合适,想要更响就得加功放。喇叭参数上,我实测下来 8Ω 比 4Ω 更稳,因为 4Ω 负载下输出电流接近翻倍,芯片发热明显,长时播报时稳定性下降。
安装位置是个纯经验问题。喇叭装在仪表外壳里,如果外壳是封闭的塑料壳,声音会被闷住,正确做法是在喇叭背面开一个小的泄压孔,或者让喇叭和外壳之间留一点空腔。另外喇叭不能贴在 PCB 上,要靠结构件固定并留出减振垫,否则车子过减速带的时候喇叭跟着板子一起振,会产生很明显的杂音,用户会以为是喇叭质量差,其实是固定方式的问题。
3.4 电机和控制器才是这套方案最大的干扰源
仪表板上的语音芯片,最坏的邻居就是旁边的电机线束和控制器。电机相线里流的是 PWM 方波大电流,换相瞬间的 dv/dt 很高,辐射和传导骚扰都会耦合到仪表板上。
我在项目上采用的组合拳是:语音芯片的供电脚就近放一颗 0.1μF 加一颗 10μF 的电容;数据线串电阻加对地小电容;如果空间允许,在喇叭线上并一颗小的磁珠。另外布局上,语音芯片和喇叭走线要尽量远离 DC-DC 的电感,DC-DC 的开关频率通常在几百 kHz,虽然听不见,但它会在音频链路上形成底噪。
还有个成本更低的办法:把喇叭线做成双绞线。这个动作不花一分钱,但对抑制共模干扰很有效。
4. 三路播报的逻辑实现:速度、电量、故障怎么触发才不难听
4.1 速度播报的核心是"迟滞"和"最小间隔"
速度播报的技术难点不在语音,而在触发策略。我见过的最糟糕实现是每检测到一次速度变化就发一条指令,结果骑行者在加速过程中,喇叭里"您的车速"、"您的车速"、"您的车速"叠在一起,完全听不清。
正确的做法是两级门限加最小间隔。举个例子,假设分三个档:低于 20km/h 不播,20 到 25km/h 之间播"请注意车速",25km/h 以上播"已超速请减速"。那么进入"请注意车速"档的门限是速度上升到 20km/h,退出这个档的门限要设成 18km/h;进入超速档的门限是 25km/h,退出设成 23km/h。这样在门限附近来回波动时不会反复触发。
最小间隔则是硬性的时间保护,比如同一档位的播报,两次之间至少间隔 30 秒。这个值不能设太小,否则语音会变成噪音;也不能设太大,否则用户已经超速一分钟了才听到提醒,失去了意义。我一般会把它做成可配置的,不同车型、不同市场要求不一样。
4.2 电量播报:从 ADC 采样到"百分之多少"之间的那几道坎
电量播报看起来简单,实际上是三路里最容易翻车的一路。从电压到百分比,中间要过好几道坎。
第一道坎是采样精度。常见的做法是用两颗电阻分压,把电池电压降到 ADC 量程内。这里要注意分压电阻的精度和温漂,如果用的是普通的 1% 电阻,在 -10℃ 到 50℃ 的温度区间内,分压比的变化足以让电量读数漂移好几个百分点。要求高的项目会用 0.5% 甚至 0.1% 的精密电阻,成本增加很小。
第二道坎是放电曲线的非线性。铅酸电池和锂电池的曲线差别巨大,铅酸的电压在放电中后段下降得很平缓,锂电在 3.7V 附近有一个很长平台期,然后迅速掉下去。如果用线性映射,锂电池在平台期会长时间显示 40% 左右,然后突然从 40% 掉到 0%,用户会觉得电量显示是假的。解决办法是查表法:把电压分区间段,每段对应一个百分比,按电池的实际放电曲线标定。这个标定工作最好拿真实电池在测功机上跑一遍,不要照抄网上的曲线。
第三道坎是静置电压和负载电压的区别。骑行中的端电压因为内阻压降,会比静置时低。如果直接用骑行时的电压查表,电量会偏低。我通常的做法是做一个简单的负载补偿:按当前放电电流乘以内阻估算的压降,把电压补回去再查表。内阻值不用很准,粗略补偿就能让电量显示平滑很多。
4.3 故障播报:控制器故障码到语音地址的映射表
故障播报是这三路里唯一需要和控制器打交道的,需要先在 MCU 侧把控制器上报的故障码解析出来,再翻译成语音地址。下面这张表是我在一个项目上用的映射关系,实际项目里要根据自己的控制器协议调整:
| 控制器故障码 | 故障含义 | 语音内容 | 语音地址 | 优先级 |
|---|---|---|---|---|
| 0x01 | 转把故障 | 转把异常,请检查 | 0x21 | 高 |
| 0x02 | 刹把故障 | 刹车信号异常 | 0x22 | 高 |
| 0x03 | 电机霍尔故障 | 电机霍尔异常,请检修 | 0x23 | 高 |
| 0x04 | 控制器过流 | 控制器过流保护 | 0x24 | 高 |
| 0x05 | 电池欠压 | 电量不足,请及时充电 | 0x25 | 中 |
| 0x06 | 电机缺相 | 电机缺相,请停止行驶 | 0x26 | 最高 |
| 0x07 | 超温保护 | 控制器温度过高,请稍后使用 | 0x27 | 中 |
表里的"优先级"这一列很关键,它是后面打断机制的依据。"电机缺相"这种情况必须打断所有正在播放的内容立刻播出来,而"电量不足"可以在当前语音播完之后再播。
映射表在代码里建议用数组或者 switch 实现,不要写成一大串 if-else,方便后续增删故障项。
typedef struct { uint8_t code; /* 控制器上报的故障码 */ uint8_t voice_addr; /* 对应的语音地址 */ uint8_t priority; /* 优先级,数值越大越急 */ } fault_map_t; static const fault_map_t fault_table[] = { {0x01, 0x21, 2}, {0x02, 0x22, 2}, {0x03, 0x23, 2}, {0x04, 0x24, 2}, {0x05, 0x25, 1}, {0x06, 0x26, 3}, {0x07, 0x27, 1}, }; uint8_t find_voice_addr(uint8_t code) { for (uint8_t i = 0; i < sizeof(fault_table)/sizeof(fault_table[0]); i++) { if (fault_table[i].code == code) { return fault_table[i].voice_addr; } } return 0; /* 0 表示无匹配,不播报 */ }4.4 三路同时来的时候谁先播:一个简单的播报仲裁器
三路播报如果不做仲裁,就会出现"故障来了但在播电量"这种尴尬。我的做法是让 MCU 维护一个小的播报队列,队列长度为 2 到 3 就够,同时维护一个"当前播放状态"的标志。
状态标志的判断方式有两种:一是查询语音芯片的忙状态输出脚,二是用软件计时(播报开始时记录时间戳,按语料长度估算结束时间)。硬件忙脚更可靠,但会多占一个 MCU 引脚;软件计时省引脚,但语料长度一变就得改参数。我一般优先用忙脚,实在没引脚了再用软件计时。
仲裁规则很简单:高优先级的新事件直接打断低优先级的正在播放内容,同优先级的排队,低优先级的如果队列已满就丢弃。丢弃是必须的,因为速度提醒这类信息时效性很强,过期的提醒没有播的必要,反而会占用喇叭资源。这一点很多项目没做,结果队列越堆越长,用户听到的永远是几十秒前的旧信息。
5. 语音文件制作和烧录:语料切分是最容易被低估的一块活
5.1 按"词元"切分而不是整句录音
这是整个语音方案里最影响体验的一环。如果按照整句录,比如"当前电量百分之三十"整句录一段,那么从 0% 到 100% 至少要录 101 段,再加上"当前电量百分之"这种前缀,容量浪费得离谱。
正确做法是按词元切分:数字 0 到 9 各一段,"十"、"百"各一段,"百分之"一段,"当前电量"一段。这样"当前电量百分之三十"就变成 前缀 + 三 + 十 四段拼接。看起来要多发几次地址,但容量节省是数量级的。
切割上有个技巧:每个词元的前后要各留一点点静音,但不能留太多。留太少,拼接的时候两个音节会粘在一起;留太多,播报听起来一顿一顿的。我一般让每个词元的头尾各留 20 到 50 毫秒的静音,具体数值按语速调整。
还有一个细节:数字的录音要注意声调。单独录的"三"和连读时的"三"在语调上会有差异,如果全部用单字录音拼接,整句话听起来会有点像机器人在念数字。要缓解这个问题,可以让配音员在录数字的时候带上统一的语调起势,或者在后期稍微做一点淡入淡出。
5.2 采样率和容量的平衡
采样率直接决定音质和容量。常见的档位是 6kHz、8kHz、16kHz 这几种,语音只要求"听得清"而不追求"好听"的时候,6kHz 到 8kHz 就够用,容量小、烧录快;如果要做得有质感一点,比如开机音是一段带背景音乐的欢迎语,那 16kHz 甚至更高会更合适。
算容量的时候别只看单段时长,要按"总秒数 × 采样率 × 位宽 ÷ 8"估算,再留 20% 到 30% 的余量。留余量是因为后续一定会加语料——"请佩戴头盔"、"请勿载人"、"已进入限速区域"这类提示,产品迭代过程中只会越来越多。我见过一个项目,第一版正好把 Flash 塞满,第二版要加两句提示音,结果只能换更大容量的型号,PCB 和软件都得改。
5.3 烧录流程和那些写不进去的原因
烧录一般是通过专用的下载器和上位机软件完成,把音频文件按顺序导入、生成地址表、然后写入芯片内部 Flash。这个过程里有几个常见的失败原因:
地址不连续。有些上位机软件对地址分配比较敏感,如果中间有空的地址,可能出现某些段播不出来。建议语料按顺序编号,中间不要留空。
音频格式不匹配。软件通常要求特定的采样率、单声道、特定的位宽,如果导入的是双声道或者 44.1kHz 的文件,要么被拒绝要么被自动重采样,重采样后的音质可能不理想。最好在导入前用工具统一转换好。
写入中途断电或接触不良。这类失败往往表现为"部分地址能播、部分不能",排查起来很烦。建议烧录工位上配稳压电源,别用劣质 USB 口供电,并且每批抽检几个地址做播放验证。
另外,如果产品后期可能要换语料,选型阶段最好确认一下芯片是否支持通过 MCU 在线更新语音内容。能在线更新的话,产线或者售后可以通过仪表接口刷新语料,不用拆机,这在多语言版本、多地区版本出货的时候价值很大。
6. 从打样到小批量,我们踩过的那些坑
6.1 播报开头总是"吃掉"半个字
这是最典型的一个现象:喇叭里出来的第一句话,开头零点几秒是不完整的,听起来像"电量百分之三十"变成了"量百分之三十"。
原因有两类。一类是发送指令和芯片真正开始播放之间有启动时间,功放或者喇叭在这段时间还没进入状态,等真正出声的时候音频已经播了一段。解决办法是在每段语料的开头多留一点静音,一般 50 到 100 毫秒就能解决。
另一类是供电问题。芯片从内部 Flash 读数据、PWM 开始输出的瞬间会有电流冲击,如果供电的 LDO 响应慢或者去耦电容不够,电压会瞬间跌一下,导致开头部分失真或者被截断。这种情况下加大去耦电容或者换响应更快的 LDO 就能明显改善。
排查的时候可以用一个简单办法分辨:把同一段语料连续播两遍。如果第一遍吃字、第二遍正常,那基本是供电或者启动的问题;如果两遍都吃字,那就是语料本身的静音留得不够。
6.2 电机一启动就误播报
这个问题的现象很迷惑人:车静止的时候一切正常,电机一启动,喇叭就自己开始播报,内容还是随机的。
根因是电磁干扰在数据线上打出了误码,芯片把噪声当成了指令。定位方法是把数据线从 MCU 上断开,看现象是否消失。如果消失,说明确实是数据线上的干扰;如果还在,那就要怀疑供电被干扰了。
解决的组合拳前面提过:数据线串电阻加对地小电容、走线远离电机线束、必要时把数据线改成带屏蔽的双绞线。有一个更彻底但成本更高的办法,是把语音芯片和 MCU 之间的通信加一层校验,比如每条指令发两遍,芯片侧用软件过滤,或者干脆把语音芯片挪到离 MCU 最近的位置,缩短受干扰的走线长度。
这里要提醒一句:不要为了图省事把数据线的上拉电阻省掉。很多这类芯片的数据线是开漏或者需要上拉的,没有上拉的时候,空闲状态电平不确定,抗干扰能力会差很多。
6.3 冷启动第一次不发声,第二次就好了
冬天做低温测试的时候遇到过一次:-10℃ 环境下静置一夜,第二天上电第一次不发声,关机再开就正常了。
这类现象一般指向两个方向。一是芯片内部 Flash 在低温下的读取时序需要更长的准备时间,MCU 发第一条指令太早,芯片还没准备好。解决办法是在初始化后加一个上电延时,并且在低温环境下实测这个延时要留多少余量。
二是电解电容在低温下容量衰减、等效串联电阻变大,导致供电纹波变大,芯片工作不正常。如果仪表板上用了电解电容做储能,不妨在语音芯片的供电脚旁边再并联一颗容量合适的陶瓷电容,陶瓷电容的低温特性比电解好得多。这个问题在北方市场销售的车型上必须做验证,不能只在常温实验室里测。
6.4 语料听久了很烦:音量、语速、频次三个旋钮
功能都通了之后,还有一个纯体验层面的问题:用户会不会嫌它烦。我总结下来有三个可调的旋钮。
音量上,语音播报的音量应该比蜂鸣器提示音略低一点。蜂鸣器是短促的提醒,音量大一点没问题;语音是连续的人声,音量太大的时候在安静小区里会显得很吵,用户会主动想关掉。
语速上,数字播报要慢一点,提示语可以快一点。"电量百分之三十"这种信息密度高的,语速快了就听不清;"请注意车速"这种熟语,快一点反而更自然。
频次上,这是最需要克制的。我的经验是速度提醒的间隔不要短于 30 秒,电量提醒一天不要超过几次,故障提醒该出的必须出。宁可少说,也不要让用户觉得"这车一直在念叨"。
7. 成本、产线和你以后一定会遇到的两件事
7.1 BOM 上的增减清单
加一个语音播报功能,BOM 上的变化其实很小,但也不是只有一颗芯片。列出来大概是这样的:
| 项目 | 变化 | 说明 |
|---|---|---|
| 语音芯片 | 新增 | 核心器件 |
| 喇叭 | 新增 | 8Ω/0.5W 到 1W,带引线和接插件 |
| 去耦电容 | 新增 | 0.1μF + 10μF 各一颗 |
| 数据线串阻 | 新增 | 100Ω 到 1kΩ |
| LDO | 可能新增 | 从 5V 降到 3.3V 时增加 |
| 结构件 | 可能改动 | 喇叭固定位、泄压孔 |
| MCU 引脚 | 占用 | 至少 1 个输出,若用忙脚则 2 个 |
真正容易被低估的是后两项。结构件一旦要改模,成本和周期都会上去,所以我在项目早期就会把喇叭的位置和固定方式先定下来,哪怕电路还没最终确定。另外 MCU 的引脚规划要提前做,别等到软件写完才发现没有空闲引脚。
7.2 产线上的烧录和测试治具
语音芯片的语料是在烧录环节写进去的,所以产线上要么用专门的烧录工位先烧后贴,要么在整机测试环节通过仪表接口烧。两种方式各有取舍:先烧后贴的话,芯片一旦烧错版本就得拆下来重烧,但产线节拍快;整机烧录则灵活,可以按订单烧不同版本,但对测试工装的通信可靠性要求高。
不管用哪种方式,我都建议在产线终检里加一个"三路播报功能自检":让测试工装发三条指令,分别触发速度、电量、故障播报,用麦克风采样或者人工听一下。这一步不花什么时间,但能把"喇叭没接好"、"芯片没烧进去"、"地址错位"这类问题拦在出厂之前。我见过因为没做这一步,一批货出去之后客户反馈喇叭不响,最后全部召回返工,损失远超测试工装的成本。
7.3 语料版本管理,是后面一定会疼的地方
最后说一件跟技术关系不大、但一定会踩的事:语料版本管理。当产品线扩展出不同车型、不同地区、不同语言版本的时候,语料会分裂成好几个版本,如果只靠文件名区分,很快就会乱。
我的做法是给每一版语料编一个版本号,版本号同时写进软件代码和烧录记录,产线烧录的时候必须核对版本号。地址表也建议统一维护在一份文档里,任何新增语料都先分配地址再录音,避免出现"录了音但没地址"或者"地址冲突"的情况。这个习惯一开始会显得有点繁琐,等到第三个车型要复用第一版的语料时,你会庆幸当初做了这件事。
我个人在实际操作中的体会是,这类离线语音方案的技术门槛并不高,真正决定项目成败的是那些琐碎的地方:喇叭装在哪、数据线怎么走、语料怎么切、版本怎么管。芯片选对了只是入门,把这四件事处理好,才是让用户觉得"这车的语音挺好用"的关键。