Funpack4-3 - 用MAX32655FTHR 评估套件实现读取小米湿度传感器3min数值
该项目使用了MAX32655FTHR,实现了读取小米湿度传感器3min数值的设计,它的主要功能为:用MAX32655FTHR 评估套件实现读取小米湿度传感器3min数值。
标签
BLE
LCD
MAX32655FTHR
冲向天空的猪
更新2026-02-10
29

1. 项目需求

本次参加活动funpack使用的板卡是MAX32655FTHR

本次完成的活动任务是任务二:
使用BLE功能读取米家温湿度计的读数,并显示在LCD屏幕上

2.思路解析

本次要求显示到LCD屏幕上,所以我们就需要自己使用LCD屏幕,我手头上有一块LCD屏幕,来完成我们这次活动的显示。
其中驱动型号是:ST7735S

image-20251012122308394

之后要处理其中BLE相关的,所以我们在下载MAX的SDK之后,选择相关BLE例程进行我们的开发。

image-20251012122513316

我们选择BLE_datc作为我们的开发例程

这里需要米家温湿度计,这里我选择了小米温湿度计3mini作为我们的获取温度湿度的器件。

image-20251012122801399

这里关于BLE的获取,我们还需要准备一个软件nRF Connect
有手机板和电脑板这里我就选择了手机版

image-20251012122930609

3.实现流程图

image-20251012123629925

4.实现步骤

4.1 获取服务与特征的UUID

在查找相关教程,基本都是通过ESP32实现的,根据其中的说明的经验,首先我们需要扫描到小米温湿度传感器的GATT的服务和特征。

在低功耗蓝牙俗称BLE,其中传输实现是通过GATT来实现的,在GATT下面是通过ATT协议来进行传输,其中将蓝牙的一些服务和特征实现我们的消息的沟通,所以我们需要先将扫描到信息获取到。

这里我们打开手机APP扫描周围的蓝牙名称:

在小米外壳上就是这个MJWSD06MMC,我们点击连接

image-20251012123956381

在外层上面看,我们的BLE设备拥有很多的服务,这里我们选择其中服务包括我们的温湿度传感器的。

image-20251012124139397

上面我们已经找到相关服务的UUID,注意这里的UUID要保存好,因为这里的UUID是每一个特征或者服务的唯一识别码。

接下来我们要保存我们的存放温湿度的特征的服务UUID
我们可以点击旁边的下载,可以获取到Value就可以知道这个当前的特征传递着什么内容,好我们现在成功获取俩个UUID。

image-20251012124324218

4.2 配置BLE_datc

我们要先修改烧录的板卡设备的整个环境,在MAX32655有俩款设备,默认不是我们的FTHR,所以我们要进行修改。

在目录下的makelife修改我们的BOARD

image-20251012124729677

之后这里也要修改,因为这里是在make编译也会识别这里的宏定义,然后将下面也进行修改,下面修改为我们小米温湿度传感器的名称

BOARD = FTHR_Apps_P1
ADV_NAME?=MJWSD06MMC

image-20251012124936818

我们就将其中的UUID填写进去,这里会根据UUID来获取,这里将小端形式格式存放。

image-20251012125201528

之后我们就需要处理识别的逻辑,其中获取的数值是16进制,我们需要对其进行转换。

我们成功连接之后其中的数值会通过这个函数来进行通知

static void datcValueNtf(attEvt_t *pMsg)
{
  if (pMsg->handle == pSecDatHdlList[pMsg->hdr.param - 1][SEC_DAT_HDL_IDX])
      printf(">> Notification from secure data service <<<\n");
   
  /* 处理接收到的数据 */
  if (datcCb.speedTestCounter == 0) {
      // 调用小米传感器数据处理函数
      Deal_MISensor(pMsg->pValue, pMsg->valueLen);
  }
}

在这里我们获取到其中的数值实现Deal_MISensor函数对其中的数值进行解析

基本代码如下,其中返回的16进制包含了温湿度和电压,所以我们通过将进制转换显示到LCD屏幕上。

// 定义存储小米传感器数据的结构体
typedef struct {
  float temperature;
  uint8_t huminity;
  float batVoltage;
} MI_SENSOR_DATA_t;

