前言
****本文忠实地展现了一个智能硬件产品纠结的诞生过程,或许可以满足大家对工程师平常工作的一点好奇心。****
立项
2014年7月的一天,几位程序猿在一起琢磨创业的点子。一个智能台灯的点子从众多的备选方案中脱颖而出。
简单介绍下这盏灯吧:它除了可以手动触控,同时还具备手机摇一摇和随屏亮灭的功能,想想已经躺在被窝里面,但是没开灯玩手机,看电视剧,是不是很刺眼?有了它以后,眼睛不需要离开手机,就可以获得光明,妈妈再也不用担心我的眼睛了,是不是很好很强大?
于是,一个小而美的创业团队顺势产生,成员分别是
L:Leader,负责商务对外协调,技术方面,10万行代码量级实践经历,iOS,Android 双平台App主程
Y:硬件专家,工作有条理,焊接手法细腻
J:Demo小王子,知乎中毒用户,原型机Demo程序实现者,安卓平台App二号程序员
H:单片机小王子,MCU固件主程
M: 产品文案,宣传设计, UI 交互设计支持
R(我):技术方案制定,质量控制,技术合作对外协调,Wifi固件主程,Android App Debug专员
寻求合作
一款硬件的产品从idea到落地,要做的事情和经历的环节,成本和时间上比做一个App要高不少,有一些坑对于做软件出身的工程师来讲是不好估计的。从外观设计,结构,零部件选购定制,组装代工厂寻找,质量把控,销售,运营,售后....很显然,我们需要一个合作方,来承载理念的落地。
于是我们找了幻响神州团队基于他们的现有产品进行合作。他们负责板级硬件的设计,我们负责编写软件,将我们的创意植入,旧瓶装新酒,实现一次大的改款升级。
搭建原型
原型,英语单词为prototype,是为了呈现和验证我们的想法所做的一个仿真,是功能上并不完整的模型。
为了证明技术的可行性,我们需要尽快做出原型。
R和J承担了原型程序的开发工作,以lua语言,一周时间做出了最初的wifi固件程序。
与此同时,Y也从硬件角度,对现有的手动开关版本的台灯进行了hacking(在没有设计资料的情况下进行改造),基于arduino实现了对台灯的程序控制。
接下来的一周时间里,制作了一台外表上看不出任何区别的智能版小灯,给幻响神州做了一次成功的演示。
这个项目,基本上算是有谱了。
没想到,苹果手机的操作系统(iOS) 差一点就给我们的产品判了"死刑"。
由于智能台灯的创意设定是:挥动手机,或者解锁屏幕,灯会自动唤醒,这就需要一个服务进程常驻后台,用于接收系统的唤醒事件和处理重力传感器数据。
当L 调研了iOS系统的开发文档,得到一个令人沮丧的结论:iOS出于省电和安全等多方面的考虑,不支持App程序以后台服务方式运行,这就意味着App必须时刻处于前台,那就失去了意义。
(插播解释一下什么是“前台”和“后台”程序:前台的概念来源于舞台表演概念,和后台相对,指的是App运行的一种状态。舞台就是前台,也就是手机的屏幕。每次舞台上只有一个表演者。
我们的App 需要在不上舞台的情况下,默默地在台下发挥作用,就像控制舞台背景音乐和灯光的调音师,调光师)
这个问题如果解决不了,那么产品功能就是不完整的,极有可能导致项目的下马。
在这个关键的时刻,L凭借着网络上的蛛丝马迹,逐渐将信息的脉络梳理清晰,发现了一种利用苹果系统隐藏API实现这个功能的方法。
(API是操作系统提供给App的接口,用来完成某种特定的功能,比如读取网络状态,打开文件。而有些操作默认是不对外公开的,只有知道”暗号”的人才能访问)。
L从iOS 零基础,到使用iOS系统隐藏API验证功能,只花了大概两周左右的时间。至此,整个技术方案就算是全部验证完成了,剩下的则是充满各种细节的开发工作了。
原型产品化
项目正式立项之后,几位小伙伴们分工协同,硬件,软件,手机端的App开发工作并发启动。
从原型到产品,需求也在不断细化,需求的数量也在不断增加:
- Wifi的功耗问题,单WiFi芯片架构无法实现电池供电使用,需要采用电池驱动低功耗MCU+外接电源给WiFi供电的方式
- MCU(单片机)和WiFi的通信协议设计,进行状态同步
- MCU承担电源管理功能,如根据是否外接电源执行不同的操作,此外还要做低功耗模式和低电量保护
-
分段调节呼吸灯的亮度,为提升呼吸灯的视觉体验,需要考虑到LED 灯亮度的视觉非线性
插播解释一下什么叫 视觉非线性:
假设我们的眼睛对亮度强弱的视觉感受用Y表示,实际的发光亮度用X 表示,那么Y和X之间,存在一个比例对应的关系:
Y = K * X,K就是这个比例系数。如果是线性关系,那么K是一个常量,体现在坐标图上,是一根直线。但实际上K会随着X的变化而变化。实际上是一个曲线。
随着需求的复杂化, 原型开发的程序已逐渐将WiFi芯片的内存资源消耗殆尽,且受制于运行环境的稳定性和性能,距离产品的要求有一定差距。于是,我们用C语言重写了一遍程序。
R完成了通信协议的设计,重写了WiFi端的固件程序,并参与了Android App的后续开发和调试。
H独立完成了MCU固件的开发;
J 则集中精力学习并接手了Android App的开发。
在第一次试产之前,我们在6块板子上进行了基本的功能验证,确认正确无明显缺陷后,进入到100片的小批量环节。
0 - 100
该环节的目标是:验证原型产品方案在批量化之后的稳定性和一致性,同时让加工厂技术工人熟悉产品的基本组装。
当我们把100套模组焊接组装好上电以后发现,有部分灯无规律地呼吸闪烁,深圳方面的硬件工程师由于缺乏对意外情况的预见,准备不足,只是尝试替换了一些元件,没有定位故障,且受设备条件限制,软件运行的调试信息也没办法提取,本来预计两天试产出样品的计划,貌似要搁浅了。
时间是最贵的成本。
第二天一早到达工厂后,我负责从WiFi软件角度排查软件,Y负责排查硬件,其他团队成员远程支持,同时检查单片机模块部分的代码设计。
问题的现象是这样的:WiF模块外接电源上电后,发生了异常复位,而我们程序的写法是每次WiFi上电,都会把单片机复位一下,实际上我们看到灯在不停地呼吸闪烁,只是单片机被反复地复位,执行上电后的呼吸灯效果而已。
补充说明一下,
WiFi芯片主动复位单片机是产品设计上的考虑:由于灯的内部装有电池,万一单片机程序有bug,如果没有主动复位的设计,就只能拔掉电池,操作会比较麻烦。
说实话,当我第一次看到WiFi的调试信息输出中有异常复位的信息时非常惊讶:之前明明正常工作的程序,怎么就成这样了?脑海中有各种可能的问题情况涌现出来。不过为了排除是软件的问题,我首先做的事情,是重新烧录一遍程序,发现无改进效果后,再改写了一个最基本的测试程序(这意味着软件上基本上不可能出错),重新烧写一遍测试,结果仍然是否定的。
Y这边的情况是,将所有的芯片上电波形,都测量了一遍,静态指标都正常,因此重点从动态特性进行观察。
到下午的时候,确认是供电的问题:给WiFi供电的芯片瞬态能力不足,复位上电程序开始执行后,无法带动芯片全速工作,会导致电压突降,从而造成WiFi芯片重启。
解决方法是,更换供电芯片,增大输出端电容。
100 - 1000
自从第一次试产100台的顺利完成,大家都松了口气,接下来该面对量产做准备了。
没想到的是,第二次试产的过程更加的纠结。
核心的问题是触控芯片的可靠性。我们采用的是一个国产的低成本的触控方案,功能非常简单,就是感应到手按下输出高电平(逻辑判断为True),可以代替单片机完成模拟到数字的转换,同时相当于做了第一级的去抖,简化了单片机的程序逻辑。可是外接电源上电一段时间后触控就失灵了,拔插也不好使,必须要拔掉内部电池彻底断电才可以。
此外,通过高温测试也发现,该芯片也会有稳定性的问题,有时候甚至会自己点亮。
问题的麻烦还在于即便给出了足够合理清晰的解释和分析,合作方的硬件工程师怀疑是我们的软件故障,而这个问题不太可能通过软件方法解决。可见在一些边界的疑难问题上,软硬件都懂的人是多么的重要。
最终解决的方法是,更换触控芯片为成本更高的方案,绕过了问题。
1000 - 10000
芯片固件在设计的时候,提供了一个量产自检的功能:即首次组装上电,灯会自己去连接路由器,测试wifi功能是否正常,并亮灭开关几次。
功能的实现方法为:提前在存储芯片上烧录一个标记,程序启动后,如果能读取到该标记,则进入量产自检,完成后将标记清除,避免下次进入。
而问题就出在,由于烧录厂的原因,并非所有的芯片都成功地烧录了该标记,因此有些灯就进不了自检,产线工人无法知晓该灯的好坏,除非进行人工检查。
为解决这个问题,我们只能另外开发了一个量产专用App,把这些灯直接配置进量产路由器,再发送一个进入量产模式的后门命令,从而实现了量产自检。
但是到这里,问题还不算是彻底地解决。于是,在下一个版本的固件中,我们修改了设计,去除了对烧录环节正确性的依赖。
总结与反思
结论其实并没有新意,无非是思想上重视,加大对测试的投入,包括从设计和开发时就要考虑系统的可测性,编写可以自我查错的代码。
然而知行合一是困难的,因为这需要和人的弱点做斗争。
回想假如当初实现进入自检的功能的时候,我只是简单地实现和测试了功能,测试了一两片觉得就万事大吉,没有留下可以重复测试的接口,那么一旦出现状况,这批几千套的模块,就需要进行人工测试,代价**是相当的高昂。
这次小试牛刀的经历给我最深的感触是:
首先,这次开发采用逐级扩大生产数量进行验证的流程再次被证明是必要的。
因为,一些细小的设计和制造缺陷,在数量少的时候,不容易被发现,因此需要扩大测试的数量和范围。逐级扩大生产数量,主要是可以较好地控制成本,
毕竟硬件每做一次生产都是烧钱,软件只需要改改代码编译就可以了。
其次,有两大基础设施,应当成为未来所有软件的标配:程序崩溃的自动捕获 和 支持在线升级。
在软件开发测试阶段,很难做到在所有的设备平台上都测试一遍,尤其是Android手机,各个品牌型号,数量众多。软件发布出去以后,用户使用过程中遇到程序崩溃闪退,用户最多是骂一句,给个差评,不太可能有心情进行反馈。
如果程序可以自动捕获故障现场,报告给开发工程师,工程师修复问题后给用户自动推送更新版本,从根本上可以提升用户体验。
最后,再正确的流程和方法论也要靠人来执行,有一群靠谱的人通力合作,才是成功的根本保障。