获得蓝牙小米温湿度传感器的例子-Arduino中文社区 - Powered by Discuz! Archiver

Zoologist 发表于 2021-7-25 19:05

获得蓝牙小米温湿度传感器的例子

代码来自 https://www.instructables.com/ESP32-Xiaomi-Hack-Get-Data-Wirelessly/

#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "esp_system.h"
#include <sstream>

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>

#define SCAN_TIME10 // seconds

boolean METRIC = true; //Set true for metric system; false for imperial

BLEScan *pBLEScan;

void IRAM_ATTR resetModule(){
    ets_printf("reboot\n");
    esp_restart();
}

floatcurrent_humidity = -100;
floatprevious_humidity = -100;
float current_temperature = -100;
float previous_temperature = -100;

class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
    void onResult(BLEAdvertisedDevice advertisedDevice)
    {
      if (advertisedDevice.haveName() && advertisedDevice.haveServiceData() && !advertisedDevice.getName().compare("MJ_HT_V1")) {

            int serviceDataCount = advertisedDevice.getServiceDataCount();
            std::string strServiceData = advertisedDevice.getServiceData(0);

            uint8_t cServiceData;
            char charServiceData;

            strServiceData.copy((char *)cServiceData, strServiceData.length(), 0);

            Serial.printf("\n\nAdvertised Device: %s\n", advertisedDevice.toString().c_str());

            for (int i=0;i<strServiceData.length();i++) {
                sprintf(&charServiceData, "%02x", cServiceData);
            }

            std::stringstream ss;
            ss << "fe95" << charServiceData;
            
            Serial.print("Payload:");
            Serial.println(ss.str().c_str());

            char eventLog;
            unsigned long value, value2;
            char charValue = {0,};
            switch (cServiceData) {
                case 0x04:
                  sprintf(charValue, "%02X%02X", cServiceData, cServiceData);
                  value = strtol(charValue, 0, 16);
                  if(METRIC)
                  {
                      current_temperature = (float)value/10;
                  }else
                  {
                      current_temperature = CelciusToFahrenheit((float)value/10);
                  }
                  displayTemperature();
                  break;
                case 0x06:
                  sprintf(charValue, "%02X%02X", cServiceData, cServiceData);
                  value = strtol(charValue, 0, 16);
                  current_humidity = (float)value/10;
                  displayHumidity();                     
                  Serial.printf("HUMIDITY_EVENT: %s, %d\n", charValue, value);
                  break;
                case 0x0A:
                  sprintf(charValue, "%02X", cServiceData);
                  value = strtol(charValue, 0, 16);                  
                  Serial.printf("BATTERY_EVENT: %s, %d\n", charValue, value);
                  break;
                case 0x0D:
                  sprintf(charValue, "%02X%02X", cServiceData, cServiceData);
                  value = strtol(charValue, 0, 16);      
                  if(METRIC)
                  {
                      current_temperature = (float)value/10;
                  }else
                  {
                      current_temperature = CelciusToFahrenheit((float)value/10);
                  }
                  displayTemperature();               
                  Serial.printf("TEMPERATURE_EVENT: %s, %d\n", charValue, value);                  
                  sprintf(charValue, "%02X%02X", cServiceData, cServiceData);
                  value2 = strtol(charValue, 0, 16);
                  current_humidity = (float)value2/10;
                  displayHumidity();                                       
                  Serial.printf("HUMIDITY_EVENT: %s, %d\n", charValue, value2);
                  break;
            }
      }
    }
};

void setup() {

Serial.begin(115200);
Serial.println("ESP32 XIAOMI Humity");

initBluetooth();
}

void loop() {

    char printLog;
    Serial.printf("Start BLE scan for %d seconds...\n", SCAN_TIME);
    BLEScan* pBLEScan = BLEDevice::getScan(); //create new scan
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
    BLEScanResults foundDevices = pBLEScan->start(SCAN_TIME);
    int count = foundDevices.getCount();
    printf("Found device count : %d\n", count);

    delay(100);
}

void initBluetooth()
{
    BLEDevice::init("");
    pBLEScan = BLEDevice::getScan(); //create new scan
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
    pBLEScan->setInterval(0x50);
    pBLEScan->setWindow(0x30);
}

void displayTemperature()
{
   if(current_temperature != previous_temperature)
   {
      
      previous_temperature = current_temperature;
   }
}

void displayHumidity()
{
   if(current_humidity != previous_humidity)
   {
      previous_humidity = current_humidity;
   }
}

String convertFloatToString(float f)
{
String s = String(f,1);
return s;
}

float CelciusToFahrenheit(float Celsius)
{
float Fahrenheit=0;
Fahrenheit = Celsius * 9/5 + 32;
return Fahrenheit;
}


我使用 DFRobot FireBeetle 测试接收


结果如下(测试有2个上面这样的传感器)






anqiw 发表于 2021-7-25 22:22

正在找,谢谢了。只限上图的温湿度计吗,米家其他的蓝牙温湿度计都支持吗?

Zoologist 发表于 2021-7-26 08:35

anqiw 发表于 2021-7-25 22:22
正在找,谢谢了。只限上图的温湿度计吗,米家其他的蓝牙温湿度计都支持吗? ...

不知道唉

我用的是图上这一款

oanger 发表于 2021-7-28 23:20

不知道他用的什么方案

Zoologist 发表于 2021-7-29 08:47

oanger 发表于 2021-7-28 23:20
不知道他用的什么方案

https://post.smzdm.com/p/alpzodd8/
可以参考一下

oanger 发表于 2021-7-29 22:51

Zoologist 发表于 2021-7-29 08:47
https://post.smzdm.com/p/alpzodd8/
可以参考一下

谢谢,新手,没看太懂。

leonclz 发表于 2021-10-20 00:47

那个soc.h是从哪里 获取的?

Zoologist 发表于 2021-10-20 08:42

leonclz 发表于 2021-10-20 00:47
那个soc.h是从哪里 获取的?

编译环境自带的。

leonclz 发表于 2021-10-20 14:15

本帖最后由 leonclz 于 2021-10-20 14:52 编辑

Zoologist 发表于 2021-10-20 08:42
编译环境自带的。
也就 是说,需要esp32的板子才有这个头文件?我用的d1 mini ,编译的时候提示 没有这个文件

Zoologist 发表于 2021-10-20 15:48

leonclz 发表于 2021-10-20 14:15
也就 是说,需要esp32的板子才有这个头文件?我用的d1 mini ,编译的时候提示 没有这个文件 ...

你可以试试 DFRobot 的 FireBeetle 环境,前几天做了一个项目,里面是有的。
页: [1] 2
查看完整版本: 获得蓝牙小米温湿度传感器的例子