FM611A
MQTT
在 《AI × LINE 聲控/人臉辨識生活大應用》的〈Lab 06 語音聲控電源插座〉中, 由於 D1 mini 是在區域網路中, 如果你不在該區域網路下就無法使用, 減損了這個實驗的應用廣度。在這篇教學中, 我們就把原本的實驗改成使用在物聯網應用相當普遍的 MQTT 傳輸協定, 讓網頁改放至公開的網路上, 並透過 MQTT 當中介傳輸資料, 讓 D1 mini 可以接收到網頁語音辨識的結果。
傳統網頁使用的 http 因為是泛用的協定, 必須考量到各種情況, 因此在傳輸資料時, 光是表頭的資料就要耗掉一定的傳輸量, 甚至常常有表頭的大小是實際傳輸資料量的數十甚至數百倍的狀況。如果採用 https, 又再加上電子憑證處理與加解密, 更是加重運算的負擔。
由於物聯網應用中, 個別裝置傳輸的資料量通常不大, 像是溫濕度數值、開關訊號等, 都是幾個位元組而以, 使用 http 不但浪費傳輸頻寬, 也會加重單晶片或是控制板的負擔。因此便有了專門為物聯網應用而生的傳輸協定–MQTT。
MQTT 傳輸協定主要區分為三種角色:發佈端 (publisher)、中介伺服器 (broker)、訂閱端 (subscriber):
digraph hierarchy {
nodesep=1.0 // increases the separation between nodes
node [color=Red,fontname=Courier,shape=box] //All nodes will this shape and colour
edge [color=Blue, style=dashed] //All the lines look like this
發佈端->中介伺服器 [label="發佈"]
中介伺服器->訂閱端 [label="轉送"]
訂閱端->中介伺服器 [label="訂閱"]
{rank=same;發佈端 中介伺服器 訂閱端} // Put them on the same level
}
由於發送端與訂閱端都是與中介伺服器溝通, 因此統稱為 MQTT 用戶端 (client), 兩者並不直接傳輸資料。每一個裝置都可以連上中介伺服器成為發佈端或是訂閱端, 甚至同時是發佈端與訂閱端。
這樣的作法連帶的好處就是發佈端與訂閱端都只要能夠連上外部網路接到 MQTT 中介伺服器即可相互通訊, 不會因為防火牆或是路由器阻擋外部裝置連入而無法傳遞資料。
本實驗就以語音辨識網頁為發佈端, Adafruit IO(簡稱 AIO) 為中介伺服器, D1 mini 控制板為訂閱端, 利用 MQTT 傳輸語音辨識結果:
digraph hierarchy {
nodesep=1.0 // increases the separation between nodes
node [color=Red,fontname=Courier,shape=box] //All nodes will this shape and colour
edge [color=Blue, style=dashed] //All the lines look like this
p[label="語音辨識網頁"]
m[label="AIO 中介伺服器"]
s[label="D1 mini 控制板"]
p->m [label="發佈"]
m->s [label="轉送"]
s->m [label="訂閱"]
{rank=same;p m s} // Put them on the same level
}
每當語音辨識網頁辨識出開燈的口令, 就要傳送 "100" 到中介伺服器的 voice 主題上;若是關燈的口令, 則要傳送 "0" 到 voice 主題上。D1 mini 則是要向中介伺服器訂閱 voice 主題, 就會自動在辨識出開關燈口令時收到 "100" 或是 "0", 即可依據收到的資料做出對應控制的動作了。
我們已經將語音辨識網頁準備好放在 https://flagtech.github.io/FM611A/voice_recog_mqtt.html, 只要使用瀏覽器連上就可以使用:
後續教學我們將著重在 AIO 以及 D1 mini 的程式上。
要完成 MQTT 傳輸, 最重要的就是中介伺服器, 請依照以下步驟到 AIO 註冊帳號, 並且建立 MQTT 傳輸主題:
請連線至 Adafruit IO:
點選Get Started fir Free
填寫必要欄位後按 CREATE ACCOUNT 建立帳號:
建立後點選上方的 IO 頁次:
點選 Feeds 頁次後按 view all:
按 New Feed
填入名稱為 "voice" 後按 Create 建立:
這裡建立的 feed 就是稍後 MQTT 傳輸時的主題。
按一下網頁右上方的 My Key:
這裡顯示的 Username 與 Active Key 就是稍後用戶端連上 AIO 時要填入的使用者名稱與金鑰:
請把網頁停留在這個畫面, 方便稍後複製使用。
建立好 AIO 帳號與傳輸主題後, 就可以使用語音辨識網頁測試:
請使用 Chrome 瀏覽器連至 https://flagtech.github.io/FM611A/voice_recog_mqtt.html, 請在網頁下方欄位分別填入剛剛看到的 AIO 使用者名稱與金鑰, 然後按一下開始辨識聲音:
按允許以便能夠使用麥克風蒐集聲音:
上方會出現訊息告知以成功連至 MQTT 伺服器:
此時即可說出『打開』口令, 若成功辨識, 便會出現訊息表示已將辨識結果傳送至 AIO:
切換到 AIO 網頁, 關閉剛剛的金鑰顯示畫面後按剛剛建立的 voice:
往下捲就會看到剛剛打開口令傳送的 100:
你可以試看看講『關閉』或是『打開』多次, 就可以看到每次辨識結果送來的資料:
有關語音辨識網頁的內容, 有興趣的人可以自行檢視原始碼, 我們並不會詳細說明。
現在已經可以讓語音辨識網頁將辨識結果發佈至 AIO 上, 最後一步就是要讓 D1 mini 程式可以跟 AIO 訂閱資料, 並依據資料執行對應的開關動作了:
你可以在這裡下載程式檔
請進入 FlagsBlock, 完成以下積木, 這部分與其他實驗相同, 不再贅述:
請務必記得修改成你自己的無線網路名稱與密碼。
定義處理收到 MQTT 訊息時的處理, 請先加入函式/定義函式積木後更改名稱為 "取得遠端指令":
加入流程控制/如果積木, 並展開否則如果分支:
加入 2 個邏輯/= 積木:
在 = 積木內部左側的欄位都放入 ESP8266 物聯網/新訊息內容積木, 右側分別放入文字/❝❞積木後填入 100 與 0:
最後填入收到個別訊息時要執行的開關繼電器動作:
指定 MQTT 中介伺服器的位址與通訊埠邊號, 請加入ESP8266 物聯網/啟用網址…埠號…的 MQTT 服務, 填入 AIO 中介伺服器的網址 io.adafruit.com 與埠號 1883:
再加入ESP8266 物聯網/使用…函式接收 MQTT 訊息積木, 並選取剛剛設計的取得遠端指令函式, 這表示當收到新的訊息時, 會自動執行這個函式:
最後就是實際連接 AIO 中介伺服器並接收資料的程式了, 請加入流程控制/重複當積木、邏輯/非積木、**ESP8266 物聯網/已連上 MQTT 伺服器?**積木後如下組合:
再加入流程控制/如果積木後展開否則如果分支, 如下組合:
加入ESP8266 物聯網/以…名稱…帳號…密碼連上 MQTT 伺服器積木, 名稱欄位請留空, 然後在帳號與密碼欄位填入剛剛看到的 AIO 名稱與金鑰:
加入ESP8266 物聯網/訂閱 MQTT 主題積木在連線成功時訂閱主題, 注意到雖然我們建立的 Feed 名稱是 "voice", 但是 AIO 規定主題要再加上使用者名稱與 "feeds" 字樣, 並以 "/" 分隔, 所以完整的主題是 "你的使用者名稱/feed/voice":
上例就是因為我的使用者名稱是 "meeboxflag", 所以訂閱的主題是 "meeboxflag/feeds/voice"。接著再加上時間/暫停 1000 毫秒積木在無法連上 MQTT 伺服器時等待 1 秒後再重試:
最後最重要的是加上ESP8266 物聯網/處理 MQTT 請求積木, 以便能夠接收 MQTT 伺服器送來的資料:
這樣就完成了 D1 mini 的程式, 請記得修改你的無線網路名稱與密碼、AIO 使用者名稱與金鑰、訂閱主題中的 AIO 使用者名稱後上傳程式, 利用語音辨識網頁辨識口令, 即可控制接在 D1 mini 上的繼電器了。
or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Do you want to remove this version name and description?
Syncing