Skip to content

Instantly share code, notes, and snippets.

@fffonion
Created June 30, 2020 09:20
Show Gist options
  • Select an option

  • Save fffonion/72ba4996020f51d80c5915514d68ad0d to your computer and use it in GitHub Desktop.

Select an option

Save fffonion/72ba4996020f51d80c5915514d68ad0d to your computer and use it in GitHub Desktop.
Read Xiaomi Mijia temperature and humidity sensor 2 (LYWSD03MMC) from ESP32
#include <Arduino.h>
#include <BLEDevice.h>
BLEClient *pClient;
BLEScan *pBLEScan;
#define SCAN_TIME 10 // seconds
bool connected = false;
#undef CONFIG_BTC_TASK_STACK_SIZE
#define CONFIG_BTC_TASK_STACK_SIZE 32768
// The remote service we wish to connect to.
static BLEUUID serviceUUID("ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6");
// The characteristic of the remote service we are interested in.
static BLEUUID charUUID("ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6");
class MyClientCallback : public BLEClientCallbacks
{
void onConnect(BLEClient *pclient)
{
connected = true;
Serial.printf(" * Connected %s\n", pclient->getPeerAddress().toString().c_str());
}
void onDisconnect(BLEClient *pclient)
{
connected = false;
Serial.printf(" * Disconnected %s\n", pclient->getPeerAddress().toString().c_str());
}
};
static void notifyCallback(
BLERemoteCharacteristic *pBLERemoteCharacteristic,
uint8_t *pData,
size_t length,
bool isNotify)
{
float temp;
float humi;
float voltage;
Serial.print(" + Notify callback for characteristic ");
Serial.println(pBLERemoteCharacteristic->getUUID().toString().c_str());
temp = (pData[0] | (pData[1] << 8)) * 0.01; //little endian
humi = pData[2];
voltage = (pData[3] | (pData[4] << 8)) * 0.001; //little endian
Serial.printf("temp = %.1f C ; humidity = %.1f %% ; voltage = %.3f V\n", temp, humi, voltage);
pClient->disconnect();
}
void registerNotification()
{
if (!connected)
{
Serial.println(" - Premature disconnection");
return;
}
// Obtain a reference to the service we are after in the remote BLE server.
BLERemoteService *pRemoteService = pClient->getService(serviceUUID);
if (pRemoteService == nullptr)
{
Serial.print(" - Failed to find our service UUID: ");
Serial.println(serviceUUID.toString().c_str());
pClient->disconnect();
}
Serial.println(" + Found our service");
// Obtain a reference to the characteristic in the service of the remote BLE server.
BLERemoteCharacteristic *pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
if (pRemoteCharacteristic == nullptr)
{
Serial.print(" - Failed to find our characteristic UUID: ");
Serial.println(charUUID.toString().c_str());
pClient->disconnect();
}
Serial.println(" + Found our characteristic");
pRemoteCharacteristic->registerForNotify(notifyCallback);
}
void createBleClientWithCallbacks()
{
pClient = BLEDevice::createClient();
pClient->setClientCallbacks(new MyClientCallback());
}
void connectSensor(BLEAddress htSensorAddress)
{
pClient->connect(htSensorAddress);
}
void setup()
{
Serial.begin(115200);
Serial.println("+ Starting MJ client...");
delay(500);
BLEDevice::init("ESP32");
createBleClientWithCallbacks();
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
pBLEScan->setInterval(0x50);
pBLEScan->setWindow(0x30);
}
std::string addresses[10];
int addressCount = 0;
void loop()
{
delay(500);
BLEScanResults foundDevices = pBLEScan->start(SCAN_TIME);
int count = foundDevices.getCount();
Serial.printf("+ Found device count : %d\n", count);
for (int i = 0; i < count; i++)
{
BLEAdvertisedDevice b = foundDevices.getDevice(i);
Serial.println(b.toString().c_str());
if (!b.getName().compare("LYWSD03MMC"))
{
BLEAddress addr = b.getAddress();
addresses[addressCount] = addr.toString();
addressCount++;
}
}
for (int i = 0; i < addressCount; i++)
{
std::string curAddr = addresses[i];
bool found = false;
for (int j = 0; j < count; j++)
{
if (foundDevices.getDevice(j).getAddress().equals(BLEAddress(curAddr)))
{
found = true;
}
}
if (!found)
{
Serial.printf("* Remove offline address : %s\n", curAddr.c_str());
for (int j = addressCount; j > max(i, 1); j--)
{
addresses[j - 1] = addresses[j];
}
continue;
}
Serial.printf("+ Connect : %s\n", curAddr.c_str());
connectSensor(BLEAddress(curAddr));
registerNotification();
while (connected)
{
delay(10);
};
}
delay(500);
}
// service data: 30585b05a5a4797938c1a408
@krschneider
Copy link

look at the variable addressCount - it is initialized at the end of setup; and adressCount++ in the loop -
but the variable is never reset back to zero. I think the variable should be reset to zero for each iteration of the loop...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment