ESP32蓝牙BLE连接米家温湿度计
文章目录
- ESP32蓝牙BLE连接米家温湿度计
- 简介
- 需要准备的东西
- 软件调试
- 代码实现
- 修改查找的名称
- 修改需要连接的服务和属性
- 添加解析数据的代码
- 上电演示
- 提示
简介
最近在学习低功耗蓝牙BLE(Bluetooth Low Energy),刚好手里有个米家蓝牙温湿度计连接一下,在网上搜索了下相关资料,结合ESP32的BLE的历程完成数据获取以及对温湿度解析的工作。
需要准备的东西
- 米家蓝牙温湿度计
- BLE调试助手 or 谷雨蓝牙调试助手(小程序) or nRF Connect
- ESP32开发环境
软件调试
- 首先我们使用谷雨蓝牙调试助手,小程序版本 搜索周边的蓝牙信号,找到名称为LWSD03MMC 的蓝牙
- 找到一个UUID为 EBE0CCB0打头 7DA3A6结尾 的服务
- 在该服务下找到UUID为EBE0CCC1打头 7DA3A6结尾的属性 权限是可读可通知
- 点击监听或者读取 将字符选择为16进制 等待监听一次数据
数据解析
我们收到的数据格式如下
440A357C0B
将其分开
0x44 0x0A 0x35 0x7C 0x0B
其中数据的格式是以大端模式存储的,即高位放低地址,高位放低地址 所以0x44 0x0a表示的温度信息就是 0x0a44
将其转换成10进制就是2628,对应的就是26.28℃,和表现的相差不大(更新时间的缘故),因此对于上面的数据 我们可以对他进行解析
0x0a44->温度数据->2628(DEC)->26.28℃
0x35->湿度数据->53(DEC)->53%
0x0B7C->电压数据->2940(DEC)->2.94V
代码实现
经过上述的讲解 我们已经可以简单的对数据进行解析,下面我们将要用ESP32的蓝牙gatt_client例程完成对蓝牙数据的解析,因为蓝牙温湿度计作为数据服务的提供者,所以是SERVER端,我们作为数据的接收者,所以是client的例程
修改查找的名称
在原本的例程中 上电会扫描周围的额蓝牙设备,直到扫描到指定名称的蓝牙设备才会停止,所以我们需要修改设备名称为LYWSD03MMC
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
修改需要连接的服务和属性
在代码中 是对BLE的属性做了过滤,这里我们填写上面调试得到的蓝牙UUID,注意这里是大端模式,所以上面的EB打头A6结尾就要变成A6打头EB结尾
添加解析数据的代码
我们在NOTIFY_EVT时间的处理中添加得到的notify信息,传入参数为收到的通知的值以及数据的长度
解析函数
解析函数如下所示,我们定义了一个数组,复制了传进来的数据,然后根据上面讲的大端模式,组成16位温度数据 8位湿度数据,16为电压数据 解析 让然后打印
//定义的存储数据的结构体
struct MI_SENSOR_DATA_t
{
float temperature;
uint8_t huminity;
float batVoltage;
};
struct MI_SENSOR_DATA_t Mi_Sensor_data;
static void Deal_MISensor(uint8_t *rawdata,uint8_t rawdata_len)
{
uint8_t rawdata_len_copy = rawdata_len;
uint8_t rawdata_copy[rawdata_len_copy+2];
uint16_t temp=0;
memcpy(rawdata_copy, rawdata, rawdata_len_copy);
ESP_LOGI(GATTC_My_TAG,"REC data len:%d ",rawdata_len_copy);
esp_log_buffer_hex(GATTC_My_TAG, (unsigned char *)rawdata_copy, rawdata_len_copy);
/*42 0a 3f 2a 0b*/
/*0x0a42 ->温度 0x3f->湿度 0x0b2a 电量*/
//获取温度
temp = rawdata_copy[1];
temp = (temp << 8)+rawdata_copy[0];
Mi_Sensor_data.temperature=temp/100.0;
//获取湿度
temp &= 0x00;
temp = rawdata_copy[2];
Mi_Sensor_data.huminity = temp;
//获取电池电量
temp &= 0x00;
temp = rawdata_copy[4];
temp = (temp << 8)+rawdata_copy[3];
Mi_Sensor_data.batVoltage = temp/1000.0;
ESP_LOGI(GATTC_My_TAG,"温度:%.2f C 湿度:%d 电量:%.3f V \r\n",
Mi_Sensor_data.temperature,
Mi_Sensor_data.huminity,
Mi_Sensor_data.batVoltage);
}
上电演示
提示
运行了一会儿,10分钟左右,发现电压从2.929掉到了2.885 掉电还是挺快的 如果我们更新时间比较快的话是比较耗电的,这也就是说为什么手机端的数据一个小时更新一次的原因,因此我们可以不再noitify属性,而是主动去read属性 或者设备只在需要的时候去搜索 连接 notify然后断掉,具体到的玩法后续再开发