ESP32 Xiaomi Hack [UPDATED Oct. 2020]
Dear friends welcome to another video! Today we are going to learn how to get the data that this Xiaomi Temperature and Humidity monitor transmits using the Bluetooth functionality of the ESP32 board. There is a lot to cover so, let’s get started!
Intro to the ESP32 Xiaomi Hack
Hello, guys, I am Nick and welcome to educ8s.tv a channel that is all about DIY electronics projects. In this channel, I share everything about the projects I build to help you develop similar projects or inspire you to start making things because it is easy, fun and creative. Subscribe to the channel now if you do not want to miss any future video.
Let’s see what we are going to build today. As you can see, I am using an ESP32 board and a 2.8” color TFT display I reviewed a few weeks ago. On the display, we display the temperature and the humidity. The cool thing is that I haven’t connected any sensors to the ESP32 board. I get the temperature and the humidity wirelessly from this commercial Xiaomi Temperature and Humidity monitor. How cool is that! The display on the Xiaomi device is updated every second but I update the display that is connected to the ESP32 board every 10 seconds to conserve power on the Xiaomi device.
This cool Xiaomi temperature and humidity sensor displays the temperature and the humidity on its LCD display and it can also transmit the data to other Xiaomi Devices or apps using the Bluetooth protocol. The devices uses a single AAA battery and since it is a commercial product, the battery life of the device is excellent. It can last on a single AAA battery for months, something we can’t achieve on our DIY projects. A few weeks ago, I discovered that some clever guys managed to reverse engineer the protocol that Xiaomi uses to transmit the data from the sensor and managed to get that data using an ESP32 board. So I tried it, and as you can see it works!
——————–
WHERE TO BUY
——————–
ESP32: https://educ8s.tv/part/ESP32
2.8″ Display: https://educ8s.tv/part/28ILI9341
Xiaomi Sensor: https://educ8s.tv/part/XiaomiThermometer
Breadboard: https://educ8s.tv/part/LargeBreadboard
Wires: https://educ8s.tv/part/Wires
USB Meter: https://educ8s.tv/part/UsbDoctorOLED
Powerbank: https://educ8s.tv/part/Powerbank
Full disclosure: All of the links above are affiliate links. I get a small percentage of each sale they generate. Thank you for your support!
[adsense]
The Electronics
First, we have to connect the ESP32 Board to the 2.8” display according to this schematic diagram.
I am using this DOIT ESP32 board which was released about two years ago. This version of the board is no longer available since there is now a newer version of it available which offers more pins, this one. The only reason I am using the old version of the board is that the GND pin of the board placed next to the SPI pins, at the same side of the board, which makes it breadboard friendly.
After connecting the display to the board we can power up the project. After a few seconds, we receive live data from the nearby Xiaomi Device. Since the device uses Bluetooth 4 the range of it is pretty good. We can easily get the data this device transmits from distances up to 10 meters or more! We can also receive the battery level of the Xiaomi Device but I don’t display this value on the screen.
If we use this USB meter, we can see that the current draw of this project is around 120-150 mA using this big display. If we use an e-paper display, put the ESP32 board in deep sleep mode, and get data from the sensor every few minutes we can make this project battery friendly. I will try this in a future video. This project is just a demonstration that we can get data from this device wirelessly.
The code of the ESP32 Xiaomi Hack
Let’s now see the software side of the project.
The code of the project is based on this project: https://github.com/turlvo/KuKuMi
I used the code which gets that data from the Xiaomi device and built a standalone project with it. In this variable, we declare that we need to get fresh data every 10 seconds. Here, we declare that we want to display the temperature in degrees Celsius. If you want to use the Imperial system just set this variable to false. At the setup function we initialize the display and the Bluetooth module of the ESP32 board and then we draw the user interface on the screen. Next, we search for Bluetooth devices nearby every 10 seconds. We don’t make a connection to the Xiaomi Device since it is not needed. We only scan for nearby Bluetooth low energy peripherals and check the broadcast advertisement packets. The humidity and temperature values are stored in those packets, so we only need to read them. After we read the values we display them on the screen. As always you can find a link to the code of this project in the description of the video below.
Now that we know how to get data wirelessly from this sensor we can build a complete battery-powered weather station. Since this Xiaomi Device is a commercial product, it offers great battery life. Unfortunately, we can’t achieve similar battery consumption on our projects yet. So, I plan to use this sensor as an outdoors sensor for a weather station project which will use a big e-paper display. It will be cool. Also, I am going to search for other Xiaomi Bluetooth enabled devices that we can hack in a similar way. Stay tuned.
——————–
CODE
——————–
——————–
SUBSCRIBE ON YOUTUBE
——————–
Never miss a video: Subscribe to educ8s.tv
Hi, with this development, can be possible to use a sonoff 5-24 DC V that has a ESP8266 with 2-4 relays to control in 1 channel the compressor and in the other relay the fan, so with the data you obtain from Xiaomi Temperature and Humidity monitor can be implement a low cost intelligent thermostat, that’s my idea and be program from a web page as the sonoff can be used when you flash other custom firmware. As you need 1.5 v from battery to give energy to the Xiaomi Temperature and Humidity monitor, you can rectify from 24 AC Volts that came from the transformer in the Air Condition unit and so the sonoff switch too, to obtain the power it need to operate.
I just buy my first sonoff switch to see how to operate with them.
can you do it as a project as I can see you how can be done.
hye all !
did anyone tried to decrypt new qingping CGG1 temp sensor? They are basically the same as the one you used, but encrypted…
Hi, thank you for sharing code and clear explanation.
How can i increase the BLE distance? Currently ESP cannot detect any data with distance longer than 4meters.
thank you
Hı Nick; I’m Murat. I try your code. I’v got ESP32 Wroom. This code i not worked for me.
It found device by name but it cannot read temp, humidity and battery level.
cServiceData[11] value always returned zero. why i don’t know. Please help me.
Thanks.
Hi, I’m experiencing the same issue, my payload is fe95d6549d5abb42 and doesn’t decode and as stated above cServiceData[11] isn’t matching any of the case statements. Anyone have any ideas. I have just purchased the Xiaomi sensor, maybe its a firmware version change on the sensor??
Thanks
Stu
Please downgrade your ESP32 package to version 1.00
Same problem
Looks like it supports only esp32 v1.0.0 release…
The issues you describe occur on v1.0.1 an onward.
Please downgrade your ESP32 package to version 1.00
Please downgrade your ESP32 package to version 1.00
Same Issue here…
Please downgrade your ESP32 package to version 1.00
Same problem here…
Please downgrade your ESP32 package to version 1.00
Yup, downgrading ESP32 board definition to v1.0 fixed this problem :) thanks for this tip Nick, and for your demo as well :)
Also, this solution is working with newer E-ink BT sensor – ClearGrass Temp & RH, just change !advertisedDevice.getName().compare(“MJ_HT_V1”) to !advertisedDevice.getName().compare(“ClearGrass Temp & RH”) and it works great!
Cool, thanks for the info about the E-Ink device. I love e-ink devices ;-)
What code did you actually use? Just the arduino ble bridge?
Can you post your actual code? It seems like the link is different.
Thanks
Andy
When I compile the code provided in this nice tutorial, the process stops at instruction “esp32_restart_noos()”; with the error description “esp32_restart_noos was not declared in this scope”.
The strange thing is that when I was working with IDE 1.8.9 everything was ok with the same code. When I downloaded the latest version 1.8.10 the error came out. I tried to reinstall the previous version with the same result.
I do not have deep knowledge of programming and cannot understand this strange behavior.
The only difference I can underline is that when I installed the version 1.8.9 the esp32 boards were installed automatically during the IDE downloading, while with the version 1.8.10 I had to install the esp boarda successively using board manager.
Somebody can help me?
I am trying to build a Thermostat using the Xiaomi tempperature&humidity sensor and I have to add some lines to the code relating to the regulation part. So I have to add and display the “reference temperature”, as well as a lever switch to change this temperature up and down, and send the result of the comparison to a digital pin to drive a small relay to activate the heating boiler.
The Xiaomi sensor has the great feature to be mobile and it can be placed in any place in the apartment to have regulation specifically in that place.
Federico from Italy
Frederico, change “esp_restart_noos()” to “esp_restart()” the noos part is depreciated.
I have a Lolin NodeMcu V3. Is it possible to use the code of this tuturiol? I’ve tried it but I get an error soc/soc.h: No such file or directory
I also have this problem with not decoded payload. If I downgrade esp32 to 1.0.0, it doesn’t compile at all.
I have uploaded a new version of the code which compiles and works as expected again.
I’m a beginner, so could someone please explain to me how you downgrade esp32 to 1.0.0. Thank you
I seriousely dont want to bash the creator of these lines – but the coding has several issues i cannot understand:
For gods sake – why is the solution a “downgrade” to 1.0.0? Kidding? Why not just fixing the code instead?
Why should one make a 3 year old library mandatory? Especially when regarding that the needed BLE code was merged into esp32 the core like 2 years ago?
So why not just:
– dump that library by fquiet
– comment out that line that does litterally nothing (//int serviceDataCount = advertisedDevice.getServiceDataCount();)
– change that line as getServiceData() doesnt expect an input (std::string strServiceData = advertisedDevice.getServiceData();)
and voila – all is running with the latest arduino core and without outdatet 3rd party libraries.
I have trie to do the change from the last comment.
Please can you tell me wats you mean with
strServiceData = advertisedDevice.getServiceData();)
First what is the type of strServiceData
and second how to change this (std::string strServiceData = advertisedDevice.getServiceData();)
Cannot find this in the code.
Thanks for any help
Just delete smile simbol at the end )))))))))))))))
I tried this code and with XIAOMI Bluetooth Digital Thermometer 2
it shows via serial monitor:
ESP32 XIAOMI DISPLAY
Start BLE scan for 10 seconds…
LYWSD03MMC
Advertised Device: Name: LYWSD03MMC, Address: a4:c1:38:50:46:bf
strServiceData LEN: 12
Advertised RAW DATA:
30 58 5B 5 63 BF 46 50 38 C1 A4 8
Payload:fe95->30:58:5b:05:63:bf:46:50:38:c1:a4:08:
Found device count : 1
Start BLE scan for 10 seconds…
Advertised Device: Name: , Address: a4:c1:38:50:46:bf
strServiceData LEN: 12
….
Thanks for this tuto Nick !
@Morten to use the LYWSD03MMC you need flash with custom FW see https://github.com/pvvx/ATC_MiThermometer#xiaomi-mijia-lywsd03mmc-hw-b14-b16-b17-b19–xiaomi-miaomiaoce-mho-c401–cgg1-mijia-bluetooth-thermometer-firmware
the data on advertising frame is describe at the end of the document, then you’ll need to change something in decoding frame but the principle is same
BR
Thierry,
@ThierryC49 -Hi.
Do you have a modified code that works with this firmware?
Good night from Spain.
I have tried to start your code on ESP32 and the xiaomi thermometers and do not find any.
it seems that there is a new version that even encrypts the data
LYWSD03MMC, Address: a4: c1: 38: 54: f6: 06
you need a password, I’ve also seen how to get it out,
https://atc1441.github.io/TelinkFlasher.html is very popular for esphome, but I have not found an arduino code to be able to start it.
Do you have any sample code for this version?
Many thanks for your attention.
In case anyone is dealing with winter temperatures, line #75 is wrong. These variables really ought to be “signed short” to properly handle negative numbers and two-complement.
With a recent cold spell I realized that the variable declarations for value and value 2 are incorrect.
These should be a “signed short” to properly handle negative temperatures. If not, when the temperature drops below 0 C the values are calculated and displayed incorrectly!
Hi, thanks for the code. What wil trigger the resetModule()? There’s no call to it.