BLYNK
HOME       📲 GETTING STARTED       📗 DOCS       ❓HELP CENTER       👉 SKETCH BUILDER

Xiaomi Mi Temperature Humidity Sensor (MJ_HT) + ESP32 + Blynk

esp32
#1

Hi Blynkers !

Here is the project I just finished, the goal was to connect the Xiaomi Temperature and Humidity sensor (that you can buy for around 12€) with Blynk through ESP32.

Code

#include <esp_log.h>
#include <string>
#include <sstream>
#include <sys/time.h>
#include <BLEDevice.h>

#include <BLEAdvertisedDevice.h>
#include <BLEClient.h>
#include <BLEScan.h>
#include <BLEUtils.h>
#include <sdkconfig.h>

#define BLYNK_PRINT Serial // Defines the object that is used for printing
#define BLYNK_DEBUG        // Optional, this enables more detailed prints
#define BLYNK_NO_BUILTIN   // Disable built-in analog & digital pin operations
#include <Time.h>
#include <TimeLib.h>
//#include <WiFi.h>
//#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

//WidgetRTC rtc;
BlynkTimer timer;
BLEClient* pClient;

//**********TOKEN (OK)**********//
char auth[] = "YOUR BLINK TOKEN";

//**********WIFI (OK)**********//
char ssid[] = "WIFI";
char pass[] = "PASS";

#define MJ_ADDR "58:2D:34:31:F8:50"
static BLEAddress MJAddress(MJ_ADDR);
static boolean connected = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
uint8_t* pData;
float temp;
float humi;
int n=0;
WidgetBridge bridge1(V10); //Initiating Bridge Widget on V1 of Device LolinD32

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
// The remote service we wish to connect to.
static BLEUUID serviceUUID("226c0000-6476-4566-7562-66734470666d");
// The characteristic of the remote service we are interested in.
static BLEUUID    charUUID("226caa55-6476-4566-7562-66734470666d");

static void notifyCallback(
  BLERemoteCharacteristic* pBLERemoteCharacteristic,
  uint8_t* pData,
  size_t length,
  bool isNotify) {
    Serial.print("Notify callback for characteristic ");
    Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
    Serial.print(" of data length ");
    Serial.println(length);
    Serial.print("data: ");
    Serial.println((char*)pData);
    temp = ((pData[2]-48)*10 + pData[3]-48 + (pData[5]-48)*0.1);
    Serial.println(temp);
    humi = ((pData[9]-48)*10 + pData[10]-48 + (pData[12]-48)*0.1);
    Serial.println(humi);
}

void sendSensorData(){
  Serial.println("Sending data to Blynk");
  Serial.println(temp);
  Serial.println(humi);
  Blynk.begin(auth, ssid, pass);
  Blynk.connect();
  bridge1.setAuthToken("BRIDGE TOKEN");
  Blynk.virtualWrite(V17, temp);
  Blynk.virtualWrite(V18, humi);
  bridge1.virtualWrite(V17, temp);
  bridge1.virtualWrite(V18, humi);
  delay(500);
  Blynk.disconnect();
  WiFi.mode(WIFI_OFF);
}


class MyClientCallback : public BLEClientCallbacks {
  void onConnect(BLEClient* pclient) {
    Serial.println("on connect");
  }

  void onDisconnect(BLEClient* pclient) {
    connected = false;
    Serial.println("onDisconnect");
    if (n==0){
      Serial.println("RESTART");
      ESP.restart();
    }
  }
};

void getSensorData1(){
  connectToServer(MJAddress);
}

void connectToServer(BLEAddress pAddress){
  n=0;
  Serial.println(" - Created client");
  pClient->setClientCallbacks(new MyClientCallback());
  Serial.println("=================== Forming a connection to Flora device ====================");
  Serial.println(pAddress.toString().c_str());
  Serial.println(" - Connection to MJ");
  pClient->connect(pAddress);
  n=1;
  Serial.println(" - Connected to MJ");

  // 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.
    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);
    timer.setTimeout(10000L, sendSensorData);
}

void setup() {
  Serial.begin(115200);
  Serial.println("Starting MJ client...");
  delay(500);
  BLEDevice::init("");
  pClient  = BLEDevice::createClient();
  delay(500);
  timer.setInterval(600000L, getSensorData1);
}

void loop() {
  timer.run();
}

You can find your sensor’s address using “nRF Connect” app on your Smartphone and replace the address in the sketch
Of course, the bridge part is not mandatory.

3 Likes

#2

How can i conect only to a local blynk raspbery server ?
I have 5 devices like this
https://www.amazon.de/Xiaomi-Bluetooth-Temperature-Humidity-Control/dp/B079XYJZ32
I search 4 days to ghet a solution

0 Likes

#3

I forgot to specify that i have raspbery pi 3 b+ and esp32

0 Likes

#4

Hi @bog, this is also the Xiaomi device I used.
I can’t tell how to use a local server, because I use Blynk Cloud server, and I have no clue how to use a local one.

Nevertheless, the code for the ESP32 in the 1st message can be adapted. What you might need to change :

  • Sensor address

#define MJ_ADDR "58:2D:34:31:F8:50"
Change it with address of your Xiaomi device (nRF Connect on Appstore/Playstore)

  • All Blynk related code, including function sendSensorData()
0 Likes

#5

////////////////////////////////////
void setup() {
Serial.begin(115200);
Blynk.begin(auth, ssid, pass, IPAddress(192,xxx,x,xxx), 8080); /// i change here
Serial.println(“Starting MJ client…”);
delay(500);
BLEDevice::init("");
pClient = BLEDevice::createClient();
delay(500);
timer.setInterval(6000000L, getSensorData1);
}
/////////////////////////

This is my serial output
image

0 Likes

#6

In my code, Blynk.begin is not called in setup() function.
Try to delete Blynk.begin from setup(), and put it into sendSensorData() function, as I did.

0 Likes

#7

It’s workyng ! :slight_smile:
How can i implement the all 5 xiaomi ?
What tipe of code i can remove ?
Because the code is ocuping 75% with modified library .

0 Likes

#8

First, set the “Partition Scheme” like my screenshot :

Next, you can remove Bridge related code if you don’t need it. You also can try to delete any libraries (like esp_log for example) and try if it’s still work. To be honest, I copied a code without checking if every library is needed.

To implement multiple sensors, you can declare multiple address’ :

static BLEAddress MJAddress(MJ_ADDR);
static BLEAddress MJAddress1(MJ_ADDR);
static BLEAddress MJAddress2(MJ_ADDR);
static BLEAddress MJAddress3(MJ_ADDR);
static BLEAddress MJAddress4(MJ_ADDR);

Then, you can call your function connectToServer(MJAddress1) when you want to have the data of the 2nd sensor, and repeat for the next sensor etc.

0 Likes