把遇到錯誤的、學習到的前端筆記在這邊

總瀏覽量

Copyright © Tzeng Ying-chi. 技術提供:Blogger.

2019/09/18

[2019鐵人賽] - 10.筆記IoT初練習- 急!在线等!用 Socket.io 建立即時連線~ (一)


為了搭上梗 標題才用簡(ㄘㄢˊ)體字的  (´∩ω∩`)

說好的物聯網呢?


現在你的心之音一定充滿疑問....

心之音:欸...不是R...都到第10天了....你這個魯宅不是說要做物聯網嗎?是連到哪了?
(╯‵□′)╯︵┴─┴
本魯:現在就來說了啦....不急不急~(我絕對不會說因為ESP8266搞了我一個月還弄不好,只好放棄無線通訊

好吧....我是真的研究很久ESP8266,可是都弄不好....
看看20天之後有沒有可能起死回生好了TAT (誰有魔法卡死者甦醒,給我一張R....(;´༎ຶД༎ຶ)
沒有ESP8266沒有關係!我們用Socket.io來實現!

### First, What is IoT ?

物聯網 - Internet of Things 簡稱 IoT ,但物聯網是什麼概念呢?試想你的生活中已經存在著多少物聯網的意象?

來點小故事舉例來說:( 絕對不是本魯的生活 )
今天寫鐵人賽寫到很累時,你去附近的便利商店買零食吃,結帳時 店員刷餅乾包裝的條碼來結帳,付款時你早就想到自己是月光族沒有新台幣只好 拿iCash付款,回家吃餅乾邊打鐵人賽總算寫好了,發表出去又完成一天了,心裡感到滿足~

這個小故事之中,包含著許多物聯網的概念!
像是:
- 店員刷餅乾包裝的條碼來結帳
- 付款 拿iCash付款(不是葉佩文
- 鐵人賽寫好了,發表出去

例子說明: 店員刷餅乾包裝的條碼來結帳
物 → 餅乾
聯 → 餅乾上的唯一商品條碼,藉由刷條碼機把條碼傳到主機上來辨別是什麼物
網 → 主機找這是什麼物品,處理完顯示餅乾的資訊

例子說明: 付款 拿iCash付款
物 → iCash
聯 → iCash上的唯一識別碼( unique identifiers, 簡寫 UID ),感應之後傳 UID 到主機上
網 → 主機利用UID找相關資訊,並且處理 扣款、存紅利點數等動作....

他們都有相同的特徵,彼此透過約定好的協定來做之間的連結、溝通 ;
物聯網不僅只是兩種裝置之間的連結,通常也連結到負責收集資料(Sensor)、協到裝置運作的Server,還有輸出介面讓使用者監控及操作。

### Introduce Socket.io &express

今天要來介紹一下 Socket.io 和 express 在物聯網之中的角色!

WebSocket通訊協定
傳統網頁使用HTTP通訊協定,當開啟網頁時 Client 用戶端會向 Sever 伺服端請求資源稱為「 request 」,接著 Server 端回應 Client 端所需要的要求稱為「 response 」
有要求才有回應,因此這種通訊模式屬於單向的,一定要由 Client 端請求才有動作, Sever 端是不會主動傳資料給用戶的!

但 WebSocket 協定能夠在 Client 端和 Server 端建立起雙向的通訊,一旦連線成功 Client 端和Sevrer端就能一直維持連線,直到其中一方中斷為止!WebSocket 使得 Client 端和 Server 端間的資料交換更加的簡單,且擁有即時性的優點~

但由於 WebSocket 這項技術需要網站伺服器和瀏覽器都要支援才能使用....
因此,我們使用Node.js 的 Socket.io 套件來解決相容性的問題٩(。・ω・。)و

> Socket.io:https://socket.io/

socket.io擔任溝通的橋樑

極簡的 Node.js Web 架構

剛談到組成物聯網的要件需要User 、Communication、Server
Socket.io擔任溝通的角色,那Server端呢?
我們使用 " express "
> Express.js:https://expressjs.com/

Express 為 Node.js Web 應用程式架構,建立在NodeJS上的輕量級Server
我們將使用 Express 來啟動服務程序。
(對伺服器架構不太了解的本魯


小試身手~就來實作吧!

我們必須要有以下要件才能達成建立即時通訊,
- Node.js
- Socket.io 套件
- express 套件


安裝 express 和 socket.io 套件

首先創立新專案資料夾,我們在 package.json 檔中 dependencies 的地方新增 express 和 socket.io 套件,新增完後在終端機輸入 " npm install " 安裝套件
```json
{
  "name": "專案名稱",
  "version": "專案版本",
  "description": "專案描述",
  "main": "專案進入點",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "作者",
  "license": "ISC",
  "dependencies": {
    "johnny-five": "^1.3.0",
    "express": "^4.12.0",
    "socket.io": "^1.3.4"
  }
}
```

新增完後先做簡單的測試頁面,來看看我們的 Socket.io 是不是運作正常~
程式部分會分成前端網頁和後端伺服器兩個部分

下集來實作程式部分~

本文到這邊先下台一鞠躬了~
有錯敬請留言改正,感謝您的閱讀 <(_ _)>

2019/09/12

[2019鐵人賽] - 9.筆記IoT初練習- Johnny Five -轉吧!七彩霓紅燈~LED.RGB


轉吧~轉啊~七彩霓虹燈~( ~'ω')~
    讓我看透這一個人生~( 'ω'~) ( ~'ω')~


今天要介紹的是三色LED,但我們要做的東西不會轉.....(被打 (´∩ω∩`)

三色LED 他可以分別發出不同的顏色(單色),也可以以混光的方式發出更廣的色域光;
由於三色LED分別由 紅色、綠色、藍色LED所包裝組成一顆LED,在外觀上則有四隻針腳, 三隻分別為RGB的腳位,其中一隻為共同腳

如果為共陰極的LED 則共同腳要接GND(接地),反之如果為共陽極的RBG LED 共腳則要接在VCC才能使其發光,外面販賣三色LED時,會說他是共陰極或是共陽極,就是這個意思~

右圖為三色LED的電路圖符號
本魯宅的三色LED是已經模組化的共陽極LED套件,
今天要實做的連接電路部分比較簡單,如果是共陰極,共同腳請接到GND,如果是共陽極,共同腳請接到VCC,其他RGB腳我們挑三個PWM腳位上即可~

硬體部分

> Arduino Uno 一片 + USB TypeB 線材一條  (這標配
> 三色LED * 1
> 電阻 220歐姆 or 330歐姆 * 3
> 杜邦線 看你用幾條準備幾條

軟體部分


> Johnny Five LED-http://johnny-five.io/api/led.rgb/

要使用Johnny Five RGB LED,元件初始化首先要new一個 five.Led.RGB 物件,並且pins為必要參數,接腳則都必須使用支援PWM的腳位

new five.Led.RGB({ pins: { red: 6, green: 5, blue: 3 } });

也可以把Pin寫成Array,簡化寫法
陣列索引值0,1,2 順序分別代表 紅色、綠色、藍色 pin腳腳位,即RGB

new five.Led.RGB({ pins: [6, 5, 3]
//[R, G, B] });

也可以省略pins參數,更簡化的寫法

new five.Led.RGB([6, 5, 3]);

陣列也一樣代表R、G、B三個腳位

剛剛提到RGB LED有共陽共陰之分,而Led.RGB物件預設為共陰極的LED,如果你使用的是
共陽極的LED,請在物件中加上 isAnode 參數,並設定為true

寫法:

new five.Led.RGB({ pins: { red: 6, green: 5, blue: 3 }, isAnode: true });

而API部分其中on()、off()、toggle()、strobe()、stop()和之前介紹LED是一樣的,這邊就不在闡述~

Led.RGB有兩個新的API分別是color(value)intensity(value)

.color(value)

 - 設定LED的顏色,假設value沒有給值的話,那預設狀態值則返回 { red: 255, green: 255, blue: 255 },LED會呈現白光 。




Value的表現方式可以有下面幾種

 -  HTML Color Names
可以直接用W3C規範的HTML Color Names字串帶入Value裡,X11顏色集的字串也可以使用,例如:
"red"、"blue"、"Violet"、"SkyBlue".....etc


HTML Color Names 相關連結:
.CSS Color Module Level 4 - World Wide Web Consortium
https://www.w3.org/TR/css-color-4/#named-colors
.HTML Color Names - W3Schools
https://www.w3schools.com/colors/colors_names.asp
.Web colors - Wikipedia
https://en.wikipedia.org/wiki/Web_colors


 -  十六進制(HEX)色碼字串
我們最常使用的色碼表示方式,由一個#號加上六個數字所組成。
無論有沒有加上 # 字號 color(value)都能接受並顯示出來,例如
"ff0000", "00ff00", "#00ff00", "#0000ff"......etc



推薦了解色碼表示方式:
.由CssCoke Amos老師所寫 - RGB、HSL、Hex 網頁色彩碼,看完這篇全懂了
http://csscoke.com/2015/01/01/rgb-hsl-hex/


 -  用陣列(Array)使用8位元表示法
顏色的明度由淺(暗)到深(亮)來表示00為最淺(暗)、ff為最深(亮),寫法為 0x00 ~ 0xff 即取值範圍為0~255,0x開頭為16進制表示法。
如果使用此寫法,value為陣列 即[0xff, 0xff, 0xff] = [R, G ,B ],舉例來說
紅色=[0xff, 0x00, 0x00]
紫色=[0xff, 0x00, 0xff]
白色=[0xff, 0xff, 0xff]
這寫法是比較麻煩啦....而且也不直觀....




參考連結:
安卓自定义View基础-颜色(看顏色部分就好....
https://www.gcssloop.com/customview/Color


 -  用物件(Object)使用8位元表示法
顏色的操作方法和上面一樣,如果使用此寫法,color(value)中的value為物件,value寫法為{ red: 0x00, green: 0xFF, blue: 0x00 },物件中的Key值為rgb,value為8-bit色碼
舉例:
紅色={ red: 0xff, green: 0x00, blue: 0x00 }
紫色={ red: 0xff, green: 0x00, blue: 0xff }
白色={ red: 0xff, green: 0xff, blue: 0xff }



----

.intensity(value)

 - 設定LED整體的亮度(明度),在LED單元中有brightness()函式,這邊使用intensity(value),value的數值為0~100,用百分比來呈現。
假設value沒有給值的話,LED則為當前亮度。



實作七彩霓虹燈 

謎之音:不就是七個顏色輪流變嗎??  (╯°Д°)╯~ ┻━┻
本魯宅:不不~我們要加上不一樣的效果當然不能都抄襲官網的範例啊 (*ˇωˇ*人)
謎之音:喔~原來是致敬啊....  (メ゚Д゚)メ


實作
有淡入效果的七彩霓虹燈~



分成三大區塊動作

1. 宣告變數與參數:
因為顏色不多只有七個顏色,就用最簡單的我們把七個顏色的色碼寫為陣列

2. 顏色部分:
利用for迴圈讓他loop 輪流紅→橙→黃→綠→藍→靛→紫,設定一秒後為下一個顏色!

3. 淡入的效果:
在進入下一個顏色內,呼叫 intensity( ) ,使LED亮度從0(暗) → 99(亮),藉此來呈現淡入的效果。

但這邊會有個問題!intensity的value值,用for迴圈累加 i 值
因為JS for迴圈執行速度太快了,又沒有像C/C++有類似sleep延遲執行的指令,value 瞬間就會從0加到99了,這樣以人眼來看根本看不出有LED有漸亮的效果....( ˘•ω•˘ )a

所以!參拜一下谷哥大神後,於是就有答案啦!ヾ(◎´・ω・`)ノ

原來JS有for迴圈的阻塞機制(註一),讓迴圈延遲幾毫秒後在繼續動作!(心之音:哇~這根本解救了我
這樣我們就可以讓LED的亮度慢慢亮起來,產生淡入的效果了~ σ`∀´)σ

註一:JS實現停留幾秒sleep,Js中for迴圈的阻塞機制,setTimeout延遲執行


進階實作 (並不是X
看透人生的七彩霓虹燈 (謎之音:這殺小....朋友啦XD
 
沒錯!我們要呼應一下開頭!
你的人生是怎樣的呢?
是色彩繽紛的人生嗎~還是充滿七彩光芒的人生呢~

本魯宅以這個例子來說明我的人生樣態

一樣分成三大區塊動作



宣告變數與參數 和顏色部分和上一個例子是一樣的,就不多說了~
19~23行,這次我們不用淡入的效果,我們用 Math.floor(Math.random() * 100 + 1)  亂數產生1~100的整數,在使用led.intensity放入數值~

我的人生七彩霓虹燈做出來啦~ヽ(・×・´)ゞ



恩..........沒錯就是這樣.........Orz

本文到這邊先下台一鞠躬了~
有錯敬請留言改正,感謝您的閱讀 <(_ _)>

2019/09/06

[2019鐵人賽] - 8.筆記IoT初練習-Johnny Five - LED Level 2練習!來點變化吧之PWM


人生短短幾個秋~來點變化吧~(  ̄ 3 ̄)y▂ξ 


上篇提到LED的簡單用法,這篇要來說還有什麼方法可以使用~

首先要提到PWM這個名詞,
PWM全名為「脈波寬度調變」英語:Pulse Width Modulation,簡稱脈寬調變

>將類比訊號轉換為脈波的一種技術,一般轉換後脈波的週期固定,但脈波的工作週期會依類比訊號的大小而改變。

在類比電路中,類比訊號的值可以連續進行變化,在時間和值的幅度上都幾乎沒有限制,基本上可以取任何實數值,輸入與輸出也呈線性變化。PWM技術是一種對類比訊號電位的數位編碼方法,通過使用高解析度計數器(調變頻率)調變方波的占空比,從而實現對一個類比訊號的電位進行編碼。其最大的優點是從處理器到被控對象之間的所有訊號都是數位形式的,無需再進行數位類比轉換過程;而且對雜訊的抗干擾能力也大大增強,這也是PWM在通訊等訊號傳輸行業得到大量應用的主要原因。

> wiki-脈波寬度調變:https://w.wiki/7ox

恩...(ㆆᴗㆆ)  看完PWM維基百科之後和天書一樣沒有看懂....(汗

簡單的說就是「把類比訊號透過脈衝方波的方式編碼,來獲得數位電路的優點!」

我做了一張解說圖來說明~
第一個波形圖,紅色部分為原始類比訊號藍色為鋸齒波
在之前的文章提到過類比訊號的特性是連續且不斷變化,現在有一個類比訊號(紅色波型)為一個正旋波,我們加入一個簡單的鋸齒波後把其相比之後,在任意時間點假設類比訊號比我們給予的鋸齒波來的大,那麼其產生出來的PWM波形為High狀態,反之類比訊號比鋸齒波來的小,那麼產出來的PWM訊號為Low狀態。

PWM通常使用在類比控制上,生活中譬如螢幕亮度的調光、LED 連續亮度的調整、喇叭音量大小的控制等等....這些都是使用到PWM這項技術~

> 圖為潛入通訊行田野調查各家手機的螢幕ψ(`∇´)ψ

而Arduino的pin腳也有提供PWM輸出的功能!( ~'ω')~
仔細看板子上digital pin有一些腳位有(~)的記號,就代表這個是有PWM的pin腳可以輸出數位類比訊號~


為什麼要介紹PWM呢?
因為接下來要介紹Johnny-five LED function brightness( )、fadeIn( )、fadeOut( )、pulse( ) 訊號需要經由PWM輸出 ( • ̀ω•́ )

> Johnny Five LED-http://johnny-five.io/api/led/#api

那開始介紹這些功能吧!d(`・∀・)b

*特別注意操作這個功能只能在PWM Pin腳上輸出,所以官方文件上的範例才會宣告LED腳位連接板子第11隻腳輸出。如果使用PWM輸出但宣告的腳位錯誤的話,執行node後會有錯誤訊息跑出

. brightness(0-255)
 - 設定LED的亮度,亮度有255階,0是最暗,255則是最亮。



.fade(brightness, ms, callback)
 - LED從當前亮度在設定的週期時間 漸亮或是漸暗。
brightness 亮度 0-255 ;ms毫秒 1000毫秒(ms)為一秒(s)



. fadeIn(ms, callback)
 - LED從當前亮度在設定的週期時間漸亮。
ms參數為必需,若沒有設定ms LED會直接亮,不會有漸亮的效果!
PS:但ms沒有設定,程式也不會報錯╮(╯_╰)╭




.fadeOut(ms, callback)
 - LED從當前亮度在設定的週期時間漸暗。
fadeIn()。




~題外話~
在我無聊的測試下(魯宅工程師的好奇心
fadeIn和fadeOut實在很神奇,怎麼說呢?
同樣在連線啟動後直接執行該函式下,fadeIn() LED會漸亮,但fadeOut()卻不會從亮到滅?





我猜想應該是初始狀態下 LED 都是滅的,執行fadeIn()的時候亮度是0→255,但換執行fadeOut()時亮度是0→0,所以fadeOut()不會有漸滅的現象.....
一定要LED初始狀態為On,才看得出效果。( ˘•ω•˘ )

. pulse(ms, callback)
 - LED在一個週期內會漸亮到漸滅在繼續下一個週期動作,一直持續下去。
pulse 有點像 fadeIn + fadeOut 的連續動作....
如blink()一樣,如果要停止動作需要使用stop()停止,stop()一樣也是停止計數器的動作,並不會把LED滅掉,如果要完整的關閉LED 需要呼叫stop()和off(),即 led.stop().off();



耶~LED終於講完了(இдஇ )

天啊......我以為可以輕鬆寫LED的文章.....
這最基本的東西....沒想到比想像中的還辛苦一百倍(果然鐵人賽很痛苦...Orz

本文到這邊先下台一鞠躬了~
有錯敬請留言改正,感謝您的閱讀 <(_ _)>

2019/09/02

[2019鐵人賽] - 7.筆記IoT初練習-Johnny Five LED Level 1練習- Hello LED World!


新手上路!初進IoT的世界就從最簡單的開始吧!(ง๑ •̀_•́)ง

發光二極體(Light-emitting diode),就是我們俗稱的「 LED 」

回溯歷史,從只有紅光、綠光兩個顏色時代,
直到藍色光LED被研發出來造就現在的LED顏色光譜!

> 節錄wiki -
2014年憑藉「發明高亮度藍色發光二極體,帶來了節能明亮的白色光源」,天野浩與赤崎勇、中村修二共同獲得諾貝爾物理學獎

題外話~以前我在讀高職、大學的時候,也都沒有藍色LED可以用...
後來自己跑去光華商場買,藍色一顆就要10元!超貴的!(●▼●;)
PS:紅、綠色一顆只要2、3元


LED有極性之分,教大家怎麼看極性,我做了幾張圖來解說~

- 從外觀來判斷
依規範來說,LED的端子長腳為正極 短腳為負極



那你們心中一定會有很大的疑問~
如果不小心在路上(欸?)撿到一顆LED,但是他的腳已經被剪掉了...
那要怎麼辨別呢? (|||゚д゚)

沒關係!還有方法可以辨別! 
仔細看LED的外觀邊緣處不是正圓形的,有一邊會有一個平面的特徵,那就是負極了!



以上兩種是由外觀來辨別LED的極性~
當然有一些廠商可能不會照著規範製作LED, 就會產生誤會了....
最好還是用電表來測試一下LED的好壞,在寫程式的時候也可以先排除硬體故障的因素。


- 從用電表來量測
電子的世界很大,無法把所有測試儀器都解釋,但是三用電表一定是最基本要準備的!
量測的方法是,先調到蜂鳴(開斷路)測試檔,紅棒接LED的正腳,黑棒接LED的負腳
如果會亮就代表成功!不亮的話反過來接再試一次,如果上述重複測試都沒有亮的話,可能要考慮看看是不是LED燒毀或是瑕疵損毀等,換一顆吧~

蜂鳴(開斷路)測試檔

紅棒接LED的正腳,黑棒接LED的負腳
如果會亮就代表成功!

那LED就介紹到這邊~(ゝ∀・)b


接下來要說Johnny-Five提供了什麼LED API 給我們~

> Johnny Five LED-http://johnny-five.io/api/led/#api

一共有13種方法可以讓我們做使用
因為很多功能都差不多就省略不說了~(好偷懶

新手LV1. 本篇就講解簡單的以下這些功能
on( )、off( )、toggle( )、stop( )、strobe( )/blink( )

. on( )
- 打開 LED



. off( )
 - 關閉LED。
但是特別注意如果你的LED 正在執行strobe() 或是blink() 的話,執行 off() 會沒有作用!
得先執行stop()函式停止strobe() 或是blink() 才行。



. toggle( )
- 切換LED目前的狀態。如果LED目前為亮則滅、為滅則亮。

假如目前LED為on則off

假如目前LED為off則on


. strobe( ) /
. blink( )
- 讓LED 亮→滅 頻率的閃爍。 可以利用stop()的方式讓閃爍停止,但注意 停止的是他的計數器,而不是讓LED回到滅(Off)狀態!
PS:strobe() 和blink()看不出有什麼差別....
連官網的注釋都說blink()只是strobe()的別名而已(。ŏ_ŏ)



. stop( )
- 停止計數器。讓blink、pulse等有時間週期類的動作停止,但注意 停止的是他的計數器,而不是讓LED回到滅(Off)狀態!如果要完全的關閉LED需要呼叫stop()和off()。

圖和off()那一張動圖一樣,就不放了..... <(_ _)>

本文到這邊先下台一鞠躬了~
有錯敬請留言改正,感謝您的閱讀 <(_ _)>

2019/08/22

[2019鐵人賽] - 6.筆記IoT初練習-利用REPL模式來開發!


今天要來簡介REPL怎麼用在Arduino上~ ٩(。・ω・。)و 


首先要來介紹REPL是什麼?

REPL 全名為「Read-Eval-Print Loop」讀取-求值-輸出 循環,是一種簡單的交互式的編輯環境 ;用戶輸入事件、表達式或是運算式,再由電腦進行處理運算,接著輸出給用戶,如此循環下去。

REPL很常見在前端開發者開發環境中,像瀏覽器的開發者工具的Console、使用終端機Terminal開啟Node,這些都是REPL~

例如以下:
→ Chrome中,開發者模式的Console drawer


→ 使用Terminal開啟Node JS的REPL模式

所以我們可以很方便的使用JavaScript在這些工具上debug或者開發等動作ヽ(・×・´)ゞ

那進入正題~
Johnny-five也提供了REPL的API,說明要怎麼在Arduino上調用REPL


Component Classes-Board #REPL: http://johnny-five.io/api/board/#repl


我們要使用Johnny-five提供的REPL範例來示範Arduino會怎樣動作~(๑•̀ㅂ•́)و✧
程式碼如下
var five = require("johnny-five"); var board = new five.Board(); board.on("ready", function() { console.log("Ready event. Repl instance auto-initialized!"); var led = new five.Led(13); this.repl.inject({ // 寫在這邊的函式可以透過REPL來操控 // 範例為操控LED的亮(on)與滅(off)
on: function() { led.on(); }, off: function() { led.off(); } }); });

Examples-Board-REPL: http://johnny-five.io/examples/repl/

當板子on ready後,REPL初始化也隨之啟動
範例中第9行呼叫了J5內建的方法 repl.inject 在大誇號裡面可以自訂函式,可以看到範例中有簡單的LED亮和滅的功能 ~


我在範例中增加上一篇的介紹的blink功能來實際操作給大家看( • ̀ω•́ )

首先執行範例檔repl.js在terminal輸入 node repl.js 電腦便會透過傳輸線上傳程式到Arduino上。
→ terminal輸入 node repl.js

可以看到執行Node JS後電腦開始找連接阜,連接上Arduino開發版之後執行REPL模式,
Connected狀態後,REPL會隨之初始化~
接下來我們試著操控LED燈即時的亮、滅、閃爍,在REPL模式中分別執行function on()、off()、blink() 來看實作結果!

→REPL模式下呼叫函式 on();

→REPL模式下呼叫函式 off();

→REPL模式下呼叫函式 blink();

很方便吧~ヽ(・×・´)ゞ

這就是Johnny-five提供REPL的方法,
「讀取函式→運算資料→輸出到Arduino運行結果→再繼續等待下一個循環動作」
讓我們可以簡易的查看實現的結果~ d(`・∀・)b

本文到這邊先下台一鞠躬了~
有錯敬請留言改正,感謝您的閱讀 <(_ _)>