Skip to content

Instantly share code, notes, and snippets.

@mokjpn
Last active May 4, 2020 15:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mokjpn/565ae0b71d0d9d53f7845bb7cefb527f to your computer and use it in GitHub Desktop.
Save mokjpn/565ae0b71d0d9d53f7845bb7cefb527f to your computer and use it in GitHub Desktop.
M5Atom and PIR unit and Switchbot
# Control SwitchBot with M5Atom+PIR sensor unit
# Many thanks to https://tech.fusic.co.jp/posts/2020-04-01-switchbot-with-m5stack/
#include <M5Atom.h>
#include "BLEDevice.h"
#define SWITCHBOT_MAC "XX:XX:XX:XX:XX:XX"
static BLEUUID serviceUUID("CBA20D00-224D-11E6-9FB8-0002A5D5C51B");
static BLEUUID characteristicUUID("CBA20002-224D-11E6-9FB8-0002A5D5C51B");
static BLEAdvertisedDevice* myDevice = NULL;
static uint8_t cmdPress[3] = {0x57, 0x01, 0x00};
uint8_t DisBuff[2 + 5 * 5 * 3];
void setBuff(uint8_t Rdata, uint8_t Gdata, uint8_t Bdata)
{
DisBuff[0] = 0x05;
DisBuff[1] = 0x05;
for (int i = 0; i < 25; i++)
{
DisBuff[2 + i * 3 + 0] = Rdata;
DisBuff[2 + i * 3 + 1] = Gdata;
DisBuff[2 + i * 3 + 2] = Bdata;
}
}
bool pressSwitchBot() {
bool result;
BLEClient* pClient = BLEDevice::createClient();
result = pClient->connect(myDevice);
if(!result) {
setBuff(0xff, 0x00, 0x00); // if not connected set color to red.
M5.dis.displaybuff(DisBuff);
delay(2000);
return(false);
}
BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
if (pRemoteService == nullptr) {
pClient->disconnect();
setBuff(0xff, 0x00, 0x00); // if no service detected, set color to red.
M5.dis.displaybuff(DisBuff);
delay(2000);
return(false);
}
BLERemoteCharacteristic* pCharacteristic = pRemoteService->getCharacteristic(characteristicUUID);
if (pCharacteristic == nullptr) {
pClient->disconnect();
setBuff(0xff, 0x00, 0x00); // if no characteristics matched, set color to red.
M5.dis.displaybuff(DisBuff);
delay(2000);
return(false);
}
pCharacteristic->writeValue(cmdPress, sizeof(cmdPress), false);
pClient->disconnect();
setBuff(0x00, 0xff, 0x00); // if the command was sent successfully, set color to green.
M5.dis.displaybuff(DisBuff);
delay(2000);
return(true);
}
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)
&& advertisedDevice.getAddress().equals(BLEAddress(SWITCHBOT_MAC))) {
Serial.println(advertisedDevice.getAddress().toString().c_str()); // if specified device found, print its MAC address to serial console.
BLEDevice::getScan()->stop();
myDevice = new BLEAdvertisedDevice(advertisedDevice);
setBuff(0x00, 0x00, 0xff); // if device found, set color to blue.
M5.dis.displaybuff(DisBuff);
}
}
};
void setup() {
Serial.begin(115200);
M5.begin(true, false, true);
delay(10);
setBuff(0xff, 0x00, 0x00); // set color to red.
M5.dis.displaybuff(DisBuff);
// PIR sensor unit connected to M5Atom port.
pinMode(32, INPUT);
BLEDevice::init("M5Press");
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setInterval(1349);
pBLEScan->setWindow(449);
pBLEScan->setActiveScan(true);
pBLEScan->start(5, false);
setBuff(0x00, 0xff, 0x00); // after initializing, set color to green.
M5.dis.displaybuff(DisBuff);
}
static uint32_t count = 0;
static bool isdark = false;
void loop() {
if (myDevice == NULL) {
setBuff(0xff, 0x00, 0x00); // if no switchbot is connected yet, set color to red.
M5.dis.displaybuff(DisBuff);
return;
}
if (M5.Btn.wasPressed()) {
pressSwitchBot();
}
if(digitalRead(32) == 0) {
if (!isdark) {
setBuff(0xff, 0x00, 0xff); // if no motion detected, set color to magenda.
M5.dis.displaybuff(DisBuff);
}
count += 1;
if(count > 2 * 60 * 5 && !isdark ) { // 5 minutes
setBuff(0x00, 0xff, 0xff); // if no motion detected for 5 miniutes, set color to cyan then try to turn switch on.
M5.dis.displaybuff(DisBuff);
isdark = true;
while(!pressSwitchBot()) true;
setBuff(0x00, 0x00, 0x00); // after turn switch on, off the light.
M5.dis.displaybuff(DisBuff);
}
} else {
isdark = false;
count = 0;
setBuff(0x00, 0xff, 0x00); // if any motion detected, set color to green.
M5.dis.displaybuff(DisBuff);
}
delay(500);
M5.update();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment