> 是時候應該反擊了
當我看到[@鄢得諼草](http://www.weibo.com/hug8217)?的那幾篇黑我黑到體無完膚的#極客愛情# @Phodal 故事的時候,我發現我竟無言以對。或許,作為一名程序員,我們或多或少都有這樣的共性。
* [技術宅不解風情](http://www.xuntayizhan.com/person/ji-ke-ai-qing-zhi-shi-ji-shu-zhai-bu-jie-feng-qing/)
* [和不會聊天的人談戀愛](http://www.xuntayizhan.com/person/ji-ke-ai-qing-zhi-shi-yi-he-bu-hui-liao-tian-de-ren-tan-lian-ai/)
難道就這么坐以待斃嗎?當然,決不。在即將來到的情人節之際,我準備奮起反擊。
對于向往浪漫的女孩來說,親手制作的禮物總是更能抓住女孩的少女心。不過,代碼除外,除非你的另一半也是一個程序員,能輕輕松松理解深意:
~~~
while(propose.times < 99) {
huahua.listen(phodal.ask("will")("you")("marry")("me"));
huahua.reply.propose ();
}
huahua.propose("Yes");
var ever = phodal.love(huahua) && huahua.love(phodal);
for(ever){;;;};
~~~
——至于像花花這樣雖然學中文出身但是長期在我身邊耳濡目染的孩子,大致能理解如此簡單的表達吧。
而對于我這樣一名極客來說,不是出自自己的親手制作,總顯得有那么幾分的沒有成就感。
到目前為止,我需要營造一個浪漫的環境,準備一份恰當好處的禮物。故而總結如下:
* 自己編成的代碼
* 營造浪漫的環境
* 親手制作的禮物
`注意`: 請將下面的`《程序員的情人節禮物》`換成xx語言。
# 《[程序員的情人節禮物](http://www.xuntayizhan.com/person/geeks-love-programmer-gift-guide/)》是怎樣煉成的
網頁Demo:?[http://valentine.phodal.com/](http://valentine.phodal.com/)
我想起她曾經滿懷著羨慕的給我看知乎上的一個答案:“一個程序員給他女友寫了一個程序,整個太陽系都是他和他女友的照片,太陽系的中心是他心中女友最美的照片,周圍是他的照片圍繞著她轉,背景音樂是男主唱的《愛轉角》。點開屏幕上他們名字的縮寫,還有男主對他女友說的一段話。”她用她那雙雖然小但炯炯有神咄咄逼人的眼睛盯著我,一副我不給她也做一個她就要宰了我的模樣。 “嗯,這個不難啊,不過我是不會給你做的。” 你覺得我會讓你有嘚瑟的資本嗎~
(會)
所以,我想要做成的效果類似與一個能滾動展示圖片的App,上面是我們相遇相知的歷程,或許還需要加上音樂、照片,等等。除了下面準備的材料之外,我還需要有:
* 那些我想說的話
* 她美麗動人的畫
在使用類似于下面的照片時,請提前做好心理準備。

我仿佛看到她怒發沖冠的模樣,哈哈哈。 言歸正傳:
## 《程序員的情人節禮物》入門之材料構思
### 情人節禮物之設備展示
想著在這個移動盛行的時代,再用電腦就不太合適了。要是做移動應用的話,那么手機或許可以和硬件結合地更加和諧。
找到了自己所有的移動設備,如圖所示:

作為一個諾基亞的粉絲,從那一刻起,我不喜歡Microsoft。
* Nokia N72
* Nokia E66
* Nokia Lumia 920
* Nokia Lumia 1020(ps:拿在手上拍照)
* Kindle
想想,還是放棄了做移動App的想法——沒有Andorid手機,沒有iPhone,沒有Win 8 + VS(ps:公司的電腦不能裝盜版軟件...)。
好在我們有Web。
### 情人節禮物之硬件設備
翻箱倒柜之下找到了下面的材料:

排除了一些老舊的設備:
* 51單片機: 用這東西我真的可以按時交付軟件么?
* STM32: Mac OS下支持得不是很好。
* PcDuino: 不合適,我對它的印象是有點不穩定。
最后挑出了`Raspberry Pi`?+?`Arduino`,這對永恒的組合。
* Raspberry Pi當服務器
* Arduino控制硬件。
### 情人節禮物之被控設備
想了想我們需要營造一個浪漫的環境,于是找到了這個`星空投影儀`,還有其他(ps:暫時還是需要保持一些神秘性的)。

應該是夠用的,當然還需要有其他模塊:
* 紅外模塊(ps:用處保密ing。)
* 繼電器(ps:用于控制星空投影儀。)
## 《程序員的情人節禮物》之美
因為我是`以編程養活自己,以寫代碼滿足自己`的極客一枚,我需要程序來控制我們的硬件設備。
### 框架選擇
關于后臺,先想到的兩個語言是`JavaScript`和`Python`,Raspberry Pi的最大優勢語言就是Python了,出現JavaScript的原因是我們可以統一前后臺。雖然[Raspberry Pi安裝Nodejs](http://www.phodal.com/blog/raspberry-pi-pcduino-install-nodejs/)也是挺簡單的,然而還是覺得用Python吧。
對比了一下Python的框架,選擇了輕量級的`flask`。
至于后臺,之前喜歡的方案是用`jQuery`?+?`BackBone`?+?`Mustache`來構建移動CMS(ps: Github見[https://github.com/phodal/moqi.mobi](https://github.com/phodal/moqi.mobi)),在這之前的一個時期覺得他們會導致代碼多了一個大小級。接著,寫了自己的JS框架——Lettuce,總覺得有點過。不過,剛好夠用,作為~6kb大小的框架,包含:
* Router
* Promise
* Event
* Template
* Effect
(小廣告:如果你有興趣的話可以試試[https://github.com/phodal/lettuce](https://github.com/phodal/lettuce),也可以加入我們.....)
也要有PySerial來控制串口。
最后我們的方案就是`Flask`?+?[`Lettuce`](http://lettuce.phodal.com/)?+?`PySerial`。
### 思路
過程大致如下:
* 網頁會在展示文字 + 圖片的時候自動跳轉
* 網頁在需要硬件執行設備的時候,會post一個指令。
* Raspberry Pi在接到指令的時候,由串口發送給Arduino
* Arduino再進行具體的操作。
## 《程序員的情人節禮物》CookBook
上面的xx語言都是瞎扯,你真正需要認真關心的是這本書。
此處省略一百字:

**沒有這個,那就不浪漫了。**
**既然不浪漫,也沒辦法發朋友圈了。**
**既然沒有辦法發朋友圈,就不能愉快地做朋友了。**
(ps:大多時候,一個女孩子可能并不在意你送的禮物是什么,她要的是一份心意,以及一份可以曬的心情)
## 《程序員的情人節禮物》實戰
### Server端
為了方便起見,只好盡可能地簡化代碼,因為簡單我也可以列出所有的代碼:
~~~
import json
import time
from flask import Flask, request
from flask_restful import Resource, Api
import serial
ser = serial.Serial("/dev/ttyACM0", 9600)
app = Flask(__name__, static_url_path='')
app.secret_key = 'why would I tell you my secret key?'
api = Api(app)
tasks = {}
@app.route('/')
def root():
return app.send_static_file('index.html')
class Task(Resource):
@staticmethod
def post(task_id):
tasks[task_id] = request.data
ser.write(request.data)
time.sleep(6)
return tasks[task_id], 201, {'Access-Control-Allow-Origin': '*'}
api.add_resource(Task, '/<string:task_id>')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
~~~
在某些地方上有區別的應該就是
~~~
ser = serial.Serial("/dev/ttyACM0", 9600)
~~~
對于不同的平臺來說,`/dev/ttyACM0`可能是不一樣的。我所做的就是將收到的信息直接發給Arduino。
### Arduino端
代碼也比較簡單有木有:
~~~
#include <IRremote.h>
int starPort = 12;
IRsend irsend;
int fullStar = 1;
int irRemote = 2;
void setup() {
Serial.begin(9600);
pinMode(starPort, OUTPUT);
}
int serialData;
void loop() {
String inString = "";
while (Serial.available()> 0)
{
int inChar = Serial.read();
if (isDigit(inChar)) {
inString += (char)inChar;
}
serialData=inString.toInt();
Serial.print(serialData);
}
if(serialData == fullStar){
digitalWrite(starPort, HIGH);
} else
if( serialData == irRemote){
irsend.sendNEC(0xFF906F,32);
delay(1000);
}
}
~~~
不斷地從串口接收數據,如果為1就點亮所有的star,如果而2就發送紅外。當然,你也可以拿Raspberry Pi做這些事。
### 前臺
詳細代碼可以見:?[https://github.com/phodal/valentine/blob/master/static/js/app.js](https://github.com/phodal/valentine/blob/master/static/js/app.js),這里簡單說一下基本的邏輯。
一個簡單的頁面代碼如下所示:
~~~
var L = new lettuce();
var data = {
rise: "一起看日出",
down: "一起看日落",
yours: "有一天,你出現了",
together: "然后",
rose: "IOU"
};
var rise = function () {
var html = '<div class="rise"><h3>{%=o.rise%}</h3></div>';
var result = L.Template.tmpl(html, data);
document.getElementById("results").innerHTML = result;
};
rise();
~~~
一個post請求,給請求發送給Arduino:
~~~
var L = new lettuce(),
irRemote = "2",
fullStar = "1";
lettuce.post("/serial", fullStar);
~~~
一個Event,用于展示最后的心形:
~~~
L.Event.on("showLove", showLove);
L.Event.trigger("showLove");
~~~
Promise與SetTimeout一起來實現頁面跳轉:
~~~
function show(func, n){
var p = new L.Promise();
var code = function () {
if (func !== undefined) {
func();
L.FX.fadeIn(document.getElementById('results'), {
duration: 3000, complete: function () {
}
});
}
p.done(null, n);
};
setTimeout(code, n);
return p;
}
show(undefined, 3000).then(
function() {
return show(rise, 0)
}
).then(
function() {
return show(down, 3000)
}
)
~~~
### 硬件連接圖
硬件連接圖如下所示:

需要注意的有:
* 用絕緣膠帶把硬件上的各種Led燈遮住
* 確保能啟動。
**注意用電安全**,如果你想用于控制強電,最好找一些有質量保證的設備。
## 其他
網頁版Demo:?[http://valentine.phodal.com/](http://valentine.phodal.com/)?(ps:由于針對的是1920x1080的設備,所以圖片在電腦上的效果可能不是很好,可以試試手機設備觀看。)
Github:?[https://github.com/phodal/valentine](https://github.com/phodal/valentine)(ps: 覺得好的就給個star,不要光fork。)
- 序
- 01.愛它,還是愛我
- 02.去實驗室約會吧
- 03.我真的不是修電腦的
- 04.我的編程養成記
- 05.極客的神邏輯
- 06.我們的戰爭
- 07.和電腦的親密接觸
- 08.邋遢IT民工拯救記
- 09.當情書遇上技術博客
- 10.技術宅不解風情
- 11.和不會聊天的人談戀愛
- 12.不想加班的程序員不是好程序員
- 13.技術宅的網購屬性
- 14.找女朋友難,找工作更難
- 15.極客的文藝情懷
- 16.二十二歲開始的初戀
- 17.當愛情遭遇遠程調試
- 18.基友一生一起走
- 19.夢想還是要有的,萬一實現了呢
- 20.待我代碼編成,娶你為妻可好 (完)
- 番外之一:愛情中的那些碎段子
- 番外之二:程序員如何邂逅真愛之偽攻略篇
- 番外之三:極客男友的情人節禮物大作戰