tag:blogger.com,1999:blog-85160576460058066832024-03-06T16:25:23.998+08:00Cooper Maa一家烤肉萬家香,開放分享才會快樂Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.comBlogger353125tag:blogger.com,1999:blog-8516057646005806683.post-58013226976240351682013-11-04T21:54:00.001+08:002015-01-29T09:49:56.835+08:00Introduction to Corona SDK 簡報上線九月初玩了一下 Corona SDK,當時整理了一份筆記,筆記簡報檔現在已經放到線上,與君分享,希望對有需要的人有所幫助。 <p> <iframe style="margin-bottom: 5px; max-width: 100%; border-top: #ccc 1px solid; border-right: #ccc 1px solid; border-bottom: #ccc 1px solid; border-left: #ccc 1px solid" height="355" marginheight="0" src="//www.slideshare.net/slideshow/embed_code/27885186" frameborder="0" width="425" marginwidth="0" scrolling="no" allowfullscreen="allowfullscreen"> </iframe> <div style="margin-bottom: 5px"><strong><a title="Introduction to corona sdk" href="//www.slideshare.net/coopermaa/introduction-to-corona-sdk" target="_blank">Introduction to corona sdk</a> </strong>from <strong><a href="//www.slideshare.net/coopermaa" target="_blank">馬 萬圳</a></strong> </div> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-12214297643400262072013-09-07T22:41:00.001+08:002013-09-10T17:04:45.067+08:00Chart.js: 一個簡單的 JS Chart Library<p><a href="http://www.chartjs.org/">Chart.js</a> 是一個 Open Source 的 JavaScript Chart Library。它一共有 6 種 Chart,全都是 HTML5 based。</p> <p>底下是 Chart.js 所提供的 6 種 Charts:</p> <table cellspacing="0" cellpadding="2" width="400" border="0"><tbody> <tr> <td valign="top" width="200"><strong>Line Chart</strong> <br /> <br /><a href="http://lh3.ggpht.com/-j5OWPNEDJg4/Uis62lbtpfI/AAAAAAAALiE/bSgcPjC6054/s1600-h/image%25255B8%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-0Bryootue_M/Uis63beP_6I/AAAAAAAALiM/CD32pGCpPao/image_thumb%25255B2%25255D.png?imgmax=800" width="422" height="316" /></a> <br /></td> <td valign="top" width="200"><strong>Bar Chart</strong><a href="http://lh5.ggpht.com/-rQoFG7yY--I/Uis64KnVm4I/AAAAAAAALiU/q5-oLXgq5ak/s1600-h/image%25255B11%25255D.png"> <br /><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-2U0q-rIX76o/Uis64uPid9I/AAAAAAAALic/M-DGhIfppLc/image_thumb%25255B3%25255D.png?imgmax=800" width="421" height="318" /></a></td> </tr> <tr> <td valign="top" width="200"><strong>Radar Chart</strong><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_eEfiQ0khyphenhyphenuDLMa8t-PfuqY0vK8N_7rqtD-Pioo9knvISi3eZPGfg-dJvlZyo0rlWEsyzKMujx86iqt78Tzx3U4oZuLKKBFF77cjebN6IcDuKB3_PPcJpZxbq7UJaO-c1TXdslM20HQfT/s1600-h/image%25255B14%25255D.png"> <br /><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh3.ggpht.com/-O49xbyWx7ow/Uis655ZUxlI/AAAAAAAALis/cw5ojhZCvx4/image_thumb%25255B4%25255D.png?imgmax=800" width="361" height="330" /></a></td> <td valign="top" width="200"><strong>Pie Chart</strong><a href="http://lh6.ggpht.com/-fuuxBea9aHw/Uis66fL5RiI/AAAAAAAALi0/Crhk2Hvd54M/s1600-h/image%25255B17%25255D.png"> <br /><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh3.ggpht.com/-fTGDr_mpCmk/Uis66_ncnrI/AAAAAAAALi8/ZGuVTE6yDSg/image_thumb%25255B5%25255D.png?imgmax=800" width="312" height="305" /></a></td> </tr> <tr> <td valign="top" width="200"><strong>Polar Area Chart</strong><a href="http://lh5.ggpht.com/-J5ZjlOfp4ZI/Uis67o5XMJI/AAAAAAAALjE/rAXCnW4Zi60/s1600-h/image%25255B20%25255D.png"> <br /><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh5.ggpht.com/-a136_x0vo6Q/Uis68W3gHEI/AAAAAAAALjM/55vS2MkDiCg/image_thumb%25255B6%25255D.png?imgmax=800" width="304" height="311" /></a></td> <td valign="top" width="200"><strong>Doughnut Chart</strong><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgovHJ-unoAfB6-f1xrO_eO-nSIA0lUg5c5WXI1VLXJ9KHaTDCOIAnw3xo1k5PjDYuS2FmULrxSYPuXPwJ95r79oXbVg4PfLZKibThssVptoFULTZIf5IFnRB9gVwZZKDdkEMGHs3iETLez/s1600-h/image%25255B23%25255D.png"> <br /><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-t-G3ambNsjY/Uis69Y89VYI/AAAAAAAALjc/SNowf8MFUJA/image_thumb%25255B7%25255D.png?imgmax=800" width="318" height="319" /></a></td> </tr> </tbody></table> <h5>快速上手</h5> <p>你可以到 github 下載 Chart.js: <a href="https://github.com/nnnick/Chart.js">https://github.com/nnnick/Chart.js</a>。Chart.js 只需要一個 .js 檔,你可以選擇一般版的 Chart.js,也可以選擇瘦身版的 Chart.min.js。</p> <p>從 github 下載後,在 samples 資料夾就有 6 種 Chart 的範例。比如打開 samples/line.html 後,瀏覽器馬上就會畫出這樣一張 Line Chart:</p> <p><a href="http://lh4.ggpht.com/-6ZwHN4qP3dA/Uis69zWlfEI/AAAAAAAALjk/SbTduCP21tU/s1600-h/image%25255B26%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-B75dcVD0wrU/Uis6-c79LsI/AAAAAAAALjs/YZyOxlD9Hjw/image_thumb%25255B8%25255D.png?imgmax=800" width="588" height="469" /></a></p> <p>line.html 的內容如下 (JavaScript 部份):</p> <p><script type="syntaxhighlighter" class="brush: javascript"><![CDATA[<br /> var lineChartData = {<br /> labels : ["January","February","March","April","May","June","July"],<br /> datasets : [<br /> {<br /> fillColor : "rgba(220,220,220,0.5)",<br /> strokeColor : "rgba(220,220,220,1)",<br /> pointColor : "rgba(220,220,220,1)",<br /> pointStrokeColor : "#fff",<br /> data : [65,59,90,81,56,55,40]<br /> },<br /> {<br /> fillColor : "rgba(151,187,205,0.5)",<br /> strokeColor : "rgba(151,187,205,1)",<br /> pointColor : "rgba(151,187,205,1)",<br /> pointStrokeColor : "#fff",<br /> data : [28,48,40,19,96,27,100]<br /> }<br /> ] <br /> }<br /> <br /> var myLine = new Chart(document.getElementById("canvas").getContext("2d")).Line(lineChartData);<br />]]></script></p> <h5>如何動態增加資料點?</h5> <p>Chart.js 沒有提供動態增加資料點的方法,這實在有點可惜。不過,我花了點時間研究了一下,發現還是有解。我的方法是這樣:在修改 datasets 的內容後,就再呼叫 new Chart() 重新產生 Chart。程式碼範例如下:</p> <p><script type="syntaxhighlighter" class="brush: javascript"><![CDATA[<br /> var lineChartData = {<br /> labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun",<br /> "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],<br /> datasets: [<br /> {<br /> fillColor: "rgba(151,187,205,0.5)",<br /> strokeColor: "rgba(151,187,205,1)",<br /> pointColor: "rgba(151,187,205,1)",<br /> pointStrokeColor: "#fff",<br /> data: [28, 48, 40, 19, 96, 27, 100, 78, 62, 77, 88, 98]<br /> }<br /> ]<br /> };<br /> <br /> var ctx = document.getElementById("canvas").getContext("2d");<br /> var myLine = new Chart(ctx).Line(lineChartData);<br /> <br /> setInterval(function() {<br /> var opts = {<br /> animation: false<br /> };<br /> <br /> lineChartData.datasets[0].data.shift();<br /> rnd = Math.round(Math.random() * 90) + 10;<br /> lineChartData.datasets[0].data.push(rnd);<br /> myLine = new Chart(ctx).Line(lineChartData, opts);<br /> }, 1000);<br />]]></script></p> <p>有一點要特別注意,因為 Chart.js 在畫圖時會有動畫,所以必須把 animation 設成 flase 把動畫關掉。</p> <p>然後就可以動態增加資料點囉:</p> <p><a href="http://lh3.ggpht.com/-hoJPMNGPnZQ/Uis6_CkfftI/AAAAAAAALj0/4r5XGLcLcQY/s1600-h/image%25255B29%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-_Zs3wcBHuvY/Uis6_t7e_VI/AAAAAAAALj8/1J6IlYL9T2I/image_thumb%25255B9%25255D.png?imgmax=800" width="616" height="513" /></a></p> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-90360644407262552932013-09-07T21:09:00.001+08:002013-09-10T17:05:04.333+08:00關閉 Arduino UNO 的 auto reset<p>在某些特殊情況下,你可能需要把 Arduino 的 auto reset 功能關掉。舉個例子,假設 Arduino 正在跑這段讓 LED 恆亮的 code:</p> <p><script type="syntaxhighlighter" class="brush: cpp"><![CDATA[<br />int led = 13;<br /><br />void setup() { <br /> pinMode(led, OUTPUT); <br /> digitalWrite(led, HIGH);<br />}<br /><br />void loop() {<br />}<br />]]></script></p> <p>假如這時用 echo 指令傳資料給 Arduino:</p> <p>    $ echo "Hello" > /dev/ttyACM0</p> <p>你會發現 Arduino 的 LED 會突然閃爍幾下,然後又恢復恆亮。這是因為在開啟 serial port 時會觸發 Arduino 的 auto reset,Arduino 重新開機了,所以 LED 才會閃爍幾下 (開機時 bootloader 叫它閃爍的)。</p> <p>要關閉 Arduino 的 auto reset,方法很簡單。以 UNO 而言,只要在 RESET 跟 GND 針腳之間放個 10uF 的電容就好 (短腳要接 GND):</p> <p><a href="http://lh5.ggpht.com/-D1dd_gFmCAM/UislddDQWsI/AAAAAAAALhA/iP3wRtTB92I/s1600-h/image%25255B2%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-6ioSQ5FvJ8A/UisleXANHDI/AAAAAAAALhI/Bf0Lz2J7sEM/image_thumb.png?imgmax=800" width="522" height="477" /></a></p> <p>其它板子我沒試過。不過,如果接電容的方法無效,據網路上的資料,可以在 5V 跟 RESET 針腳間放個 120 ohm 的電阻 (120 ohm 電阻還真不好找,可能要組合一下才行)。</p> <p><a href="http://lh4.ggpht.com/-vIfKRnMokRg/Uisv8qSWqdI/AAAAAAAALhs/1btWtx2suig/s1600-h/image%25255B3%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh3.ggpht.com/-QCEfeMmgdhY/Uisv9HyfQQI/AAAAAAAALh0/eo8r7p9F528/image_thumb%25255B1%25255D.png?imgmax=800" width="606" height="484" /></a></p> <p>至於 Leonardo 的話就不需要了,因為 Leonardo 的硬體線路跟 UNO 不一樣,不會在 serial port 連線時 reset,所以應該沒這方面的困擾 (<font color="#008080">補充: 當以1200 鮑率開個 serial port 時,Leonardo 就會重置</font>)。</p> <p><strong>參考資料</strong></p> <ul> <li><a href="http://playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection">DisablingAutoResetOnSerialConnection</a> </li> <li><a href="http://yehnan.blogspot.tw/2013/09/arduinoleonardouno.html">葉難: Leonardo與Uno的差異比較</a> </li> </ul> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-42758588786919277512013-09-03T17:05:00.001+08:002013-09-10T17:06:26.630+08:00Facebook 「讚」電子顯示器」Again<p>我把昨天製作的 <a href="http://coopermaa2nd.blogspot.tw/2013/09/facebook.html">Facebook 「讚」電子顯示器</a> (簡稱 fblikes) 做了一些調整,現在 fblikes 比較好安裝,有一個 LuCI 設定介面,而且也可以安排到 OpenWRT 開機時自動執行了。fblikes 現在放在 github 上,repo 路徑是:</p> <blockquote> <p><a href="https://github.com/coopermaa/fblikes">https://github.com/coopermaa/fblikes</a></p> </blockquote> <p>安裝方法在 github 上可以找到。不過,底下還是稍微說明一下:</p> <p><strong>1.</strong> 所需器材: 可跑 OpenWrt 的無線路由器 (我用 TL-WR703N。FWR171-3G 也是可以的)、Arduino,以及 <a href="http://coopermaa2nd.blogspot.tw/2013/09/tm1638-led-display.html">TM1638 LED Display</a>。</p> <p><strong>2.</strong> 連接 Arduino 與 TM1638,上傳 arduino 資料夾裏的 fblikesDemo sketch 到 Arduino 板子上</p> <p><strong>3.</strong> 連接 Arduino 與 OpenWrt。</p> <p><strong>4.</strong> 上傳 install.sh 與 files 整個資料夾到 OpenWrt,輸入以下指令:</p> <p>    $ chmod +x install.sh <br />    $ ./install.sh</p> <p>這個動作會把 fblikes 相關檔案 (Init Script, configuration file, LuCI module, Lua Script 等) 裝到預設的目地的。</p> <p>接著,先確定 OpenWrt 可以連上 Internet,然後輸入以下指令啟動 fblikes:</p> <p>    $ /etc/init.d/fblikes start</p> <p>如果你希望 fblikes 在 Linux 開機時便自動執行,那麼就輸入以下指令:</p> <p>    $ /etc/init.d/fblikes enable</p> <p>底下是一個範例。這是 Fablab Taipei 的<a href="https://www.facebook.com/FablabTPE">粉絲頁</a> (<a title="https://www.facebook.com/FablabTPE" href="https://www.facebook.com/FablabTPE">https://www.facebook.com/FablabTPE</a>):</p> <p><a href="http://lh3.ggpht.com/-8C6ZQNF-HlA/UiWmVIIdXPI/AAAAAAAALfM/4A9xakeq7vY/s1600-h/2013-09-03_16h28_42%25255B6%25255D.png"><img title="2013-09-03_16h28_42" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="2013-09-03_16h28_42" src="http://lh5.ggpht.com/-hRKJEBFpXlM/UiWmVz7odtI/AAAAAAAALfU/9HItHrFY9OA/2013-09-03_16h28_42_thumb%25255B1%25255D.png?imgmax=800" width="846" height="528" /></a></p> <p>這是 Fablab Taipei 的 Facebook 「讚」電子顯示器 (器材是 Arduino + TM1638 LED Display):</p> <p><a href="http://lh3.ggpht.com/-i-M2cpil9k0/UiWmWrTfxUI/AAAAAAAALfc/7_jrz-uqZJE/s1600-h/2013-09-03%25252016.28.36%25255B3%25255D.jpg"><img title="2013-09-03 16.28.36" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="2013-09-03 16.28.36" src="http://lh3.ggpht.com/-g3sCP8ygYro/UiWmXTbEXNI/AAAAAAAALfk/7gCDb9VVJ3U/2013-09-03%25252016.28.36_thumb.jpg?imgmax=800" width="794" height="596" /></a></p> <p>如果你想修改 fblikes 的參數,比如 Facebook 粉絲專頁的 URL (Facebook URL),多久更新一次電子顯示器 (Refresh Interval) 等,只要瀏覽 http://<IP of OpenWrt>/cgi-bin/luci/fblikes 連入 LuCI 設定介面就可以進行操作: </p> <p><a href="http://lh3.ggpht.com/-4Ru4fw5wto4/UiWmXzGaPPI/AAAAAAAALfs/ToxaeZgxVJM/s1600-h/2013-09-03_16h39_22%25255B2%25255D.png"><img title="2013-09-03_16h39_22" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="2013-09-03_16h39_22" src="http://lh3.ggpht.com/-mLi8AvGV8WE/UiWmYa7oRHI/AAAAAAAALf0/uZtbEVz5AEg/2013-09-03_16h39_22_thumb.png?imgmax=800" width="589" height="570" /></a></p> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-70393578162523535572013-09-03T12:32:00.001+08:002013-09-10T17:07:07.901+08:00寫個 OpenWrt Init Scripts<p>在看過 <a href="http://wiki.openwrt.org/doc/techref/initscripts">OpenWrt: Init Scripts</a> 這篇後,我發現 OpenWrt Init Scripts 很簡單。舉個例子,寫個 /etc/init.d/fblikes 如下:</p> <p><script type="syntaxhighlighter" class="brush: shell"><![CDATA[<br />#!/bin/sh /etc/rc.common<br /># Init Script for fblikes<br /># Save this file to /etc/init.d/fblikes<br /><br />START=10<br />STOP=15<br /><br />start() {<br /> fblikes > /dev/null 2>&1 &<br />}<br /><br />stop() {<br /> killall -9 fblikes<br />}<br />]]></script></p> <p><font color="#008080">註:fblikes 是我昨天貼的 <a href="http://coopermaa2nd.blogspot.tw/2013/09/facebook.html">Facebook 「讚」電子顯示器</a></font><font color="#008080"></font><font color="#008080">,我事先已經把 fblikes 存到 /usr/bin/fblikes</font></p> <p>建立 /etc/init.d/fblikes 後,執行 "<code>/etc/init.d/fblikes enable</code>",就會在 /etc/rc.d 裏產生一個 symbolic link。START=10 代表會建立 /etc/rc.d/S10fblikes,10 是指 S10fblikes 的執行順序,在系統開機時數字愈小的 script 會優先執行,OS 會呼叫 script 的 start()。 而 STOP=15 是 optional 的,它會建立 /etc/rc.d/K15fblikes,一樣,15 是指 K15fblikes 的執行順序,在系統關機時數字愈小的 script 會優先執行,OS 會呼叫 script 的 stop()。</p> <p>OpenWrt 每支 Init Script 都有下列指令可以使用:</p> <blockquote> <p><code>/etc/init.d/example <br />/etc/init.d/example enable <br />/etc/init.d/example boot <br />/etc/init.d/example start <br />/etc/init.d/example restart <br />/etc/init.d/example stop <br />/etc/init.d/example disable</code></p> </blockquote> <p>簡單地說,如果你想啟動 fblikes,只管輸入以下指令:</p> <p>    <code>$ /etc/init.d/fblikes start</code></p> <p>如果你要停止 fblikes,只管輸入以下指令:</p> <p>    <code>$ /etc/init.d/fblikes stop</code></p> <p>如果要想讓 fblikes 在開機時自動執行,就輸入以下指令:</p> <p>    <code>$ /etc/init.d/fblikes enable</code></p> <p>反之,不想讓 fblikes 在開機時自動執行,那就用 disable 指令把它取消:</p> <p>    <code>$ /etc/init.d/fblikes disable</code></p> <p>disable 指令會把 /etc/rc.d/S10fblikes 和 /etc/rc.d/K15fblikes 兩個 symbolic links 移除掉。</p> <h5>參考資料:</h5> <ul> <li><a href="http://wiki.openwrt.org/doc/techref/initscripts">OpenWRT: Init Scripts</a> </li> </ul> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-60130810681948825652013-09-02T23:09:00.001+08:002013-09-10T17:08:02.546+08:00Facebook 「讚」電子顯示器<p>有自己的粉絲專頁還不夠酷,Facebook 粉絲專頁上都有個「讚」計數器,如果可以把它搬到實體的電子顯示器上,那才叫酷!</p> <p><a href="http://lh3.ggpht.com/-msMTlTjLz9w/UiSqIvts1LI/AAAAAAAALdQ/3fPe9Qj39Hc/s1600-h/image%25255B8%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-t8-zQnkYbWo/UiSqJ-7eoUI/AAAAAAAALdY/4Z7GYMatFxk/image_thumb%25255B4%25255D.png?imgmax=800" width="800" height="511" /></a></p> <p>江湖一點訣,說穿不值一文錢。要取得 Facebook 頁面「讚」次數,其實很簡單,只要在網址列上輸入:<a href="http://api.facebook.com/restserver.php?method=links.getStats&urls">http://api.facebook.com/restserver.php?method=links.getStats&urls=</a>,然後加上想要看的 Facebook 頁面,就會得到一個像底下這樣的 XML 格式的回應,比如 <a title="http://api.facebook.com/restserver.php?method=links.getStats&urls=https://www.facebook.com/cutespring" href="http://api.facebook.com/restserver.php?method=links.getStats&urls=https://www.facebook.com/cutespring">https://www.facebook.com/cutespring</a> 這個粉絲專頁:</p> <p><a href="http://lh4.ggpht.com/-SOMdHuQlp5g/UiSqKotFcxI/AAAAAAAALdg/H_XRUtwmwlo/s1600-h/image%25255B11%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT4LecsZ1Ty3YwfEqFLxnxtHuRnRZI4tBNGa1bC1QIcAURXVqHVK2WfVR6Iyzi1v1xfxwxkMj_rTqCc3tWNmoYBIL2TZrtob-p1zpadNNgsQZLJM6K7lLDmMc7pcBUquqetlFSQ_TCwELA/?imgmax=800" width="600" height="469" /></a></p> <p>其中 total_count 就是「讚」的次數了。(PS: 按 Facebook <a href="https://developers.facebook.com/docs/reference/fql/link_stat/">這裏</a>的說明,totaol_count 是 like_count + comment_count + share_count 的總合,按道理來說,「讚」次數應該是 like_count 才對,不過咱們不是 Facebook 工程師,沒必要那麼深入)。</p> <p>知道怎麼取得 Facebook 「讚」的數目後,接下來是把它搬電子顯示器上。</p> <p>其實在 Maker Faire Taipei 2013 的工作坊上,<a href="http://ben6.blogspot.tw/">Ben6</a> 就用 OpenWrt + Arduino + <a href="http://coopermaa2nd.blogspot.tw/2013/09/tm1638-led-display.html">TM1638 LED Display</a> 搭配 Bash Shell Script <a href="http://ben6.blogspot.tw/2013/05/maker-faire-2013-facebook-like.html">示範</a>過了。因為想練習 Lua,所以底下我便用 Lua 重新改寫了程式。簡單說明一下步驟:</p> <p><strong>1.</strong> 首先,連接 Arduino 與 TM1638 (本例將 DIO, CLKC, STB1 分別接到 Arduino 的 8, 7, 6 接腳)</p> <p><strong>2.</strong> 到 <a href="https://code.google.com/p/tm1638-library/">https://code.google.com/p/tm1638-library/</a> 下載並安裝 tm1638 library</p> <p><strong>3.</strong> 上傳底下的程式到 Arduino:</p> <p><script type="syntaxhighlighter" class="brush: cpp"><![CDATA[<br />#include <TM1638.h><br />// define a module on data pin 8, clock pin 7 and strobe pin 6<br />TM1638 module(8, 7, 6);<br /><br />static unsigned long num = 0;<br />static unsigned long display_num = 0;<br /><br />void setup() {<br /> Serial.begin(57600);<br /> // Display number 1 with no dots set and no leading zeros <br /> module.setDisplayToDecNumber(1, 0, false); <br />}<br /><br />void loop() {<br /> if (Serial.available()) {<br /> int ch = Serial.read();<br /> if (ch >= '0' && ch <= '9') num = num * 10 + (ch - 0x30);<br /> if (ch == '.') {<br /> display_num = (num < 100000000) ? num : num % 100000000;<br /> module.setDisplayToDecNumber(display_num, 0, false); <br /> num = 0; <br /> }<br /> } <br />}<br />]]></script></p> <p>程式說明:</p> <ul> <li>使用 TM1638 module(8, 7, 6) 定義 TM1638 物件,DIO 接在 pin 8, CLK 接在 pin 7, STB1 接在 pin 6 </li> <li>使用 module.setDisplayToDecNumber(1, 0, false) 讓 LED Display 一開始顯示數字 1,第二和第三個參數的意思是不要顯示小數點也不要 Leading Zero。 </li> <li>在 Loop() 函式中,不斷讀取輸入的數值,小數點 '.' 字元代表封包結束,所以遇到小數點時便把收到的「讚」數目搬到 TM1638 顯示器上 </li> </ul> <p><strong>4.</strong> 把底下的 Lua script 存檔為 fblikes.lua,傳到 OpenWrt 上並改為可執行:</p> <p><script type="syntaxhighlighter" class="brush: python"><![CDATA[<br />#!/usr/bin/lua<br />require 'nixio'<br />require 'luci.util'<br /><br />-- 臉書讚數目專頁<br />source_url="https://www.facebook.com/cutespring"<br /><br />local serialPort = "/dev/ttyACM0"<br />local baud_rate = 57600<br />local sleepInterval = 5 -- in seconds<br />local DEBUG = 1<br /><br />url = "http://api.facebook.com/restserver.php?method=links.getStats&urls=" .. source_url<br />cmd = "wget -qO - '" .. url .. "' | grep total_count"<br /><br />function get_fblikes()<br /> -- output 會是 " <total_count>44830</total_count>" 之類的字串<br /> output = luci.util.exec(cmd)<br /> likes = string.match(output, "%d+") -- 取出字串中的數字<br /> return likes<br />end<br /><br />-- Open Serial Port<br />local cmd = string.format("stty -F %s cs8 %s ignbrk -brkint -icrnl -imaxbel -opost " ..<br /> "-onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl " ..<br /> "-echoke noflsh -ixon -crtscts > /dev/null 2>&1"<br /> , serialPort, baud_rate)<br />os.execute("stty -F " .. serialPort .. " raw speed " .. baud_rate .. " > /dev/null 2>&1")<br />local flags = nixio.open_flags("rdwr")<br />local mySerial = nixio.open(serialPort, flags)<br />assert(mySerial)<br /><br />while true do<br /> local likes = get_fblikes()<br /> <br /> if likes ~= nil and tonumber(likes) > 0 then <br /> mySerial:write(likes .. ".") -- a dot '.' is for packet end <br /> if DEBUG ~= 0 then print("Likes: " .. likes) end<br /> end<br /> <br /> nixio.nanosleep(sleepInterval)<br />end<br />]]></script></p> <p>完成後,啟動 fblikes.lua 程式。過幾秒鐘後...</p> <p><a href="http://lh4.ggpht.com/-km-6XMzfXk0/UiSqNpctYwI/AAAAAAAALdw/ZrQiEW9MoG0/s1600-h/image%25255B7%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh5.ggpht.com/-w-eYTg5ckNQ/UiSqPXTLlgI/AAAAAAAALd4/XW9LrU1xKQ0/image_thumb%25255B3%25255D.png?imgmax=800" width="800" height="592" /></a></p> <p>耶!大功告成!</p> <h5>參考資料</h5> <ul> <li>OSSLab: <a href="http://www.osslab.com.tw/Hardware/Open_Embedded_System/MIPS/Atheros/WR-703N/OSSLAB_firmware/Facebook">利用 OpenWRT, Arduino 和 TM1638 製作 Facebook 按讚次數的顯示器</a> </li> <li>英倍達國際: <a href="http://www.embeda.com.tw/tw/?p=4314">本篇能有多少個讚?</a> </li> <li><a href="http://coopermaa2nd.blogspot.tw/2013/09/tm1638-led-display.html">TM1638 LED Display</a> </li> </ul> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-71391080510150750052013-09-02T19:54:00.001+08:002013-09-10T17:08:28.741+08:00TM1638 LED Display<p>TM1638 是一款 8 位數的 7 段顯示器,板子上有 8 顆雙色 LED (紅和綠),以及 8 顆按鈕。依 7 段顯示器的顏色來區別,TM1638 分成紅色和綠色兩種款式。TM1638 還可以串聯 (daisy-chained),最多可以串 6 組。TM1638 是大陸深圳天微這家公司做的。</p> <p>這是 TM1638 的正面照:</p> <p><a href="http://lh4.ggpht.com/-4ClfAieIDnQ/UiR8XlIl1dI/AAAAAAAALcI/GQuv1ujSuZw/s1600-h/image%25255B2%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-6QpF0pFVqEU/UiR8Y80iV4I/AAAAAAAALcQ/rkPIEdm02h8/image_thumb.png?imgmax=800" width="800" height="418" /></a></p> <p>如果有需要,可以用 cable 把 TM1638 串聯起來,最多可同時串 6 組 (賣家通常會提供 cable):</p> <p><a href="http://lh4.ggpht.com/-8xfI8ktE0EQ/UiR8aJ5rNLI/AAAAAAAALcY/N5Ia6jtixww/s1600-h/image%25255B17%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvFG78bQjQ8_k7S2xsCIrvEiznBdh9D79IaqKo_IRNUZIpRyQ933ZgY8oWQEyBVtgdjLJLdmAMVkQbO-_x9PB1KFGmBL7mbQdISmh4iigwHeIgPRHlhZQoGh8Z6zUvx9kwVg035zVYrRS0/?imgmax=800" width="800" height="409" /></a></p> <p>TM1638 的腳位圖印在板子背面:</p> <p><a href="http://lh4.ggpht.com/-GVfPbfOedbQ/UiR8c4o4q-I/AAAAAAAALco/AQfaT-0ta44/s1600-h/image%25255B5%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh3.ggpht.com/-s8QM8yWmZmE/UiR8eGgil4I/AAAAAAAALcw/E6Md6YmQpwk/image_thumb%25255B1%25255D.png?imgmax=800" width="800" height="427" /></a></p> <p>TM1638 的接線很簡單。如果只有一組 TM1638,只需要 5 根跳線就可以跟 Arduino 連接起來,分別是 VCC 與 GND 兩支電源接線,另外再用 Arduino 三支 GPIO 接腳接到 DIO, CLK 和 STB1 就可以了。</p> <h5>實測</h5> <p><strong>1.</strong> 首先,連接 Arduino 與 TM1638 (本例將 DIO, CLKC, STB1 分別接到 Arduino 的 8, 7, 6 接腳)</p> <p><strong>2. </strong>到 <a href="https://code.google.com/p/tm1638-library/">https://code.google.com/p/tm1638-library/</a> 下載並安裝 tm1638 library</p> <p><strong>3.</strong> 點按 <strong>Sketchbook > libraries > TM1638 > tm1638_one_module_example</strong> 打開 TM1638 library 提供的範例程式。完整程式碼如下:</p> <p><script type="syntaxhighlighter" class="brush: cpp"><![CDATA[<br />#include <TM1638.h><br /><br />// define a module on data pin 8, clock pin 7 and strobe pin 6<br />TM1638 module(8, 7, 6);<br /><br />void setup() {<br /> // display a hexadecimal number and set the left 4 dots<br /> module.setDisplayToHexNumber(0x1234ABCD, 0xF0);<br />}<br /><br />void loop() {<br /> byte keys = module.getButtons();<br /><br /> // light the first 4 red LEDs and the last 4 green LEDs as the buttons are pressed<br /> module.setLEDs(((keys & 0xF0) << 8) | (keys & 0xF));<br />}<br />]]></script></p> <p>程式說明:</p> <ul> <li>使用 TM1638 module(8, 7, 6) 定義 TM1638 物件,DIO 接在 pin 8, CLK 接在 pin 7, STB1 接在 pin 6 </li> <li>使用 module.setDisplayToHexNumber() 顯示16 進位數字,第二個參數可設定打開七段顯示器的小數點 </li> <li>要顯示 10 進位數字的話,把 module.setDisplayToHexNumber() 這行換掉,改成呼叫 module.setDisplayToDecNumber() 就行了 </li> </ul> <p>上傳程式到 Arduino 後…</p> <p><a href="http://lh6.ggpht.com/-1dmkTNovQwQ/UiR8gSVksjI/AAAAAAAALc4/LWxKjYEjfqI/s1600-h/image%25255B13%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-FmrheY9FPMA/UiR8iB_HXwI/AAAAAAAALdA/2L-zGw41Kbc/image_thumb%25255B5%25255D.png?imgmax=800" width="800" height="591" /></a></p> <p>耶,成功囉!</p> <h5>參考資料</h5> <ul> <li>OSSLab: <a href="http://www.osslab.com.tw/Hardware/Open_Embedded_System/MIPS/Atheros/WR-703N/OSSLAB_firmware/Facebook">利用 OpenWRT, Arduino 和 TM1638 製作 Facebook 按讚次數的顯示器</a> </li> </ul> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-60989159828262553572013-09-02T13:29:00.001+08:002013-09-10T17:08:17.147+08:00Arduino Ethernet Shield 簡介<p>Arduino Ethernet Shield 可以讓 Arduino 控制板連到 LAN 或 Internet。</p> <p>這塊板子用的 Ethernet 晶片是 WIZnet 5100:</p> <p><a href="http://lh6.ggpht.com/-uG-qijX31Cs/UiQiExwODzI/AAAAAAAALaA/PKftqnYjSZs/s1600-h/20120712_22h03_591.png"><img title="2012-07-12_22h03_59" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="2012-07-12_22h03_59" src="http://lh6.ggpht.com/-9fOQDzYmKfA/UiQiFhcrtoI/AAAAAAAALaI/RBCrHVOT10M/20120712_22h03_59_thumb.png?imgmax=800" width="450" height="324" /></a> <br />▲ Ethernet Shield 正面照</p> <p><a href="http://lh5.ggpht.com/-JsfwfLC1_TY/UiQiGcL_lMI/AAAAAAAALaQ/G21IeZGwrn4/s1600-h/20120712_22h04_301.png"><img title="2012-07-12_22h04_30" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="2012-07-12_22h04_30" src="http://lh5.ggpht.com/-eHv319wwS2w/UiQiHdk3sBI/AAAAAAAALaY/h8rDD7IeSQI/20120712_22h04_30_thumb1.png?imgmax=800" width="380" height="505" /></a> <br />▲ Ethernet Shield 背面照 (標籤上印的是 Ethernet MAC Address)</p> <p>WIZnet 5100 主要特色:</p> <blockquote> <p>- Support Hardwired TCP/IP Protocols TCP, UDP, ICMP, IPv4 ARP, IGMP, PPPoE, Ethernet <br />- 10BaseT/100BaseTX Ethernet PHY embedded <br />- Support Auto Negotiation (Full-duplex and half duplex) <br />- Support Auto MDI/MDIX <br />- Support ADSL connection (with support PPPoE Protocol with PAP/CHAP Authentication mode) <br />- Supports 4 independent sockets simultaneously <br />- Not support IP Fragmentation <br />- Internal 16Kbytes Memory for Tx/Rx Buffers <br />- 0.18 µm CMOS technology <br />- 3.3V operation with 5V I/O signal tolerance <br />- Small 80 Pin LQFP Package <br />- Lead-Free Package <br />- Support Serial Peripheral Interface(SPI MODE 0, 3) <br />- Multi-function LED outputs (TX, RX, Full/Half duplex, Collision, Link, Speed)</p> </blockquote> <p>(資料來源: <a href="http://www.wiznet.co.kr/Sub_Modules/en/product/Product_Detail.asp?cate1=5&cate2=7&cate3=26&pid=1011">WIZnet W5100 Product page</a>)</p> <p>下圖是 W5100 的 Block Diagram:</p> <p><a href="http://lh3.ggpht.com/-QuiI92q3mqo/UiQiID6GZVI/AAAAAAAALag/qtZZfqfHO8E/s1600-h/image8.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; float: none; margin-left: auto; display: block; border-top-width: 0px; margin-right: auto" border="0" alt="image" src="http://lh6.ggpht.com/--pHqcLGEluI/UiQiIs-3anI/AAAAAAAALao/1KEYMn9n2uM/image_thumb2.png?imgmax=800" width="310" height="483" /></a> </p> <p>W5100 主要特色是把 TCP/IP Protocols (TCP, UDP, ICMP, IPv4 ARP, IGMP, PPPoE, Ethernet) 做在硬體電路上,減輕了 MCU 的負擔 (也就是 Arduino 的負擔)。不過 W5100 也不是沒有缺點,因為它有一個限制,就是最多只允許同時 4 個 socket 連線。Arduino 程式只要使用 <a href="http://arduino.cc/it/Reference/Ethernet">Ethernet Library</a> 便可以輕易完成連至 internet 的動作。</p> <p>Arduino Ethernet Shield 使用加長型的 Pin header (如下圖一),可以直接插到 Arduino 控制板上 (如下圖二),而且原封不動地保留了 Arduino 控制板的 Pin Layout,讓使用者可以在它上面疊其它的擴充板。</p> <p><a href="http://lh3.ggpht.com/-tPeTjWw9F0g/UiQiJzuTawI/AAAAAAAALaw/W1ckxQ88Ib8/s1600-h/20120712_22h03_252.png"><img title="2012-07-12_22h03_25" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="2012-07-12_22h03_25" src="http://lh6.ggpht.com/-s7aFrG2vBR8/UiQiKg8fxjI/AAAAAAAALa4/0VIWcjAbmYQ/20120712_22h03_25_thumb.png?imgmax=800" width="574" height="466" /></a> </p> <p><a href="http://lh3.ggpht.com/-nMsyHIvhuEE/UiQiLdI1OuI/AAAAAAAALbA/Z6xeWRWjbUE/s1600-h/20120712_23h33_212.png"><img title="2012-07-12_23h33_21" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="2012-07-12_23h33_21" src="http://lh5.ggpht.com/-rigLk_lUw8w/UiQiMSIz9pI/AAAAAAAALbI/PlIAyvpBnxI/20120712_23h33_21_thumb.png?imgmax=800" width="489" height="406" /></a> </p> <p>比較新的 Ethernet Shield 增加了 micro-SD card 插槽,可以用來儲存檔案,你可以用 Arduino 內建的 SD library 來存取板子上的 SD card。(<font color="#008000">註:雖然 microSD 一張只要幾百塊台幣,不過現在全球經濟不景氣,而且當紅的雲端服務喊得震天價聲,網路上有一堆免費的 Cloud Storage 可用,我懷疑有多少人會願意再花錢去買 microSD :D </font>)。</p> <p>Ethernet Shield 相容於 UNO 和 Mega 2560 控制板。</p> <p>Arduino 控制板跟 W5100 以及 SD card 之間的通訊都是透過 SPI bus (通過 ICSP header)。以 UNO 而言,SPI bus 腳位位於 pins 11, 12 和 13,而 Mega 2560 則是 pins 50, 51 和 52。UNO 和 Mega 2560 都一樣,pin 10 是用來選擇 W5100,而 pin 4 則是用來選擇 SD card。這邊提到的這幾支腳位都不能拿來當 GPIO 使用。</p> <p>另外,在 Mega 2560 上,pin 53 是 hardware SS pin,這支腳位也必須保持為 output,不然 SPI bus 就不能動作。</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX-v92R1zs-gbpX7CYpH3z5ZEDjQcdjg-9TbaRG5ZvM-cDKRi33221nTyixVu6504lUyF7r2mSAPYcOBMGOHniPRfJr6MetX_vnh37FlXHMBPbt5N6SQMqNzcBfK3WsQ2jgE0xygwHFb_s/s1600-h/image2.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-lTl-pMVg0_U/UiQiNX3I-NI/AAAAAAAALbY/gLLpxA1Da5c/image_thumb.png?imgmax=800" width="500" height="431" /></a> </p> <p><a href="http://lh6.ggpht.com/-_yodyJwwmiI/UiQiODjVpKI/AAAAAAAALbg/wj2FYpF5uqQ/s1600-h/image5.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-3Y_k4ylnkxU/UiQiOjAT0GI/AAAAAAAALbo/SYMTb6uTOJw/image_thumb1.png?imgmax=800" width="800" height="339" /></a></p> <p>在使用的時候要注意一件事,因為 W5100 和 SD card 共享 SPI bus,所以在同一個時間只能使用其中一個設備。如果你程式裏會用到 W5100 和 SD card 兩種設備,那在使用對應的 library 時就要特別留意,要避免搶 SPI bus 資源的情形。</p> <p>假如你確定不會用到其中一個設備的話,你可以在程式裏明白地指示 Arduino,方法是: 如果不會用到 SD card,那就把 pin 4 設置成 output 並把狀態改為 high,如果不會用到 W5100,那麼便把 pin 10 設置成 output 並把狀態改為 high。</p> <p>Ethernet Shield 上有幾顆狀態指示燈 (LEDs):</p> <ul> <li>PWR: 表示 Arduino 控制板和 Ethernet Shield 已經上電 </li> <li>LINK: 網路指示燈,當燈號閃爍時代表正在傳送或接收資料 </li> <li>FULLD: 代表網路連線是全雙工 </li> <li>100M: 表示網路是 100 MB/s (相對於 10 Mb/s) </li> <li>RX: 接收資料時閃爍 </li> <li>TX: 傳送資料時閃爍 </li> <li>COLL: 閃爍時代表網路上發生封包碰撞的情形 (network collisions are detected) </li> </ul> <p><a href="http://lh4.ggpht.com/-CPXTR8g7YpY/UiQiPTruYCI/AAAAAAAALbw/wT5hgPaLTHU/s1600-h/ArduinoEthernetShield5.jpg"><img title="ArduinoEthernetShield" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="ArduinoEthernetShield" src="http://lh4.ggpht.com/-uys17jQiiMg/UiQiP868t3I/AAAAAAAALb4/I_FG90yWbUc/ArduinoEthernetShield_thumb17.jpg?imgmax=800" width="649" height="488" /></a></p> <h5>參考資料</h5> <ul> <li><a href="http://arduino.cc/en/Main/ArduinoEthernetShield">Arduino Ethernet Shield</a> </li> <li><a href="http://arduino.cc/en/Guide/ArduinoEthernetShield">Arduino Ehternet Shield Getting Started</a> </li> <li><a href="http://arduino.cc/it/Reference/Ethernet">Ethernet Library</a> </li> <li><a href="http://www.wiznet.co.kr/Sub_Modules/en/product/Product_Detail.asp?cate1=5&cate2=7&cate3=26&pid=1011">WIZnet W5100 Product page</a> </li> <li><a href="http://www.aroboto.com/shop/goods.php?id=294">藝科 Arduino Ethernet Shield R3</a> </li> </ul> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-90498457992789860462013-09-02T12:50:00.001+08:002013-09-10T17:09:04.953+08:00TL-WR703N 刷機成 OpenWrt<p>TL-WR703N 刷 OpenWrt 的步驟如下:</p> <p><strong>1.</strong> 用 Ethernet cable 直接把 TL-WR703N 接到 PC,PC 端要設定 192.168.1.x 網段的固定 IP (不能用 192.168.1.1,不然會跟 TL-WR703N 衝到),例如 192.168.1.2,subnet mask: 255.255.255.0 </p> <p><strong>2.</strong> 連到 <a href="http://192.168.1.1/%20">http://192.168.1.1/</a> 登入 TL-WR703N 的管理介面,以使用者名稱 admin 和密碼 admin 登入</p> <p><strong>3.</strong> 在左手邊的選單找出軟件升級頁面,或是直接連到 <a href="http://192.168.1.1/userRpm/SoftwareUpgradeRpm.htm">http://192.168.1.1/userRpm/SoftwareUpgradeRpm.htm</a>,升級介面如下:</p> <p><a href="http://lh5.ggpht.com/-51ZO87PrRBo/UiQY9a1LqeI/AAAAAAAALZI/_5AAYqAeln4/s1600-h/image10.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-_rtL1eotKwc/UiQY9-GG6iI/AAAAAAAALZQ/2o7yrym6SXQ/image_thumb4.png?imgmax=800" width="521" height="276" /></a> </p> <p><strong>4.</strong> 下載最新版 <a href="http://downloads.openwrt.org/snapshots/trunk/ar71xx/openwrt-ar71xx-generic-tl-wr703n-v1-squashfs-factory.bin">OpenWrt snapshot</a> 並上傳到 TL-WR703N</p> <p><strong>5.</strong> 等大概 3 到 4 分鐘,直到藍色 LED 不再閃爍時,升級程序便完成了 </p> <p>刷機後,可以 telnet 192.168.1.1 登入 TL-WR703N (不用輸入密碼),應該會看到 OpenWrt prompt:</p> <h5><a href="http://lh5.ggpht.com/-VSNglDXKO9Q/UiQY-TdrEUI/AAAAAAAALZY/H0K72N6NQAo/s1600-h/image13.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-NI2T2xVzP9I/UiQY_DQRpWI/AAAAAAAALZg/OXa5xCyiBPE/image_thumb5.png?imgmax=800" width="669" height="454" /></a> </h5> <p>下個 cat /proc/cpuinfo 指令看看 TL-WR703N 的 CPU 資訊:</p> <p><a href="http://lh3.ggpht.com/-pd0kmJRMH-I/UiQY_pls1yI/AAAAAAAALZo/7jm-nYkiGeQ/s1600-h/20120628_21h52_192.png"><img title="2012-06-28_21h52_19" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="2012-06-28_21h52_19" src="http://lh4.ggpht.com/-EI6mD91jCbk/UiQZAMOrZRI/AAAAAAAALZw/dJZJS9U5lv4/20120628_21h52_19_thumb.png?imgmax=800" width="669" height="374" /></a></p> <h5>啟動 SSH / 關閉 telnet</h5> <p>telnet 到 TL-WR703N 後下 passwd 指令設定密碼,設定完成後,便可以與 TL-WR703N 建立 SSH 連線,OpenWrt 會自動關閉 telnet 功能。</p> <h5>參考資料</h5> <ul> <li><a href="http://www.tp-link.com.cn/product_225.html">TP-LINK TL-WR703N</a> </li> <li><a href="http://wiki.openwrt.org/toh/tp-link/tl-wr703n">OpenWrt Wiki: TP-LINK TL-WR703N</a> </li> <li><a href="http://wiki.openwrt.org/doc/howto/luci.essentials">http://wiki.openwrt.org/doc/howto/luci.essentials</a> </li> </ul> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-77171297798980148982013-08-31T18:20:00.001+08:002013-09-10T17:09:29.069+08:00寫個 LuCI 介面設定 Serial Port 的 baud rate<p>OpenWrt 很多設定檔都是透過 UCI 介面 (Unified Configuration Interface) 來進行大部份的系統設定,包括 network, wireless, dhcp, firewall, dropbear (SSH Server) 以及跟網頁開發有關的 uhttpd 和 luci 都是。</p> <p>UCI 的檔案格式是一致的。以 /etc/config/system 為例,它的內容如下:</p> <p><script type="syntaxhighlighter" class="brush: text"><![CDATA[<br />config system<br /> option hostname 'OpenWrt'<br /> option zonename 'UTC'<br /> option timezone 'GMT0'<br /> option log_size '16'<br /> option conloglevel '8'<br /> option cronloglevel '8'<br /><br />config timeserver 'ntp'<br /> list server '0.openwrt.pool.ntp.org'<br /> list server '1.openwrt.pool.ntp.org'<br /> list server '2.openwrt.pool.ntp.org'<br /> list server '3.openwrt.pool.ntp.org'<br />]]></script></p> <p>在 LuCI 的 Web 管理介面上,有一頁是系統設定的操作介面,這個介面正是用來管理 /etc/config/system 設定檔:</p> <p><a href="http://lh5.ggpht.com/-J3kg2F8iSbQ/UiHDbcVWKQI/AAAAAAAALYQ/4bqOPqq7UOU/s1600-h/image%25255B12%25255D.png"><img title="image" style="display: inline" alt="image" src="http://lh6.ggpht.com/-H_Q6d0JwNbA/UiHDbxAlpPI/AAAAAAAALYY/haHwp3iW01s/image_thumb%25255B4%25255D.png?imgmax=800" width="565" height="610" /></a></p> <p>LuCI 便是透過 UCI 程式介面來讀寫 /etc/config/system 設定檔。</p> <p>我們也可以用 LuCI 來讀寫與管理自己的 UCI 設定檔。</p> <h5>Serial Port 的 baud rate 設定介面</h5> <p>來做個練習。首先編輯 /etc/config/arduino,輸入以下內容:</p> <p><script type="syntaxhighlighter" class="brush: text"><![CDATA[<br />config core 'main'<br /> option serialport '/dev/ttyACM0'<br /> option baud_rate '9600'<br />]]></script></p> <p>接著寫段程式碼 (arduino.lua,請存至 /usr/lib/lua/luci/model/cbi/myapp/arduino.lua):</p> <p><script type="syntaxhighlighter" class="brush: python"><![CDATA[<br />-- Save this to /usr/lib/lua/luci/model/cbi/myapp/arduino.lua<br />local fs = require "nixio.fs"<br />require "luci.sys"<br />local m = nil<br /><br />if fs.access("/etc/config/arduino") then <br /> m = Map("arduino", "Arduino", <br /> "Configure the basic aspects of Arduino") <br /> <br /> s = m:section(NamedSection, "main", translate("Main Settings"))<br /> o = s:option(Value, "serialport", translate("Serial Port"))<br /> <br /> local bauds = {9600, 19200, 28800, 38400, 57600, 115200} <br /> o = s:option(ListValue, "baud_rate", translate("Baud Rate"))<br /> for i = 1,#bauds do o:value(bauds[i]) end <br />end<br /><br />return m<br />]]></script></p> <p>其中,以 Map 對應 /etc/config/arduino,然後以 NamedSection 對應 /etc/config/arduino 設定檔中的 main 這個 section,然後建立兩個物件分別對應 serialport 與 baud_rate 這兩個 options。Value 屆時會在網頁上產生 TextBox,而 ListValue 則會在網頁上產生 Dropdown List (HTML 的 <select><option>…)</p> <p>我們還要準備個 Controller 模組 (index.lua, 請存至 /usr/lib/lua/luci/controller/myapp/index.lua):</p> <p><script type="syntaxhighlighter" class="brush: python"><![CDATA[<br />-- Save this to /usr/lib/lua/luci/controller/myapp/index.lua<br />-- Browse to: /cgi-bin/luci/myapp/<br /><br />module("luci.controller.myapp.index", package.seeall)<br /><br />function index()<br /> -- 定義節點, request 時會呼叫 model/cbi/myapp/arduino.lua<br /> page = entry({"myapp"}, cbi("myapp/arduino"))<br /> page.dependent = false<br /> <br /> -- 必須以 root 身分登入<br /> page.sysauth = "root"<br /> page.sysauth_authenticator = "htmlauth" <br /> <br /> -- 定義節點, request 時會呼叫 action_logout 函式<br /> entry({"myapp", "logout"}, call("action_logout"), "Logout")<br />end<br /><br />function action_logout()<br /> local dsp = require "luci.dispatcher"<br /> local sauth = require "luci.sauth"<br /> if dsp.context.authsession then<br /> sauth.kill(dsp.context.authsession)<br /> dsp.context.urltoken.stok = nil<br /> end<br /> <br /> luci.http.header("Set-Cookie", "sysauth=; path=" .. dsp.build_url())<br /> -- redirect to /cgi-bin/luci/myapp<br /> luci.http.redirect(luci.dispatcher.build_url() .. "/myapp")<br />end<br />]]></script></p> <p>完成後,瀏覽 /cgi-bin/luci/myapp,便會看到如下畫面:</p> <p><a href="http://lh4.ggpht.com/-otwNzIYytrs/UiHDcoHYEkI/AAAAAAAALYg/IEPCvulBU_Y/s1600-h/image%25255B5%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-Dcn5ga0kiI8/UiHDdMFkwpI/AAAAAAAALYo/Exk1k6NO2og/image_thumb%25255B1%25255D.png?imgmax=800" width="564" height="486" /></a></p> <p>這是 LuCI 自動產生的介面,可以讓使用者管理 /etc/config/arduino 這個設定檔的內容,當你在 UI 上做好設定,點按 [Save & Apply] 後,/etc/config/arduino 的檔案內容就會自動更新。</p> <h5>再進一步</h5> <p>前一個版本只是方便管理 /etc/config/arduino 這個設定檔。現在,讓我們進一步做件事「當使用者改變 baud rate 時,便呼叫 stty 指令改變 serial port 的 baud rate」:</p> <p>將 arduino.lua 修改成這樣:</p> <p><script type="syntaxhighlighter" class="brush: python"><![CDATA[<br />-- Save this to /usr/lib/lua/luci/model/cbi/myapp/arduino.lua<br />local fs = require "nixio.fs"<br />require "luci.sys"<br />local m = nil<br /><br />if fs.access("/etc/config/arduino") then <br /> m = Map("arduino", "Arduino", <br /> "Configure the basic aspects of Arduino") <br /> <br /> s = m:section(NamedSection, "main", translate("Main Settings"))<br /> o = s:option(Value, "serialport", translate("Serial Port"))<br /> <br /> local bauds = {9600, 19200, 28800, 38400, 57600, 115200} <br /> o = s:option(ListValue, "baud_rate", translate("Baud Rate"))<br /> for i = 1,#bauds do o:value(bauds[i]) end <br /> <br /> function o.write(self, section, value)<br /> local serialport = m.uci:get("arduino", "main", "serialport")<br /> local str = string.format("stty -F %s raw speed %s >/dev/null 2>&1",<br /> serialport, value)<br /> os.execute(str) <br /> m.uci:set("arduino", "main", "baud_rate", value)<br /> end<br />end<br /><br />return m<br />]]></script></p> <p>現在,當使用者在 Web 管理介面上改變 baud rate 時,就會同時呼叫 stty 去修改 serial port 的 baud rate 囉。你可以利用 stty –F <serial port> 來確認 baud rate 是否有改變:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxJloLLWJciVaPSXzuj3Mncs_TA5Qtey8xFQgJJiRCRWz9f9NQmgOYxtTVnpfbXoSzh9Qa6Rz1b6K0MfgHxETkE2ZV9J9Bo0OkjTV-45C-ihXnFiW8lMwho31ApRw8UgBBXcV0QmY8XaO3/s1600-h/image%25255B8%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-uTBZpj635Ho/UiHDeIGqdaI/AAAAAAAALY4/9IS5hTt3ik8/image_thumb%25255B2%25255D.png?imgmax=800" width="659" height="232" /></a></p> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-40352013899277079302013-08-31T13:29:00.001+08:002013-09-10T17:09:59.088+08:00寫個 LuCI 模組<p>LuCI (Lua Configiration Interface) 是 OpenWRT 的 Web 管理介面。LuCI 是一個 MVC (Model View Controller) framework,所以我們可以在 LuCI 的基礎上寫 Web 的應用程式。</p> <h5>第一個 controller 模組</h5> <p>假設我們想做一件事:「當使用者瀏覽 /cgi-bin/luci/myapp/mymodule/time.htm 時,便在網頁上顯示 OpenWRT 目前的系統時間」。那麼可以寫一段程式碼如下 (mymodule.lua):</p> <p><script type="syntaxhighlighter" class="brush: python"><![CDATA[<br />-- Save this to /usr/lib/lua/luci/controller/myapp/mymodule.lua<br />-- Browse to: /cgi-bin/luci/myapp/mymodule/time.htm<br /><br />module("luci.controller.myapp.mymodule", package.seeall)<br /><br />function index()<br /> -- 定義節點, request 時會呼叫 action_time<br /> page = entry({"myapp", "mymodule", "time.htm"}, call("action_time"))<br /> <br /> -- 沒有上層節點<br /> page.dependent = false <br /> -- 假如是葉節點, 就設成 true 避免錯誤<br /> page.leaf = true<br />end<br /> <br />function action_time()<br /> luci.http.prepare_content("text/html") <br /> luci.http.write("<h1>Hello LuCi</h1>")<br /> luci.http.write("<h2>Current time: " .. os.date("%D %T") .. "</h2")<br />end<br />]]></script></p> <p>其中,以 entry() 定義了一個節點,作用是「當使用者瀏覽 /cgi-bin/luci/myapp/mymodule/time.htm 時,便會呼叫 action_time() 函式」,而 action_time() 函式則會負責產生一個顯示目前系統時間的網頁。</p> <p>把 mymodule.lua 放到 /usr/lib/lua/luci/controller/myapp/mymodule.lua,然後瀏覽 /cgi-bin/luci/myapp/mymodule/time.htm,就會看到底下的結果:</p> <p><a href="http://lh6.ggpht.com/-jNLwfpQ3qoM/UiF_JcK_lgI/AAAAAAAALXo/AQhsn4GNdFI/s1600-h/image%25255B2%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-fxWTdYeyHoA/UiF_Jxy7I0I/AAAAAAAALXw/Lzgqd_ohnzk/image_thumb.png?imgmax=800" width="656" height="244" /></a></p> <h5>建立 VIEW</h5> <p>跟 PHP, ASP.NET, JSP 一樣,LuCI 也有 template 的功能,可以在 HTML 裏混用 Lua Script 產生動態網頁。底下做個示範。</p> <p>首先,建立了一個 template 檔如下,並把它存到 /usr/lib/lua/luci/view/myapp_mymodule/time.htm:</p> <p><script type="syntaxhighlighter" class="brush: xml"><![CDATA[<br /><!-- Save this to /usr/lib/lua/luci/view/myapp_mymodule/time.htm --><br /><%+header%><br /><h1>Hello LuCI</h1><br /><h2>Current Time: <%= os.date("%D %T")%></h2> <br /><%+footer%><br />]]></script></p> <p>接著寫個 controller 模組如下,把它存到 /usr/lib/lua/luci/controller/myapp/mymodule.lua:</p> <p><script type="syntaxhighlighter" class="brush: python"><![CDATA[<br />-- Save this to /usr/lib/lua/luci/controller/myapp/mymodule.lua<br />-- Browse to: /cgi-bin/luci/myapp/mymodule/<br /><br />module("luci.controller.myapp.mymodule", package.seeall)<br /><br />function index()<br /> -- 定義節點, 當作 myapp.mymodule.time.htm 的別名<br /> page = entry({"myapp", "mymodule"}, <br /> alias("myapp", "mymodule", "time.htm"), "My Module")<br /> page.dependent = false<br /><br /> -- 定義節點, request 時會 render view/myapp_mymodule/time.htm<br /> page = entry({"myapp", "mymodule", "time.htm"}, <br /> template("myapp_mymodule/time"), "Time") <br /> page.dependent = false; page.leaf = true <br />end<br /> <br />]]></script></p> <p>其中,程式以 entry() 定義了兩個節點。先說第二個節點,它的作用是「當使用者瀏覽 /cgi-bin/luci/myapp/mymodule/time.htm 時,會 描繪呈現 (render) /usr/lib/lua/luci/view/myapp_mymodule/time.htm 這個 template 的內容 」,而第一個節點只是第二個節點的別名,所以你可以瀏覽 /usr/lib/lua/luci/view/myapp_mymodule/time.htm,也可以簡寫成 /usr/lib/lua/luci/view/myapp_mymodule 這樣就好,兩者結果都是一樣的。當你執行這支程式時,會看到這樣的結果:</p> <p><a href="http://lh4.ggpht.com/-_kx1uPxrbaI/UiF_KXB1XfI/AAAAAAAALX4/_6woCXgkfo0/s1600-h/image%25255B5%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-6uv4SGdDZkk/UiF_K-lX-fI/AAAAAAAALYA/_JDh0_hvUr4/image_thumb%25255B1%25255D.png?imgmax=800" width="707" height="324" /></a></p> <p>LuCI 現在預設都是用 bootstrap CSS frontend,time.htm 引入了 header template,因此享受 bootstrap 的好處,變得比較美觀了。</p> <h5>暫除 LuCI 模組暫存檔</h5> <p>在學習寫 LuCI 模組時,有件特別注意的事。由於 LuCI 會把 module 暫存起來,就算你寫的 module 有做過變動,LuCI 也不會跑更新過後的版本。所以當你更新 module 時,記得刪除 LuCI 的模組暫存檔,這樣 LuCI 才會跑新版本的模組。</p> <p>刪除 LuCI 模組暫存檔的指令為:</p> <p><code>  rm /tmp/luci-indexcache /tmp/luci-modulecache/*</code></p> <h5>參考資料</h5> <ul> <li><a href="http://luci.subsignal.org/trac/wiki/Documentation/ModulesHowTo">HOWOT: Write Modules</a> </li> </ul> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-39232789874468750362013-08-24T23:40:00.001+08:002013-09-10T17:10:32.685+08:00寫個 uhttpd 的 CGI<p>uhttpd 是一個小型的 HTTP Server,支援 TLS, CGI, Lua。OpenWRT 的 Web 管理介面 LuCI (Lua Configuration Interface) 一般都是搭配 uhttpd 使用。底下是一張 LuCI 的畫面截圖。新版 LuCI 現在預設都用 twitter bootstrap 當作佈景主題 (Theme),非常美觀,看起來很舒服。</p> <p><a href="http://lh5.ggpht.com/-9HdgA655iTY/UhjT5y4Ra0I/AAAAAAAALW4/4hu4X0Y9SoA/s1600-h/image%25255B3%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh3.ggpht.com/-MkuS6tPyuPI/UhjT6QLJW9I/AAAAAAAALXA/YsfSCLBIXak/image_thumb%25255B1%25255D.png?imgmax=800" width="668" height="571" /></a></p> <p>uhttpd 的 Docuement Root 預設是在 /www,而 /cgi-bin/luci 則是預設的 CGI Gateway。</p> <p>我們可不可以自己也寫個 CGI?當然可以,舉個例子,用 Lua 寫段簡單的程式碼如下:</p> <p><script type="syntaxhighlighter" class="brush: python"><![CDATA[<br />#!/usr/bin/lua<br /><br />-- HTTP header<br />print("Content-Type: text/html")<br />print("") -- An empty line<br /><br />-- body<br />print("<h1>Hello CGI</h1>")<br />print("<h2>Current time: " .. os.date("%D %T") .. "</h2")<br />]]></script></p> <p>檔名取為 helloCGI,把它存到 /www/cgi-bin/helloCGI,接著把檔案屬性改為可執行:</p> <p><code>  chmod +x /www/cgi-bin/helloCGI</code></p> <p>然後瀏覽 http://<OpenWrt’ IP Address>/cgi-bin/helloCGI,會得到這樣的結果:</p> <p><a href="http://lh4.ggpht.com/-BUdLcOI9pwA/UhjT65P0I_I/AAAAAAAALXI/oYq3Wowevmk/s1600-h/image%25255B6%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-yV1l3JvlEss/UhjT7dO2GcI/AAAAAAAALXQ/_JcJKmjPjtc/image_thumb%25255B2%25255D.png?imgmax=800" width="547" height="234" /></a></p> <p>這就是一個簡單的 uhttpd 的 CGI 程式了。</p> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-21908656825810768042013-08-24T16:05:00.001+08:002013-09-10T17:11:03.792+08:00uloop: 一個簡單的 Event Loop implementation<p>我在 OpenWrt 裏找到一個小工具 uloop,一個簡單的 Event Loop Implementation,藏身在 libubox 裏。</p> <p>uloop() 主要提供兩個功能,一個是簡單的 timer,可以設定在 timeout 後自動執行指定的 function,另一個是類似 exec 指令,可以執行外部程式,後面這個功能好像沒多大用處。uloop() 有 lua binding,所以可以在 lua 程式裏套用。</p> <p>底下的程式示範 uloop()  timer 的使用方法 (timer_demo.lua):</p> <p><script type="syntaxhighlighter" class="brush: jscript"><![CDATA[<br />#!/usr/bin/env lua<br /><br />local uloop = require("uloop")<br />uloop.init()<br /><br />-- timer example 1<br />function t1()<br /> print("1000 ms timer run");<br /> print("t1 runs only once");<br />end<br />uloop.timer(t1, 1000)<br /><br />-- timer example 2<br />local timer<br />function t2()<br /> print("2000 ms timer run");<br /> timer:set(2000)<br />end<br />timer = uloop.timer(t2)<br />timer:set(2000)<br /><br />-- timer example 3, cancelled, will not run<br />uloop.timer(function() print("3000 ms timer run"); end, 3000):cancel()<br /><br />uloop.run()<br />]]></script></p> <p>執行結果如下:</p> <p><a href="http://lh6.ggpht.com/-xkhFnuxfIG8/UhhpUHNtktI/AAAAAAAALWg/TL6QLaS7qww/s1600-h/image%25255B2%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh5.ggpht.com/-5-ImyYG2WHs/UhhpUrUWaCI/AAAAAAAALWo/E9PR0etFQtg/image_thumb.png?imgmax=800" width="539" height="280" /></a></p> <p>其中,t1 只跑一次,t2 每兩秒跑一次,而 t3 則不會跑,因為它被取消了。</p> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-55450785702444139002013-08-20T13:18:00.001+08:002013-08-20T15:43:03.707+08:00scp for Windows<p>在 Linux 上,要在兩台電腦之間傳輸檔案,最簡單的方法是用 scp (Secure Copy) 指令,例如「把 README 傳到 Arduino-Wrt 的 /tmp 資料夾下」:</p> <code>   coopermaa@ubuntu:~$</a> scp README root@Arduino-Wrt:/tmp </code> <p>如果想要複製目錄,那麼只要加個 -r 選項。</p> <p>Windows 上也有 scp 指令可用。我找到兩個,一個是 <a href="http://msysgit.github.io/">msysgit</a> (Git for Windows),msysgit 打包了很多 Linux 的指令,包括了 scp。另一個是 <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html">pscp</a> (Putty Secure Copy)。這兩個工具的 scp 指令用法和 Linux 版本幾乎一模一樣。</p> <p>除了指令列工具,你也可以用 <a href="http://winscp.net/">WinSCP</a>。WinSCP 是 GUI 的介面,用滑鼠就可以操作:</p> <p><strong>1)</strong> 安裝好 WinSCP 後,登入你的 Linux (Raspberry Pi or Openwrt or whatever):</p> <p><a href="http://lh5.ggpht.com/-ShUM95Tq5Vs/UhL8Jhsox8I/AAAAAAAALV4/UfbTJKPfnsk/s1600-h/image%25255B2%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh3.ggpht.com/-1dCf3vU5jPc/UhL8KBLoDaI/AAAAAAAALWA/X0PJcV8-3r4/image_thumb.png?imgmax=800" width="529" height="470" /></a></p> <p><strong>2)</strong> 登入後,會看到 WinSCP 的管理介面,左邊是你的 PC,右邊則是你 Linux 的檔案系統。你只要用滑鼠拖放就可以傳輸檔案。</p> <p><a href="http://lh3.ggpht.com/-3SNsQHnrClY/UhL8Kp8GOZI/AAAAAAAALWI/rLx8TL2zNTc/s1600-h/image%25255B5%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh4.ggpht.com/--dYlreVUuA0/UhL8Lo5HNTI/AAAAAAAALWQ/mL_ak5EWSFQ/image_thumb%25255B1%25255D.png?imgmax=800" width="732" height="512" /></a></p> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-20011055005451319352013-07-19T20:26:00.001+08:002013-09-10T17:12:05.970+08:00Virtual Serial Port<p>ser2net 是把 serial port 轉成 TCP Socket (請參考我寫的 <a href="http://coopermaa2nd.blogspot.tw/2013/07/ser2net-for-openwrt.html">ser2net for OpenWrt</a> 一文) ,而 Virtual Serial Port 則剛好相反,會反過來把 TCP Socket 轉換變成系統上的一個 Serial Port。這篇將介紹 Virtual Serial Port 的使用方法。</p> <p><strong>1.</strong> 先連到底下的網站下載 HW VSP Singleport:</p> <blockquote> <p><a href="http://www.hw-group.com/products/hw_vsp/index_en.html">http://www.hw-group.com/products/hw_vsp/index_en.html</a></p> </blockquote> <p><a href="http://lh4.ggpht.com/-EZxyyqlL_mM/UekwU3rX_UI/AAAAAAAALPw/ya5B7NwwJhs/s1600-h/image%25255B2%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-F1L4CgAR3s4/UekwVRvLv_I/AAAAAAAALP4/RpgIJu7t1ho/image_thumb.png?imgmax=800" width="280" height="230" /></a></p> <p>HW VSP 有兩種版本,Singleport 是免費的版本,Multiport 則是商用版本。這裏請下載 Singleport 的版本。</p> <p><strong>2.</strong> 執行安裝程式</p> <p><a href="http://lh6.ggpht.com/-_fw4jL4ta0M/UekwV8_teqI/AAAAAAAALQA/A13fxfO5r4s/s1600-h/image%25255B5%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh5.ggpht.com/-b1_fyKS3d5U/UekwWAlTgmI/AAAAAAAALQI/JM0lZO-3O-E/image_thumb%25255B1%25255D.png?imgmax=800" width="513" height="398" /></a></p> <p>安裝程序最後一步會跳出底下視窗,問你要不要把程式加到防火牆的例外清單,請按 [是(Y]:</p> <p><a href="http://lh3.ggpht.com/-7EvR-hhf94w/UekwWsnXPZI/AAAAAAAALQQ/EVymLIz06S0/s1600-h/image%25255B8%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh5.ggpht.com/-gWfZ3RF3q10/UekwXD8nocI/AAAAAAAALQY/A2WdnME8Ccs/image_thumb%25255B2%25255D.png?imgmax=800" width="482" height="178" /></a></p> <p><strong>3.</strong> 打開 HW Virtual Serial Port</p> <p><a href="http://lh6.ggpht.com/-anOMbREaEWE/UekwXpZqHMI/AAAAAAAALQg/Jsku3hYZ5bs/s1600-h/image%25255B11%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-eBAoiFMiWM4/UekwYJ1sAOI/AAAAAAAALQo/EMiZB_i-LQI/image_thumb%25255B3%25255D.png?imgmax=800" width="603" height="490" /></a></p> <p>要先登入,請點一下右手邊的 Login,跳出底下視窗後,直接按下 OK 鈕:</p> <p><a href="http://lh5.ggpht.com/-CQ5F1DPUa5o/UekwYoRBnMI/AAAAAAAALQw/1A5jPCckND4/s1600-h/image%25255B14%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-ePcSmXw9mk0/UekwZAdAkbI/AAAAAAAALQ4/qKjvnI4yjSc/image_thumb%25255B4%25255D.png?imgmax=800" width="306" height="176" /></a></p> <p><strong>4.</strong> 假設要為 192.168.10.1:2001 建立一個 Virtual Serial Port (我在 <a href="http://coopermaa2nd.blogspot.tw/2013/07/ser2net-for-openwrt.html">ser2net for OpenWrt</a> 一文中建立的 Socket Port) ,那麼就照底下視窗填好相關欄位,然後按下 Create COM 鈕:</p> <p><a href="http://lh4.ggpht.com/-9jbviSGAnrw/UekwZjucVWI/AAAAAAAALRA/bVSYk4lPzfk/s1600-h/image%25255B17%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh5.ggpht.com/-dkKcL1bv4po/UekwaTQOsMI/AAAAAAAALRI/1_j2hItsti4/image_thumb%25255B5%25255D.png?imgmax=800" width="603" height="490" /></a></p> <p>過幾秒鐘後,在裝置管理員裏就會多出一個 COM3 的 Serial Port:</p> <p><a href="http://lh5.ggpht.com/-Q11UXljCQsA/Uekwa0d8u7I/AAAAAAAALRQ/hn752zKPGA8/s1600-h/image%25255B20%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh3.ggpht.com/--6JxmwJnqVk/UekwbX2ETpI/AAAAAAAALRY/GYCnPSFc3t8/image_thumb%25255B6%25255D.png?imgmax=800" width="615" height="502" /></a></p> <p>接下來我們就可以把這個 COM3 當作是一般的 Serial Port 來使用囉。</p> <p>例如我在筆電上建立了一個 COM3 的 Vritual Serial Port,我可以用 Arduino Software 的 Serial Monitor 收 Arduino 的資料:</p> <p><a href="http://lh6.ggpht.com/-YJYqLOg-gFQ/Uekwb6JRJTI/AAAAAAAALRg/vica8loD7p8/s1600-h/image%25255B26%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-mmG40oZehOE/UekwcU6fKOI/AAAAAAAALRo/CQT1brvzBss/image_thumb%25255B8%25255D.png?imgmax=800" width="500" height="468" /></a></p> <p>要知道,這個 COM3 其實是 OpenWrt 上以 ser2net 轉成 TCP port 2001 的網路服務。</p> <p><font color="#ff0000"><strong>注意!</strong></font>雖然可以用 Serial Monitor 開啟 Virtual Serial Port,但是 Virtual Serial Port 有一個限制:「我們不能透過 Virtual Serial Port 上傳 Arduino 的 Sketch」,這一點要切記,因為畢竟 Virtual Serial Port 跟一般的 Serial Port 是不一樣的。</p> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-36615293030327364492013-07-19T17:02:00.001+08:002013-09-10T17:11:34.888+08:00ser2net for OpenWrt<p><a href="http://ser2net.sourceforge.net/">ser2net</a> 可以把 Serial port 的通訊轉成 TCP Socket 的通訊。大部份的 Arduino 都是用 USB 介面接到筆電、Raspberry Pi 或是 OpenWrt,只能走 Serial 通訊,底下說明如何用 ser2net 把 Arduino 的 Serial 通訊轉成 TCP Socket 通訊:</p> <p><strong>1.</strong> 上傳 [<strong>File > Examples > 01. Basics > AnalogReadSerial</strong>] 到 Arduino 板子上,我們將用這支程式示範:</p> <p><a href="http://lh4.ggpht.com/-9G6eWHnBFI0/UekAn6AXgGI/AAAAAAAALOo/RY28PQaYKCU/s1600-h/image%25255B2%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-FH606q9Ukmo/UekAonUubiI/AAAAAAAALOw/9jNg9wAivNA/image_thumb.png?imgmax=800" width="500" height="524" /></a></p> <p><strong>2)</strong> 登入到你的 OpenWrt,以底下指令安裝 ser2net (若使用 Raspberry Pi 等 Debian Linux,請用 apt-get 安裝):</p> <blockquote> <p><code>opkg update <br />opkg install ser2net </code></p> </blockquote> <p><a href="http://lh4.ggpht.com/-Cq6mHBMQkoM/UekApFFC1lI/AAAAAAAALO4/3KXzzKk4cFY/s1600-h/image%25255B5%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-8IY_rrSzJRs/UekApvlKWEI/AAAAAAAALPA/eB72DZ4Wzd0/image_thumb%25255B1%25255D.png?imgmax=800" width="675" height="280" /></a></p> <p><strong>3)</strong> 以指令 vi /etc/ser2net.conf 編輯設定檔,設定 Arduino 所在的 serial port 與 baud rate:</p> <blockquote> <p>2001:raw:600:/dev/ttyACM0:9600 NONE 1STOPBIT 8DATABITS XONXOFF LOCAL –RTSCTS</p> </blockquote> <p>此例 Arduino 接在 /dev/ttyACM0,baud rate 是 9600。</p> <p>接著輸入底下指令啟動 ser2net:</p> <blockquote><code> <p>ser2net</p> </code></blockquote> <p>執行後,ser2net 會把 Arduino 的通訊轉成網路 port 2001。</p> <p><strong>4)</strong> 用 Putty 或 Telnet 工具連入 OpenWrt:</p> <p><a href="http://lh5.ggpht.com/-yHl2UwvbLgY/UekAqKJXBcI/AAAAAAAALPI/IUjTDLO9rwU/s1600-h/image%25255B14%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh3.ggpht.com/-btXJwgLlujo/UekAqjoPkUI/AAAAAAAALPQ/8RbaMeBtZ8A/image_thumb%25255B4%25255D.png?imgmax=800" width="466" height="448" /></a></p> <p>其中:</p> <ul> <li>IP Address 是你 OpenWrt 或 Raspberry Pi 的網路位址 </li> <li>Port 要與 ser2net 的設定一樣,此例為 2001 </li> <li>Connection type 要選擇 Telnet </li> </ul> <p>最後按下 [Open] 連線,在 Putty 視窗上就會看到 Arduino 模擬輸入 (Analog Input) 的讀值囉:</p> <p><a href="http://lh4.ggpht.com/-1CdhlC5Ssy4/UekArKjGhtI/AAAAAAAALPY/e-8j07o4ruA/s1600-h/image%25255B11%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh5.ggpht.com/-nzDdS4UZIBY/UekArmANozI/AAAAAAAALPg/DyV-QZrE7n4/image_thumb%25255B3%25255D.png?imgmax=800" width="675" height="424" /></a></p> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-77919957574166146532013-06-01T18:47:00.001+08:002013-06-01T22:47:07.185+08:00RawCap + Wireshark 截取 loopback 封包<p>在 Windows 上跑 Wireshark,居然沒辦法截取 loopback address 127.0.0.1 的網路封包,<a href="http://www.hsc.fr/ressources/articles/win_net_srv/missing_loopback.html">據說</a>是 Windows 的 TCP/IP stack 沒實作 loopback interface 的關係。真相究竟為何,實在沒辦法沒能力也沒空繼續看下去。幸好,剛發現有支叫 <a href="http://www.netresec.com/?page=RawCap">RawCap</a> 的工具可以抓 Windows 上 localhost 的網路封包,所以還是有解的,只要以 RawCap 抓到封包後,再用 Wireshark 來呈現與分析封包就行了。</p> <p>RawCap 可以在底下的網址取得:</p> <blockquote> <p><a href="http://www.netresec.com/?page=RawCap">http://www.netresec.com/?page=RawCap</a></p> </blockquote> <p>我們必須用 Administrator 的身分執行 RawCap,以 <code>rawcap --help </code>指令看使用說明,rawcap 同時會列出所有可用的 interfaces:</p> <p><a href="http://lh4.ggpht.com/-xbIdwIcwz5I/UanRRS2pdaI/AAAAAAAALLc/YnTUTYdtwPM/s1600-h/image%25255B8%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh3.ggpht.com/-KC5FzPTpWyg/UanRR-YuZRI/AAAAAAAALLk/C71_pnx4vX8/image_thumb%25255B2%25255D.png?imgmax=800" width="677" height="602" /></a></p> <p>要抓 loopback 的網路封包,只要輸入以下指令:</p> <code> <p>  rawcap 127.0.01 dumpfile.pcap</p> </code> <p>截取到網路封包後,再用 Wireshark 開啟資料檔 dumpfile.pcap 就可以分析囉:</p> <p><a href="http://lh6.ggpht.com/-h0u-QK5fWHQ/UanRSoXC3FI/AAAAAAAALLs/Xvr3yx3dvWA/s1600-h/image%25255B5%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh5.ggpht.com/-ruIZbaf6mv8/UanRTIgnz5I/AAAAAAAALL0/3jf7wnvZTsU/image_thumb%25255B1%25255D.png?imgmax=800" width="731" height="604" /></a></p> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-50824570197165357592013-05-28T20:42:00.001+08:002013-09-10T17:05:20.996+08:00Putty 自動登入 Raspberry Pi<p><a href="http://lh4.ggpht.com/-YtIS7vMhoEQ/UaSmBAnjKcI/AAAAAAAALIk/Ub-J5d2cgms/s1600-h/image%25255B29%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-IDS_elHLUWU/UaSmBvx_E-I/AAAAAAAALIs/l7txookoxo8/image_thumb%25255B9%25255D.png?imgmax=800" width="675" height="136" /></a></p> <p>每次登入 Raspberry Pi 都要輸入密碼,實在有點麻煩,來做個設定讓 Putty 自動登入 Raspberry Pi 吧。</p> <p><strong>Step 1. 產生 SSH Keys</strong></p> <p>下載 <a href="http://the.earth.li/~sgtatham/putty/latest/x86/puttygen.exe">puttygen</a> 然後執行程式。啟動後,點一下 Generate 鈕產生 SSH Keys:</p> <p><a href="http://lh4.ggpht.com/-rx1uLVfznQs/UaSmCJq3jLI/AAAAAAAALI0/7xaXArG2a_Q/s1600-h/image%25255B2%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-nnlzh2GODog/UaSmCscnQQI/AAAAAAAALI8/XC-WwTOF87o/image_thumb.png?imgmax=800" width="493" height="477" /></a></p> <p>按下 Generate 鈕後,要在視窗空白區域動一動滑鼠,好讓 puttygen 根據滑鼠的軌跡隨機產生亂數值:</p> <p><a href="http://lh4.ggpht.com/-TlZXNKqmEzA/UaSmDJq7PoI/AAAAAAAALJE/ZViNNmvKKtg/s1600-h/image%25255B5%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-eVZPHcgISOo/UaSmDn7ZsFI/AAAAAAAALJM/WpKQuweTbmI/image_thumb%25255B1%25255D.png?imgmax=800" width="493" height="477" /></a></p> <p>SSH Keys 建立完成囉。接著點一下 Save Private Key 把 Private Key 存起來,檔案要放哪裏隨你高興:</p> <p><a href="http://lh6.ggpht.com/-yeZalZ2kXqs/UaSmEC4VPOI/AAAAAAAALJU/JvwkJopX65A/s1600-h/image%25255B8%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-1POYHWGKmbY/UaSmExJi4iI/AAAAAAAALJc/lL0omNMmb9Y/image_thumb%25255B2%25255D.png?imgmax=800" width="493" height="477" /></a></p> <p>過程中會出現底下這個警告訊息,不理它,按下 Y 就對了:</p> <p><a href="http://lh3.ggpht.com/-UA4PZd8Z3oM/UaSmFehBXWI/AAAAAAAALJk/o1e8qsJrofE/s1600-h/image%25255B11%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-EBV4R7nU50U/UaSmF8BIThI/AAAAAAAALJs/xTfO6hXCTZE/image_thumb%25255B3%25255D.png?imgmax=800" width="329" height="178" /></a></p> <p><strong>Step 2. 複製 Public key 到 Raspberry Pi</strong></p> <p>下一步要把 Public key 放到 Raspberry Pi,先用 Putty 登入 Raspberry Pi,然後輸入底下指令編輯 .ssh/authorized_keys 這個檔案:</p> <code> <p>    $ mkdir .ssh <br />    $ vi .ssh/authorized_keys</p> </code> <p>接著把 Puttygen 產生的 Publich Key 複製並貼到 vi 的編輯視窗,存檔後即可登出 Raspberry Pi:</p> <p><a href="http://lh4.ggpht.com/-ee3pJvtySrk/UaSmGWnWYyI/AAAAAAAALJ0/Tn9sjkLDH_Y/s1600-h/image%25255B14%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh5.ggpht.com/-9gtm6G0X9tM/UaSmG2PZVKI/AAAAAAAALJ8/0-8w_Sz0VNA/image_thumb%25255B4%25255D.png?imgmax=800" width="725" height="642" /></a></p> <p><strong>Step 3. 設定 Putty</strong></p> <p>最後一步是設定 Putty。</p> <p>打開 Putty,輸入 Raspberry Pi 的 IP address,確定所用的 Connection type 是 SSH:</p> <p><a href="http://lh4.ggpht.com/-KHMhejUDVeg/UaSmHXXqJXI/AAAAAAAALKA/QXuyQ6wnuf8/s1600-h/image%25255B17%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-ymonXbsebwo/UaSmH5-A29I/AAAAAAAALKI/ig34oQbtBWo/image_thumb%25255B5%25255D.png?imgmax=800" width="466" height="448" /></a></p> <p>切到 Connection > SSH > Auth 頁面,在 Private Key for authentication 這個欄位輸入剛剛在第一步所儲存的 Private Key 檔路徑:</p> <p><a href="http://lh3.ggpht.com/-YswJUCNtxw0/UaSmIe_JO7I/AAAAAAAALKM/QHWmvVm2ZHw/s1600-h/image%25255B20%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-Fo-OWuxHblE/UaSmI_lUc4I/AAAAAAAALKY/MFQ4w4wN4Y0/image_thumb%25255B6%25255D.png?imgmax=800" width="466" height="448" /></a></p> <p>跟著切到 Connection > Data 頁面,在 Auto-login username 欄位上輸入 pi:</p> <p><a href="http://lh5.ggpht.com/-PnlLMwyA1lU/UaSmJVBL4jI/AAAAAAAALKg/Rs9I-ZZvsro/s1600-h/image%25255B23%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh5.ggpht.com/-f3vtsOIcik4/UaSmKNzorBI/AAAAAAAALKs/5LhQNgoAkBQ/image_thumb%25255B7%25255D.png?imgmax=800" width="466" height="448" /></a></p> <p>回到 Session 主畫面,把這個 Session 存起來:</p> <p><a href="http://lh5.ggpht.com/-l1aKrrxyi5k/UaSmKg7mITI/AAAAAAAALK0/4nm9AUM1-5I/s1600-h/image%25255B32%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-Nrv5zNsFMVw/UaSmLK7NE7I/AAAAAAAALK8/ISg6xFOCAbw/image_thumb%25255B10%25255D.png?imgmax=800" width="466" height="448" /></a></p> <p>最後,按下 Open…</p> <p>耶!成功囉!</p> <p><a href="http://lh5.ggpht.com/-aaUnnoN5K5A/UaSmL3i9mEI/AAAAAAAALLE/phJ24Lbe60Y/s1600-h/image%25255B36%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh3.ggpht.com/-czo7ceXG2ws/UaSmMUvZ0zI/AAAAAAAALLM/mI4foklJIUI/image_thumb%25255B11%25255D.png?imgmax=800" width="675" height="312" /></a></p> <p>以後 Putty 就會自動登入 Raspberry Pi 了。</p> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-89735631800367877562013-05-19T17:31:00.001+08:002013-05-19T17:32:20.171+08:00Maker Faier Taipei 2013 – Workshop<p>Maker Faier Taipei 2013 第二天的參觀,突然想到應該拍幾張照片留念。今年人潮真多,我實在不習慣在人群裏穿梭穿梭去,因此一直待在工作坊區附近,所以便就近拍了幾張 Workshop 的照片。</p> <p>下午第一場工作坊,Ben6 介紹雲端智慧車與粉絲人氣顯示器:</p> <p><a href="http://lh3.ggpht.com/-uJI1q3_udpE/UZib06Fbl2I/AAAAAAAALGc/rmGM6q0k56k/s1600-h/2013-05-19%25252013.10.06%25255B4%25255D.jpg"><img title="2013-05-19 13.10.06" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="2013-05-19 13.10.06" src="http://lh3.ggpht.com/-DuXLrWlzbxI/UZib1cShNmI/AAAAAAAALGk/qQYFmvbyI5Q/2013-05-19%25252013.10.06_thumb%25255B1%25255D.jpg?imgmax=800" width="640" height="480" /></a></p> <p><a href="http://lh6.ggpht.com/-wlv_UyuboRI/UZib2GQ1jCI/AAAAAAAALGs/9Mj1DtBZ-L4/s1600-h/2013-05-19%25252013.13.32%25255B4%25255D.jpg"><img title="2013-05-19 13.13.32" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="2013-05-19 13.13.32" src="http://lh3.ggpht.com/-iUwSHAcNMdE/UZib2rGUZFI/AAAAAAAALG0/xHvClixpCdU/2013-05-19%25252013.13.32_thumb%25255B1%25255D.jpg?imgmax=800" width="640" height="480" /></a></p> <p>現場的學生和助教:</p> <p><a href="http://lh3.ggpht.com/-slL-ioEQkHo/UZib3FMibpI/AAAAAAAALG8/5l5TMyiVmkQ/s1600-h/2013-05-19%25252013.37.03%25255B4%25255D.jpg"><img title="2013-05-19 13.37.03" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="2013-05-19 13.37.03" src="http://lh6.ggpht.com/-y21Eao3aOQs/UZib3-P65YI/AAAAAAAALHE/Y9QPv-w-z6A/2013-05-19%25252013.37.03_thumb%25255B1%25255D.jpg?imgmax=800" width="640" height="480" /></a></p> <p><a href="http://lh3.ggpht.com/-NBxPDUH7cjQ/UZicIC4SSeI/AAAAAAAALH8/BLoPKftcGcI/s1600-h/2013-05-19%25252013.36.40%25255B4%25255D.jpg"><img title="2013-05-19 13.36.40" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="2013-05-19 13.36.40" src="http://lh4.ggpht.com/-utq1mKzkGIM/UZicItrNrdI/AAAAAAAALIE/DE4hEHKsoeA/2013-05-19%25252013.36.40_thumb%25255B1%25255D.jpg?imgmax=800" width="360" height="480" /></a></p> <p>第二場是今村謙之先生介紹「大人的科學之電子積木」:</p> <p><a href="http://lh5.ggpht.com/-nf9uVNwmw_o/UZib4Z57wxI/AAAAAAAALHM/co3G8BjX6mc/s1600-h/2013-05-19%25252014.47.27%25255B4%25255D.jpg"><img title="2013-05-19 14.47.27" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="2013-05-19 14.47.27" src="http://lh5.ggpht.com/-EsD9ocChl2c/UZib4-19AxI/AAAAAAAALHU/voRjhMgxXzE/2013-05-19%25252014.47.27_thumb%25255B1%25255D.jpg?imgmax=800" width="640" height="480" /></a></p> <p>這是電子積木:</p> <p><a href="http://lh6.ggpht.com/-vUvZ71QLMZM/UZib5qDzWgI/AAAAAAAALHc/k1wvqmkl3K8/s1600-h/2013-05-19%25252014.46.05%25255B8%25255D.jpg"><img title="2013-05-19 14.46.05" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="2013-05-19 14.46.05" src="http://lh6.ggpht.com/-rm1ka2TDrfE/UZib6JwNpAI/AAAAAAAALHk/SWc7wSCMPGs/2013-05-19%25252014.46.05_thumb%25255B2%25255D.jpg?imgmax=800" width="640" height="480" /></a><a href="http://lh5.ggpht.com/-WhGyk2bIyQ8/UZib6gF6uiI/AAAAAAAALHs/vuij7fzOTNI/s1600-h/2013-05-19%25252014.57.43%25255B4%25255D.jpg"><img title="2013-05-19 14.57.43" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="2013-05-19 14.57.43" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidwt64LgiEEJ9jMIcXjLHP7Lhn_MjaIA3aZ0S4nYNPE8DhMfoTYUna6ch2tcSjEi38HGagGq1UA2Gfrevm3_XZG_9A7W_3OsQViBK5WYNT5iRHQWbMEfAsjVYGbNTUdLI2CPOaZasmF-15/?imgmax=800" width="640" height="480" /></a></p> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-78287932445711001402013-04-29T01:19:00.001+08:002013-05-27T22:07:56.732+08:00node-webduino<p>I have just released node-webduino - A web FrontEnd for Arduino. Node-webduino will let you do real-time I/O monitoring and controlling in your browser. See README.md on the repo for more information:</p> <blockquote> <p><a href="https://github.com/coopermaa/node-webduino">https://github.com/coopermaa/node-webduino</a></p> </blockquote> <p>Here is a screenshot of node-webduino. </p> <p><a href="http://lh4.ggpht.com/-HZZUgyDABJc/UX1aIqKwDeI/AAAAAAAALDo/qvfIUQN8gHo/s1600-h/687474703a2f2f6269742e6c792f58487461336d%25255B2%25255D.png"><img title="687474703a2f2f6269742e6c792f58487461336d" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="687474703a2f2f6269742e6c792f58487461336d" src="http://lh3.ggpht.com/-ohVrpeR00jM/UX1aJO1ZJVI/AAAAAAAALDw/k-2_5tN3hyw/687474703a2f2f6269742e6c792f58487461336d_thumb.png?imgmax=800" width="678" height="783" /></a></p> <p>2013/04/30: Here is a demo video:</p> <div id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:5c4f7ed7-cfcb-4121-a983-a2784fce9d66" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"><div id="1e32f270-d791-4be7-a600-37ca4fadb488" style="margin: 0px; padding: 0px; display: inline;"><div><a href="http://www.youtube.com/watch?v=W_gz78ovBE4" target="_new"><img src="http://lh3.ggpht.com/-tyoeqiNV95k/UaNou4UE9yI/AAAAAAAALIU/DBx3aI9Vnv8/video94356f8decd6%25255B2%25255D.jpg?imgmax=800" style="border-style: none" galleryimg="no" onload="var downlevelDiv = document.getElementById('1e32f270-d791-4be7-a600-37ca4fadb488'); downlevelDiv.innerHTML = "<div><object width=\"602\" height=\"338\"><param name=\"movie\" value=\"http://www.youtube.com/v/W_gz78ovBE4?hl=en&hd=1\"><\/param><embed src=\"http://www.youtube.com/v/W_gz78ovBE4?hl=en&hd=1\" type=\"application/x-shockwave-flash\" width=\"602\" height=\"338\"><\/embed><\/object><\/div>";" alt=""></a></div></div></div> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-4525169963030939422013-04-27T16:30:00.001+08:002013-04-27T21:15:03.637+08:00ABC – Arduino Basic Connections<p><a href="https://plus.google.com/u/0/108783946679541011308/posts">Alberto Piganti</a>,就是那位畫了很多超棒的 <a href="http://coopermaa2nd.blogspot.tw/2013/04/arduino-pinout-diagrams.html">Arduino pinout diagrams</a> 的義大利人,最近他又畫了好多精美的電路圖,這次的創作叫作 <a href="http://www.pighixxx.com/abc-arduino-basic-connections/">Arduino Basic Connections</a>,有關 Arduino 如何連接各種電子零件,所有你想知道的,全都在這本畫冊中。</p> <p><a href="http://www.pighixxx.com/abc-arduino-basic-connections/">Arduino Basic Connections</a> 畫冊以集合為單位,每個集合有三張卡片。這本畫冊還在持續進行中,我三月份看到的時候,當時只看到 15 張,現在已經畫到第 14 集合了。</p> <p>據我所知,為了方便查閱,大部份硬體工程師都會準備一本記載著基本而常用的電路的筆記本。<a href="https://plus.google.com/u/0/108783946679541011308/posts">Alberto Piganti</a> 真的很佛心,常用的電子零件怎麼接,在這本畫冊中幾乎都找的到,而且電路圖畫得真的很漂亮。底下這張是 Card 3 中的繼電器電路:</p> <p><a href="http://lh6.ggpht.com/-qoXZGLgnezI/UXuMl0RD9sI/AAAAAAAALDQ/640ljo0IppY/s1600-h/image%25255B4%25255D.png"><img title="image" style="display: inline" alt="image" src="http://lh4.ggpht.com/-8jnIQzT565Y/UXuMmerXIJI/AAAAAAAALDY/9mAwrW_0b14/image_thumb%25255B2%25255D.png?imgmax=800" width="730" height="537" /></a></p> <p>如下,在寫<a href="http://coopermaa2nd.blogspot.tw/2011/03/blog-post_26.html">繼電器簡介</a>這篇時,我自己也畫了張控制繼電器的電路圖,圖是用 Visio 畫的。我不是學硬體出身的,也不是學設計的,當時可以畫出這樣一張圖,覺得很佩服自己,現在想想,跟 <a href="https://plus.google.com/u/0/108783946679541011308/posts">Alberto Piganti</a> 畫的圖比起來,實在是不能比,我只能告訴自己:「工程師真的需要培養一些美感啊!」</p> <p><img alt="image" src="http://lh5.ggpht.com/_Ap9EEd9K-fg/TY13L3qwCdI/AAAAAAAAEB4/v41KtGnUMO8/image_thumb14.png?imgmax=800" /></p> <p><a href="http://www.pighixxx.com/abc-arduino-basic-connections/">Arduino Basic Connections</a> 這本畫冊有 PDF 檔可以下載,或者也可以到 <a href="http://www.flickr.com/photos/28521811@N04/8671264345/in/photostream/">Flickr</a> 取得 PNG 圖檔。</p> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-35900126722248493342013-04-25T23:46:00.001+08:002013-04-26T01:51:26.793+08:00在 PC 上玩 Flipboard<p>我的手機應該有感覺,自從前陣子裝了 Flipboard 後,我變了,以前不常打招呼,如果有打開來用的話,通常也只是對它指指點點,很不溫柔,現在只要一到休閒時刻就來找它玩,常常在它身上滑來滑去的。確實,我的閱讀習慣似乎正在改變,我現在都用 Flipboard 來看新聞、部落格和網站,Flipboard 讓我有一種「在翻閱雜誌」的感覺。Flipboard 也可以連結 Facebook, Twitter, Google+, Google Reader 等社群網路,所有資訊都可以匯流到 Flipboard 裏,所以現在我不需要打開那麼多 App,既不必學習各個 App 的操作方式,又可以節省手機的電力,而且還可以把社群網站當成雜誌來翻閱,感覺很特別。</p> <p><a href="http://lh3.ggpht.com/-UceHaAnI5R8/UXlPLALFcvI/AAAAAAAALCI/battGZyPzqg/s1600-h/2013-04-25%25252022.55.13%25255B5%25255D.png"><img title="2013-04-25 22.55.13" style="display: inline" alt="2013-04-25 22.55.13" src="http://lh3.ggpht.com/-zruP6-cTrkU/UXlPMI4NMtI/AAAAAAAALCQ/8J95eFBClqE/2013-04-25%25252022.55.13_thumb%25255B3%25255D.png?imgmax=800" width="300" height="480" /></a></p> <p>我還有一台 Nexus 7 平板電腦,在七吋的平板上翻 Flipboard 雜誌,感覺更棒,我相信用 iPad Mini 或是螢幕尺寸更大的 iPad 玩 Flipboard 應該會更過癮。那麼,能不能在 PC 上跑 Flipboard 呢?</p> <p>行,只要裝個 <a href="http://www.bluestacks.com/">Bluestacks</a> 就可以在 PC 上跑 Flipboard 等各種 Android Apps。Bluestacks 支援 Windows 和 Mac 作業系統。我在 Windows 上裝了 Bluestacks,以我的 Google 帳號登入,然後安裝了 Flipboard,結果:</p> <p><a href="http://lh6.ggpht.com/-QRqlMZDiHbI/UXlPN56B1nI/AAAAAAAALCY/tV-RojP1iWI/s1600-h/image%25255B3%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh5.ggpht.com/-B_BkeRlj03Q/UXlPPJM3beI/AAAAAAAALCg/alalHHlpeXQ/image_thumb%25255B1%25255D.png?imgmax=800" width="730" height="446" /></a></p> <p>哇嗚!成功了,現在我在 PC 上也可以玩 Flipboard 了!</p> <p>所有 Flipboard 的功能都可以正常使用,而且用自己的帳號登入後 Flipboard 會自動跟你手機上的設定同步,PC 和手機上訂閱的雜誌兩邊都看得到。</p> <p>對了,你還可以建立一個 Flipboard 的捷徑。方法是切到 C:\Users\Public\Libraries\Apps.library-ms 資料夾:</p> <p><a href="http://lh4.ggpht.com/-wko5JSG0Xp8/UXlPQJZy-cI/AAAAAAAALCo/ChGnMRQUH6w/s1600-h/image%25255B7%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-PamkqwXCRR4/UXlPQxzR-eI/AAAAAAAALCw/FY3SZ2aSStI/image_thumb%25255B3%25255D.png?imgmax=800" width="730" height="462" /></a></p> <p>然後你會看到 Fliboard 的圖示,只要建個捷徑把它放到桌面上就好了:</p> <p><a href="http://lh3.ggpht.com/-ZaVlipKuJ2Q/UXlP26Lmj6I/AAAAAAAALC4/AjCVmScs6C8/s1600-h/image%25255B10%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-KhtAUIeMbcE/UXlP3iVQONI/AAAAAAAALDA/JyLjWinSbS4/image_thumb%25255B4%25255D.png?imgmax=800" width="275" height="212" /></a></p> <h5>參考資料</h5> <ul> <li><a href="http://briian.com/?p=8135">重灌狂人 – BlueStacks 免買手機、平板電腦,直接在電腦玩 Android 遊戲、App</a> </li> </ul> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-46207611566158762452013-04-15T21:32:00.000+08:002013-04-15T21:34:52.414+08:00GPIO_UGLY for Cubieboard<p>在<a href="http://coopermaa2nd.blogspot.tw/2013/04/cubieboard.html">快速認識 Cubieboard</a> 後,我們知道 Cubieboard 背面有 96 支擴充針腳,我們可以利用這些 GPIO 針腳連接各種電子零件,譬如 LED、開關、馬達、光敏電阻、溫度感測器等等,藉以擴充 Cubieboard 的功能,製作各種電子專題。可惜的是,目前 Cubieboard 的 Linux 作業系統,其提供的 Kernel 大部份都還沒支援 GPIO 控制(官方比較新版的 Kernel 似乎已經有 GPIO 的 kernel module,不過我還沒試),所以如果你想使用 GPIO 針腳,也許可以試試 GPIO_UGLY 這個 Kernel module。</p> <h5>安裝</h5> <p>首先,請下載這兩個檔案:</p> <ul> <li><a href="http://bit.ly/XKMqCy">kernel_a10_aufs.img</a> </li> <li><a href="http://bit.ly/116tKdy">script.bin</a> </li> </ul> <p>kernel_a10_aufs.img 是給 Cubieboard 用的 Linux Kernel,我已經把 GPIO_UGLY 這個 Kernel module 編譯進去,適用於<a href="http://coopermaa2nd.blogspot.tw/2013/04/berryboot-cubieboard.html">使用 berryboot 刷機</a>的系統。Kernel 的版本是 3.4.24,我用 <a href="http://sourceforge.net/projects/berryboot/files/?source=navbar">berryboot-cubieboard-beta6</a> 測試過,可以正常運作。</p> <p>下載後,把 SD Card 插到電腦 USB Port,然後把兩個檔案複製到 SD Card 覆蓋掉 berryboot 原來的版本,如果你擔心這個動作失敗從此開不了機,那麼可以把原始檔改個名字備份起來。完成後,把 SD Card 插回 Cubieboard,然後上電,開機。</p> <p><a href="http://lh3.ggpht.com/-nS7WvlVMoVU/UWqKWgl2EyI/AAAAAAAALAE/RtwA40h2hGU/s1600-h/image%25255B23%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN_TtyPy5H1czEBX7_NTfmDj5NyD6JeOAC5FY-_H9WrdpHUi6A9f3ormMAUavgc4RWg5B5J7BfxpBzvXmkCxSoyZuqiJXtezDSu_2lrW4nFF-nlqlI6s3foGMbDnI3kmxYNzNtv5oz4gO1/?imgmax=800" width="774" height="445" /></a></p> <h5>使用說明</h5> <p>更新好 Kernel 後,就可以開始使用 GPIO 針腳了。</p> <p>首先,先看看可以用的 GPIO 針腳有哪些:</p> <p>    $ ls /sys/devices/virtual/misc/sun4i-gpio/pin</p> <p>看到的結果應該會是:</p> <p><a href="http://lh3.ggpht.com/-AuPld0YVaJI/UWqKXrhOggI/AAAAAAAALAU/nQYR14M2zwM/s1600-h/image%25255B2%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh5.ggpht.com/-pUkVwQrYhn4/UWqKX7qbpQI/AAAAAAAALAc/O_BH3LKYxGs/image_thumb.png?imgmax=800" width="643" height="200" /></a></p> <p>算一算,總共有 67 支針腳可用。雖說有 96 支針腳,但其實有很多針腳是 PWR, GND 等電源針腳,還有一些針腳不能用,可能有特殊用途吧。</p> <p>接著,我們選一支針腳來玩,但是要怎麼知道針腳的對應關係呢?方法是查 <a href="http://linux-sunxi.org/Cubieboard#Expansion_ports">Cubieboard Expansion ports</a>,總共有兩張對應表,一張是靠近 SATA 介面的兩排針腳的對應表,另一張是介於 Ethernet port 與 USB port 之間的兩排針腳的對應表。</p> <p>以 SATA 介面的兩排針腳的對應表為例:</p> <p><a href="http://lh5.ggpht.com/-0BzlA7D4Lec/UWqKYY9lyLI/AAAAAAAALAk/qUxDELRUDrY/s1600-h/image%25255B5%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-BpFRNA13MUs/UWqKY0LQOBI/AAAAAAAALAs/sVuT4fROru0/image_thumb%25255B1%25255D.png?imgmax=800" width="464" height="738" /></a></p> <p>查表後,可知 Pin 1 是 PD0,而 Pin 2 是 GND:</p> <p><a href="http://lh6.ggpht.com/-WLMtAJhT0i0/UWrKl-vQ3EI/AAAAAAAALBs/8iGVCeCo7UI/s1600-h/image9%25255B1%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh5.ggpht.com/-DCM6ciQM68E/UWqKdKqWEWI/AAAAAAAALB0/duzDczIGG9I/image9_thumb.png?imgmax=800" width="730" height="423" /></a></p> <p>好,PD0,就是你了,出列吧,誰叫你要排最前面啊。^o^</p> <p>現在,在 PD0 上接一顆 LED,LED 接法是長腳接 PD0,短腳接 GND。</p> <p><a href="http://lh4.ggpht.com/-P7yWTemW-g4/UWqKf50C0tI/AAAAAAAALB4/GxO8plknIQA/s1600-h/image25%25255B1%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh5.ggpht.com/-Jtxg_HVJrUE/UWqKhl645CI/AAAAAAAALB8/Slcg7pKCNSI/image25_thumb.png?imgmax=800" width="730" height="544" /></a></p> <p><a href="http://lh3.ggpht.com/-1aEvNsz9i4g/UWqKjhWOYrI/AAAAAAAALBU/52cyW5uHVMw/s1600-h/image%25255B31%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh6.ggpht.com/-6eAOvawdHoI/UWqKlStOgsI/AAAAAAAALBc/m170d9V4yM0/image_thumb%25255B11%25255D.png?imgmax=800" width="500" height="676" /></a></p> <p>然後以底下的指令控制 LED 的明滅:</p> <p><code>    $ echo 1 > /sys/devices/virtual/misc/sun4i-gpio/pin/pd0 <br />    $ echo 0 > /sys/devices/virtual/misc/sun4i-gpio/pin/pd0 </code></p> <p>耶!完成囉!</p> <p>也可以寫個簡單的 Shell Script 控制 LED 的明滅,例如底下的 blink.sh:</p> <p><script type="syntaxhighlighter" class="brush: bash"><![CDATA[<br />#!/bin/sh<br /><br /># IMPORTANT! To run this script, you have to be root<br />#<br /># sudo ./blink.sh<br /><br />LED=/sys/devices/virtual/misc/sun4i-gpio/pin/pd0 <br /><br />ON=1<br />OFF=0<br /><br /># We will play the blue one here<br />while true; do<br /> echo $ON > $LED<br /> sleep 1<br /> echo $OFF > $LED<br /> sleep 1<br />done<br /><br /><br />]]></script></p> <p>以 sudo ./blink.sh 執行後,接在 PD0 的 LED 燈就會亮一下,滅一下,不斷地循環。</p> <h5>參考資料</h5> <ul> <li><a href="http://coopermaa2nd.blogspot.tw/2013/04/cubieboard.html">快速認識 Cubieboard</a> </li> <li><a href="http://coopermaa2nd.blogspot.tw/2013/04/berryboot-cubieboard.html">用 Berryboot 刷 Cubieboard</a> </li> <li><a href="http://my.oschina.net/lanybass/blog/107688">在 Cubieboard 上通過 GPIO 成功點亮第一個 LED</a> </li> <li><a href="http://cn.cubieboard.org/forum.php?mod=viewthread&tid=138">如何編譯單個驅動文件</a> </li> </ul> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-3486902472641224412013-04-14T15:21:00.001+08:002013-04-14T16:47:37.517+08:00備份 SD Card<p>終於,Raspberry Pi 作業系統跑起來了,要玩的應用程式也都安裝好並且設定完成了,接下來你應該備份 SD Card 以防萬一,免得將來又得重灌所有的東西。所以,咱們來備份 Raspberry Pi 的 SD card 吧。</p> <p>在 Windows 上,你可以用 <a href="https://launchpad.net/win32-image-writer/+download">Win32diskimager</a>。步驟很簡單,只要輸入 image 的檔名,選擇 SD Card 的 Device,接著點選 Read 鈕就行了:</p> <p><a href="http://lh4.ggpht.com/-3VCdX1rVShU/UWpY4gq3QqI/AAAAAAAAK_c/z31iINPblBI/s1600-h/image%25255B2%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyxZVeLXKTUVXhokDAZAc2Uvx_3f148zDB76r_nxnkfAndtzXsxNEPtjatKIQ3buzmwQ_Lt2qb6n-ZpMZ20-zZ1eHbos7hPHjNVZfnNxAeBtkyrnMm-QJArD2CrIKyCrl848h8vDKtIVpb/?imgmax=800" width="421" height="213" /></a></p> <p>然後,稍候一下,過幾分鐘後 SD Card 就備份完成了。</p> <p><a href="http://lh4.ggpht.com/-nZJdTnkNETE/UWpY56jmiFI/AAAAAAAAK_s/nWLErQaTe4g/s1600-h/image%25255B5%25255D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://lh4.ggpht.com/-AwCqkDV8gh4/UWpY6AvlnQI/AAAAAAAAK_0/ddT1rPFoceg/image_thumb%25255B1%25255D.png?imgmax=800" width="421" height="213" /></a></p> <p>看你用的 SD Card 有多大,image 檔就有多大,比如 SD Card 是 8GB,那 image 檔就是 8GB。image 製作完成後,你可以把檔案壓縮一下,這樣比較省空間。</p> <p>在 Linux 上,請以底下的指令備份 SD Card:</p> <p><code>    $ dd if=/dev/sdX of=/path/to/image</code></p> <p>或者是備份的時候順便壓縮:</p> <p><code>    $ dd if=/dev/sdx | gzip > /path/to/image.gz</code></p> <p>其中 /dev/sdX 是你的 SD Card 設備。</p> <p>要把 image 還原到 SD Card,就反過來做:</p> <p><code>    $ dd if=/path/to/image of=/dev/sdx</code></p> <p><code>如果檔案有經過壓縮,請以底下的指令還原:</code></p> <p><code>   $ </code><code>gzip -dc /path/to/image.gz | dd of=/dev/sdx</code></p> <h5>參考資料</h5> <ul> <li><a href="http://linux.vbird.org/linux_basic/0240tarcompress.php#dd">鳥哥的私房菜 – dd 備份工具</a> </li> </ul> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0tag:blogger.com,1999:blog-8516057646005806683.post-4086105686792499612013-04-12T09:56:00.001+08:002013-04-12T09:56:11.978+08:00超棒的 Arduino pinout diagrams<p>有個叫 Pighixxxx 的義大利人,最近製作了好多 Arduino 的 pinout diagrams 貼在 <a href="http://arduino.cc/forum/index.php/topic,146315.0.html">Arduino forum</a> 上,有 Arduino UNO 的,有很多張 ATMega 的,例如 ATMega328 與 ATMega1284p 等,也有幾張是 ATTiny 的。例如底下這張是 UNO 的 pinout diagram:</p> <p><a href="http://lh6.ggpht.com/-hYTC_QJLIUo/UWdpq8bvQ5I/AAAAAAAAK-0/8sLizJ70ll4/s1600-h/ARDUINO_V2%25255B4%25255D.png"><img title="ARDUINO_V2" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="ARDUINO_V2" src="http://lh6.ggpht.com/-PlsYLyLJ77E/UWdpseQBu3I/AAAAAAAAK-8/KFLzqBDyAi4/ARDUINO_V2_thumb%25255B2%25255D.png?imgmax=800" width="720" height="509" /></a></p> <p>這些圖畫的真棒,好清楚,對如何使用 Arduino 的針腳幫助很大。</p> <p>之前我寫過「<a href="http://coopermaa2nd.blogspot.tw/2011/07/from-arduino-to-avr.html">From Arduino to AVR 單晶片教學</a>」一系列的教學文章,搭配這些精美的圖來學習,真是再好不過了。</p> <p><a href="http://lh5.ggpht.com/-it15hEOUu7s/UWdptoq7mLI/AAAAAAAAK_E/9atR_EAw5H4/s1600-h/arduino_atmega328_Web%25255B3%25255D.png"><img title="arduino_atmega328_Web" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="arduino_atmega328_Web" src="http://lh3.ggpht.com/-0nqsFUYxORM/UWdpulTpAtI/AAAAAAAAK_M/avw0M5OcHW0/arduino_atmega328_Web_thumb%25255B1%25255D.png?imgmax=800" width="720" height="509" /></a></p> <p>pighixxx 畫的這些圖,除了可以在 <a href="http://arduino.cc/forum/index.php/topic,146315.0.html">Arduino forum</a> 上看到外,也可以到他<a href="http://www.pighixxx.com/">個人網站</a>下載,圖檔有 PNG 格式,也有 PDF 格式。</p> Cooper Maahttp://www.blogger.com/profile/14597993167511073460noreply@blogger.com0