平成の時代に
wakwak-koba.hatenadiary.jp
という記事を書きました。
書いたこともすっかり忘れかけていましたが、最近になって、この記事をご覧になった方から
@wakwak_koba 2018年ごろの話題で恐縮ですが、ダイソーのBLEモバイルシャッターを手に入れ2018-10-09のブログ https://t.co/IZnp6Ij5ck にあるVolumeDown版を試しています。現時点(2020年7月末)で、Arduino IDE 1.8.13上でESP32_BLE_Arduino 1.0.4を入れて上記ブログのスケッチをビルドすると(続)
— Hiroyuki Ohno (@hohno_at_kuimc) 2020年7月23日
というリプライを頂き思い出しました。
この記事で参照してるリポジトリを消してしまったではないか!
いやぁ、ESP32_BLE_Arduino(のお守りをしてるコミッター)があまりにポンコツすぎて愛想が尽きたんですよ。
細かい話は気が向いたらするとして、あれはオワコンです。
その代替えというか救世主というか、そんな立ち位置のところに NimBLE-Arduino なるものが爆誕しました。
arduino_esp32 の次か次の次くらいのメジャーアップデートで ESP32_BLE_Arduino は追放され、NimBLE-Arduino に置き換わることはほぼ間違いないです。
ということで、2年も前に書いた「ダイソー BLE リモートシャッター で SwitchBot を操る」のほうも ESP32_BLE_Arduino ではなく NimBLE-Arduino に対応させるべく修正を施すことにいたしました。
導入する NimBLE-Arduino ですが、今回もまた 本家 をベースに私のほうで修正を加えており、そちらを使っていただきます。
github.com
メインのスケッチは以下のとおり。
//#include "BLEDevice.h" #include <NimBLEDevice.h> static BLEUUID UUID_ABSHUTTER((uint16_t)0x1812); static BLEUUID UUID_SWITCHBOT("cba20d00-224d-11e6-9fb8-0002a5d5c51b"); static BLEUUID CHAR_SWITCHBOT("cba20002-224d-11e6-9fb8-0002a5d5c51b"); static BLEClient* BLEC_ABSHUTTER = NULL; static BLEClient* BLEC_SWITCHBOT = NULL; static uint16_t clicked_button = 0; class MyAdvertisedDeviceCallbacks: public NimBLEAdvertisedDeviceCallbacks { void onResult(NimBLEAdvertisedDevice* advertisedDevice) { if (advertisedDevice->haveServiceUUID()) { if(advertisedDevice->getServiceUUID().equals(UUID_ABSHUTTER)) { BLEC_ABSHUTTER = BLEDevice::createClient(advertisedDevice->getAddress()); Serial.print("registered:"); } else if(advertisedDevice->getServiceUUID().equals(UUID_SWITCHBOT)) { BLEC_SWITCHBOT = BLEDevice::createClient(advertisedDevice->getAddress()); Serial.print("registered:"); } else Serial.print(" "); Serial.printf("%s %s", advertisedDevice->getServiceUUID().toString().c_str(), advertisedDevice->getName().c_str()); Serial.println(); if(BLEC_ABSHUTTER && BLEC_SWITCHBOT) advertisedDevice->getScan()->stop(); } } }; static void notifyCallback(BLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) { if(length == 2 && !clicked_button) clicked_button = pData[0] << 8 | pData[1]; } void setup() { Serial.begin(115200); BLEDevice::init(""); auto pBLEScan = BLEDevice::getScan(); pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); pBLEScan->setActiveScan(true); pBLEScan->start(30); } void loop() { if(BLEC_ABSHUTTER && !BLEC_ABSHUTTER->isConnected()) if(BLEC_ABSHUTTER->connect()) { Serial.println("connected:ABShutter"); auto pServices = BLEC_ABSHUTTER->getServices(true); for(auto pService : *pServices) { auto pCharacteristics = pService->getCharacteristics(true); for(auto pCharacteristic : *pCharacteristics) if(pCharacteristic->canNotify()) pCharacteristic->registerForNotify(notifyCallback); } } if(BLEC_SWITCHBOT && !BLEC_SWITCHBOT->isConnected() && BLEC_ABSHUTTER && BLEC_ABSHUTTER->isConnected()) { BLEC_SWITCHBOT->connect(); Serial.println("connected:SwitchBot"); } if(BLEC_SWITCHBOT && BLEC_SWITCHBOT->isConnected() && clicked_button) { Serial.printf("button pressed:%04x", clicked_button); Serial.println(); uint8_t buf[] = {0x57, 0x01, 0x00}; switch(clicked_button) { case 0x0100: // Volume Up buf[2] = 0x03; break; case 0x0200: // Volume Down buf[2] = 0x04; break; case 0x0028: // Enter break; } BLEC_SWITCHBOT->getService(UUID_SWITCHBOT)->setValue(CHAR_SWITCHBOT, std::string((char *)buf, sizeof(buf))); clicked_button = 0; } }