我之前發(fā)布了一篇關(guān)于如果用手機APP控制LED燈的文章,是基于Blink APP和它的服務器實現(xiàn)的,這一講我們在之前的基礎上做一些擴展,通過手機的小愛同學,使用語音控制燈光。沒有看過上一篇博客的同學可以先看一下。
Arduino應用開發(fā)——手機APP控制LED
1 工作原理
Blinker APP控燈原理:
Blinker廠家有自己的一個服務器,我們的設備(esp8266、esp32、手機等)都可以通過網(wǎng)絡接入到這個服務器,手機app我們看不到源碼不確定是以什么樣的方式接入的,我主要講一下MCU(esp8266、esp32等)這邊,MCU是通過WIFI連接到互聯(lián)網(wǎng)的,然后通過MQTT協(xié)議接入到Blinker的服務器,MCU作為客戶端,服務器作為服務端。具體MQTT的實現(xiàn)原理這里不多說了,光是MQTT這一個話題都可以寫好多文章了,想深入了解的同學可以自行查閱資料。
當MQTT連成功之后,MCU會一直偵聽,等待服務器下發(fā)數(shù)據(jù)。這個時候我們可以通過手機app操作,比如點一下開燈,服務器收到這個開燈命令后會通過MQTT發(fā)送命令到MCU,MCU接收到數(shù)據(jù)并解析命令后執(zhí)行點燈的操作。服務器在這里相當于一個中轉(zhuǎn)站,把手機的操作轉(zhuǎn)發(fā)到設備端,實現(xiàn)了手機和設備之間的互動。不過有一點要說明的是,設備和服務器是通過MQTT連接的,而手機app和服務器則不一定是用MQTT,個人覺得用http的可能性更大,但是看不到源碼,所以實際上是怎么通訊的就不清楚了,這個也不是很重要,并不影響實際的使用。
小愛同學控燈原理:
說明:這里的小愛同學可以是小米手機里面的小愛,也可以是小米的智能音箱。
前面我們已經(jīng)把我們的設備(esp8266、esp32等)連接到了Blinker的服務器,實現(xiàn)了數(shù)據(jù)的上傳下發(fā)。而Blinker本身是有對接小愛同學的,并且設定好了一些固定的語音指令。我們只通過米家APP關(guān)聯(lián)Blinker的賬號就能實現(xiàn)小愛同學和Blinker服務器的聯(lián)動,再結(jié)合之前Blinker服務器和我們的硬件設備的連接,就可以間接的實現(xiàn)小愛同學和硬件設備的交互。
簡單來說就是我們的語音指令通過小愛同學發(fā)送到Blinker的服務器,再由Blinker的服務器轉(zhuǎn)發(fā)到我們的硬件設備。Blinker服務器在這里起到一個數(shù)據(jù)解析、中轉(zhuǎn)的作用。
2 硬件準備
我這里以ESP8266和ESP32為例講解,其他MCU方法和原理都是一樣的,所以根據(jù)自己的MCU選擇其中一種即可。
硬件配置如下:
模塊 | 型號 | 說明 |
---|---|---|
ESP8266 | ESP-12F | 這是安信可的一款模組,內(nèi)部主要是用樂鑫的ESP8266EX再加上一個片外FLASH組成,開發(fā)板型號是NodeMCU-12F(CH340版本) |
ESP32 | ESP-WROOM-32 | MCU是樂鑫的一款芯片,開發(fā)板型號ESP32 DEVKITV1 |
具體的硬件參數(shù)和電路原理圖這里就不發(fā)出來了,不同廠家做的開發(fā)板引腳可能會有點差別。
3 軟件準備
版本說明:
本文測試時各軟件使用的版本如下:
軟件 | 版本 | 備注 |
---|---|---|
Arduino IDE | 1.8.16 | Blinker需要配合1.8.x及以上版本的Arduino IDE |
ESP8266 package | 3.0.2 | Blinker需配合使用3.0.0或以上release版本的ESP8266 package |
ESP32 package | 3.0.2 | Blinker需配合使用2.0.0或以上版本的ESP32 package |
Blinker arduino package | 0.3.9 | 當前最新版本,以后可能會有更新 |
Blinker APP | 2.5.2(安卓版) | 當前最新版本,以后可能會有更新 |
米家APP | 7.5.705.5319(安卓版) | 當前最新版本,以后可能會有更新 |
3.1 Arduino IDE環(huán)境搭建
這個在我的博客里面講過很多次了,這里就不再說了,不懂的同學先按上一講把環(huán)境搭好(根據(jù)自己的MCU選擇對應的教程)。
esp8266開發(fā)入門教程(基于Arduino)——環(huán)境安裝
3.2 Blinker APP賬號注冊和使用
這個內(nèi)容比較多,這里不再贅述了,不懂的同學先看下上一講的第4點。
4 編寫程序
上一講的教程講了怎么用Blinker APP創(chuàng)建設備并實現(xiàn)遠程控制。
這一講在這基礎上增加小愛同學的語音控制。我們保留上一講的功能,然后增加電源控制和設備查詢這兩個回調(diào)函數(shù),這兩個函數(shù)的接口在Blinker的庫源碼中已經(jīng)定義好了,我們直接使用即可。我們通過電源控制回調(diào)函數(shù)實現(xiàn)LED燈的開關(guān)控制。
示例代碼:
提示:代碼中的WIFI的賬號和密碼根據(jù)實際情況修改。
#define BLINKER_WIFI
#define BLINKER_MIOT_LIGHT // 燈設備
// #define BLINKER_MIOT_OUTLET // 插座設備
// #define BLINKER_MIOT_MULTI_OUTLET // 多個插座設備
// #define BLINKER_MIOT_SENSOR // 傳感器設備
// #define BLINKER_MIOT_FAN // 風扇設備
// #define BLINKER_MIOT_AIR_CONDITION // 空調(diào)設備
#include <Blinker.h>
char auth[] = "e6fce38e525a"; // 設備密鑰
char ssid[] = "test"; // WIFI賬號
char pswd[] = "123456789"; // WIFI密碼
#define LED_PIN 2 // LED引腳
// 新建組件對象
BlinkerButton Button1("btn-abc");
BlinkerNumber Number1("num-abc");
int counter = 0;
bool oState = false;
// 電源控制回調(diào)函數(shù)
void miotPowerState(const String & state)
{
BLINKER_LOG("need set power state: ", state);
if (state == BLINKER_CMD_ON)
{// 打開開關(guān)
digitalWrite(LED_PIN, HIGH); // 開燈
BlinkerMIOT.powerState("on");
BlinkerMIOT.print();
oState = true;
}
else if (state == BLINKER_CMD_OFF)
{// 關(guān)閉開關(guān)
digitalWrite(LED_PIN, LOW); // 關(guān)燈
BlinkerMIOT.powerState("off");
BlinkerMIOT.print();
oState = false;
}
}
// 查詢設備狀態(tài)回調(diào)函數(shù)
void miotQuery(int32_t queryCode)
{
BLINKER_LOG("MIOT Query codes: ", queryCode);
switch (queryCode)
{
case BLINKER_CMD_QUERY_ALL_NUMBER : // 查詢所有設備
BLINKER_LOG("MIOT Query All");
BlinkerMIOT.powerState(oState ? "on" : "off");
BlinkerMIOT.print();
break;
case BLINKER_CMD_QUERY_POWERSTATE_NUMBER : // 查詢電源類設備
BLINKER_LOG("MIOT Query Power State");
BlinkerMIOT.powerState(oState ? "on" : "off");
BlinkerMIOT.print();
break;
default : // 查詢其他設備
BlinkerMIOT.powerState(oState ? "on" : "off");
BlinkerMIOT.print();
break;
}
}
// 按下按鍵即會執(zhí)行該函數(shù)
void button1_callback(const String & state)
{
BLINKER_LOG("get button state: ", state);
digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // 翻轉(zhuǎn)LED燈狀態(tài)
}
// 如果未綁定的組件被觸發(fā),則會執(zhí)行其中內(nèi)容
void dataRead(const String & data)
{
BLINKER_LOG("Blinker readString: ", data);
counter++;
Number1.print(counter);
}
void setup()
{
// 初始化串口
Serial.begin(115200);
BLINKER_DEBUG.stream(Serial);
BLINKER_DEBUG.debugAll();
// 初始化LED的IO
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
// 初始化blinker
Blinker.begin(auth, ssid, pswd);
Blinker.attachData(dataRead); // 未綁定設備回調(diào)
Button1.attach(button1_callback); // 按鍵回調(diào)
BlinkerMIOT.attachPowerState(miotPowerState); // 電源控制回調(diào)
BlinkerMIOT.attachQuery(miotQuery); // 查詢設備狀態(tài)回調(diào)
}
void loop() {
Blinker.run();
}
5 關(guān)聯(lián)米家APP和Blinker設備
打開 米家APP
,點擊我的
,點擊其他平臺設備
,點擊添加
,在列表中找到點燈科技
,點擊綁定賬號
,登錄你的Blinker賬號,最后點擊同步設備
即可。設備同步成功之后就可以看到你在Blinker APP上創(chuàng)建的所有設備。
提示1:Blinker賬號的注冊以及APP的使用請?zhí)D(zhuǎn)到3.2查看。我在上一篇博客有詳細的教程。
提示2:同步設備可能會出現(xiàn)失敗的情況,我一開始同步的時候一直失敗,過了一段時間之后再嘗試又沒出現(xiàn)了,不知道是不是APP的bug。
6 語音控制測試
特別說明:我沒有小愛同學的智能音箱,我這里是直接用小米的手機來測試的。
注:其他品牌的手機可以下載米家APP,但是沒法使用小愛同學。
把燒錄好代碼的設備通上電,通過串口打印的一些信息,我們可以看到設備正常連上網(wǎng)絡之后會連接到Blinker的服務器,連接成功之后可以在Blinker的APP上看到設備的狀態(tài)由 ‘離線’ 變成 ‘在線’。
小愛同學支持的開關(guān)類控制語音如下:
打開/關(guān)閉{門口}的{燈}
提示1:{}里面的內(nèi)容是通配多種關(guān)鍵詞的,你可以在Blinker APP修改設備的名稱,然后語音對應的命令也要跟著改變,保持一致才能正確的控制設備。
對著小米手機呼叫小愛同學
,收到回應之后再說打開燈
,就能看到設備的LED燈被打開了。同理,關(guān)閉燈的指令也是一樣的操作。
通過串口打印的信息也可以看到開燈和關(guān)燈相關(guān)的指令。
至此,從小愛同學到硬件設備的整個流程就走通了。流程走通了之后我們就可以在這個基礎上增加更多的功能,比如控制燈的亮度,設備工作模式等等,也可以修改設備的名稱,或者控制更多其他類型的設備。
7 進階用法
通過Blinker關(guān)聯(lián)小愛同學控制設備其實有很大的局限性,因為小愛同學所有的語音指令都是Blinker定義好的,不支持做過多的修改,而且目前支持的語音指令實在是有點少,當我們需要自定義一些指令時并不能通過這套代碼實現(xiàn)。不過如果只是玩一下或者學習的話,還是可以去研究一下的。
關(guān)于Blinker以及小愛同學所支持的設備和語音指令在點燈科技的官網(wǎng)上其實有比較詳細的介紹。
點燈科技小米小愛技術(shù)文檔:https://diandeng.tech/doc/xiaoai
我們這里也基于這些給定的語音指令做一些進階的操作。
前面的示例我們通過小愛同學控制了燈的亮滅,然后現(xiàn)在我們增加LED燈亮度、色溫以及模式的控制。
特別說明:要實際控制燈的亮度和色溫的話我們需要用到RGB燈,而且有些比較簡單的GRB燈只能調(diào)節(jié)三色燈的亮滅,最多也只能調(diào)出8種顏色,如果需要調(diào)節(jié)出多種色溫,還需要調(diào)節(jié)三色燈里面每一個燈的亮度。每個燈的亮度階梯越多,能跳出來的色彩就越多。如果是單色LED的話最多只能調(diào)亮度,是沒辦法改變顏色的,亮度調(diào)節(jié)可以通過PWM實現(xiàn)。
我這里因為現(xiàn)在手頭上也沒有合適的燈,這里就不做具體的演示了,我這里只講一下怎么把小愛語音和LED燈的控制代碼關(guān)聯(lián)起來,至于實際的一些操作,感興趣的同學可以自己再補充。
7.1 亮度控制
小愛同學支持的亮度控制語音如下:
把{臥室}的{燈}的{亮度調(diào)高一點}
亮度范圍為1-100
注:括號里面的的關(guān)鍵字是可以用戶自己修改定義的。比如:燈可以換成其他關(guān)鍵字,如氛圍燈、大燈等,這個是跟你在Blinker APP里面修改的設備名稱保持一致的。
示例代碼:
提示:我這里只把新增的函數(shù)列出來,等后面把亮度、色溫以及模式的控制全部講完之后再列一個完整的代碼。
// 燈光亮度控制回調(diào)函數(shù)
void miotBright(const String & bright)
{
BLINKER_LOG("need set brightness: ", bright); // 打印需要設置的亮度
uint8_t colorW = bright.toInt();
BLINKER_LOG("now set brightness: ", colorW);
// 在此處我們可以根據(jù)實際情況添加一些控制的代碼,比如:通過修改PWM占空比的值,從而達到調(diào)節(jié)燈亮度的目的
BlinkerMIOT.brightness(colorW);
BlinkerMIOT.print();
}
// 燈光亮度控制初始化
BlinkerMIOT.attachBrightness(miotBright);
測試結(jié)果:
特別說明:因為我的硬件并沒有接入能調(diào)光的燈,所以這里我只把接收到的語音指令打印了出來,硬件上并沒有做實際的操作。
對著小愛同學說:把燈的亮度調(diào)到60
。通過串口打印的信息我們可以看到,設備已經(jīng)收到了這個命令,并且把要調(diào)節(jié)的亮度值60解析出來了,只不過我實際上并沒有做控燈的操作,因此,LED燈是沒有變化的。
7.2 色溫控制
小愛同學支持的色溫控制語音如下:
把{臥室}的{燈}調(diào)為{紅色}
顏色范圍為0-16777215(0xFFFFFF)
示例代碼:
提示:我這里只把新增的函數(shù)列出來,等后面把亮度、色溫以及模式的控制全部講完之后再列一個完整的代碼。
// 燈光色溫控制回調(diào)函數(shù)
void miotColor(int32_t color)
{
BLINKER_LOG("need set color: ", color);
// 從接收到的數(shù)據(jù)中解析得到需要配置的R G B三色光的亮度值
uint8_t colorR = color >> 16 & 0xFF;
uint8_t colorG = color >> 8 & 0xFF;
uint8_t colorB = color & 0xFF;
BLINKER_LOG("colorR: ", colorR, ", colorG: ", colorG, ", colorB: ", colorB);
// 在此處我們可以根據(jù)實際情況添加一些控制的代碼,比如:通過修改R G B三個燈的亮度從而達到修改燈顏色的目的
BlinkerMIOT.color(color);
BlinkerMIOT.print();
}
// 燈光色溫控制初始化
BlinkerMIOT.attachColor(miotColor);
測試結(jié)果:
特別說明:因為我的硬件并沒有接入能調(diào)光的燈,所以這里我只把接收到的語音指令打印了出來,硬件上并沒有做實際的操作。
對著小愛同學說:把燈調(diào)為紫色
。通過串口打印的信息我們可以看到,設備已經(jīng)收到了改命令,只不過我實際上并沒有做控燈的操作,因此,LED燈是沒有變化的。
提示:這里RGB三元光的亮度范圍是0-255,把三種亮度不同的光混合在一起就能產(chǎn)生多種多樣的顏色。
7.3 模式控制
小愛同學支持的色溫控制語音如下:
把{臥室}的{燈}設置為{xx模式}
示例代碼:
提示:我這里只把新增的函數(shù)列出來,后面有完整的代碼。
// 模式控制回調(diào)函數(shù)
void miotMode(uint8_t mode)
{
BLINKER_LOG("need set mode: ", mode); // 打印接收到需要設置的模式,數(shù)值是(0-6),對應7種模式
if (mode == BLINKER_CMD_MIOT_DAY) {
// 日光模式,在這里面可以添加自己實際需要控制的代碼
}
else if (mode == BLINKER_CMD_MIOT_NIGHT) {
// 夜光模式,在這里面可以添加自己實際需要控制的代碼
}
else if (mode == BLINKER_CMD_MIOT_COLOR) {
// 彩光模式,在這里面可以添加自己實際需要控制的代碼
}
else if (mode == BLINKER_CMD_MIOT_WARMTH) {
// 溫馨模式,在這里面可以添加自己實際需要控制的代碼
}
else if (mode == BLINKER_CMD_MIOT_TV) {
// 電視模式,在這里面可以添加自己實際需要控制的代碼
}
else if (mode == BLINKER_CMD_MIOT_READING) {
// 閱讀模式,在這里面可以添加自己實際需要控制的代碼
}
else if (mode == BLINKER_CMD_MIOT_COMPUTER) {
// 電腦模式,在這里面可以添加自己實際需要控制的代碼
}
BlinkerMIOT.mode(mode);
BlinkerMIOT.print();
}
// 模式控制初始化
BlinkerMIOT.attachMode(miotMode);
測試結(jié)果:
特別說明:因為我的硬件并沒有接入能調(diào)光的燈,所以這里我只把接收到的語音指令打印了出來,硬件上并沒有做實際的操作。
對著小愛同學說:把燈調(diào)為夜光模式
。通過串口打印的信息我們可以看到,設備已經(jīng)收到了改命令,只不過我實際上并沒有做控燈的操作,因此,LED燈是沒有變化的。
前面我也講過,Blinker這套方案有比較大的局限性,就比如這里的模式,雖然支持多種模式,但是每一個模式都只能通過固定的關(guān)鍵字(日光、夜光、彩光等)來觸發(fā),不能自定義,如果是控燈還好,很多都可以用上,但是如果控制的是其他設備,這些模式的關(guān)鍵字就牛頭不對馬嘴了。
我也沒有找到改指令關(guān)鍵字的接口,應該是Blinker沒有開放這個接口或者不支持這個功能。這一點是不太友好的,不過Blinker畢竟是一個公司,目的還是盈利,而且維護服務器也是需要成本的,白嫖黨也不能要求太多。
完整的進階示例代碼:
#define BLINKER_WIFI
#define BLINKER_MIOT_LIGHT // 燈設備
// #define BLINKER_MIOT_OUTLET // 插座設備
// #define BLINKER_MIOT_MULTI_OUTLET // 多個插座設備
// #define BLINKER_MIOT_SENSOR // 傳感器設備
// #define BLINKER_MIOT_FAN // 風扇設備
// #define BLINKER_MIOT_AIR_CONDITION // 空調(diào)設備
#include <Blinker.h>
char auth[] = "e6fce38e525a"; // 設備密鑰
char ssid[] = "tst"; // WIFI賬號
char pswd[] = "123456789"; // WIFI密碼
#define LED_PIN 2 // LED引腳
// 新建組件對象
BlinkerButton Button1("btn-abc");
BlinkerNumber Number1("num-abc");
int counter = 0;
bool oState = false;
// 電源控制回調(diào)函數(shù)
void miotPowerState(const String & state)
{
BLINKER_LOG("need set power state: ", state);
if (state == BLINKER_CMD_ON)
{// 打開開關(guān)
digitalWrite(LED_PIN, HIGH); // 開燈
BlinkerMIOT.powerState("on");
BlinkerMIOT.print();
oState = true;
}
else if (state == BLINKER_CMD_OFF)
{// 關(guān)閉開關(guān)
digitalWrite(LED_PIN, LOW); // 關(guān)燈
BlinkerMIOT.powerState("off");
BlinkerMIOT.print();
oState = false;
}
}
// 查詢設備狀態(tài)回調(diào)函數(shù)
void miotQuery(int32_t queryCode)
{
BLINKER_LOG("MIOT Query codes: ", queryCode);
switch (queryCode)
{
case BLINKER_CMD_QUERY_ALL_NUMBER : // 查詢所有設備
BLINKER_LOG("MIOT Query All");
BlinkerMIOT.powerState(oState ? "on" : "off");
BlinkerMIOT.print();
break;
case BLINKER_CMD_QUERY_POWERSTATE_NUMBER : // 查詢電源類設備
BLINKER_LOG("MIOT Query Power State");
BlinkerMIOT.powerState(oState ? "on" : "off");
BlinkerMIOT.print();
break;
default : // 查詢其他設備
BlinkerMIOT.powerState(oState ? "on" : "off");
BlinkerMIOT.print();
break;
}
}
// 燈光亮度控制回調(diào)函數(shù)
void miotBright(const String & bright)
{
BLINKER_LOG("need set brightness: ", bright);
uint8_t colorW = bright.toInt();
BLINKER_LOG("now set brightness: ", colorW);
// 在此處我們可以根據(jù)實際情況添加一些控制的代碼,比如:通過修改PWM占空比的值從而達到調(diào)節(jié)燈亮度的目的
BlinkerMIOT.brightness(colorW);
BlinkerMIOT.print();
}
// 燈光色溫控制回調(diào)函數(shù)
void miotColor(int32_t color)
{
BLINKER_LOG("need set color: ", color);
// 從接收到的數(shù)據(jù)中解析得到需要配置的R G B三色光的亮度值
uint8_t colorR = color >> 16 & 0xFF;
uint8_t colorG = color >> 8 & 0xFF;
uint8_t colorB = color & 0xFF;
BLINKER_LOG("colorR: ", colorR, ", colorG: ", colorG, ", colorB: ", colorB);
// 在此處我們可以根據(jù)實際情況添加一些控制的代碼,比如:通過修改R G B三個燈的亮度從而達到修改燈顏色的目的
BlinkerMIOT.color(color);
BlinkerMIOT.print();
}
// 模式控制回調(diào)函數(shù)
void miotMode(uint8_t mode)
{
BLINKER_LOG("need set mode: ", mode); // 打印接收到需要設置的模式,數(shù)值是(0-6),對應7種模式
if (mode == BLINKER_CMD_MIOT_DAY) {
// 日光模式,在這里面可以添加自己實際需要控制的代碼
}
else if (mode == BLINKER_CMD_MIOT_NIGHT) {
// 夜光模式,在這里面可以添加自己實際需要控制的代碼
}
else if (mode == BLINKER_CMD_MIOT_COLOR) {
// 彩光模式,在這里面可以添加自己實際需要控制的代碼
}
else if (mode == BLINKER_CMD_MIOT_WARMTH) {
// 溫馨模式,在這里面可以添加自己實際需要控制的代碼
}
else if (mode == BLINKER_CMD_MIOT_TV) {
// 電視模式,在這里面可以添加自己實際需要控制的代碼
}
else if (mode == BLINKER_CMD_MIOT_READING) {
// 閱讀模式,在這里面可以添加自己實際需要控制的代碼
}
else if (mode == BLINKER_CMD_MIOT_COMPUTER) {
// 電腦模式,在這里面可以添加自己實際需要控制的代碼
}
BlinkerMIOT.mode(mode);
BlinkerMIOT.print();
}
// 按下按鍵即會執(zhí)行該函數(shù)
void button1_callback(const String & state)
{
BLINKER_LOG("get button state: ", state);
digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // 翻轉(zhuǎn)LED燈狀態(tài)
}
// 如果未綁定的組件被觸發(fā),則會執(zhí)行其中內(nèi)容
void dataRead(const String & data)
{
BLINKER_LOG("Blinker readString: ", data);
counter++;
Number1.print(counter);
}
void setup()
{
// 初始化串口
Serial.begin(115200);
BLINKER_DEBUG.stream(Serial);
BLINKER_DEBUG.debugAll();
// 初始化LED的IO
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
// 初始化blinker
Blinker.begin(auth, ssid, pswd);
Blinker.attachData(dataRead); // 未綁定設備回調(diào)
Button1.attach(button1_callback); // 按鍵回調(diào)
BlinkerMIOT.attachPowerState(miotPowerState); // 電源控制回調(diào)
BlinkerMIOT.attachQuery(miotQuery); // 查詢設備狀態(tài)回調(diào)
BlinkerMIOT.attachBrightness(miotBright); // 燈光亮度控制回調(diào)
BlinkerMIOT.attachColor(miotColor); // 燈光色溫控制回調(diào)
BlinkerMIOT.attachMode(miotMode); // 模式控制回調(diào)
}
void loop() {
Blinker.run();
}
結(jié)束語
好了,關(guān)于如何在Arduino上通過小愛同學控制燈光就到這里。Blinker的這套框架局限性比較大,只適用于某些設備,也只能使用比較固定的命令,不能做過多的修改,這一點是不太好的,但好處是比較省事,不需要我們做語音這部分的開發(fā),有利有弊吧,對于學生黨或者剛?cè)腴T的初學者來說是可以去玩一下的,而且Blinker維護服務器本身也是需要成本的,能免費提供這個平臺給大家用就算不錯了,白嫖黨要求也不能太過分是吧。如果有條件的話就自己搭服務器,這樣可操作性會大大的增加。
想了解更多Arduino的內(nèi)容,可以關(guān)注一下博主,后續(xù)我還會繼續(xù)分享更多的經(jīng)驗給大家。
還有什么問題的話,歡迎在評論區(qū)留言。
如果這篇文章能夠幫到你,就…你懂得。