前言
****本文忠實(shí)地展現(xiàn)了一個(gè)智能硬件產(chǎn)品糾結(jié)的誕生過(guò)程,或許可以滿足大家對(duì)工程師平常工作的一點(diǎn)好奇心。****
立項(xiàng)
2014年7月的一天,幾位程序猿在一起琢磨創(chuàng)業(yè)的點(diǎn)子。一個(gè)智能臺(tái)燈的點(diǎn)子從眾多的備選方案中脫穎而出。
簡(jiǎn)單介紹下這盞燈吧:它除了可以手動(dòng)觸控,同時(shí)還具備手機(jī)搖一搖和隨屏亮滅的功能,想想已經(jīng)躺在被窩里面,但是沒(méi)開(kāi)燈玩手機(jī),看電視劇,是不是很刺眼?有了它以后,眼睛不需要離開(kāi)手機(jī),就可以獲得光明,媽媽再也不用擔(dān)心我的眼睛了,是不是很好很強(qiáng)大?
于是,一個(gè)小而美的創(chuàng)業(yè)團(tuán)隊(duì)順勢(shì)產(chǎn)生,成員分別是
L:Leader,負(fù)責(zé)商務(wù)對(duì)外協(xié)調(diào),技術(shù)方面,10萬(wàn)行代碼量級(jí)實(shí)踐經(jīng)歷,iOS,Android 雙平臺(tái)App主程
Y:硬件專(zhuān)家,工作有條理,焊接手法細(xì)膩
J:Demo小王子,知乎中毒用戶,原型機(jī)Demo程序?qū)崿F(xiàn)者,安卓平臺(tái)App二號(hào)程序員
H:?jiǎn)纹瑱C(jī)小王子,MCU固件主程
M: 產(chǎn)品文案,宣傳設(shè)計(jì), UI 交互設(shè)計(jì)支持
R(我):技術(shù)方案制定,質(zhì)量控制,技術(shù)合作對(duì)外協(xié)調(diào),Wifi固件主程,Android App Debug專(zhuān)員
尋求合作
一款硬件的產(chǎn)品從idea到落地,要做的事情和經(jīng)歷的環(huán)節(jié),成本和時(shí)間上比做一個(gè)App要高不少,有一些坑對(duì)于做軟件出身的工程師來(lái)講是不好估計(jì)的。從外觀設(shè)計(jì),結(jié)構(gòu),零部件選購(gòu)定制,組裝代工廠尋找,質(zhì)量把控,銷(xiāo)售,運(yùn)營(yíng),售后....很顯然,我們需要一個(gè)合作方,來(lái)承載理念的落地。
于是我們找了幻響神州團(tuán)隊(duì)基于他們的現(xiàn)有產(chǎn)品進(jìn)行合作。他們負(fù)責(zé)板級(jí)硬件的設(shè)計(jì),我們負(fù)責(zé)編寫(xiě)軟件,將我們的創(chuàng)意植入,舊瓶裝新酒,實(shí)現(xiàn)一次大的改款升級(jí)。
搭建原型
原型,英語(yǔ)單詞為prototype,是為了呈現(xiàn)和驗(yàn)證我們的想法所做的一個(gè)仿真,是功能上并不完整的模型。
為了證明技術(shù)的可行性,我們需要盡快做出原型。
R和J承擔(dān)了原型程序的開(kāi)發(fā)工作,以lua語(yǔ)言,一周時(shí)間做出了最初的wifi固件程序。
與此同時(shí),Y也從硬件角度,對(duì)現(xiàn)有的手動(dòng)開(kāi)關(guān)版本的臺(tái)燈進(jìn)行了hacking(在沒(méi)有設(shè)計(jì)資料的情況下進(jìn)行改造),基于arduino實(shí)現(xiàn)了對(duì)臺(tái)燈的程序控制。
接下來(lái)的一周時(shí)間里,制作了一臺(tái)外表上看不出任何區(qū)別的智能版小燈,給幻響神州做了一次成功的演示。
這個(gè)項(xiàng)目,基本上算是有譜了。
沒(méi)想到,蘋(píng)果手機(jī)的操作系統(tǒng)(iOS) 差一點(diǎn)就給我們的產(chǎn)品判了"死刑"。
由于智能臺(tái)燈的創(chuàng)意設(shè)定是:揮動(dòng)手機(jī),或者解鎖屏幕,燈會(huì)自動(dòng)喚醒,這就需要一個(gè)服務(wù)進(jìn)程常駐后臺(tái),用于接收系統(tǒng)的喚醒事件和處理重力傳感器數(shù)據(jù)。
當(dāng)L 調(diào)研了iOS系統(tǒng)的開(kāi)發(fā)文檔,得到一個(gè)令人沮喪的結(jié)論:iOS出于省電和安全等多方面的考慮,不支持App程序以后臺(tái)服務(wù)方式運(yùn)行,這就意味著App必須時(shí)刻處于前臺(tái),那就失去了意義。
(插播解釋一下什么是“前臺(tái)”和“后臺(tái)”程序:前臺(tái)的概念來(lái)源于舞臺(tái)表演概念,和后臺(tái)相對(duì),指的是App運(yùn)行的一種狀態(tài)。舞臺(tái)就是前臺(tái),也就是手機(jī)的屏幕。每次舞臺(tái)上只有一個(gè)表演者。
我們的App 需要在不上舞臺(tái)的情況下,默默地在臺(tái)下發(fā)揮作用,就像控制舞臺(tái)背景音樂(lè)和燈光的調(diào)音師,調(diào)光師)
這個(gè)問(wèn)題如果解決不了,那么產(chǎn)品功能就是不完整的,極有可能導(dǎo)致項(xiàng)目的下馬。
在這個(gè)關(guān)鍵的時(shí)刻,L憑借著網(wǎng)絡(luò)上的蛛絲馬跡,逐漸將信息的脈絡(luò)梳理清晰,發(fā)現(xiàn)了一種利用蘋(píng)果系統(tǒng)隱藏API實(shí)現(xiàn)這個(gè)功能的方法。
(API是操作系統(tǒng)提供給App的接口,用來(lái)完成某種特定的功能,比如讀取網(wǎng)絡(luò)狀態(tài),打開(kāi)文件。而有些操作默認(rèn)是不對(duì)外公開(kāi)的,只有知道”暗號(hào)”的人才能訪問(wèn))。
L從iOS 零基礎(chǔ),到使用iOS系統(tǒng)隱藏API驗(yàn)證功能,只花了大概兩周左右的時(shí)間。至此,整個(gè)技術(shù)方案就算是全部驗(yàn)證完成了,剩下的則是充滿各種細(xì)節(jié)的開(kāi)發(fā)工作了。
原型產(chǎn)品化
項(xiàng)目正式立項(xiàng)之后,幾位小伙伴們分工協(xié)同,硬件,軟件,手機(jī)端的App開(kāi)發(fā)工作并發(fā)啟動(dòng)。
從原型到產(chǎn)品,需求也在不斷細(xì)化,需求的數(shù)量也在不斷增加:
- Wifi的功耗問(wèn)題,單WiFi芯片架構(gòu)無(wú)法實(shí)現(xiàn)電池供電使用,需要采用電池驅(qū)動(dòng)低功耗MCU+外接電源給WiFi供電的方式
- MCU(單片機(jī))和WiFi的通信協(xié)議設(shè)計(jì),進(jìn)行狀態(tài)同步
- MCU承擔(dān)電源管理功能,如根據(jù)是否外接電源執(zhí)行不同的操作,此外還要做低功耗模式和低電量保護(hù)
-
分段調(diào)節(jié)呼吸燈的亮度,為提升呼吸燈的視覺(jué)體驗(yàn),需要考慮到LED 燈亮度的視覺(jué)非線性
插播解釋一下什么叫 視覺(jué)非線性:
假設(shè)我們的眼睛對(duì)亮度強(qiáng)弱的視覺(jué)感受用Y表示,實(shí)際的發(fā)光亮度用X 表示,那么Y和X之間,存在一個(gè)比例對(duì)應(yīng)的關(guān)系:
Y = K * X,K就是這個(gè)比例系數(shù)。如果是線性關(guān)系,那么K是一個(gè)常量,體現(xiàn)在坐標(biāo)圖上,是一根直線。但實(shí)際上K會(huì)隨著X的變化而變化。實(shí)際上是一個(gè)曲線。
隨著需求的復(fù)雜化, 原型開(kāi)發(fā)的程序已逐漸將WiFi芯片的內(nèi)存資源消耗殆盡,且受制于運(yùn)行環(huán)境的穩(wěn)定性和性能,距離產(chǎn)品的要求有一定差距。于是,我們用C語(yǔ)言重寫(xiě)了一遍程序。
R完成了通信協(xié)議的設(shè)計(jì),重寫(xiě)了WiFi端的固件程序,并參與了Android App的后續(xù)開(kāi)發(fā)和調(diào)試。
H獨(dú)立完成了MCU固件的開(kāi)發(fā);
J 則集中精力學(xué)習(xí)并接手了Android App的開(kāi)發(fā)。
在第一次試產(chǎn)之前,我們?cè)?塊板子上進(jìn)行了基本的功能驗(yàn)證,確認(rèn)正確無(wú)明顯缺陷后,進(jìn)入到100片的小批量環(huán)節(jié)。
0 - 100
該環(huán)節(jié)的目標(biāo)是:驗(yàn)證原型產(chǎn)品方案在批量化之后的穩(wěn)定性和一致性,同時(shí)讓加工廠技術(shù)工人熟悉產(chǎn)品的基本組裝。
當(dāng)我們把100套模組焊接組裝好上電以后發(fā)現(xiàn),有部分燈無(wú)規(guī)律地呼吸閃爍,深圳方面的硬件工程師由于缺乏對(duì)意外情況的預(yù)見(jiàn),準(zhǔn)備不足,只是嘗試替換了一些元件,沒(méi)有定位故障,且受設(shè)備條件限制,軟件運(yùn)行的調(diào)試信息也沒(méi)辦法提取,本來(lái)預(yù)計(jì)兩天試產(chǎn)出樣品的計(jì)劃,貌似要擱淺了。
時(shí)間是最貴的成本。
第二天一早到達(dá)工廠后,我負(fù)責(zé)從WiFi軟件角度排查軟件,Y負(fù)責(zé)排查硬件,其他團(tuán)隊(duì)成員遠(yuǎn)程支持,同時(shí)檢查單片機(jī)模塊部分的代碼設(shè)計(jì)。
問(wèn)題的現(xiàn)象是這樣的:WiF模塊外接電源上電后,發(fā)生了異常復(fù)位,而我們程序的寫(xiě)法是每次WiFi上電,都會(huì)把單片機(jī)復(fù)位一下,實(shí)際上我們看到燈在不停地呼吸閃爍,只是單片機(jī)被反復(fù)地復(fù)位,執(zhí)行上電后的呼吸燈效果而已。
補(bǔ)充說(shuō)明一下,
WiFi芯片主動(dòng)復(fù)位單片機(jī)是產(chǎn)品設(shè)計(jì)上的考慮:由于燈的內(nèi)部裝有電池,萬(wàn)一單片機(jī)程序有bug,如果沒(méi)有主動(dòng)復(fù)位的設(shè)計(jì),就只能拔掉電池,操作會(huì)比較麻煩。
說(shuō)實(shí)話,當(dāng)我第一次看到WiFi的調(diào)試信息輸出中有異常復(fù)位的信息時(shí)非常驚訝:之前明明正常工作的程序,怎么就成這樣了?腦海中有各種可能的問(wèn)題情況涌現(xiàn)出來(lái)。不過(guò)為了排除是軟件的問(wèn)題,我首先做的事情,是重新燒錄一遍程序,發(fā)現(xiàn)無(wú)改進(jìn)效果后,再改寫(xiě)了一個(gè)最基本的測(cè)試程序(這意味著軟件上基本上不可能出錯(cuò)),重新燒寫(xiě)一遍測(cè)試,結(jié)果仍然是否定的。
Y這邊的情況是,將所有的芯片上電波形,都測(cè)量了一遍,靜態(tài)指標(biāo)都正常,因此重點(diǎn)從動(dòng)態(tài)特性進(jìn)行觀察。
到下午的時(shí)候,確認(rèn)是供電的問(wèn)題:給WiFi供電的芯片瞬態(tài)能力不足,復(fù)位上電程序開(kāi)始執(zhí)行后,無(wú)法帶動(dòng)芯片全速工作,會(huì)導(dǎo)致電壓突降,從而造成WiFi芯片重啟。
解決方法是,更換供電芯片,增大輸出端電容。
100 - 1000
自從第一次試產(chǎn)100臺(tái)的順利完成,大家都松了口氣,接下來(lái)該面對(duì)量產(chǎn)做準(zhǔn)備了。
沒(méi)想到的是,第二次試產(chǎn)的過(guò)程更加的糾結(jié)。
核心的問(wèn)題是觸控芯片的可靠性。我們采用的是一個(gè)國(guó)產(chǎn)的低成本的觸控方案,功能非常簡(jiǎn)單,就是感應(yīng)到手按下輸出高電平(邏輯判斷為T(mén)rue),可以代替單片機(jī)完成模擬到數(shù)字的轉(zhuǎn)換,同時(shí)相當(dāng)于做了第一級(jí)的去抖,簡(jiǎn)化了單片機(jī)的程序邏輯??墒峭饨与娫瓷想娨欢螘r(shí)間后觸控就失靈了,拔插也不好使,必須要拔掉內(nèi)部電池徹底斷電才可以。
此外,通過(guò)高溫測(cè)試也發(fā)現(xiàn),該芯片也會(huì)有穩(wěn)定性的問(wèn)題,有時(shí)候甚至?xí)约狐c(diǎn)亮。
問(wèn)題的麻煩還在于即便給出了足夠合理清晰的解釋和分析,合作方的硬件工程師懷疑是我們的軟件故障,而這個(gè)問(wèn)題不太可能通過(guò)軟件方法解決??梢?jiàn)在一些邊界的疑難問(wèn)題上,軟硬件都懂的人是多么的重要。
最終解決的方法是,更換觸控芯片為成本更高的方案,繞過(guò)了問(wèn)題。
1000 - 10000
芯片固件在設(shè)計(jì)的時(shí)候,提供了一個(gè)量產(chǎn)自檢的功能:即首次組裝上電,燈會(huì)自己去連接路由器,測(cè)試wifi功能是否正常,并亮滅開(kāi)關(guān)幾次。
功能的實(shí)現(xiàn)方法為:提前在存儲(chǔ)芯片上燒錄一個(gè)標(biāo)記,程序啟動(dòng)后,如果能讀取到該標(biāo)記,則進(jìn)入量產(chǎn)自檢,完成后將標(biāo)記清除,避免下次進(jìn)入。
而問(wèn)題就出在,由于燒錄廠的原因,并非所有的芯片都成功地?zé)浟嗽摌?biāo)記,因此有些燈就進(jìn)不了自檢,產(chǎn)線工人無(wú)法知曉該燈的好壞,除非進(jìn)行人工檢查。
為解決這個(gè)問(wèn)題,我們只能另外開(kāi)發(fā)了一個(gè)量產(chǎn)專(zhuān)用App,把這些燈直接配置進(jìn)量產(chǎn)路由器,再發(fā)送一個(gè)進(jìn)入量產(chǎn)模式的后門(mén)命令,從而實(shí)現(xiàn)了量產(chǎn)自檢。
但是到這里,問(wèn)題還不算是徹底地解決。于是,在下一個(gè)版本的固件中,我們修改了設(shè)計(jì),去除了對(duì)燒錄環(huán)節(jié)正確性的依賴。
總結(jié)與反思
結(jié)論其實(shí)并沒(méi)有新意,無(wú)非是思想上重視,加大對(duì)測(cè)試的投入,包括從設(shè)計(jì)和開(kāi)發(fā)時(shí)就要考慮系統(tǒng)的可測(cè)性,編寫(xiě)可以自我查錯(cuò)的代碼。
然而知行合一是困難的,因?yàn)檫@需要和人的弱點(diǎn)做斗爭(zhēng)。
回想假如當(dāng)初實(shí)現(xiàn)進(jìn)入自檢的功能的時(shí)候,我只是簡(jiǎn)單地實(shí)現(xiàn)和測(cè)試了功能,測(cè)試了一兩片覺(jué)得就萬(wàn)事大吉,沒(méi)有留下可以重復(fù)測(cè)試的接口,那么一旦出現(xiàn)狀況,這批幾千套的模塊,就需要進(jìn)行人工測(cè)試,代價(jià)**是相當(dāng)?shù)母甙骸?/p>
這次小試牛刀的經(jīng)歷給我最深的感觸是:
首先,這次開(kāi)發(fā)采用逐級(jí)擴(kuò)大生產(chǎn)數(shù)量進(jìn)行驗(yàn)證的流程再次被證明是必要的。
因?yàn)?,一些?xì)小的設(shè)計(jì)和制造缺陷,在數(shù)量少的時(shí)候,不容易被發(fā)現(xiàn),因此需要擴(kuò)大測(cè)試的數(shù)量和范圍。逐級(jí)擴(kuò)大生產(chǎn)數(shù)量,主要是可以較好地控制成本,
畢竟硬件每做一次生產(chǎn)都是燒錢(qián),軟件只需要改改代碼編譯就可以了。
其次,有兩大基礎(chǔ)設(shè)施,應(yīng)當(dāng)成為未來(lái)所有軟件的標(biāo)配:程序崩潰的自動(dòng)捕獲 和 支持在線升級(jí)。
在軟件開(kāi)發(fā)測(cè)試階段,很難做到在所有的設(shè)備平臺(tái)上都測(cè)試一遍,尤其是Android手機(jī),各個(gè)品牌型號(hào),數(shù)量眾多。軟件發(fā)布出去以后,用戶使用過(guò)程中遇到程序崩潰閃退,用戶最多是罵一句,給個(gè)差評(píng),不太可能有心情進(jìn)行反饋。
如果程序可以自動(dòng)捕獲故障現(xiàn)場(chǎng),報(bào)告給開(kāi)發(fā)工程師,工程師修復(fù)問(wèn)題后給用戶自動(dòng)推送更新版本,從根本上可以提升用戶體驗(yàn)。
最后,再正確的流程和方法論也要靠人來(lái)執(zhí)行,有一群靠譜的人通力合作,才是成功的根本保障。