ESP-WROOM-32D開発ボードでSwitchbotを動作させる
ESP-WROOM-32D開発ボードとSwitchbotを動かしてみたいと思います。
前回のコードからM5StickC関係の部分を削除するだけで動作しました。
並列処理はまだ使い方が分からないので、スライドスイッチを利用してPIN 25がONであればスイッチボットが10秒に一回動作するように設定します。
配線
ESP-WROOM-32D開発ボードの25番ピンとGNDを接続すると、PIN25=ONと判断されスイッチボットが動作するようにします。なのでこの間にスライドスイッチを差し込んでおきます。
スライドスイッチがONである間は、10秒に一回スイッチボットへ動作指令が飛ぶようなプログラムになってます。
部品
スライドスイッチはブレッドボード専用ではないですが、一応使えてます。ブレッドボードはこの開発ボードには6穴のほうが良いと思います
・ESP32−DevKitC ESP−WROOM−32開発ボード: 無線、高周波関連商品 秋月電子通商-電子部品・ネット通販
・小型スライドスイッチ 1回路2接点 SS12D01G4: パーツ一般 秋月電子通商-電子部品・ネット通販
・ブレッドボード BB−801: パーツ一般 秋月電子通商-電子部品・ネット通販
コード
static String MAC_SWITCHBOT = "xx:xx:xx:xx:xx:xx";のxxの部分にスイッチボットのMACアドレスを入力してください。
//#include <M5StickC.h> #include <driver/i2s.h> #include "BLEDevice.h" //追加 #define BTN_A_PIN 34 #define BTN_B_PIN 18 #define LED_PIN 10 // このLEDは、GPIO10の電位を下げることで発光するタイプ #define LED_ON LOW #define LED_OFF HIGH // INPUT_PULLUPが有効かは不明だが、有効という前提で定義 #define BTN_ON LOW #define BTN_OFF HIGH uint8_t prev_btn_a = BTN_OFF; uint8_t btn_a = BTN_OFF; // このLEDは、GPIO10の電位を下げることで発光するタイプ #define LED_ON LOW #define LED_OFF HIGH // INPUT_PULLUPが有効かは不明だが、有効という前提で定義 #define BTN_ON LOW #define BTN_OFF HIGH // 手元のSwitchBotのMACアドレス static String MAC_SWITCHBOT = "C3:8D:26:47:8A:55"; // SwitchBotのBLE情報 static BLEUUID SERV_SWITCHBOT("cba20d00-224d-11e6-9fb8-0002a5d5c51b"); static BLEUUID CHAR_SWITCHBOT("cba20002-224d-11e6-9fb8-0002a5d5c51b"); // SwitchBot へ送信するコマンド // アームを倒し、引く動作の場合 {0x57, 0x01, 0x00} // 以下2つはスマートフォンアプリでモードを変える必要あり // アームを倒す動作の場合 {0x57, 0x01, 0x01} // アームを引く動作の場合 {0x57, 0x01, 0x02} static uint8_t cmdPress[3] = {0x57, 0x01, 0x01}; #define PIN_CLK 0 #define PIN_DATA 34 #define READ_LEN (2 * 1024) #define SAMPLING_FREQUENCY 44100 uint8_t BUFFER[READ_LEN] = {0}; uint16_t *adcBuffer = NULL; //const uint16_t FFTsamples = 256; // サンプル数は2のべき乗//消去 //double vReal[FFTsamples]; // vReal[]にサンプリングしたデーターを入れる//消去 //double vImag[FFTsamples];//消去 //arduinoFFT FFT = arduinoFFT(vReal, vImag, FFTsamples, SAMPLING_FREQUENCY); // FFTオブジェクトを作る//消去 bool doScan = true; BLEScan* pBLEScan; static BLEAddress *pGattServerAddress; static BLEAdvertisedDevice* myDevice; static BLERemoteCharacteristic* pRemoteCharacteristic; static BLEClient* pClient = NULL; unsigned int sampling_period_us; float dmax = 10000.0; bool doDetection = false; bool sendFlg = false; bool cas = false; //int printCount = 0; void log(String s) { Serial.println(s); } // BLEへの接続 コールバック class MyClientCallback : public BLEClientCallbacks { void onConnect(BLEClient* pclient) { Serial.println("onConnect"); // log("cc conn"); } void onDisconnect(BLEClient* pclient) { Serial.println("onDisconnect"); // log("dis"); // doScan = true; // doDetection = false; if (cas) { esp_restart(); } } }; // アドバタイズ検出時のコールバック class advdCallback: public BLEAdvertisedDeviceCallbacks { void onResult(BLEAdvertisedDevice advertisedDevice) { Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str()); if (advertisedDevice.haveServiceUUID()) { String addr = advertisedDevice.getAddress().toString().c_str(); Serial.printf("It have service addr: %s \n", advertisedDevice.getAddress().toString().c_str()); if (addr.equalsIgnoreCase(MAC_SWITCHBOT)) { // SwitchBot を発見 // if (advertisedDevice.getServiceUUID().equals(SERV_SWITCHBOT)) { log("found"); advertisedDevice.getScan()->stop(); pGattServerAddress = new BLEAddress(advertisedDevice.getAddress()); myDevice = new BLEAdvertisedDevice(advertisedDevice); doScan = false; doDetection = true; // m5LED(500, 2); } } } }; void setup() { Serial.begin(115200); pinMode(BTN_A_PIN, INPUT_PULLUP);//追加 log("Start"); // BLE 初期化 BLEDevice::init(""); // デバイスからのアドバタイズをスキャン pBLEScan = BLEDevice::getScan(); pBLEScan->setAdvertisedDeviceCallbacks(new advdCallback()); pBLEScan->setActiveScan(true); pBLEScan->setInterval(100); pBLEScan->setWindow(99); // less or equal setInterval value } void loop() { btn_a = digitalRead(BTN_A_PIN);//追加 if((btn_a == BTN_ON)){//追加 if (doScan) { log("Scan"); pBLEScan->start(5, false); } if(doScan == false){ digitalWrite(LED_PIN, LED_ON); //digitalWrite(LED_PIN, LED_OFF); if (connectAndSendCommand(*pGattServerAddress)) { log("Done!"); sendFlg = false; doScan = false; delay(10000); } else { log("Failed."); doScan = true; delay(3000); } } } vTaskDelay(500 / portTICK_RATE_MS); } // SwitchBot の GATT サーバへ接続 ~ Press コマンド送信 static bool connectAndSendCommand(BLEAddress pAddress) { cas = true; try { pClient = BLEDevice::createClient(); pClient->setClientCallbacks(new MyClientCallback()); log("Connecting"); while (!pClient->connect(myDevice)) { log("reconnect"); delay(1000); } // 対象サービスを得る BLERemoteService* pRemoteService = pClient->getService(SERV_SWITCHBOT); if (pRemoteService == nullptr) { log("e:service not found"); return false; } // 対象キャラクタリスティックを得る pRemoteCharacteristic = pRemoteService->getCharacteristic(CHAR_SWITCHBOT); if (pRemoteCharacteristic == nullptr) { log("e:characteristic not found"); return false; } // キャラクタリスティックに Press コマンドを書き込む pRemoteCharacteristic->writeValue(cmdPress, sizeof(cmdPress), false); // pRemoteCharacteristic->writeValue("test", true); log("Send"); cas = false; delay(3000); pClient->disconnect(); pClient = NULL; delay(1000); } catch (...) { log("error"); if (pClient) { pClient->disconnect(); pClient = NULL; } return false; } return true; }
動作
ESP32開発モジュールでスイッチボット動いた。スライドスイッチがオンの間は10秒に一回プレスする仕様。 pic.twitter.com/vVZdUCxLL8
— タラオ (@chem_phys_elec) June 1, 2020