1188|3

136

帖子

2

TA的资源

一粒金砂(高级)

楼主
 

【FireBeetle 2 ESP32 C6开发板】-3- C6获取小米温湿度计2数据 [复制链接]

本帖最后由 慕容雪花 于 2024-5-2 12:36 编辑

小米温湿度计2 是从设备,同时也是BLE SERVER,部署了多个sevice,其中serviceUUID("ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6")里面的charUUID("ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6")就是温湿度数据。

 

esp32c6是主设备,同时也是BLE CLIENT,通过BLE的协议来访问Server上的Characteristic,从而获取到温湿度数据。

C6启动后,会开始扫描周围的BLE设备,此时进行一个判断,设备名称是否为XiaomiDeviceName = "LYWSD03MMC"

 /**
   * Called for each advertising BLE server.
   */
  void onResult(BLEAdvertisedDevice advertisedDevice) {
    Serial.println("*-------------------------------------------------------------------*");
    Serial.print("BLE Advertised Device found: ");
    Serial.println(advertisedDevice.toString().c_str());

    // We have found a device, let us now see if it contains the service we are looking for.

    Serial.println(advertisedDevice.getServiceUUID().toString().c_str());
    Serial.println(advertisedDevice.getName().c_str());

    if(0 == advertisedDevice.getName().compareTo(XiaomiDeviceName)){
      Serial.println("Great, Found " + advertisedDevice.getName());

      Serial.println("advertisedDevice.getServiceUUIDCount() = " + String(advertisedDevice.getServiceUUIDCount()));

      BLEDevice::getScan()->stop();
      myDevice = new BLEAdvertisedDevice(advertisedDevice);
      doConnect = true;
      doScan = true;      
    }
  } // onResult

找到小米设备后,进行连接:

bool connectToServer() {
    Serial.print("Forming a connection to ");
    Serial.println(myDevice->getAddress().toString().c_str());
    
    BLEClient*  pClient  = BLEDevice::createClient();
    Serial.println(" - Created client");

    pClient->setClientCallbacks(new MyClientCallback());

    // Connect to the remove BLE Server.
    pClient->connect(myDevice);  // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
    Serial.println(" - Connected to server");
    pClient->setMTU(517); //set client to request maximum MTU from server (default is 23 otherwise)
  
    // 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();
      return false;
    }
    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();
      return false;
    }
    Serial.println(" - Found our characteristic");

    // Read the value of the characteristic.
    if(pRemoteCharacteristic->canRead()) {
      String value = pRemoteCharacteristic->readValue();
      Serial.print("The characteristic value was: ");
      Serial.println(value.c_str());
    }

    if(pRemoteCharacteristic->canNotify())
      pRemoteCharacteristic->registerForNotify(notifyCallback);

    connected = true;
    return true;
}

从小米设备获取到数据,共有5个字节。

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);


    uint16_t TempVal = pData[1]*256 + pData[0];
    Serial.println("Temperature is: "+ String(TempVal/100) + "." + String(TempVal%100) + " degree");

    uint8_t HumidityVal = pData[2];
    Serial.println("Humidity is: " + String(pData[2]) + "% ");

    uint16_t BatteryVal = pData[4]*256 + pData[3];
    Serial.println("Battery Voltage is: "+ String(BatteryVal/100) + "." + String(BatteryVal%100) + " mV");


    Serial.println();
}

注意数据为小端模式存储。

 

  

-------------------------------------------------------------------------------------------------------------------

5.2日更新:

上文中BLE SERVER notify上来的数据是没有问题的,温湿度值跟实际设备对比也是OK的,但是仔细观察设备启动,首次连接小米设备成功后,直接读取Characteristic的值,竟然是4??

 

这个肯定是读取的姿势不对,我接下来一番笨丁解牛。

小米温湿度数据格式为:F2 07 4A C3 0A。也就是5个十六进制数据。仔细看当前的直接读取Characteristic值代码:

    // Read the value of the characteristic.
    if(pRemoteCharacteristic->canRead()) {
      String value = pRemoteCharacteristic->readValue();
      Serial.print("The characteristic value was: ");
      Serial.println(value.c_str());
    }

readValue()方法返回的是String类型变量,更合适的应该是:

uint8_t* test = pRemoteCharacteristic->readRawData();

 

计算一下使用直接读取数据所对应的温湿度:

 

 

代码:

uint8_t* test = pRemoteCharacteristic->readRawData();
      uint8_t i;
      uint8_t  test_temp_val[5]={0};

      for(i = 0; i < 5; i++){
        if(test != nullptr){
          Serial.print("The characteristic value using readRawData was: ");
          Serial.println(*test);
          test_temp_val = *test;
        }else{
          Serial.println("pRemoteCharacteristic->readRawData() returns NULL PTR");
        }
        test++;
      }

    static uint16_t Test_TempVal = test_temp_val[1]*256 + test_temp_val[0];
    Serial.println("Test Temperature is: "+ String(Test_TempVal/100) + "." + String(Test_TempVal%100) + " degree");

    static uint8_t Test_HumidityVal = test_temp_val[2];
    Serial.println("Test Humidity is: " + String(test_temp_val[2]) + "% ");

    static uint16_t Test_BatteryVal = test_temp_val[4]*256 + test_temp_val[3];
    Serial.println("Test Battery Voltage is: "+ String(Test_BatteryVal/100) + "." + String(Test_BatteryVal%100) + " mV");      

参考:

读取小米蓝牙温湿度计2数据 https://www.cnblogs.com/qsbye/p/15913753.html

此帖出自无线连接论坛

最新回复

C6启动后,会开始扫描周围的BLE设备,此时进行一个判断,设备名称是否为XiaomiDeviceName = "LYWSD03MMC" 不会吧,直接可以读出小米的东西吗?   详情 回复 发表于 2024-5-1 22:49
点赞 关注
 

回复
举报

756

帖子

5

TA的资源

纯净的硅(高级)

沙发
 

感谢楼主分享的技术内容,有机会一定买块板子动手测试一下这些例子

此帖出自无线连接论坛
 
 

回复

7096

帖子

11

TA的资源

版主

板凳
 

C6启动后,会开始扫描周围的BLE设备,此时进行一个判断,设备名称是否为XiaomiDeviceName = "LYWSD03MMC"

不会吧,直接可以读出小米的东西吗?

此帖出自无线连接论坛

点评

可以的大佬,是我太菜了。我尝试扫描周围设备,想直接根据SERVICE UUID来锁定小米温湿度度计2,但可能小米设备的广播报文里面并没有包含serviceUUID("ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6")。所以才直接根据设  详情 回复 发表于 2024-5-2 08:52
 
 
 

回复

136

帖子

2

TA的资源

一粒金砂(高级)

4
 
lugl4313820 发表于 2024-5-1 22:49 C6启动后,会开始扫描周围的BLE设备,此时进行一个判断,设备名称是否为XiaomiDeviceName = "LYWSD03MMC ...

可以的大佬,是我太菜了。我尝试扫描周围设备,想直接根据SERVICE UUID来锁定小米温湿度度计2,但可能小米设备的广播报文里面并没有包含serviceUUID("ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6")。所以才直接根据设备名称来锁定小米设备。

此帖出自无线连接论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
快速回复 返回顶部 返回列表