我的ESP32實做書籍:https://youyouyou.pixnet.net/blog/post/121105860
博客來網址:https://www.books.com.tw/products/0010901195


本章將介紹ESP32的藍芽通訊,藍芽與WiFi都是用來通訊,藍芽通常用於近端點對點通訊,WiFi則常用來連入網際網路,所謂的點對點就像是藍芽無線耳機與手機連接,用來播放音樂,或者藍芽滑鼠鍵盤功能是輸入文字,只是一種序列通訊,功能較為簡單,因此不需要像WiFi這樣太複雜的設定,不過藍芽雖然簡單,但是使用上方便,只要配對就可以取用服務,所以也非常流行。
與藍芽同位階的應該算是紅外線,不過紅外線有方向性,是要對準裝置才能傳輸,速度慢不說,距離大概不能超過10公尺,而藍芽則無方向性,因此不用對準,而且傳輸距離遠、速度也比紅外線快很多。
本書將會介紹如何使用ESP32藍芽與手機連線通訊,並透過手機的語音辨識遙控電風扇及檯燈,此外也會介紹最新的ibeacon室內定位裝置原理及實做。本章先簡介ESP32的藍牙通訊設定與使用,由於是藍芽內建的,所以不用接線或設定AT COMMAND,也不用宣告TXRX相關的通訊協定,而且ESP32內建的藍芽是採用低功率藍芽(BLE:Bluetooth Low Energy)耗電量較少,傳輸距離理論可達300公尺遠,實際測試30公尺沒問題,而常見搭配UNO使用的HC-05屬於藍芽2.1,理論傳輸距離只有10公尺,本章將介紹如何的啟動ESP32藍芽裝置,並搭配Android手機進行通訊,以下為本章的架構。

一、藍芽單向傳輸
二、藍芽雙向傳輸
三、藍芽指令與語音辨識

 

一、藍芽單向傳輸
本節說明使用ESP32藍芽將資訊傳遞給藍芽裝置(手機)進行接收,由於bluetooth函式庫iOS手機不相容的原因,後續章節都將使用Android裝置進行解說。
ESP32藍芽的開啟僅需幾個步驟:
1. 使用藍芽函式庫:#include <BluetoothSerial.h>
2. 宣告藍芽序列通訊物件:BluetoothSerial BT;//BT為藍芽通訊物件
3. 在Setup中開啟藍芽:BT.begin("BTName");// BTName為藍芽廣播名稱
4. 當要傳輸資訊時:BT.print("要傳輸的文字");//println則是換行
我們先來一個簡單的測試,就是每秒傳輸一次"Hello World!"到手機中,程式如下


#include <BluetoothSerial.h>
BluetoothSerial BT;//宣告藍芽物件,名稱為BT

void setup() {
Serial.begin(115200);
BT.begin("Eric1030");//請改名例如英文+生日,以免與其他同學名稱重複
}

void loop() {
  BT.println("Hello World!");
  delay(1000);
}


完成程式上傳後,我們來處理手機的部份,請將Android手機開啟App store,並搜尋Arduino Bluetooth Control,其圖示如下,APP Store有很多類似的APP其實功能都差不多,但是我們選定的這個APP有提供語音辨識的功能,後續練習將會用到。讀者若無法找到該APP,可能是版本不相容,但可從筆者雲端空間中下載備份APK檔案:https://t.ly/YRWpD
image
Arduino Bluetooth Control(Google Play網址:https://t.ly/eA2R3)

手機安裝好APP後,啟動藍芽連線設定如圖2,如果未在可用裝置中出現請點選不常用類型裝置,您所設定的ESP32藍芽名稱就會出現在這裡(如圖3),點選您的ESP裝置就會出現配對訊息(如圖4),點選下方的配對即可完成配對(如圖5)。

image image
圖2:開啟藍芽設定 圖3:藍芽不常用裝置列表
image image
圖4:開始配對     圖5:配對完成

完成配對後,開啟剛剛安裝的Arduino Bluetooth Control APP,若沒有自動連線,則點選上方的箭頭圖示選擇要本次要連線的ESP32裝置(如圖6)。
連線成功時,下方會出現「Connected to 裝置名稱」的訊息(如圖7),此時再點選序列通訊的功能,即可看到每秒一次的「Hello World!」訊息(如圖8)。

image image
圖6:開啟APP連線藍芽裝置 圖7:等候連線成功(connected)
image image
圖8:點選右上序列通訊功能 圖9:觀察傳入的資訊

接下來我們使用DHT11溫濕度計為範例,將溫濕度的值傳入手機中,關於DHT11溫濕度計的使用方式請參考前面章節的內容,另外每次ESP32更新程式時重新啟動時,APP都必須按一下連線的圖示 ,重新與裝置建立連線,才能讀取資訊。
 


#include <SimpleDHT.h>
#include <BluetoothSerial.h>
BluetoothSerial BT;
int pinDHT11 = 25; //本例請將溫度計S腳接在左11 (GPIO25)
SimpleDHT11 dht11(pinDHT11);

void setup() {
  Serial.begin(115200);
  BT.begin("Eric1030");//請改名
}

void loop() {
  // start working...
  Serial.println("=================================");
  Serial.println("Sample DHT11...");
  // read without samples.
  byte temperature = 0;
  byte humidity = 0;
  int err = SimpleDHTErrSuccess;
  if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
    Serial.print("Read DHT11 failed, err="); Serial.println(err); delay(1000);
    return;
  }
  //將溫濕度傳輸到藍芽裝置
  BT.print((int)temperature);
  BT.print(" *C,");
  BT.print((int)humidity);
  BT.println(" H");
  delay(1000); //休息1秒
}


