嗨各位,這個 Blogger 以後不會再有新文章更新。
之後我會改在 Medium 上面發表文章,歡迎各位前往參觀。
網址:
https://medium.com/%E8%B1%AC%E7%AA%A9%E9%83%A8%E8%90%BD%E6%A0%BC
謝謝大家!
2018年1月10日 星期三
2017年1月5日 星期四
「晚餐吃什麼 - 找附近餐廳」 - 我的第一個 Android APP
![]() |
| 「晚餐吃什麼?附近有什麼吃的?」 |
「晚餐吃什麼 - 找附近餐廳」是我的第一個 Android APP。它的目標是為了解決人生最重要的一個疑問:
晚餐到底要吃什麼?
這個 APP 可以在 Google Play 下載,連結為:https://play.google.com/store/apps/details?id=com.pychen0918.wheretoeat
搜尋附近餐廳,隨機選出餐廳
無法決定要吃什麼嗎?這個 APP 可以列出指定距離與類型的附近餐廳,甚至幫你從中隨機挑選一家。選擇餐廳後,可以直接觀看餐廳照片、評價、距離、營業時間及其他基本資訊。還可以開啟地圖進行導航、直接撥號給餐廳詢問或是訂位、或者開啟瀏覽器,連上餐廳網站等,相當方便易用。
無論是出外旅行時,使用這個 APP 尋找當地美食;或是在一成不變的上班族生活中,利用「晚餐吃什麼」在公司附近尋找食物,都可以為你省去煩惱時間。
選擇餐廳類別,快速瀏覽餐廳列表
餐廳類型包含一般餐廳、咖啡簡餐、酒吧夜店等多種選擇。不想出門的話,也可以選擇只尋找擁有外送服務的店家。在餐廳列表中,可以非常快速瀏覽餐廳名稱、類型、評價、距離等資訊,方便進行挑選。
自訂關鍵字搜尋功能、觀看顧客評論
如果沒有適合的類別,也可以選擇自訂關鍵字進行搜尋,它會從餐廳名稱、提供的餐點內容、顧客評論等等資訊,找出相符的店家。如果有想吃的料理種類(例如日式料理、牛排等),或是指定餐廳名稱(例如麥當勞、星巴克等),都可以在這裡搜尋。它還會記錄最近使用過的幾條關鍵字,方便下次使用。
在餐廳詳細資訊中,也可以看到顧客最近的評價與評等,讓你藉此挑選餐廳。
分享餐廳列表與詳細資訊、全球皆可使用
無論在餐廳列表頁面或是餐廳資訊頁面,都有分享按鈕,可以透過 Line、Facebook、Gmail 等等 APP ,將資訊發送給其他人,參與討論。
「晚餐吃什麼」支援中英文介面,同時可以顯示日文、韓文及世界各國文字。由於資料來源是 Google 地圖服務,這個 APP 在世界各地都可以使用。
下載連結、聲明
這個 APP 可以在 Google Play 商店下載,歡迎各位留下評論:
https://play.google.com/store/apps/details?id=com.pychen0918.wheretoeat
「晚餐吃什麼」所使用的圖示來自 www.flaticon.com ,為免費授權。由 Freepik、Madebyoliver、Pixel Buddha、Vectors Market等作者製作。(Icons made by Freepik, Madebyoliver, Pixel Buddha, and Vectors Market from www.flaticon.com)
2016年3月28日 星期一
台灣花季地圖
這份「台灣花季地圖」紀錄了我從網路上收集而來的賞花資訊。包括台灣各地的賞花景點以及它們的花期。希望大家能有機會利用此地圖,安排出外旅遊行程。
本地圖連結為
https://www.google.com/maps/d/viewer?mid=zRgPfb9BIGoE.kpr_bUJzRbC0
地圖上每個標記都是一個賞花景點,不同顏色代表不同的行政區域。點選圖示後會顯示該地點在不同月份盛開的花卉種類等等資訊。
點選左上角的圖示可以進一步開啟地點列表,方便尋找。
電腦版使用者可以利用地圖左下角的 + / - 符號,或是滑鼠滾輪來放大、縮小地圖。在地圖的空白地方按住滑鼠左鍵,可以移動地圖。
點選右上角的方框圖示,或進入本地圖連結
https://www.google.com/maps/d/viewer?mid=zRgPfb9BIGoE.kpr_bUJzRbC0
可以進入全螢幕模式,將有更大的空間瀏覽地圖。
在全螢幕模式中,可以使用搜尋功能(點選列表上端的放大鏡圖示),搜尋想要尋找的地點或是花卉種類等等。
這份地圖的資料來源主要來自於
本地圖連結為
https://www.google.com/maps/d/viewer?mid=zRgPfb9BIGoE.kpr_bUJzRbC0
使用說明
地圖上每個標記都是一個賞花景點,不同顏色代表不同的行政區域。點選圖示後會顯示該地點在不同月份盛開的花卉種類等等資訊。
點選左上角的圖示可以進一步開啟地點列表,方便尋找。
電腦版使用者可以利用地圖左下角的 + / - 符號,或是滑鼠滾輪來放大、縮小地圖。在地圖的空白地方按住滑鼠左鍵,可以移動地圖。
點選右上角的方框圖示,或進入本地圖連結
https://www.google.com/maps/d/viewer?mid=zRgPfb9BIGoE.kpr_bUJzRbC0
可以進入全螢幕模式,將有更大的空間瀏覽地圖。
在全螢幕模式中,可以使用搜尋功能(點選列表上端的放大鏡圖示),搜尋想要尋找的地點或是花卉種類等等。
資料來源
這份地圖的資料來源主要來自於
- 玩台灣賞花 http://www.onetw.com.tw/index.asp
- 初心小格 http://sinea100.pixnet.net/blog
- 林務局全球資訊網 http://www.forest.gov.tw
- 林務局台灣山林悠遊網 http://trail.forest.gov.tw
- 各國家公園管理處網站
- 各旅遊景點官網
- 縣市政府機關網站
更多資料
這份地圖將會不定時更新,並修改、加入更多的賞花資料,歡迎大家經常回來點選觀看。另外,也歡迎大家提供自己知道的賞花景點資訊。
2016年1月31日 星期日
Node.js 的中文與英文髒話過濾
2016年1月6日 星期三
利用 Async.js 平行處理多筆 MongoDB 查詢
在使用 MongoDB 資料庫的時候,我們常常需要同時送出多筆查詢,並在所有資料都讀取完畢後進行下一步動作,例如將資料顯示在網頁上。這篇文章將會簡單介紹利用 Async.js 與 mongoose 達成上述需求的方法與程式碼。
在 javascript 中雖然有著 callback 機制,可以在事件完成後接著執行其他動作。但如果要等待很多事件完成,可能會寫成很多層的 callback:
這種寫法不僅難看,而且由於並非平行處理,在每個 findMoreData 函式中等待 I/O 處理的時間都會累積起來,影響效能。
我們可以使用 Async.js 套件提供的 parallel 方法,來改寫上面的程式碼:
上面的 async.parallel 方法接受一個物件當作參數,裡面包含各個需要平行處理的工作。範例中為了獲得資料 A,我們呼叫了 findMoreData 來處理,而在 findMoreData 等待 I/O 處理的時間中,parallel 會試著繼續處理資料 B 的部分。因此,我們可以平行化的處理這些工作,不用等待前一個完成才接著執行。
程式碼中的 cb 是 Async.js 的一個 callback function。執行後,parallel 就會認為這部分的工作已經完成,而我們要確保每個工作都會呼叫到 cb,整個 parallel 的處理流程才會正常結束。cb 接受兩個參數,第一個是 error 物件(可以為 null),第二個則是我們要的資料,它會存到 results 裡面。
等到獲得所有資料,最後一段的 callback function就會被執行,讓使用者可以處理後續工作。
對於 Async.js 有簡單的認識後,我們正式把 mongoose 讀取資料的 API 整合進來:
這邊用 find 函式來查詢資料庫的資料,並把得到的全部結果原封不動的存放到 results 去。藉由修改 find 的參數,我們也可以在這邊針對不同資料,自訂各項查詢條件。
使用 parallel 可以自訂要同步執行的不同工作,因此有著很大的彈性。但有時候我們所需要的只是針對不同資料執行相同的工作,用 parallel 必須要不斷的重複相同的程式碼(如上例中,不斷重複 find 的動作),看起來有些雜亂。
Async.js 另外提供其他流程控制與資料處理方法,其中一個方法是 each,它可以針對多筆資料平行處理相同的一件工作。例如以下範例,使用 each 來取得資料:
我們輸入一個參數 array,裡面存放不同 MongoDB collection 的名字,async.each 會去讀取這些 collection 名字,再利用 find 找到當中的所有資料,存放到物件變數 results 當中,最後呼叫 cb 結束。
這篇文章簡單介紹 Async.js 裡的 parallel 與 each 兩種方法,並配合 mongoose 來達到平行處理多筆 MongoDB 查詢的方法。
| Copyright jaketrent.com |
Async.js 簡介
在 javascript 中雖然有著 callback 機制,可以在事件完成後接著執行其他動作。但如果要等待很多事件完成,可能會寫成很多層的 callback:
1 2 3 4 5 6 7 8 9 10 11 12 13 | var findData = function(input, callback){ var data = new Data; findMoreData(inputA, function(dataA){ data.add(dataA); findMoreData(inputB, function(dataB){ data.add(dataB); findMoreData(inputC, function(dataC){ ... }); }); }); callback(data); } |
這種寫法不僅難看,而且由於並非平行處理,在每個 findMoreData 函式中等待 I/O 處理的時間都會累積起來,影響效能。
我們可以使用 Async.js 套件提供的 parallel 方法,來改寫上面的程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | var async = require('async'); var findData = function(input, callback){ async.parallel({ A: function(cb){ findMoreData(inputA, function(dataA){ cb(null, dataA); }); }, B: function(cb){ findMoreData(inputB, function(dataB){ cb(null, dataB); }); }, ... }, // 這裡是 async.parallel 的 callback function function(err, results) { // 在這裡 results 的內容是個物件:{A: dataA, B: dataB, ...} callback(results); }); } |
上面的 async.parallel 方法接受一個物件當作參數,裡面包含各個需要平行處理的工作。範例中為了獲得資料 A,我們呼叫了 findMoreData 來處理,而在 findMoreData 等待 I/O 處理的時間中,parallel 會試著繼續處理資料 B 的部分。因此,我們可以平行化的處理這些工作,不用等待前一個完成才接著執行。
程式碼中的 cb 是 Async.js 的一個 callback function。執行後,parallel 就會認為這部分的工作已經完成,而我們要確保每個工作都會呼叫到 cb,整個 parallel 的處理流程才會正常結束。cb 接受兩個參數,第一個是 error 物件(可以為 null),第二個則是我們要的資料,它會存到 results 裡面。
等到獲得所有資料,最後一段的 callback function就會被執行,讓使用者可以處理後續工作。
parallel 與 Mongoose 的整合
對於 Async.js 有簡單的認識後,我們正式把 mongoose 讀取資料的 API 整合進來:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | var async = require('async'); var mongoose = require('mongoose'); var Schema = mongoose.Schema; var dataASchema = new Schema({...}); var dataAModel = mongoose.model('dataA', dataASchema); ... var findData = function(callback){ async.parallel({ A: function(cb){ dataAModel.find({}, function(err, data, count){ cb(null, data); }); }, B: function(cb){ dataBModel.find({}, function(err, data, count){ cb(null, data); }); }, ... }, function(err, results) { callback(results); }); } |
這邊用 find 函式來查詢資料庫的資料,並把得到的全部結果原封不動的存放到 results 去。藉由修改 find 的參數,我們也可以在這邊針對不同資料,自訂各項查詢條件。
改用 each 取得資料
使用 parallel 可以自訂要同步執行的不同工作,因此有著很大的彈性。但有時候我們所需要的只是針對不同資料執行相同的工作,用 parallel 必須要不斷的重複相同的程式碼(如上例中,不斷重複 find 的動作),看起來有些雜亂。
Async.js 另外提供其他流程控制與資料處理方法,其中一個方法是 each,它可以針對多筆資料平行處理相同的一件工作。例如以下範例,使用 each 來取得資料:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | var findData = function(array, callback){ var results = {}; async.each(array, function(item, cb){ var model = mongoose.model(item); model.find({},function(err, data, count){ results[item] = data; cb(); }); }, function(err){ callback(results); }); } findData(['dataA', 'dataB'], function(results){ // results 物件的內容為 {'dataA': ... , 'dataB': ...} // 省略部分為資料庫中的資料 }); |
我們輸入一個參數 array,裡面存放不同 MongoDB collection 的名字,async.each 會去讀取這些 collection 名字,再利用 find 找到當中的所有資料,存放到物件變數 results 當中,最後呼叫 cb 結束。
結論
這篇文章簡單介紹 Async.js 裡的 parallel 與 each 兩種方法,並配合 mongoose 來達到平行處理多筆 MongoDB 查詢的方法。
2015年10月21日 星期三
在 Raspberry Pi 上使用和測試 XBee
這篇文章介紹把 XBee module 裝到 Raspberry Pi 上面的方法,並且使用 PC 上的 XCTU 軟體與 Node.js 測試它的連線。
下面是我們所需要的硬體材料:
在這裡我用的是Arduino XBee shield。把它如下圖的方式插好,接上電腦。注意有個開關會控制XBee的資料輸出,記得把它扳到USB那端去。
另外,為了不讓 Arduino 裡的程式碼干擾 XBee 運作,請先燒錄 BareMinimum 範例程式,或是任何不會使用 serial console 輸出的程式碼。
到 Digi International 的官方網站去,下載 XCTU 這套軟體。它有兩種版本,一個是較新的6.x.x版,有著比較漂亮好操作的介面,另一種是舊版的5.2.8.6。我們底下的說明以新版的6.2.0為主,而網路上有多數教學資源是使用舊版本。
打開 XCTU,點選主畫面左上的按鈕,新增 XBee Module。
如果你的模組有正確連接上 PC,它應該會以 COM port 的方式出現在列表中。點選正確的 COM port 後,按下 "Finish" 讓軟體連線。
順利連線後,可以在主畫面左側看到它。點選它會開始讀取它的出廠設定。我們可以在畫面右端看到許多設定,首先請特別注意下面幾個選項:
Raspberry Pi B+的接線方式如下圖,也就是分別是把XBee module的3.3V電源、Tx、Rx與Ground接到Raspberry Pi的對應腳位。如果你用的是不同的板子,請注意更換到對應的針腳。
另外,在 Raspbian 中,UART Tx/Rx 腳位預設是給 serial console 使用。我們要改接 XBee 的話,需要做出一些對應的修改。
首先編輯 /boot/cmdline.txt 檔案,把所有 ttyAMA0 相關的字眼都移除。最後檔案內容看起來會像這個樣子。
然後停用 tty console:
如果有在 /etc/initab 設定過 tty console,也記得拿掉任何會占用到 ttyAMA0 的服務。
我們會進行兩種測試,一種是測試雙方連線的訊號強度,另一種則是進行訊息的收發。
首先我們回到 XCTU,找到目前與PC連線中的裝置,再點旁邊的藍色小按鈕,軟體會自動搜尋網路上的其他節點。當全部跑完後,選擇我們要連線的對象,按下 "Add selected devices" 按鈕。
完成後,再到畫面上方點選工具箱按鈕,選擇 "Range Test"。
在下一個畫面中,分別在左側點選目前連線到 PC 的 Module,再到右側點選我們早先搜尋到的其他 Module。下面有些測試項目可以調整。我們使用 "Cluster ID 0x12" 這個測試方式。它會送出一串帶有 0x12 這個特殊 Cluster ID 的封包。收到這個 ID 封包的裝置,會將其收到的內容原封不動的送回。
最後,按下 "Start Range Test" 開始測試。畫面會顯示封包的丟失率,以及 RSSI 值等等。能成功跑完此測試代表我們的兩片裝置都能正常運作,連接的線路也都正確。
我們接著在 Raspberry Pi 上面撰寫 Node.js 程式,用來收發封包。目標是在 XCTU 上收到 Raspberry 送過來的 XBee 封包,同時在 XCTU 也可以送出封包給 Raspberry Pi。
首先在 XCTU 上開啟 console 模式。點選右上角的電腦終端機符號,並在主畫面點選連線的符號。XCTU 就會跟 XBee module 建立終端機連線。

接著到 Raspberry Pi 這邊,先透過 NPM 安裝兩個必要套件:
如果安裝過程中出了錯誤,通常都是套件庫裡面沒有適合目前平台與 Node.js 版本的套件。請試著參考這篇,安裝新版的 npm 與 Node.js。
接著開啟任何你喜歡的文字編輯器,輸入下面這段程式碼:
回到主畫面後,按下 Send Packet 欄位的小加號按鈕,切換到 HEX 模式後,貼上我們剛剛複製的內容。完成後,按下 Add Packet 離開。
回到 Raspberry Pi 上,它會將我們剛剛送出的訊息顯示出來,大功告成!
xbee-api on NPM, by jouz
https://www.npmjs.com/package/xbee-api
"Connecting XBee to Raspberry Pi", by Sony Arouje
硬體材料
- 兩片 XBee module,請務必使用相同規格。
- 四條杜邦線,母對母佳。
- 一台樹莓派
- 任何一種可以把 XBee module 連接上電腦的方法與材料。例如使用 SparkFun XBee Explorer,或是 Arduino XBee shield。
PC端設定
在這裡我用的是Arduino XBee shield。把它如下圖的方式插好,接上電腦。注意有個開關會控制XBee的資料輸出,記得把它扳到USB那端去。
另外,為了不讓 Arduino 裡的程式碼干擾 XBee 運作,請先燒錄 BareMinimum 範例程式,或是任何不會使用 serial console 輸出的程式碼。
測試軟體與模組設定
到 Digi International 的官方網站去,下載 XCTU 這套軟體。它有兩種版本,一個是較新的6.x.x版,有著比較漂亮好操作的介面,另一種是舊版的5.2.8.6。我們底下的說明以新版的6.2.0為主,而網路上有多數教學資源是使用舊版本。
打開 XCTU,點選主畫面左上的按鈕,新增 XBee Module。
如果你的模組有正確連接上 PC,它應該會以 COM port 的方式出現在列表中。點選正確的 COM port 後,按下 "Finish" 讓軟體連線。
順利連線後,可以在主畫面左側看到它。點選它會開始讀取它的出廠設定。我們可以在畫面右端看到許多設定,首先請特別注意下面幾個選項:
- CH (Operating Channel):這是指 XBee module 的工作頻道。注意 XBee - 或者說 ZigBee/802.15.4 - 使用的是 2.4GHz,會跟 Wi-Fi / 802.11 衝突。如果環境中有 Wi-Fi 訊號,請改用不同頻道或是避開它。更多資訊請參考這裡。
- ID (Network ID):要互相通訊的XBee module,必須把此值都設定為相同。每個XBee module只會接收、轉發跟自己相同ID的訊息。
- CE (Routing/Messaging Mode):在 ZigBee 的網路中,每個節點都會是 Coordinator、Router 或 End Device 其中之一。在這邊我們可以把 Module 都設定成 Router 以方便測試。
- DH/DL (Destination Address):要通訊的端點位址。在單純一對一的通訊中,可以把此欄位設定為對端的 SH/DL (Source Address)值,雙方會以 unicast 的方式互通。如果把 DH 設定為 0,DL 設定為 FFFF,則封包會以廣播方式發送。在這邊我們把兩片 Module 都設定為廣播。
- NI (Node Identifier):給 XBee module 取個名稱,方便辨識。
設定完成後,按下上方的鉛筆圖案,將設定寫入 XBee module。記得兩片 Module 必須要擁有相同的 CH、ID 值,並且要有適當的 DH/DL。
樹莓派端的準備工作
Raspberry Pi B+的接線方式如下圖,也就是分別是把XBee module的3.3V電源、Tx、Rx與Ground接到Raspberry Pi的對應腳位。如果你用的是不同的板子,請注意更換到對應的針腳。
| Copyright https://dzone.com/articles/connecting-xbee-raspberry-pi |
另外,在 Raspbian 中,UART Tx/Rx 腳位預設是給 serial console 使用。我們要改接 XBee 的話,需要做出一些對應的修改。
首先編輯 /boot/cmdline.txt 檔案,把所有 ttyAMA0 相關的字眼都移除。最後檔案內容看起來會像這個樣子。
dwc_otg.lpm_enable=0 console=115200 console=tty1 root=/dev/mmcblk0p6 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
然後停用 tty console:
sudo systemctl stop serial-getty@ttyAMA0.service
sudo systemctl disable serial-getty@ttyAMA0.service
如果有在 /etc/initab 設定過 tty console,也記得拿掉任何會占用到 ttyAMA0 的服務。
連線測試
我們會進行兩種測試,一種是測試雙方連線的訊號強度,另一種則是進行訊息的收發。
訊號強度測試
首先我們回到 XCTU,找到目前與PC連線中的裝置,再點旁邊的藍色小按鈕,軟體會自動搜尋網路上的其他節點。當全部跑完後,選擇我們要連線的對象,按下 "Add selected devices" 按鈕。
完成後,再到畫面上方點選工具箱按鈕,選擇 "Range Test"。
在下一個畫面中,分別在左側點選目前連線到 PC 的 Module,再到右側點選我們早先搜尋到的其他 Module。下面有些測試項目可以調整。我們使用 "Cluster ID 0x12" 這個測試方式。它會送出一串帶有 0x12 這個特殊 Cluster ID 的封包。收到這個 ID 封包的裝置,會將其收到的內容原封不動的送回。
最後,按下 "Start Range Test" 開始測試。畫面會顯示封包的丟失率,以及 RSSI 值等等。能成功跑完此測試代表我們的兩片裝置都能正常運作,連接的線路也都正確。
封包收發測試
我們接著在 Raspberry Pi 上面撰寫 Node.js 程式,用來收發封包。目標是在 XCTU 上收到 Raspberry 送過來的 XBee 封包,同時在 XCTU 也可以送出封包給 Raspberry Pi。
首先在 XCTU 上開啟 console 模式。點選右上角的電腦終端機符號,並在主畫面點選連線的符號。XCTU 就會跟 XBee module 建立終端機連線。

接著到 Raspberry Pi 這邊,先透過 NPM 安裝兩個必要套件:
npm install xbee-api serialport
如果安裝過程中出了錯誤,通常都是套件庫裡面沒有適合目前平台與 Node.js 版本的套件。請試著參考這篇,安裝新版的 npm 與 Node.js。
接著開啟任何你喜歡的文字編輯器,輸入下面這段程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | var util = require('util'); var SerialPort = require('serialport').SerialPort; var xbee_api = require('xbee-api'); var C = xbee_api.constants; var xbeeAPI = new xbee_api.XBeeAPI({ api_mode: 1 }); var serialport = new SerialPort("/dev/ttyAMA0", { baudrate: 9600, parser: xbeeAPI.rawParser() }); serialport.on("open", function () { var frame_obj = { type: 0x10, id: 0x01, destination64: "000000000000ffff", broadcastRadius: 0x00, options: 0x00, data: "Hello world" }; serialport.write(xbeeAPI.buildFrame(frame_obj)); console.log('Sent to serial port.'); }); serialport.on('data', function (data) { console.log('data received: ' + data); }); // All frames parsed by the XBee will be emitted here xbeeAPI.on("frame_object", function (frame) { console.log(">>", frame); }); |
此程式會以廣播方式,送出一個包含 "Hello World" 字串的封包,接著等待任何進來的封包,並在螢幕上顯示出來。我們直接以 node 指令執行這段程式碼。
回到 XCTU,應該可以看到以紅字顯示的訊息,這就是我們剛剛送來的封包。可以將整段封包內容全選複製起來,然後使用工具箱內的 "Frames Interpreter" 來檢視它的內容。
接著我們要產生封包送回去。打開工具箱內的 "Frames Generator" 工具。注意裡面要調整的參數:
回到 XCTU,應該可以看到以紅字顯示的訊息,這就是我們剛剛送來的封包。可以將整段封包內容全選複製起來,然後使用工具箱內的 "Frames Interpreter" 來檢視它的內容。
- Mode:選擇 API 1,我們上面的 Node.js 程式碼預期收到 API 1 格式的封包。
- Frame Type:請選擇 "0x10 - Transmit Request"。
- 64-bit dest. ID:請輸入000000000000FFFF,也就是廣播位址。
- RF data:在ASCII這邊輸入你想要夾帶的訊息。
完成後,按下 "Copy Frame" 按鈕,將整個封包複製起來,再按下 Close 離開。
回到主畫面後,按下 Send Packet 欄位的小加號按鈕,切換到 HEX 模式後,貼上我們剛剛複製的內容。完成後,按下 Add Packet 離開。
最後一步了,在主畫面選擇我們剛剛建好的新封包,按下右側的 "Send selected packet" 按鈕。主畫面上會以藍字顯示我們剛剛丟出去的訊息。
回到 Raspberry Pi 上,它會將我們剛剛送出的訊息顯示出來,大功告成!
結論
這篇文章紀錄了我在 Raspberry Pi 上使用和測試 XBee module 的過程,包括一開始的接線到作業系統上的調整。同時也列出了使用 PC 軟體 XCTU 對兩片 XBee module 進行測試與設定的方法及步驟。我們除了可以使用 XCTU 內建的工具測試訊號強度以外,還可以使用文中附上的 Node.js 程式碼,測試封包發送與接收的能力。
參考資料
xbee-api on NPM, by jouz
https://www.npmjs.com/package/xbee-api
"Connecting XBee to Raspberry Pi", by Sony Arouje
https://dzone.com/articles/connecting-xbee-raspberry-pi
"XBee 模組通訊實驗", by 網昱多媒體
"XBEE S1 – Sending Remote AT commands using API packet to toggle an I/O", by alselectro"XBee 模組通訊實驗", by 網昱多媒體
https://alselectro.wordpress.com/2014/07/01/xbee-s1-sending-remote-at-commands-using-api-packet-to-toggle-an-io/
"XBee/XBee-PRO® DigiMesh 2.4 User Guide", by Digi International
https://www.google.com.tw/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CB0QFjAAahUKEwiSxfmT9NPIAhVINJQKHejfAKA&url=https%3A%2F%2Fwww.digi.com%2Fsupport%2Fgetassetfile%3Ffn%3D90000991%26tp%3D3&usg=AFQjCNEhKsuFPG4Plie433O4N4szT5S7ew&sig2=KNkn8zcuM9RQec9Bgt-4ig
https://www.google.com.tw/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CB0QFjAAahUKEwiSxfmT9NPIAhVINJQKHejfAKA&url=https%3A%2F%2Fwww.digi.com%2Fsupport%2Fgetassetfile%3Ffn%3D90000991%26tp%3D3&usg=AFQjCNEhKsuFPG4Plie433O4N4szT5S7ew&sig2=KNkn8zcuM9RQec9Bgt-4ig
2015年10月15日 星期四
在Raspberry Pi上面安裝Node.js與MongoDB
這文章簡單記錄在Raspbian上面安裝Node.js與MongoDB的方式。
Raspbian套件庫裡面的Node.js版本很舊,大約是0.10.x,無法符合許多新套件的需求。網路上可以找到很多安裝方式,但他們大多不可行。下面我只列出一個最簡單有用的方法。
Node.js
Raspbian套件庫裡面的Node.js版本很舊,大約是0.10.x,無法符合許多新套件的需求。網路上可以找到很多安裝方式,但他們大多不可行。下面我只列出一個最簡單有用的方法。
wget http://node-arm.herokuapp.com/node_latest_armhf.deb
sudo dpkg -i node_latest_armhf.deb
這兩行指令會從node-arm.herokuapp.com這個網站下載打包好,供ARM使用的deb檔案,再用dpkg安裝它。
node的版本是4.0.0,npm版本是2.14.2。
MongoDB
官方沒有提供給ARM使用的版本,所以我們可以自己下載原始碼進行編譯,或是下載別人編譯好的檔案。
我們可以在這裡找到一個事先編譯好的版本:
https://github.com/brice-morin/ArduPi
直接使用mongodb-rpi/bin裡面的檔案即可。比較完整的指令為:
svn co https://github.com/brice-morin/ArduPi/tree/trunk/mongodb-rpi
sudo cp -r mongodb-rpi/mongo/ /opt/
sudo ln -s /opt/mongo/bin/* /usr/local/bin/
這幾行指令會先用svn下載我們要的檔案,把MongoDB的執行檔都安裝到/opt下面,再建立symbolic link,方便我們存取。
mongo的版本是2.1.1。
總結
網路上有很多在Raspbian安裝這兩樣東西的文章,但多數無法成功運作。在這邊把一個在我的板子上(Raspberry Pi B+)可以運作的方式記錄下來,供有需要的人參考。
(2016/3/16補充:關於 Node.js 在樹莓派上面的安裝方式,可以參考 http://swf.com.tw/?p=836 這篇文章,有許多詳細資訊。安裝 MongoDB 的方式,可以參考 http://swf.com.tw/?p=833)
(2016/3/16補充:關於 Node.js 在樹莓派上面的安裝方式,可以參考 http://swf.com.tw/?p=836 這篇文章,有許多詳細資訊。安裝 MongoDB 的方式,可以參考 http://swf.com.tw/?p=833)
2015年9月14日 星期一
快速建立與開放本地HTTP伺服器至網際網路
這篇文章簡單敘述如何使用node.js的http-server套件與ngrok,快速在本地端建立HTTP伺服器並公開至網際網路。
![]() |
| Copyright ngrok.com |
快速建立HTTP伺服器
在開發網站的過程中我們經常需要建立HTTP伺服器進行測試。雖然在Linux上有很多HTTP伺服器套件可用,但他們大多需要相當繁複的設定。當只是在本地端進行初步開發之時,我們其實可以使用下面介紹的http-server,快速建立本地端伺服器。
我們先在本地端寫一個簡單的index.html網頁:
接著透過npm取得http-server套件
npm install -g http-server
安裝完後,在index.html的目錄下執行http-server
預設情況下,它會抓取當前目錄下的網頁,並在port 8080上建立伺服器。此時可用本地瀏覽器連到http://localhost:8080看看是否已經正確執行。
將本地伺服器開放到網際網路
在協同開發過程可能還會需要將此網站提供給他人使用,此時我們可以利用ngrok將本地網站開放到網路上。
首先先去ngrok的官方網站下載軟體。在這裡以Linux為例,將下載下來的zip檔解壓後,透過下面的指令執行:
./ngrok http 8080
這個指令會將本地port 8080的HTTP伺服器開放出去。執行後可以看到這個畫面:
其他人就可以透過圖中的這個網址連線到這台伺服器。
注意這個網域名稱是會改變的,也就是每次重新使用ngrok時都會產生不同的名稱。如果有固定域名的需求,可以利用ngrok的付費服務達成。
TL;DR:
npm install -g http-server
http-server ./
ngrok http 8080
透過http-server與ngrok,只要簡單的幾個指令,不需要繁複的設定就可以建立起HTTP伺服器,很適合開發階段使用
http-server套件的網頁,可以在這裡看更詳細的使用方式:
ngrok的官方網站:
2015年9月11日 星期五
遊戲中的二項式分佈
遊戲裡面常常有成功率這個東西,像是成功強化武器的機率、某個技能附加能力的發動機率、抽中稀有卡片的機率等等。大多時候,單看這個數字並沒有甚麼意思,我們反而比較會在意,到底在我成功以前我要失敗幾次、投入多少資源?
以抽卡來說好了,假設抽一次有5%的機率會成功抽中稀有卡片,除此之外抽中非稀有卡片都算是失敗,而且每次抽卡結果都是獨立事件。那到底要連抽幾次,才能有50%以上的機會可以抽中一張稀有卡?
這種情況就可以套用二項式分佈。二項式分佈的一般性公式我們可以寫成:

其中,k代表目標成功次數,n代表測試總數,p代表單次測試的成功機率。
回到抽卡的例子,我如果要計算出,在 10 次測試裡面,抽中 0 張稀有卡的機率,其中單一抽抽中稀有卡的機率為 5% ,那麼套進去計算:

答案大約為59.9%,也就是有接近六成的機會,10 抽抽不到稀有卡。
那要怎麼計算至少一張的機率?很簡單,排除掉完全抽不到稀有卡的情況以後,剩下來的情況就代表有抽中至少一張。所以在這裡,有1 - 59.9% = 40.1%的機率會抽到至少一張。
到這邊其實可以用Excel的 BINOMDIST 公式來幫我們計算。BINOMIDIST分別接受四個參數,其中前三個參數分別是k, n, p。第四個參數改變此函數的行為,如果為 0 ,表示計算正好為 k 次成功的機率;如果為 1 ,表示計算最多有 k 次成功的機率。
正確的成功率公式如上圖,紅圈圈起來的那格。
藉由Excel的功能,我們可以很輕鬆的增加 n 值,觀察在不同測試次數下的中獎機會。回到前面抽卡的例子,我們可以看出,在14次抽獎以後,抽中至少一張稀有卡的機率會提升到50%以上。
知道了達成50%成功率的最小 n 值後,我們可以用它來估計所需要投入的資源成本,不管是虛擬貨幣還是新台幣,從而與得到的回報相比,判斷是否需要把珍貴的資源投入進去。
雖然我這裡以遊戲為例子,但這個計算可以套用到生活中的許多例子,希望供大家參考利用。
關於二項式分佈,可以參考以下網頁:
https://zh.wikipedia.org/wiki/%E4%BA%8C%E9%A0%85%E5%88%86%E4%BD%88
http://dufu.math.ncu.edu.tw/calculus/calculus_eng/node222.html
到底要嘗試幾次,在這其中至少有一次成功的機率才可以提升到50%以上?
以抽卡來說好了,假設抽一次有5%的機率會成功抽中稀有卡片,除此之外抽中非稀有卡片都算是失敗,而且每次抽卡結果都是獨立事件。那到底要連抽幾次,才能有50%以上的機會可以抽中一張稀有卡?
這種情況就可以套用二項式分佈。二項式分佈的一般性公式我們可以寫成:

其中,k代表目標成功次數,n代表測試總數,p代表單次測試的成功機率。
回到抽卡的例子,我如果要計算出,在 10 次測試裡面,抽中 0 張稀有卡的機率,其中單一抽抽中稀有卡的機率為 5% ,那麼套進去計算:

答案大約為59.9%,也就是有接近六成的機會,10 抽抽不到稀有卡。
那要怎麼計算至少一張的機率?很簡單,排除掉完全抽不到稀有卡的情況以後,剩下來的情況就代表有抽中至少一張。所以在這裡,有1 - 59.9% = 40.1%的機率會抽到至少一張。
用Excel列表
到這邊其實可以用Excel的 BINOMDIST 公式來幫我們計算。BINOMIDIST分別接受四個參數,其中前三個參數分別是k, n, p。第四個參數改變此函數的行為,如果為 0 ,表示計算正好為 k 次成功的機率;如果為 1 ,表示計算最多有 k 次成功的機率。
藉由Excel的功能,我們可以很輕鬆的增加 n 值,觀察在不同測試次數下的中獎機會。回到前面抽卡的例子,我們可以看出,在14次抽獎以後,抽中至少一張稀有卡的機率會提升到50%以上。
算這個要幹嘛?
知道了達成50%成功率的最小 n 值後,我們可以用它來估計所需要投入的資源成本,不管是虛擬貨幣還是新台幣,從而與得到的回報相比,判斷是否需要把珍貴的資源投入進去。
雖然我這裡以遊戲為例子,但這個計算可以套用到生活中的許多例子,希望供大家參考利用。
關於二項式分佈,可以參考以下網頁:
https://zh.wikipedia.org/wiki/%E4%BA%8C%E9%A0%85%E5%88%86%E4%BD%88
http://dufu.math.ncu.edu.tw/calculus/calculus_eng/node222.html
在Blogger新增Paypal捐贈按鈕
國外有些軟體作者會在個人網頁上面放上一個Paypal的捐贈按鈕,讓支持者可以自由選擇金額捐贈給作者。網路上可以找到一些教學:
如果你跟我一樣是個新手,大概會遇到一個"資料與輸入的字元集或預設編碼不符。欲知更多資料,請聯絡商店。"的錯誤訊息。這邊有個網頁提供了解決方法:
http://wordpress.bestdaylong.com/blog/archives/6751
以上是我新增這個按鈕的小記錄,各位可以在右上角看到這個按鈕。但這篇文章發表之時,Paypal才剛宣布要在2015年9月21日之後,關閉台灣帳號之間的買賣交易。我想這個按鈕暫時只能拿來當作裝飾,等待Paypal重新開放交易吧。
不過,在Blogger這裡可以透過POWr提供的第三方小工具來嵌入捐贈按鈕,可以自訂外觀等等,相當方便。首先進入到Blogger的管理後台,選擇"版面配置",並在想要的位置按下"新增小工具"。
之後會跳出提示視窗,提醒你到網誌版面上直接點選編輯按鈕去修改它。不過我們可以先在這個提示視窗中,修改按鈕的標題與高度。這邊建議把高度改成約120px。
按下儲存離開,按鈕就會出現在網誌頁面上。我們接著要點選右上角的齒輪圖案去修改它。
第一步是輸入Paypal帳號。
第二步是可以自訂關於此按鈕的相關資訊,首先打開Product Info頁面,將付款類別改為Donation,並自訂其他內容。你可以自訂想要的捐款金額和貨幣,或者決定是否允許使用者自訂金額和商品數量。Button Text則是要顯示在按鈕上的文字。
第三步的Design可以修改此按鈕的顏色等等外觀設定,直接保留預設設定就好。
第四步是建議你註冊POWr帳號以取得更多外掛,可以自行決定要不要註冊。最後按下面的Save,儲存設定並離開。
恭喜,你的Blogger上有了這個捐贈按鈕。你可以試著點選它看看會發生甚麼事。
http://wordpress.bestdaylong.com/blog/archives/6751
以上是我新增這個按鈕的小記錄,各位可以在右上角看到這個按鈕。但這篇文章發表之時,Paypal才剛宣布要在2015年9月21日之後,關閉台灣帳號之間的買賣交易。我想這個按鈕暫時只能拿來當作裝飾,等待Paypal重新開放交易吧。
關於Paypal停止台灣帳號之間的交易新聞,可以看這邊
2015年8月27日 星期四
第一個Pebble App - Where to Eat?
我的第一個Pebble App - Where to Eat 終於在昨天上架了。這個App的目標是為了解決人生中最重要的一個疑問:
晚餐到底要吃什麼?
更方便的是,它還可以從中自動幫你挑選一家,省去你下決定的時間。
方便的過濾條件
你可以在手錶上設定要尋找的範圍(最遠可以到以你為中心的10公里距離)、要尋找的餐廳類型,以及是否限定當下正在營業中的店家。這樣能更快為你找到適合的店家。
支援多種語言及多種平台
目前此App介面支援正體中文、簡體中文和英文。另外它支援Pebble、Pebble Steel和Pebble Time等目前市面上的Pebble手錶平台。同樣它也可以顯示彩色。
下載連結
可以在Pebble的App Store裡面找到它。目前分類是在Tools & Utilities底下。
App Store的連結:
https://apps.getpebble.com/applications/55dd6d104374cb930300000d
本App為Open Source,可以在GitHub上找到它:
https://github.com/pychen0918/pebble-where-to-eat
歡迎大家給予批評與指教,謝謝!
訂閱:
文章 (Atom)



































