對編程感興趣的程序員是否都對電路、單片機也懷有濃厚的興趣?
看到很多程序員大佬從小都很喜歡電子電路,可編程組件這種看起來很"硬"的東西(現在可以換成3d印表機 無人機之類)。碼農們對於編程的熱愛最初就來自於什麼呢?
是否濃厚很難說,不過我在2015~2016年工余時間做了一個寫生機器人,你坐在前面,就會觀察你,然後埋頭苦幹地用筆為你畫一張素描。
它用 Intel RealSense 做臉部追蹤,Intel Edison 控制雲台和機器臂,機器臂也是自己設計的。當然,繪畫演算法和機器臂的運作也是自己實現的。
雖然和最初的構想還有不少距離,但能完成到這程度我也滿足了。
我從中自學了不少新知識和技能,第一次學習使用 SolidWorks,第一次設計機械,第一次組裝,第一次使用微控制器等等??
此小項目獲得公司一個內部比賽的幾個獎項,最近獲邀撰文回顧,寫好後也放到專欄吧。
更新1:兌現承諾,在飛機上先寫了上篇 《寫生機器人》製作經驗分享(上)。
大部分CS科班出身的程序員,真正接觸到硬核電路級別的開發,都會頭疼得要死。
要知道,程序員思維的最大的前提條件,就是你的CPU絕對可靠,編譯器絕對可靠,你所用的庫、包99%的功能和設計都可靠,你所看到的文檔99%都是準確且全面覆蓋的,你真正要解決的問題,只有你自己寫的那堆代碼和架構,你自己寫得對,那麼運行的結果就是正確的。如果你在編譯器或者庫中發現了bug,你很有可能換一套東西就沒問題了,或者你跟作者提出,作者在三天後把bug修復了,更新了最新的版本。
而電路級別的開發是什麼?是你不可以信任你手上的任何東西。是不是外圍電路的電阻太大了?是不是虛焊了某個管腳?是不是時鐘頻率錯了?就算晶元本身出現了問題,你也絕對不可能像找編譯器的bug一樣用幾分鐘就能驗證你的想法——最關鍵的是,就算出現了問題,你聯繫了廠商,然後廠商又有什麼辦法呢?難道讓你等著廠商重新設計,流片,驗證,發售,然後再寄到你家裡來?估計那時候你早就放棄了。
其實大部分人上過高級一點的電路、微機原理之類的課,只要不用現成的開發板而是用麵包板,需要你手工查幾十根線的這種任務的時候,大部分人都是頭疼的,因為有一個口口相傳的定理——只要手動插線超過100根,有99.99%的概率第一次不會跑通,哪怕你是100%的像素級抄襲,抄來個電路自己做成PCB板然後焊上元件——這絕不是像編程作業一樣耗時和成果是成正比的——寫程序的事情,就算再麻煩,只要想通原理,付出時間,想好架構,總是能一點點寫完調試的,然而真正搭建一個硬體的東西出了bug,花個三四天時間找不出問題盯著示波器眼睛都瞎了沒有一丁點進展,簡直是在正常不過了。
我相信很多程序員喜歡用單片機開發板寫點東西,或者用Arduino、樹莓派之類的東西搞點發明創造,做出點硬體的東西,但恕我直言,這跟你在計算機上裝好了驅動,用寫好了串口或者USB的東西控制其他設備沒有任何區別,因為你的工作量絕大部分都在軟體上,而真正跟電路、系統級別的開發,還是有著天壤之別。
這篇可能略枯燥。
編程對我的一個影響是,不再把問題看做黑箱,而是通過了解原理,分解模塊,來變成可理解,可實現的解決方案。
幾年前,我們家空調是松下的,溫控不準,26℃太冷,27℃太熱,早上起來,兒子就打噴嚏,流鼻涕。老婆非常不爽,要我解決問題。
分析一下,問題的關鍵在於,空調的溫控模塊在本機上,而我們需要的是,根據孩子床邊的實際溫度調節。
作為程序員,相信遇到的絕大多數的問題,都是別人解決過的,在自己造輪子前,搜一下 stackoverflow/github,是個基本禮儀。
購物界的 stackoverflow,據說是淘寶。讓我震驚的是,淘寶沒有。而且,直到今天,淘寶上也沒有一個很好的溫控方案,都是5,6百塊的zigbee溫度計,聯網手機,插座,通過開關空調實現。
簡單的問題複雜化。
自己搞。
第一步,做個紅外信號 repeater。
簡單的說,就是錄下遙控信號,並重播。一個接收器,可以記錄下遙控器信號。一個發射器,根據記下來的數值,重複遙控信號。
紅外遙控的原理是什麼?
紅外線是光,由led燈泡發出,只是人看不到而已。燈只能亮,或者不亮,按遙控器時,通過不同時長閃爍led燈,來編碼信號。
接收器收到的信號,是個數組,表示遙控器上led燈亮和滅的時長。如果我的裝置上的 led 燈,能按照這個數組閃爍,理論上就可以重複遙控命令了。
我用電風扇試試,果然,轉了!
見證奇蹟的時刻來臨了,我捧著麵包板,揪著led發射頭,叫上老婆和我媽,來,看魔術。
空調沒開,我上竄下跳,站椅子上,對著空調發射,它也沒開。
我媽表示,就你那幾根破線想開空調,造空調的人都可以去喝西北風了。
面對群眾的冷嘲熱諷,我並不氣餒,寫個程序,還要 debug 幾次,第一次跑不過,很正常嘛。
只是,硬體的 debug 環境太惡劣了。
沒有 log, 沒有 exception,空調就是沒反應,這可怎麼下手?
我的第一想法是,信號可能有加密,或者有某種數字簽名。
窮舉。
我錄下了所有按鈕的信號,一個一個跑去空調那裡試。發現大部分不管用,但有一兩個按鈕信號有效,空調有接受,大概是定時器之類的信號,調溫度風量的都沒用。
這說明信號沒加密。
我意識到,無論按溫度,還是風量鈕,都會把溫度,風量,風向等數值一次發出去,也就是說,很多信息要傳輸。
溢出!
程序底層用的是一個叫IRRemote的開源庫,查到它用來存儲信號的數組長度是255,超過了就會覆蓋。改成 512,果然,收到了一個長度三百多的數組。
又叫老婆和我媽來見證奇蹟,這次空調開了。
第二步,溫控。
LM35,插上麵包板,沒反應,奇怪,拔下來...
嗷!!!
手上燙個泡,超痛!搞硬體就是危險,軟體寫這麼多年,都沒受過傷。只是把正負極接反了,它就變成電爐了。
LM35是模擬電路的,誤差大,精度不行,白被燙一下,換成了ds18b20,編程麻煩點,但精度和穩定性都好很多。
第三步,演算法。
熱了調低,冷了調高,好像很簡單。
其實不然。
1,因為測量的是房間實際溫度,升溫和降溫都有一個時差,不是說調了立刻有用,
2,目標溫度是一個範圍,比如,26.2℃ 到 27℃,在範圍內,不調節。
3,超出範圍後,發射預錄信號,室溫超過27℃,就調空調至25℃,15分鐘後還沒降下來,就發射 24℃的信號,以此類推。
見證奇蹟的時候到了,我很自豪的把它布置到床邊。
夜裡空調噼里啪啦的響,風忽大忽小,溫度忽高忽低,我的裝置不停的發射信號,有種山雨欲來風滿樓的感覺。半夜起來,拔下裝置電源,裹在被裡,思考哪裡出了問題。
第四步,屏顯。
離開電腦,我不知道它發了什麼信號,為什麼發。痛定思痛,裝了兩個 led 燈上去,熱了,就閃紅燈,冷了,就閃藍燈。
別看燈小,真亮啊!
半夜三更,空調呼呼的吹,藍燈紅燈刷刷的閃,好像飛碟來了,超有feel。
顯然,老婆是不欣賞的。我對debug的精度也有追求,拔了燈,上了個1602的 lcd屏,用電烙鐵,怕燙手,焊腳焊的好像被炮轟過一樣,但至少亮了,能顯示室內溫度,和空調溫度。
第五步,優化演算法。
有了屏幕,有種 ide 在手的主場感,信心滿滿,很快就找到問題。
比如,太熱,發射信號調低溫度,15分鐘後,還熱,再調低... 等到室溫開始下降時,空調溫度可能已經很低了,而室溫會越降越快,掠過目標溫度範圍,變成太冷,裝置又開始一度一度向上調,直到過熱。
重要的不僅是當前的溫度,還有趨勢!
我調整了演算法,考慮到溫度變化的趨勢,在到達適宜溫度附近時,就開始預回調空調溫度,讓它用一個更和緩的姿勢,進入舒適區。
還發現,同樣的室溫,早上的時候,感覺會更冷。為了更舒適的睡眠,設了個規則,在首兩個小時候後,每小時溫度範圍提高0.1℃。
這個時候,睡覺已經很爽了。
第六步,輸入。
不想每次調數值都用電腦燒入,就要有個輸入裝置。 lcd屏佔了太多的介面,剩下的只能接一個按鈕。
一個按鈕怎麼調呢?
我設計了個單按鈕菜單,5大功能,長按跳轉功能,短按循環數值,剛開始調試的時候,天天蹲在床邊按按鈕,有種地下黨發電報的刺激感。
最後,雜項。
實際操作中,還有很多小問題。
比如,內存只有1k還是2k,我放了幾個整數數組來存空調命令,程序就崩潰了。還要研究編碼,把300多的數組壓縮成幾個數字,才能繼續下去。
溫度模塊可能有擾動,需要求動態平均值才比較妥當。
作為程序員,遇到問題,需要用宏,腳本,就用;需要爬網頁,資料庫,就爬;需要插麵包板,焊針腳,就插;我感興趣的不只是語言或硬體,而是分析問題,解決問題的過程。
不知道吃什麼,就爬了央視的天天飲食;炒股虧錢,就做了個模擬交易的平台;覺得時光飛逝,不知所措,就寫了一個安排生活的 app。
從分析,設計,實現,到最終應用,解決問題,看著自己的想法,從無到有,一步步落地,這個過程讓人著迷。
我的溫控裝置跑了兩年,每晚守護兒子睡覺,直到搬家 :)
越底層的東西越難做。
編程其實是很高層了。編程的時候,我們通常可以假設電腦是好的而不是壞的。編寫的程序,在沒有改動的情況下,如果今天運行是正確的,那麼通常明天運行也會是正確的。
電路相對來說就更底層一些。有時候電路做不對,就是因為某個元件壞了,換一個元件就好了。一些更糟糕的情況,是電路工作基本正常但是性能不好,其實是因為某個元件買到了殘次品、仿冒品。有時候電路今天是好的,但是掉進去了一個金屬渣,明天電路就壞掉了。甚至一些時候,換個電容的品牌,好的電路就不好用了,尤其是做射頻電路的時候。
另外,編程可以在一個小屋裡足不出戶地專註地編寫。但是做電路板需要買元件。很多時候,元件不是一家商店能湊齊的,常常需要十來個商店雜七雜八地買,才能湊齊一個電路板的元件。
編程比較容易改。一個小程序,編譯不需要很長時間的話,可以說是改動後立刻能驗證。但是電路板改動一次,需要重新印製、焊接,改一次周期很長。
繼而,對於一般的PC程序,練習編程幾乎是不要錢的。所以常常有中學生甚至小學生在編程上取得一些造詣。但是做電路是費錢的,中學生或小學生在沒有親友贊助的情況下很難在做電路上有造詣。
實際上,有很多人是因為做電路做得太痛苦了,改行到編程,只寫程序、不做硬體。但是本來做編程的人改行去做電路的,就我的觀察來說編程改電路的人遠遠少於電路改編程的人。
有興趣,但不濃厚,因為硬體開發debug的體驗真的是太tm差了
我高中的時候,在麵包板上把CMOS4000系列那些集成電路玩了個遍。這麼多年過去了我還能記得4013是雙D型觸發器,4096是六個反相器或是什麼來的,二十多年前的事了……
拿那些與或非門、二進位十進位轉換器、觸發器、並串轉換器、寄存器自己搭電路。輸入就是按鈕、開關或者脈衝發生電路,輸出就是一大堆單個的LED,或者8段數字管,或者喇叭(當把受控的分頻器串接在脈衝源和功放之間的時候)。
有時候能廢寢忘食的畫一張巨大巨大的圖紙來描述自己的想法,然後用N多麵包板和密密麻麻的導線去實現電路。當然沒有一次能一次性上電就成功的。然後慢慢分析錯哪兒了,從而自行發現了對比法、排除法等一些簡單的debug方法。
直到後來有一天,我看了一篇8008的科普文章,雖然能看懂的不多,而且現在也不記得了,但我記得那一次我明白了,我那根本不是在玩電路。
本質上就是在編程。只不過不是用指令,更不是語句,而是與或非。與或非實現觸發器,觸發器產生狀態,狀態拼湊出更複雜的邏輯,邏輯約等於行為,行為就能為人做事情。
------------------------
我至今都記得剛理解了4013後,給我家做的第一個「貢獻」就是把家裡拉繩的電燈,換成按鈕的了,一片4013,一個三極體驅動一個繼電器,機械按鈕用一個電阻一個電容消除雜訊。按一下就亮,再按就滅。
當天中午著實把我媽鎮住了。
當天下午就壞了。因為在我的「設計」中,繼電器通電從而開關跳轉後,電燈斷電,整個控制電路由電池供電……我是EE出身,做了好幾年FPGA開發,所以很喜歡硬體,每次看到板子和晶元都很興奮,但是實驗室的師弟們基本沒有喜歡的。實驗室花了好幾年做了兩款晶元,設計晶元的一代又一代碩士們畢業後大部分都去做軟體了。圖中左邊是一塊FPGA評估板,右邊子板上的晶元就是實驗室設計的DSP,正在用邏輯分析儀進行測試。個人覺得很有魅力。另外這些線不是飛線,只是為了用邏輯分析儀測試把引腳信號印出來。
沒有,我對硬體毫無興趣。我小時候從一開始就是沖著開發遊戲去的,只是沒想到遊戲行業對員工這麼不友好,才去的微軟。
當然不是,還是取決於個人愛好了。
當前總的來說,計算機系出身的人,尤其是本科生,雖然也學過數字電路、計算機體系結構、嵌入式系統,但基本上說起來編程,還是只存在於visual studio、vim、eclipse這種x86的上層工具裡面。我見過的來說,計算機系出身的,如果從事的工作不是在電子和嵌入式行業的,能玩玩樹莓派和arduino就算差不多到頭了,因為這兩個東西把底層封裝的比較好、硬體本身性能也高,社區資源也多,不太用擔心底層硬體問題。
這兩種平台,不太需要考慮到底是寄存器寫的不對還是硬體本身就壞了-那樣子需要拿著示波器萬用表信號發生器之類的東西去檢測。也不需要考慮時鐘、資源和流水線的問題,硬體都是不能改動的了。
我還是覺得「編程的人是否業餘該玩硬體」,是個個人愛好的問題,不是必要的,現在分工這麼細,不存在那種什麼都會的人,高層碼農們業餘做個小製作就好,沒必要事必躬親啥都干。就像c羅梅西這種top2的前鋒,去個低水平比賽客串個中場後衛什麼的相信都沒問題,但是在歐冠裡面就算小組賽也不能這麼浪吧(德羅巴倒是可以打左後衛)
我本科剛開始時候是天天和搞純軟體的人混在一起的 @牛耿 ,當時一起寫個java什麼的也挺開心的,到了後來做的東西就越來越不一樣了,一起吃飯的時候我說我的破爛單片機居然主頻有72MHz,內存有32k,幸福的不得了,還說起來如何中斷之間如何設置優先順序,微型os進程如何同步,外面電路怎麼操作。他們聽了都哈哈大笑,他們都是玩集群裡面至少幾十上百G內存的。我對於cs流行技術早就落伍了,但是玩玩嵌入式還是比cs的一般碼農稍微強一些的。
我懂電子,但不喜歡
比如你要我給你設計個鍵盤,從裡到外,我是可以的,再複雜的,我就不願意了無人機和立體列印從來不看
這個推論不成立,就完全不是一回事,我從來勸人遠離靠近硬體的軟體開發少量二值演算法確實有非常優雅的迭代實現方法,也往往可以有非常優雅的電路運算圖來進行表示。
典型如極化碼, 原作者初始版的蝶形圖非常讓我著迷,無論是編碼還是解碼。。後來主要的介紹類文章都喜歡換一種電路序來介紹,但是我自己畫草圖的時候,始終不自覺的畫作者的那個原版。
還有一個就是用於turbo碼和ldpc碼的置信擴散解碼演算法,,真的就是個運算放大器啊。。後來我也用那個對應的和積演算法思路來算一些組合題目。 個人其實也對Berlekamp-Massey algorithm 之類的思路挺感興趣的。
但要說更多的喜歡,那真的確實沒有了。 軟的和硬的 其實還是有點距離的。正是因為了解,才知道自己能力有限,而且動手能力不強,畫點抽象的運算電路還行,真要做點啥,需要考慮的方方面面真的是太複雜了,非我所能。
不過我也知道了硬體運算電路一般喜歡啥:可以用移位寄存器的電路(設計方便容易,而且提升頻率的限制少),大部分情況能迭代收斂的閉合(或者叫反饋)運算電路(運算快),蝶形的電路(可以用多個小電路來組合成大電路,方便擴展)。。。這就是當時想要發文章時候的腦迴路:任何一點修改優化,都想想,是否更方便了硬體實現啊,是否更方便了硬體時序的並行啊。。。
我沒有接觸過單片機。不過我本科是電子系的,所以電路、麵包板當然玩過,還玩過 FPGA,用它製作小車參加了系裡的電子設計大賽。
我感覺,像電路這些硬體的東西,我真正覺得能夠完全駕馭它們的時候,就已經是把它們進行了層層的抽象,而可以當成軟體的時候了。比如在 FPGA 課上,我實現了一個超級瑪麗版的彈球遊戲。在實現的過程中,我進行了多層的抽象與封裝,基本上就像在設計軟體,至於這些功能在 FPGA 晶元上是如何實現的,我其實並不太關心。
所以我覺得,我的真愛還是軟體,是用編程創造秩序的快感。硬體對我來說,更像是一個解謎遊戲,而它的解法,就是化歸成軟體問題。
我的步驟是這樣的:
小學4年級開始:喜歡無線電,一隻玩到工作,有電台執照。HAM一枚。自己設計製作電台。
初中開始:玩appleII ,寫basic。
高中開始:玩數字電路,單片機。都是自己做。然後寫彙編。
工作後:寫C、C++等等
現在:不玩無線電了,因為有潔癖,不喜歡家裡亂。只寫代碼:C、C++、Java、javascript、pasic、PHP、erlang、actionscript等等
已經43歲了,轉了一圈回來,現在會教孩子玩 Arduino ,寫C,刷noip。
我覺得對於硬體是否有興趣,可能取決於自己 DIY 改變生活的樂趣。
大學學的是電焊:
焊多了,就敢拆開你的 MBP,換個電池:
額,不對是電子信息工程。不過,主要的實踐時間裡都電鉻筆與編程上。畢業三年多,還在燒錢中:
最喜歡的硬體還是 Raspberry Pi、Arduino 和 ESP8266,計劃在寫一個相關的教程《寫給軟體工程師看的硬體編程指南》,但是感覺力不從心了。
只是對於一個已經工作的人來說,這些錢沒有在學校的時候壓力那麼大。
硬體是代碼與現實世界的介面,有了這個介面,我們可以做任何我們想做的事情。用 Raspberry Pi 跑個 RetroPie 加幾個 XBox 控制器遊戲機:
跑個 XMBC 當媒體中心:
再找個 Raspberry Pi,然後根據我寫的智能家居教程(phodal/smart-home):運行個 Homebridge 或者 Home Assistant 當個智能家居的中樞:
有個 iPhone 就可以用 Siri 語音控制,有個能聯網的設備,就可以用網頁控制,有個 Alexa,就可以語音控制:
使用 ESP8266 模擬個 Wemos,就可以輕鬆地將 Alexa 與 Broadlink 連接到一起,就能輕鬆地控制你們家的所有紅外設備,如空調、電室。
你還可以像我最近在翻譯的 DIY 類文章一樣(http://play.phodal.com/play/) 做更多的事情。使用 Ngrok 來從外網訪問:
搭建個 MineCraft 私服:
自製基於 Snips 和 Snowboy 的聲控音箱來保護你的隱私:
硬體,可以讓生活充滿可能性
不喜歡,一點都不喜歡
我特別小的時候沒電腦,就只能玩電路,而且我爹就是搞電路的,家裡元件多,隨我折騰。最早就三極體二極體電容電阻啥的,那時候偶然得到一些電阻是色環的,數色環都興奮的不得了。我記得那時候有種集成塊叫555的,特別好,可以用來做很多東西。
單片機我玩的不多,就玩過8031/51,每個引腳都如數家珍啊,可惜我只有一片,當時總想著搞兩塊聯動。大學時候競賽還玩過一個富士通的,競賽完了就還回去了,主辦方太小氣了,那小破玩意送我又能怎地。玩樹莓派不能算玩單片機吧,那系統已經非常完備,和台電腦沒差別了。
其實自從有電腦可以寫程序了,電路就很少玩了,還是寫代碼更爽。。。。我覺得我對編程的熱愛不能說來自電路,我就是愛動手而已。
當然來自於它:
但是發現自己時間不夠了…
不啊,我更喜歡公司發的程序員鼓勵師。
她穿著性感嫵媚動人,輕輕在我耳邊摩擦來摩擦去,她的頭髮滑落在我的臉上,有淡淡的誘惑味道,看著我寫的代碼,手輕輕按上我的胸,用輕不可聞的夢囈告訴我,只要解決了這一個bug我就可以開房做任何我想做的事。
然後我像打了雞血一樣迅速把bug完美改掉,打開了11開了房找幾個兄弟開黑玩起了鍾愛的dota1。大學也學了數電和模電,做了些萬用表、萬能充這樣的玩意,畫得了電路圖,也能焊soc。
當年arduino帶我走向了編程興趣的大門,但很快就對硬體編程感到失望了:一百多塊錢贈送的組件包就那麼一些舵機、LED、液晶屏、馬達,要想實現更多的功能,還得買更多的硬體,想看到更多的效果、對實體的更多的反饋得花錢,簡直是編程界的頁游好吧。。。
後來很快陷入了Python編程然後到處爬古裝小姐姐照片了。。成本極低,一樣有實時積極的反饋。。
大學就是學的電子,天天鼓搗單片機,pcb,電烙鐵啥的,說實話硬體做出來的成果比軟體成就感更強
問題是太累了啊,而且我手笨啊,總要把時間花在不起眼的地方,而且要學的東西太多了,真的累,數電還好點,模電要人命啊,畫電路圖也是累,一點錯整塊板子就廢了
後來畢業先去了硬體公司,做電錶啥的,發現這種為了穩定程序都是幾年不大改的,工作崗位是研發,實際上工作內容大部分都是跟工廠和採購打交道,而且晉陞前途渺茫,七八年經驗只敢說自己略懂一二……工資對比軟體的虛高也是低的可憐,於是那時候果斷放棄轉去做軟體了……
其實對硬體方面的興趣還是有的,只是當工作就算了吧……現在可編程硬體也比較發達了,那個半成品來玩玩還可以,自己從畫板子開始的話,還是算了……推薦閱讀:
※如何開發一個能夠運行在JAVA虛擬機上的編程語言?
※Apache和Apache Tomcat的區別是什麼?
※為什麼計算機專業好多年了,就是學不會編程?
※為什麼 .NET 就業市場不大?