image
圖10:利用藍芽傳輸DHT11溫濕度

二、藍芽雙向傳輸
只有ESP32傳送資料到手機,可以反過來讓手機傳資料到ESP32嗎?當然可以,而且更好玩。這部份ESP32的流程是這樣的
1.檢測藍芽是否有資料:BT.available()
2.如果有資料,我們就把資料讀出:BT.readString()
3.將資料從電腦的序列視窗(Serial)中印出來。
這部份的程式如下


#include <BluetoothSerial.h>
BluetoothSerial BT;

void setup() {
  Serial.begin(115200);
  BT.begin("Eric1030");//請改名
}
void loop() {
  //檢查藍芽內是否有資料
  while (BT.available()) {
    //讀取藍芽資料
    String BTdata=BT.readString();
    //顯示在序列視窗
    Serial.println(BTdata);
  }
  delay(1);
}


連線成功後,一樣點選右上序列通訊功能後,此次在下方的空白處,輸入文字並按鍵盤的Done或Enter送出後,我們即可在電腦的序列通訊視窗中收到手機傳來的訊息。

image image
圖11:在手機輸入訊息 圖12:ESP32的序列視窗中讀取訊息

不過這樣單方面只能手機講話有點孤單,我們要如何讓ESP32也能打字回覆?
其實語法很類似,只是與藍芽的方向相反,就是檢查序列是否有資料輸入Serial.available(),當Serial.available()時用Serial.readString()將資料讀入後,再用BT.println()將資料送到手機。不過ESP32要在哪裡打字呢?是透過序列通訊視窗上面的空白處(如圖13),本部份程式如下


#include <BluetoothSerial.h>
BluetoothSerial BT;

void setup() {
  Serial.begin(115200);
  BT.begin("Eric1030");//請改名
}

void loop() {
  //檢查序列內是否有資料
  while (Serial.available()) {
    //讀取序列資料
    String Sdata = Serial.readString();
    //傳輸給藍芽
    BT.println(Sdata);
  }

  //檢查藍芽內是否有資料
  while (BT.available()) {
    //讀取藍芽資料
    String BTdata = BT.readString();
    //顯示在序列視窗
    Serial.println(BTdata);
  }
  delay(1);
}


image image
圖13:ESP32在序列視窗輸入訊息 圖14:雙向資料傳輸

三、藍芽指令與語音辨識
這樣的程式只能拿來藍芽聊天嗎?其實這可以用來遙控一些東西,例如我們用簡單的LED燈來測試,將LED依照前面的內容依序將綠黃紅放置在GPIO4,16,17(麵包板右7,8,9)位置,接下來我們假設ESP32從藍芽接到傳來'1'時,就開啟綠LED,而'2'代表關閉綠LED,其餘雷同,'3''4'代表開啟及關閉黃LED,'5''6'代表開啟及關閉紅LED,這樣我們就可以用手機來遙控三個燈號。完整程式如下


#include <BluetoothSerial.h>
BluetoothSerial BT;

void setup() {
  Serial.begin(115200);
  BT.begin("Eric1030");//請改名
  pinMode(15, OUTPUT); //綠色LED
  pinMode(2, OUTPUT); //黃色LED
  pinMode(4, OUTPUT); //紅色LED
}

void loop() {
  //檢查序列內是否有資料
  while (Serial.available()) {
    //讀取序列資料
    String Sdata = Serial.readString();
    //傳輸給藍芽
    BT.print(Sdata);
  }

  //檢查藍芽內是否有資料
  while (BT.available()) {
    //讀取藍芽資料
    String BTdata = BT.readString();
    //顯示在序列視窗
    Serial.println(BTdata);
    //檢查藍芽資料及相對的指令
    if (BTdata == "1") {
      //1:開綠燈
      digitalWrite(15, HIGH);
    }
    if (BTdata == "2") {
      //2:關綠燈
      digitalWrite(15, LOW);
    }
    if (BTdata == "3") {
      //3:開黃燈
      digitalWrite(2, HIGH);
    }
    if (BTdata == "4") {
      //4:關綠燈
      digitalWrite(2, LOW);
    }
    if (BTdata == "5") {
      //5:開紅燈
      digitalWrite(4, HIGH);
    }
    if (BTdata == "6") {
      //6:關紅燈
      digitalWrite(4, LOW);
    }

  }
  delay(1);
}


