###### tags: `Blynk` `FM628A`
# \[Blynk 新版\]《用 Python 蓋出物聯網智慧屋》
由於 Blynk 改版, 因此《[用 Python 蓋出物聯網智慧屋](https://www.flag.com.tw/maker/FM628A)》中與 Blynk 相關的實驗操作也要隨之更改, 本文就說明如何使用 Blynk 新版實作同樣的實驗。
## 更新 MicroPython 韌體
由於新版本的 Blynk 程式庫會跟舊版本的的 MicroPython 不相容, 請先參考[燒錄 MicroPython 韌體](/Rnn9Neh0RXSBO0FWi1DN9A)一文更新 MicroPython 至 1.19.1 版。
## Blynk 註冊帳號與 App 安裝
本文假設您已先閱讀並實作過〈[Blynk 新版使用說明](/N7YOLBKNTNyTPWejuK5Eqw)〉, 所以您應該已經註冊好新版的 Blynk 帳號, 也在您的 D1 mini 控制板上安裝好 Blynk 相關的程式庫, 如果您尚未完成, 請立刻閱讀〈[Blynk 新版使用說明](/N7YOLBKNTNyTPWejuK5Eqw)〉。
## 下載範例檔
使用原[下載網址](https://www.flag.com.tw/DL.asp?FM628A)即可以下載包含程式庫等檔案在內的範例檔。
:::info
如果您有舊版的 Blynk Legacy 仍在運作, 要使用原始的程式碼搭配執行, 可以在這裡[下載舊版的範例檔與程式庫](https://github.com/FlagTech/FM628A_IoTHouse/archive/refs/heads/Legacy.zip)。
:::
## 安裝編譯版的程式庫
由於 Blynk 程式庫比較肥大, 請先更換成編譯版的程式庫, 避免實驗時遇到記憶體不足的窘境:
1. 請先開啟檢視檔案的功能:

1. 將原本的程式庫按滑鼠右鍵選『**刪除**』:

1. 再將同名的 .mpy 檔上傳:

1. 確認上傳成功即可:

編譯版的程式庫使用方法一模一樣, 只是檔案比較小, 占用較少的記憶體。
## Lab 03 親友按門鈴
請先依照手冊組裝步驟完成硬體接線, 並以測試程式確認接線正確無誤。
### 建立樣版
1. 請登入 Blynk 網頁, 按一下左邊 **𓃑** 鈕進入樣板頁面後, 按一下右上角的 **+ New Template** 建立本套產品所要使用的 Blynk 樣板:

1. 請如下設定後按 **Done** 完成:

1. 我們希望可以在使用者按下門鈴時在手機端出現通知訊息, 這有賴於 Blynk 的**事件 (event)** 功能。請切換到 **Events** 頁次後按 **+ Add New Event**:

輸入事件名稱 "ring", 請選取 **Critical** 事件類型:

切換到 **Notifications** 頁次:

- 啟用 **Notifications** 功能。
- 設定通知對象為**裝置擁有者 (Device Owner)**。
- 設定 **Notification limit** 為 **1 minute**, 這表示 1 分鐘內若引發相同事件不會重複顯示多次通知訊息。
- 按 **Create** 完成。
1. 確認新增 ring 事件後, 按一下上方的 **Save** 儲存樣板:

### 建立裝置
接著建立本套件要使用的裝置:
1. 按一下左側放大鏡圖示按鈕切換到裝置頁面, 按一下 **+ New Device** 新增裝置:

:::info
由於免費帳號的 Blynk 只能擁有 2 個裝置, 因此若您已經建立過 2 個裝置, 就必須先移除 1 個裝置才能建立新的裝置。
1. 勾選現有的裝置後按 **Actions** 欄位的 ... 按鈕後選『**Delete**』:

1. 在確認交談窗中再按一下 **Delete** 刪除裝置:

:::
1. 選取 **From template** 依照樣板建立裝置:

1. 如下設定後按 **Create**:

1. 按右上角的 **×** 鈕關閉提示交談窗:

1. 切換到 **Device Info** 即可看到此裝置的認證權杖, 稍後程式中需用到:

### 設計手機 App 畫面
設計完樣板後, 就可以設計手機端的畫面了:
1. 開啟 Blynk App 後, 就會看到剛剛建立的裝置:

1. 按一下裝置進入後會看到 **Setup Dashboard** 按鈕, 提示您尚未設計手機畫面:

1. 此實驗只會在手機端顯示通知訊息, 不需要設計任何畫面。
### 撰寫程式
本實驗的程式如下:
```python=
from machine import Pin
import time, network
import BlynkLib
sta_if=network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect("WiFi 基地台", "WiFi 密碼")
while not sta_if.isconnected():
pass
print('wifi connect')
token="Blynk 認證權杖"
blynk=BlynkLib.Blynk(token)
# door D4
door=Pin(2,Pin.IN)
while True :
blynk.run()
print(door.value())
if door.value() == 0 :
print('有人按門鈴')
blynk.log_event("ring", "有人按門鈴")
time.sleep(1)
```
1. 第 25 列使用 log_event() 可以引發事件, 第 1 個參數是事件的識別名稱、第 2 個參數是選用的訊息, 這會顯示在手機端的通知訊息中。
### 測試程式
1. 請先更改程式中的無線網路名稱、密碼以及 Blynk 的認證權杖後執行:
1. 程式執行後看到連接 Blynk 的訊息後會不斷顯示按鈕狀態:
```
>>> %Run -c $EDITOR_CONTENT
___ __ __
/ _ )/ /_ _____ / /__
/ _ / / // / _ \/ '_/
/____/_/\_, /_//_/_/\_\
/___/ for Python v1.0.0 (esp8266)
wifi connect
Connecting to blynk.cloud:443...
1
1
1
0
有人按門鈴
1
1
1
```
1. 按下按鈕觸發事件, 手機端就會顯示快顯訊息如下:

快顯訊息中包含有裝置名稱、事件名稱、以及程式中指定的訊息內容。
1. 即使不在 Blynk App 畫面中, 也一樣會顯示快顯訊息:

:::danger
Blynk 的事件加上手機端的通知顯示很好用也很方便, 不過卻有以下限制:
1. 同一事件每秒鐘最多僅能引發 1 次。
2. 每 1 個裝置每天最多僅能引發 100 次事件。
如果這個限制不敷使用, 建議改用其他 Blynk 元件
:::
## Lab 04 遙控打開門
從這個實驗開始, 都是沿用前一個實驗建立的裝置, 我們僅會依照需求修改樣板。
### 修改樣板
此實驗要新增資料流, 讓 Blynk App 可以傳送指令給控制板開關門 (轉動伺服馬達):
1. 回到樣板頁面按一下剛剛設計的樣板:

1. 按一下右上角的 **Edit** 進入修改模式後切換到 **Datastreams** 頁次:

1. 新增使用虛擬腳位的資料流:

1. 如下設定後按 **Create** 完成:

1. 確認無誤按上方的 **Save** 儲存修改內容:

由於已經有依據該樣板建立的裝置, 所以會再出現確認畫面, 請選取 **Update 1 active device** 讓樣板的修改可以立即在現有的裝置中生效, 最後按 **Continue** 完成修改樣板:

### 修改 App 畫面
我們要在 App 畫面上新增按鈕, 讓使用者可以遙控伺服馬達開關門:
1. 在 Blynk App 中進入裝置畫面, 按一下 **Setup dashboard**:

1. 按一下右上角的 **☰** 鈕展開元件清單:

1. 加入 **Button** 元件:

調整元件大小及位置如下圖:

按一下元件進入設定頁面後如下設定按鈕, 設定完成後上左上角 **←** 回到畫面設計頁面:

再按一下上圖左上角逃生門圖示鈕離開設計畫面:

1. 這樣就完成畫面的設計了:

### 撰寫程式
以下是本實驗搭配新版 BLynk 的程式:
```python=
from machine import Pin,PWM
import time, network
import BlynkLib
sta_if=network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect("Wifi 基地台", "Wifi 密碼")
while not sta_if.isconnected():
pass
print('wifi connect')
token="Blynk 權杖"
blynk=BlynkLib.Blynk(token)
# servo D1
servo = PWM(Pin(5), freq=50)
servo.duty(30) # 舵機角度設定
def v0_handler(value):
print(value[0])
if value[0]=="0":
servo.duty(30)
print('大門打開')
else :
servo.duty(100)
print('大門關閉')
blynk.on("V0", v0_handler)
while True:
blynk.run()
```
這個程式和舊版幾乎一樣, 就不再多做說明了。
### 測試程式
更改程式中的無線網路名稱、密碼以及 Blynk 的認證權杖後執行:
```
>>> %Run -c $EDITOR_CONTENT
___ __ __
/ _ )/ /_ _____ / /__
/ _ / / // / _ \/ '_/
/____/_/\_, /_//_/_/\_\
/___/ for Python v1.0.0 (esp8266)
wifi connect
Connecting to blynk.cloud:443...
1
大門關閉
0
大門打開
```
就可以按畫面上的按鈕開關門, 控制板連接的伺服馬達就會隨之轉到預先設定的角度:
 
## Lab 05 空氣好不好
### 修改樣板
這個實驗要新增一個資料流, 讓控制板可以傳送 AQI 空污指數給 Blynk App:
1. 切換到樣板頁面的 **Datastreams** 頁次後按 **Edit**:

1. 新增一個使用虛擬腳位的資料流:

1. 儲存修改內容並套用到目前的裝置:

### 修改 App 畫面
在 App 畫面上要新增一個顯示空污指數的元件:
1. 按一下右上角的扳手圖示按鈕進入修改頁面:

1. 新增一個 **Value Display** 元件後如下設定:

1. 調整大小及位置如下圖:

### 撰寫程式
撰寫程式時要特別留意的就是新版 Blynk 的元件無法自動週期性地向控制板要資料, 因此程式中會使用計時器主動週期性地推送資料給 Blynk。
```python=
import time, network, urequests
import BlynkLib
from BlynkTimer import BlynkTimer
sta_if=network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect("Wifi 基地台", "Wifi 密碼")
while not sta_if.isconnected():
pass
print('wifi connect')
token="Blynk 權杖"
blynk=BlynkLib.Blynk(token)
def v1_handler():
res= urequests.get("AQI 網址")
j=res.json()
print(j['data']['city']['name'],j['data']['aqi'])
blynk.virtual_write(1,j['data']['aqi'])
timer_aqi = BlynkTimer()
timer_aqi.set_interval(5, v1_handler)
while True :
blynk.run()
timer_aqi.run()
```
### 測試程式
更改程式中的無線網路名稱、密碼、Blynk 的認證權杖以及 AQI 請求網址後執行:
```
>>> %Run -c $EDITOR_CONTENT
___ __ __
/ _ )/ /_ _____ / /__
/ _ / / // / _ \/ '_/
/____/_/\_, /_//_/_/\_\
/___/ for Python v1.0.0 (esp8266)
wifi connect
Connecting to blynk.cloud:443...
Shilin, Taiwan (士林) 57
Shilin, Taiwan (士林) 57
```
手機畫面上即會出現空污指數:

## Lab 06 怎麼有點熱
### 修改樣板
本實驗會再增加兩個讓控制板可以傳送溫、濕度的資料流:
1. 請進入樣板修改頁面後如下新增一個使用虛擬腳位的資料流:

2. 再新增一個如下的資料流:

3. 完成後記得儲存並套用到目前的裝置。
### 修改 App 畫面
在 App 畫面上再新增 2 個元件個別顯示溫濕度:
1. 請進入畫面修改頁面後新增一個 **Value Display** 元件, 並如下設定:

2. 再新增一個 **Value Display** 元件, 並如下設定:

3. 調整大小及位置如下後離開修改頁面:

### 撰寫程式
這是實驗的程式同時推送空污指數、溫度、濕度給 Blynk:
```python=
from machine import Pin
import time, network, urequests
import dht
import BlynkLib
from BlynkTimer import BlynkTimer
sta_if=network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect("Wifi 基地台", "Wifi 密碼")
while not sta_if.isconnected():
pass
print('wifi connect')
token="Blynk 權杖"
blynk=BlynkLib.Blynk(token)
# temp D7
temp = dht.DHT11(Pin(13))
def timer_handler():
res= urequests.get("AQI 請求網址")
j=res.json()
print(j['data']['city']['name'],'空污指數',j['data']['aqi'])
blynk.virtual_write(1, j['data']['aqi'])
try:
temp.measure()
print('溫度 濕度',temp.temperature(),temp.humidity())
blynk.virtual_write(2, temp.temperature())
blynk.virtual_write(3, temp.humidity())
except OSError as e:
print("尚未更新溫濕度")
timer = BlynkTimer()
timer.set_interval(5, timer_handler)
while True :
blynk.run()
timer.run()
```
### 測試程式
更改程式中的無線網路名稱、密碼、Blynk 的認證權杖以及 AQI 請求網址後執行, 即可在手機 App 上看到溫濕度:

## Lab 09 遙控全彩燈
### 修改樣板
本實驗需要新增 3 個可讓 Blynk 傳送紅、綠、藍顏色值的資料流:
1. 進入樣板修改頁面後新增如下使用虛擬腳位的資料流:

1. 再新增如下使用虛擬腳位的資料流:

1. 再新增如下使用虛擬腳位的資料流:

### 修改 App 畫面
本實驗需要新增可以讓使用者指定色彩的元件:
1. 進入畫面修改頁面後新增 **zeRGBa** 斑馬元件, 並如下設定:

1. 如下調整大小及位置:

## 撰寫程式
```python=
from machine import Pin
import time,network
import neopixel
import urandom,BlynkLib
sta_if=network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect("Wifi 基地台", "Wifi 密碼")
while not sta_if.isconnected():
pass
print('wifi connect')
token="Blynk 權杖"
blynk=BlynkLib.Blynk(token)
# RGB D5
np = neopixel.NeoPixel(Pin(14),1)
r=0
g=0
b=0
def v4_handler(R_Value):
global r
r=int(R_Value[0])
def v5_handler(G_Value):
global g
g=int(G_Value[0])
def v6_handler(B_Value):
global b
b=int(B_Value[0])
print(r,g,b)
blynk.on("V4", v4_handler)
blynk.on("V5", v5_handler)
blynk.on("V6", v6_handler)
while True :
blynk.run()
np[0] = (r,g,b)
np.write()
```
### 測試程式
更改程式中的無線網路名稱、密碼及 Blynk 的認證權杖後執行:
```
>>> %Run -c $EDITOR_CONTENT
___ __ __
/ _ )/ /_ _____ / /__
/ _ / / // / _ \/ '_/
/____/_/\_, /_//_/_/\_\
/___/ for Python v1.0.0 (esp8266)
wifi connect
Connecting to blynk.cloud:443...
0 155 119
61 130 0
88 0 0
220 0 0
0 39 155
```
即可用手觸碰畫面上班馬的不同位置, 控制板連接的燈珠就會改變為對應的顏色:

:::warning
zeRGBa 元件目前有遇到**無法傳送顏色資料**的問題, 經測試後應該是 App 版本的問題, 1.3.7 及 1.3.8 會有上述問題, 新版本 1.5.3 可正常運作。
:::
## Lab 11 外面有人嗎?
## 修改樣板
本實驗需要新增一個事件:
1. 進入樣板修改頁面後如下新增事件:

記得要啟用 **Notification** 功能:

## 修改 App 畫面
本實驗不需要修改 App 畫面。
## 撰寫程式
```python=
from machine import ADC, Pin
import time,network
import BlynkLib
sta_if=network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect("Wifi 基地台", "Wifi 密碼")
while not sta_if.isconnected():
pass
print('wifi connect')
token="Blynk 權杖"
blynk=BlynkLib.Blynk(token)
# light A0
light = ADC(0)
# laser D6
laser=Pin(12,Pin.OUT)
laser.value(1)
while True :
blynk.run()
print(light.read(),laser.value()==1)
if light.read() < 200 and laser.value()==1 :
print('外面有人喔')
blynk.log_event("someone", "外面有人喔")
time.sleep(1)
```
### 測試程式
更改程式中的無線網路名稱、密碼及 Blynk 的認證權杖後執行:
```
>>> %Run -c $EDITOR_CONTENT
___ __ __
/ _ )/ /_ _____ / /__
/ _ / / // / _ \/ '_/
/____/_/\_, /_//_/_/\_\
/___/ for Python v1.0.0 (esp8266)
wifi connect
Connecting to blynk.cloud:443...
150 True
外面有人喔
80 True
外面有人喔
228 True
645 True
1024 True
```
只要用手擋住雷射光, 就會觸發事件, 在手機上看到以下通知訊息:

## Lab 12 是誰回來了
我們將手冊上原本使用 D1 mini 自己建立網頁伺服器的方式改掉, 改成將網頁放在 github 上, 請依照以下步驟測試:
1. 由於微軟已經不再提供手冊上說明的 7 天免費帳號, 請依照以下教學, 改用學生帳號或是以信用卡申請一年免費帳號:
- [微軟 Azure 學生帳號 Face API 服務申請 (需要學校單位配發的 email 認證)](/5wKuia3-RiqSOarg5Bve_w)
- [微軟 Azure Face API 服務申請 (需信用卡認證身份)](/8Bm3ywUgTa2PZC-glpaXJQ)
1. 取得端點和金鑰後, 就可以用手機或具有相機的筆電開啟瀏覽器連到 https://FlagTech.github.io/FM628A/face_recog_blynk.html 頁面:

請填入金鑰和端點, 按下**載入人臉資料**。

出現成功載入列表即可。
1. 鍵入人名後按**新增人名**:

會看到『已經新增』訊息。
1. 對著要記錄的人臉後按下**拍臉提升準確度**:

若有正確拍到人臉, 會出現『已經儲存您的臉孔』訊息, 若有錯誤, 表示沒有拍到人臉。請多拍幾張不同角度的人臉。
1. 按下**訓練**讓電腦記住臉的特徵:

會看到『訓練完成』的訊息。
1. 接著就可以試看看對著剛剛拍過的人臉按下**辨識身份**:

若辨識成功, 就會看到『XXXX您好, 歡迎回來』的訊息。
## Lab 13 自動打開門
本實驗接續上一個實驗, 並利用 Lab 04 的程式, 會在辨識出人臉時透過 Blynk 傳送指令給控制板開關門:
1. 請填入你的 Blynk 權杖:

3. 執行 Lab 04 的程式。
4. 對著記錄過的人臉辨識, 若辨識成功, 大門就會打開, 並在 5 秒後自動關閉。
## Lab 14 寶寶在哭了
### 修改樣板
本實驗需要新增事件:
1. 進入樣板修改頁面如下新增事件:

記得啟用 **Notification** 功能:

### 修改 App 畫面
本實驗不需修改 App 畫面。
### 撰寫程式
```python=
from machine import Pin
import time,network
import BlynkLib
sta_if=network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect("Wifi 基地台", "Wifi 密碼")
while not sta_if.isconnected():
pass
print('wifi connect')
token="Blynk 權杖"
blynk=BlynkLib.Blynk(token)
# sound D2
sound=Pin(4,Pin.IN)
count=0
while True :
blynk.run()
if sound.value()==1 :
count+=1
if sound.value()==0 :
count=0
if count==5 :
print('嬰兒房有聲響,快去查看')
blynk.log_event("sound", "嬰兒房有聲響,快去查看")
count=0
print(sound.value(),count)
time.sleep(.2)
```
更改程式中的無線網路名稱、密碼及 Blynk 的認證權杖後執行:
```
>>> %Run -c $EDITOR_CONTENT
___ __ __
/ _ )/ /_ _____ / /__
/ _ / / // / _ \/ '_/
/____/_/\_, /_//_/_/\_\
/___/ for Python v1.0.0 (esp8266)
wifi connect
Connecting to blynk.cloud:443...
0 0
0 0
0 0
0 0
0 0
1 1
1 2
1 3
1 4
嬰兒房有聲響,快去查看
1 0
1 1
1 2
0 0
0 0
0 0
```
只要持續製造聲響一小段時間就會引發事件, 在手機上看到通知訊息:

## Lab 15 心情好音樂
本實驗如同 Lab 12 一樣, 會將網頁改放置 github, 但會透過 Blynk 的 V7 虛擬腳位傳送代表表情的數值, 當收到代表心情不好的 60 時就會播音樂, 請依照以下步驟測試:
1. 在 Blynk 上新增以下的資料流:

1. 撰寫一個接收 V7 虛擬腳位的程式, 並在收到 60 時以 RTTTL 播放音樂:
```python=
import network,time
from machine import Pin,PWM
from rtttl import RTTTL
import BlynkLib
buzzer = PWM(Pin(15))
buzzer.duty(0)
def play_tone(freq, msec):
if freq > 0:
buzzer.freq(freq) # 設定頻率
buzzer.duty(512) # 50% 工作週期
time.sleep(msec*0.001) # 播放 msec 豪秒
buzzer.duty(0) # 停止播放
time.sleep(0.05)
music = "Moonheart:d=4,o=5,b=140:c.,8e,g.,8c,b.4,8e,g.,8g,a.,8b,c.6,8a,2g,8e,8d,c.,8c,8c,8p,8e,8d,c.,8c,8c,8p,8d,8e,d.,8a4,b.4,16c,16d,2c"
# tune = RTTTL("mario:d=4,o=5,b=100:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,8p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,16p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16c7,16p,16c7,16c7,p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16d#6,8p,16d6,8p,16c6")
# Connect to Wi-Fi if not connected
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect("Wifi 基地台", "Wifi 密碼")
while not sta_if.isconnected():
pass
print('wifi connect')
token="Blynk 權杖"
blynk=BlynkLib.Blynk(token)
def v7_handler(value):
print(value[0])
if value[0]=="60":
print('play music')
tune = RTTTL(music)
for freq, msec in tune.notes():
play_tone(freq, msec)
buzzer.duty(0)
else:
buzzer.duty(0)
blynk.on("V7", v7_handler)
while True:
blynk.run()
```
3. 用手機或是具備相機的電腦打開瀏覽器連到 https://FlagTech.github.io/FM628A/face_emotion_blynk.html 網頁:

填入你的金鑰、端點以及 Blynk 權杖。
1. 做好表情後按下**AI 心情點播機 - 播放音樂**, 若辨識出心情不好的表情, 控制板就會播音樂。
## Lab 16 聲控播音樂
本實驗也如同 Lab 15, 將網頁改放置 github 上了, 並會在辨識出口令時傳送 100 到 Blynk 的 V7 虛擬腳位, 由於是和前一個實驗使用相同的虛擬腳位, 因此 Blynk 這邊不需要額外設置。請依照以下步驟測試:
1. 這個實驗的程式幾乎和上一個實驗相同, 只有改成判斷收到 100 時才播放音樂, 播放的音樂也換成馬力歐遊戲的音樂:
```python=
import network,time
from machine import Pin,PWM
from rtttl import RTTTL
import BlynkLib
buzzer = PWM(Pin(15))
buzzer.duty(0)
def play_tone(freq, msec):
if freq > 0:
buzzer.freq(freq) # 設定頻率
buzzer.duty(512) # 50% 工作週期
time.sleep(msec*0.001) # 播放 msec 豪秒
buzzer.duty(0) # 停止播放
time.sleep(0.05)
music = "mario:d=4,o=4,b=100:16e5,16e5,32p,8e5,16c5,8e5,8g5,8p,8g,8p,8c5,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e5,16g5,8a5,16f5,8g5,8e5,16c5,16d5,8b,16p,8c5"
# Connect to Wi-Fi if not connected
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect("Wifi 基地台", "Wifi 密碼")
while not sta_if.isconnected():
pass
print('wifi connect')
token="Blynk 權杖"
blynk=BlynkLib.Blynk(token)
def v7_handler(value):
print(value[0])
if value[0]=="100":
print('play music')
tune = RTTTL(music)
for freq, msec in tune.notes():
play_tone(freq, msec)
buzzer.duty(0)
else:
buzzer.duty(0)
blynk.on("V7", v7_handler)
while True:
blynk.run()
```
1. 使用手機或具備麥克風的筆電打開瀏覽器連到 https://FlagTech.github.io/FM628A/voice_recog_blynk.html 網頁:

請先輸入 Blynk 的權杖。
1. 你也可以在『開啟關鍵字』那個欄位輸入想要播放音樂的口令, 預設是『開』, 請按**開始辨識聲音**, 然後說出『打開』、『開啟』或是你自訂的口令, 只要辨識出來就會傳送 100 到控制板, 播放音樂了。
## Lab 18 Blynk 功能彙整
以下是整合所有上述 Blynk 功能的整合範例:
```python=
# import gc
# gc.enable()
# gc.threshold(1000)
from machine import Pin,PWM,ADC
import time, network, dht, urequests, neopixel
import BlynkLib
from BlynkTimer import BlynkTimer
from rtttl import RTTTL
sta_if=network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect("Wifi 基地台", "Wifi 密碼")
while not sta_if.isconnected():
pass
print('wifi connect')
token="Blynk 權杖"
blynk=BlynkLib.Blynk(token)
# buzzer D8
buzzer = PWM(Pin(15))
buzzer.duty(0)
def play_tone(freq, msec):
if freq > 0:
buzzer.freq(freq) # Set frequency
buzzer.duty(10)# 50% duty cycle
time.sleep(msec*0.001) # Play for a number of msec
buzzer.duty(0) # Stop playing
time.sleep(0.05)
# door D4
door=Pin(2,Pin.IN)
# servo D1
servo = PWM(Pin(5), freq=50)
servo.duty(30)
# temp D7
temp = dht.DHT11(Pin(13))
# fan D3
fan=Pin(0,Pin.OUT)
fan.value(0)
# RGB D5
np = neopixel.NeoPixel(Pin(14),1)
r=0
g=0
b=0
# light A0
light = ADC(0)
# laser D6
laser=Pin(12,Pin.OUT)
laser.value(1)
# sound D2
sound=Pin(4,Pin.IN)
# window D0
window=Pin(16,Pin.IN)
def v0_handler(value):
print(value[0])
if value[0]=="0":
servo.freq(50)
servo.duty(30)
print('大門打開')
else :
servo.freq(50)
servo.duty(100)
print('大門關閉')
def timer_handler():
# gc.collect()
# 請把 AQI 網址中的 https 改為 http
res= urequests.get("AQI 網址")
j=res.json()
print(j['data']['city']['name'],j['data']['aqi'])
blynk.virtual_write(1, j['data']['aqi'])
res.close()
try:
temp.measure()
blynk.virtual_write(2, temp.temperature())
blynk.virtual_write(3, temp.humidity())
print('溫度 濕度',temp.temperature(),temp.humidity())
if temp.humidity()>80:
fan.value(1)
print("濕度過高,開啟空調")
else :
fan.value(0)
except :
print("尚未更新溫濕度")
timer = BlynkTimer()
timer.set_interval(5, timer_handler)
def v4_handler(R_Value):
global r
r=int(R_Value[0])
def v5_handler(G_Value):
global g
g=int(G_Value[0])
def v6_handler(B_Value):
global b
b=int(B_Value[0])
music_moon = "Moonheart:d=4,o=5,b=140:c.,8e,g.,8c,b.4,8e,g.,8g,a.,8b,c.6,8a,2g,8e,8d,c.,8c,8c,8p,8e,8d,c.,8c,8c,8p,8d,8e,d.,8a4,b.4,16c,16d,2c"
music_mario = "mario:d=4,o=4,b=100:16e5,16e5,32p,8e5,16c5,8e5,8g5,8p,8g,8p,8c5,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e5,16g5,8a5,16f5,8g5,8e5,16c5,16d5,8b,16p,8c5"
def v7_handler(value):
print(value[0])
if value[0]=="60":
print('play music')
tune = RTTTL(music_moon)
for freq, msec in tune.notes():
play_tone(freq, msec)
buzzer.duty(0)
if value[0]=="100":
print('play music')
tune = RTTTL(music_mario)
for freq, msec in tune.notes():
play_tone(freq, msec)
buzzer.duty(0)
else:
buzzer.duty(0)
blynk.on("V0", v0_handler)
blynk.on("V4", v4_handler)
blynk.on("V5", v5_handler)
blynk.on("V6", v6_handler)
blynk.on("V7", v7_handler)
count=0
while True :
blynk.run()
timer.run()
if door.value() == 0 :
print('有人按門鈴')
blynk.log_event("ring", "有人按門鈴")
time.sleep(5)
if light.read() < 100 and laser.value()==1 :
print("外面有人喔")
blynk.log_event("someone", "外面有人喔")
time.sleep(5)
if sound.value()==1 :
count+=1
if sound.value()==0 :
count=0
if count==5 :
print('嬰兒房有聲響,快去查看')
blynk.log_event("sound", "嬰兒房有聲響,快去查看")
count=0
if window.value() == 1 :
print('家裡遭小偷,請盡速查看')
# 請把 IFTTT 網址中的 https 改為 http
res = urequests.get("IFTTT 網址")
res.close()
time.sleep(10)
np[0] = (r,g,b)
np.write()
```
由於 Blynk 程式庫佔用不少記憶體, AQI 請求以及 IFTTT 請求的發送與接受也會耗用不少記憶體, 因此請都把原先預設使用的 https 改為 http。由於 https 涉及加密金鑰等處理, 會耗用大量記憶體, 容易造成記憶體不足, 改用 http 可以避免問題。
:::info
並非所有的請求網址都可以隨意在 https 與 http 之間改用, AQI 以及 IFTTT 是我們目前測試沒有問題的網站。
:::