ESP32開発ボードでSwitchbot温湿度計のデータを取得する
これまではラズパイで2台のSwitchbot温湿度計のデータを取得していたのですが(Switchbot温度計とラズパイで快適IoTライフ - 愛と工作の日々)、より安価で低消費電力のESP32開発ボードの使用を検討しました。開発ボードはESP32-DevKitC-VE ESP32-WROVER-E開発ボードを使用しました。
qiita.com
こちらの記事のコードをchatGPT(GPT-4)の協力の元モディファイしました。
#include <BLEDevice.h> #include <BLEUtils.h> #include <BLEScan.h> #include <BLEAdvertisedDevice.h> int scanTime = 5; //In seconds BLEScan* pBLEScan; BLEAddress* addr01 = new BLEAddress("xx:xx:xx:xx:xx:xx"); BLEAddress* addr02 = new BLEAddress("xx:xx:xx:xx:xx:xx"); BLEUUID serviceUUID = BLEUUID("cba20d00-224d-11e6-9fb8-0002a5d5c51b"); BLEUUID serviceDataUUID = BLEUUID("00000d00-0000-1000-8000-00805f9b34fb"); int globalBattery; float globalTemperature; int globalHumidity; bool newDataAvailable = false; BLEAddress* detectedAddress = nullptr; class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { void onResult(BLEAdvertisedDevice advertisedDevice) { if(advertisedDevice.getAddress().equals(*addr01) || advertisedDevice.getAddress().equals(*addr02)){ // OK } else { return; } if(!advertisedDevice.haveServiceUUID()) return; if(!advertisedDevice.getServiceUUID().equals(serviceUUID)) return; if(!advertisedDevice.haveServiceData()) return; std::string s = advertisedDevice.getServiceData(); const char* servicedata = s.c_str(); int battery = servicedata[2] & 0b01111111; bool isTemperatureAboveFreezing = servicedata[4] & 0b10000000; float temperature = ( servicedata[3] & 0b00001111 ) / 10.0 + ( servicedata[4] & 0b01111111 ); if (!isTemperatureAboveFreezing) { temperature = -temperature; } int humidity = servicedata[5] & 0b01111111; detectedAddress = new BLEAddress(advertisedDevice.getAddress()); globalBattery = battery; globalTemperature = temperature; globalHumidity = humidity; newDataAvailable = true; } }; void setup() { Serial.begin(115200); Serial.println("Scanning..."); BLEDevice::init(""); pBLEScan = BLEDevice::getScan(); pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks(), true); pBLEScan->setActiveScan(true); pBLEScan->setInterval(100); pBLEScan->setWindow(99); } void loop() { BLEScanResults foundDevices = pBLEScan->start(scanTime, false); pBLEScan->clearResults(); if (newDataAvailable) { Serial.print("Address: "); Serial.println(detectedAddress->toString().c_str()); Serial.print("Battery: "); Serial.print(globalBattery); Serial.println("%"); Serial.print("Temperature: "); Serial.print(globalTemperature); Serial.println("°C"); Serial.print("Humidity: "); Serial.print(globalHumidity); Serial.println("%"); newDataAvailable = false; delete detectedAddress; detectedAddress = nullptr; } delay(2000); }
このコードをアップロードすると、シリアルモニタに2つの温湿度計のデータが交互に表示されました。