我們將數字1~6按過一次,就會發現燈號依序亮起熄滅,代表藍芽傳輸正常。

image
圖15:將數字1-6輸入,查看燈號變化

除了使用序列通訊用自己打字的方式之外,也可以使用APP上其他的功能,我們先來看看左側上方的方向鍵,我們點選不同方向時,觀察獲得的資訊,會發現其實每個方向對應的是一個數字(如圖17),因此按下不同方向,剛好可以控制燈號,例如「^」對應數字「1」,所以按「^」就會開啟綠燈,在按鈕時要請讀者慢慢按,不要太急,否則他會將很多數字合成一個字串才送出,例如一直按往上「^」會送出「11111」,而這樣的方式我們的程式是無法判讀的,因為我們是用字串比對,而非字元比對。

image image
圖16:APP上的所有功能 圖17:方向鍵功能

而在加速器上,則對應的方向與上面的方向鍵是相同的,不過他的控制是用手機的傾斜方向來控制送出的訊號,例如你將手機向前傾斜一秒鐘後復原水平狀態,手機會對ESP32送出一連串的「11111111」,向後則會送出「2222222…..」等,有些手機硬體沒有支援加速器,就不會送出任何資料,與上面相同的,我們程式以字串比對,所以這個功能無法控制燈號。

image image
圖18:加速器功能
(請透過傾斜你的手機來觸發)    
圖19:接收到的資料

按鈕的功能如圖示,不過這裡APP有一個小bug,就是5、6是標錯的,預設標成4、4(如圖20),我們要進入設定進行修改。點選右上機器人圖示按鈕進入設定功能,尋找「Command button configuration」(如圖21),點選Button E,然後修改對應的值從4改為5,相同的步驟,請設定Button F對應的值為6。完成修改設定之後,一樣依序點選按鈕,也可以觀察到燈號的變化

image image
圖20:按鈕的功能  圖21:設定Button E按鈕為5
image image
圖22:設定Button F按鈕為6 圖23:正確的按鈕功能

最後我們來看右下角的功能語音指令(Voice Control),也就是透過語音辨識來控制傳輸的,不過我們一樣必須先設定語音及所對應的文字,例如,當我們說「開綠燈」,手機就送出「1」到ESP32,而根據判斷ESP32獲得1就會開啟綠色LED。
我們先點選右上角的機器人圖示來設定語音指令,進入設定後往下拉到底,可以找到「Vocal Command Configuration」的功能(如圖24),進入設定畫面後,該APP一共提供10個語音指令(如圖25),我們先設定一個作為示範。

image image
圖24:設定語音指令 圖25:一共有10組語音指令

設定方式如下,我們點選第一個語音指令「Vocal Command no1」後,一共有兩個值要設定,第一個Vocal command代表要講的話,第二個Data to send則是要在藍芽發送的文字,舉例來說,要講的話就是「開綠燈」(如圖26),而要在藍芽發送的文字則是「1」(如圖27)。這樣當手機聽到我們講「開綠燈」時,就會發送1到ESP32,而依據程式的判斷,收到1就會開啟綠燈。而其餘的語音指令則可以依照相同的方式設定,例如「Vocal Command no2」的Vocal command設定為「關綠燈」、Data to send設定為「2」,而「Vocal Command no3」的Vocal command設定為「開黃燈」、Data to send設定為「3」等等。

image image
圖26:設定語音命令為「開綠燈」     圖27:設定要送出的文字「1」

接下來我們就可以利用手機語音辨識的功能,來控制燈號開關,回到APP首頁畫面後(如圖28),點選右下角的「Voice Control」語音按鈕就會跳出麥克風圖示(如圖29),點選麥克風後,請讀者說出設定好的語音指令,例如「開綠燈」,此時手機辨識「開綠燈」成功後(如圖30),就會在藍芽送出「1」給ESP32,ESP32就可以開啟綠燈。

image image
圖28:點選右下角的Voice Control  圖29:點選麥克風圖示
image image
圖30:「開綠燈」辨識成功     圖31:ESP32從藍芽收到「1」

本練習只用來開啟或關閉LED,當然有點大材小用,但是讀者可以自行開發新的功能,例如透過繼電器relay來開啟或關閉電風扇、檯燈、甚至冷氣等等的家電,而達到簡易的智慧家電的功能。

參考本人之前的作品如下

PS.本練習其實只有用到ESP32 藍芽2.0 Serial Port Profile(SSP)通訊。

arrow
arrow

    夜市 小霸王 發表在 痞客邦 留言(0) 人氣()