// 全局变量存储传感器数据
static 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;
  uint8_t buffer[32] = {0};
  memcpy(rawdata_copy, rawdata, rawdata_len_copy);
  printf("REC data len: %d\n", rawdata_len_copy);
   
  // 打印原始16进制数据
  printf("Raw data (hex): ");
  for (int i = 0; i < rawdata_len_copy; i++) {
      printf("%02X ", rawdata_copy[i]);
  }
  printf("\n");
  /* 数据格式: 42 0a 3f 2a 0b */
  /* 0x0a42 -> 温度, 0x3f -> 湿度, 0x0b2a -> 电量 */
   
   
  // 方法1: 小端序 (原始方法)
  temp = rawdata_copy[1];
  temp = (temp << 8) + rawdata_copy[0];
  Mi_Sensor_data.temperature = (float)temp / 100.0;
  printf("Method1 - Temp (LE): 0x%04X = %.2f°C\n", temp, Mi_Sensor_data.temperature);
   
   
  // 湿度 (字节2)
  temp = rawdata_copy[2];
  Mi_Sensor_data.huminity = temp;
  printf("Humi: 0x%02X (%d%%)\n", temp, temp);

  // 电压 - 方法1: 小端序
  temp = rawdata_copy[4];
  temp = (temp << 8) + rawdata_copy[3];
  Mi_Sensor_data.batVoltage = (float)temp / 1000.0;
  printf("Method1 - Volt (LE): 0x%04X = %.3fV\n", temp, Mi_Sensor_data.batVoltage);
   
  // 电压 - 方法2: 大端序
  // 使用单个打印调用输出所有结果
  printf("Result: temp=%.2f, humi=%d, vol=%.3fV\n",
          Mi_Sensor_data.temperature,
          Mi_Sensor_data.huminity,
          Mi_Sensor_data.batVoltage);
   
  // 在LCD上显示温湿度数据
  // 显示标题
  sprintf((char *)buffer, "Xiaomi Sensor 3mini");
  LCD_ShowString(0, 25, (uint8_t *)buffer, BRRED, BLACK, 16, 0);
   
  // 显示温度
  sprintf((char *)buffer, "Temp:");
  LCD_ShowString(10, 40, (uint8_t *)buffer, GREEN, BLACK, 16, 0);
  sprintf((char *)buffer, "%.2f C", Mi_Sensor_data.temperature);
  LCD_ShowString(100, 40, (uint8_t *)buffer, WHITE, BLACK, 16, 0);
   
  // 显示湿度
  sprintf((char *)buffer, "Humidity:");
  LCD_ShowString(10, 60, (uint8_t *)buffer, BLUE, BLACK, 16, 0);
  sprintf((char *)buffer, "%d %%", Mi_Sensor_data.huminity);
  LCD_ShowString(100, 60, (uint8_t *)buffer, WHITE, BLACK, 16, 0);
   
  // 显示电压
  sprintf((char *)buffer, "Voltage:");
  LCD_ShowString(10, 80, (uint8_t *)buffer, RED, BLACK, 16, 0);
  sprintf((char *)buffer, "%.3f V", Mi_Sensor_data.batVoltage);
  LCD_ShowString(100, 80, (uint8_t *)buffer, WHITE, BLACK, 16, 0);
   
  // 显示状态
  // sprintf((char *)buffer, "Status: Connected");
  // LCD_ShowString(10, 120, (uint8_t *)buffer, YELLOW, BLACK, 12, 0);
}

在main函数下我们初始化了LCD,上电显示等待连接,LCD不是本次的重点,这里没有对其详细讲解,如果感兴趣可以查看我存放的代码进行移植。

image-20251012125628159

最后我们点击终端任务,去执行bulid 和flash就可以成功将代码烧录到我们的板卡上了。

image-20251012125905972

5.效果展示

串口显示我们的相关数据,这里对字符支持不好,所以显示乱码。
image-20251012130002905

上电状态

image-20251012130313153

成功连接,由于屏幕太亮了所以调节了以下亮度会导致有点模糊

image-20251012130345764

遇到的问题

一开始想着可以使用image-20251012130447775

通过elf下载,导致程序一直没有正常烧录,最后还是修复了电脑的环境实现通过task通过openocd进行烧录程序。

附件下载
BLE_datc.zip
团队介绍
个人
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号