我的ESP32實做書籍:我出書了 ESP32 物聯網專題
博客來網址:https://www.books.com.tw/products/0010901195
我家那狗子在家嗎?不知道有沒有趁我加班溜出去鬼混?
我想每一個人都會想知道另外一半有沒有乖乖在家,除了打電話查勤、請鄰居(閨蜜!)看管,或者安裝監視器隨時遠端查看之外,還有另外一個選擇,就是藍芽掃描,不過這得他有戴著狗環,歐不,是手環才行。
現在的手環為了能時時與手機連線或者其他(機密)功能都會做藍芽Beacon廣播,那麼我們就可以利用這個特性,偷偷在背後收集藍芽廣播,如果找不到他的手環廣播,就可以確定他不在家了,至於出去鬼混,還是只是去巷口711買杯咖啡這就是你們之間的問題,科技只能解決問題,你才是那個能解決有問題的人。
本篇我們透過ESP32做BLE掃描,如果掃描到你家狗子的手環,且RSSI超過-80的話,就判定為在家,否則就判定不在家,然後再將訊號傳送到ThingSpeak製作成圖表,這樣你就可以監視這狗子的行蹤了。
1.當然你必須先取得你家狗子手環的Mac address
手機APP安裝一下Lightblue就可以掃描,他的畫面如下,紅色圈圈就是我的手環,下方的「E0:E2:0A:25:FE:2F」就是我的Mac address,不過到時候要用小寫喔「e0:e2:0a:25:fe:2f」
2.到ThingSpeak開啟一個channel來收資料
這部份請參閱:第十四篇 ESP32 資料庫存取ThingSpeak圖表製作
3.將程式燒錄到ESP32中,並修改相關設定即可。
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#include <WiFi.h>
#include <HTTPClient.h>
char ssid[] = "SSID"; //無線網路SSID
char password[] = "PASSWORD"; //無線網路密碼
String url = "http://api.thingspeak.com/update?api_key=你的ThingSpeak Key";
String Myaddress = "Beacon Address"; //Beacon或手錶MAC address: xx:xx:xx:xx (小寫字母)
int RSSIThreshold =-80;//以RSSI強度做簡易測距
int scanTime = 20; //設定20秒掃描一次
BLEScan* pBLEScan;
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
//列出Beacon所有資訊
//Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
//取得address
String BeaconAddress = advertisedDevice.getAddress().toString().c_str();
Serial.print("Address:");Serial.print(BeaconAddress);
//取得RSSI
int BeaconRSSI = advertisedDevice.getRSSI();
Serial.print(",RSSI:");Serial.println(BeaconRSSI);
if (BeaconAddress == Myaddress) {
if ( BeaconRSSI >= RSSIThreshold) {
Serial.println("在家");
HTTPClient http;
String url1 = url + "&field1=1";
//http client取得網頁內容
http.begin(url1);
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
//讀取網頁內容到payload
String payload = http.getString();
//將內容顯示出來
Serial.print("網頁內容=");
Serial.println(payload);
} else {
//讀取失敗
Serial.println("網路傳送失敗");
}
http.end();
}
else {
Serial.println("不在家");
HTTPClient http;
String url1 = url + "&field1=0";
//http client取得網頁內容
http.begin(url1);
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
//讀取網頁內容到payload
String payload = http.getString();
//將內容顯示出來
Serial.print("網頁內容=");
Serial.println(payload);
} else {
//讀取失敗
Serial.println("網路傳送失敗");
}
}
}
}
};
void setup() {
Serial.begin(115200);
Serial.println("開始連線WiFi網路");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.println("WiFi連線完成");
//設定BLE掃描
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
pBLEScan->setInterval(100);
pBLEScan->setWindow(99); // less or equal setInterval value
}
void loop() {
Serial.print("BLE掃描開始....");
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
Serial.print("一共找到裝置: ");
Serial.println(foundDevices.getCount());
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
delay(100);
}