在前面两个章节中我们详细介绍过的基于MM32W系列芯片开发的智能灯控方案和蓝牙自拍杆方案,在本章节我们将继续给大家介绍一个使用场景较为丰富的蓝牙应用方案——基于MM32W系列开发的温湿度监测仪。
图1 方案应用图
温度、湿度与我们的生活息息相关,科研实验室、农业大棚、食品储存室、疫苗存储及配送、贮藏室等对环境的温度、湿度有着严格的控制标准,温度、湿度的异常变化都可能会给其造成严重的影响。传统的人工巡查和记录环境温湿度变化并非易事,随着时代的发展,可实现智能化监测环境温湿度的温湿度传感器出现了。如今,科研、农业、暖通、机房、航天航空、电力等工业部门都开始采用智能化的温湿度传感器监测环境的温湿度。利用温湿度传感器对环境的温湿度进行实时监测,不仅能够及时发现环境温湿度的异常,进而做出应对措施,避免或减少损失,还能够减少员工工作量,降低人力成本。
硬件资源如下:
本方案基于MM32 BLE\_Test Board进行测试验证,搭配上温湿度传感器DHT11作为采集环境中温湿度数据,再加上一款小型的OLED屏幕作为本地式数据输出显示窗口,另外可以通过手机APP获取温湿度变化情况。在硬件原理上,本方案的DHT11模块的单线数据传输引脚连接到MCU的PA7,为了解析模块的数据时序,该引脚复用为TIM3\_CH2输入捕获功能;使用硬件IIC接口连接到OLED屏上去,引脚为PB6(SCL)、PB7(SDA),可以将温湿度数据显示在OLED;蓝牙相关的功能引脚与前面介绍的方案一致,此处不做过多展开。
软件资源如下:
结合上述使用到的硬件资源,下面我们着重介绍软件实现流程以及相关配置代码。使用MCU的引脚复用为TIM3\_CH2输入捕获功能DHT11模块,在开启捕获时将PA7配置为浮空输入模式,复用功能选择AF1配置为TIM3的CH2输入捕获通道,并且将TIM3开启;在停止捕获时将PA7配置为推挽输出模式,并且将TIM3关闭。由于DHT11模块限制,温湿度采样周期间隔必须大于1S,本方案采样和显示周期为2S。
在使用OLED屏幕需要用到硬件IIC外设接口,需要将对应的PB6 PB7配置为复用开漏输出模式,初始化时还需要根据不同的OLED模块在函数IIC\_Init()中修改slave设备地址,使能IIC接口后即可以开始传输工作了。由于数据采集和定时显示需要,本方案的低功耗模式采用STOP模式。
以下为主函数初始化配置内容,主要将所有的外设资源和蓝牙协议栈初始化,并且以中断服务程序的方式运行蓝牙,代码如下:
主函数的循环中主要实现的功能为定时采集和显示当前环境的温湿度数据,而该数据也将在蓝牙服务中发送到APP端显示,代码如下:
下面简单介绍一下OLED操作相关的几个函数:
//初始化IIC
void IIC_Init(I2C_TypeDef* I2Cx);
//发送命令函数
static void Write_Command(unsigned char Command);
//发送数据显示在屏幕
static void Write_DataBuff(unsigned char *Data, unsigned char Len);
//OLED屏初始化
void OLED_Init(void);
//设置坐标
void OLED_SetPos(unsigned char x, unsigned char y);
//字符串显示
void OLED_DispStr(unsigned char x, unsigned char y, char *ch);
//显示logo
void OLED_DispLogo(void);
//清屏操作
void OLED_Clear(void);
下面简单介绍一下DHT11模块操作相关的几个函数:
// TIM3_CH2输入捕获初始化
void CaptureInit(void); //用TIM3_CH2 PB5 AF3
//启动捕获
void CaptureStart(void);
//停止捕获
void CaptureStop(void);
在TIM3\_IRQHandler()中针对捕获的数据进行解析和处理。
我们在gatt\_user\_send\_notify\_data\_callback函数中给手机发送数据,该函数属于回调函数,协议栈会在系统允许的时候(异步)回调本函数,该函数可用于蓝牙模块端主动发送数据之用,函数内部不得增加阻塞代码。该应用中我们在此函数中实现将采集转换好的温湿度数据传输给手机APP。详细实现代码如下:
//蓝牙连接成功后协议在空闲的时候会调用本回调函数
void gatt_user_send_notify_data_callback(void){
static u8 notiCnt = 0;//回调次数计数器
u16 humiBat ,tempBpm = 0;
unsigned char DHTData[3]={0x00,0x00,0x01};
notiCnt++; //每进一次该函数回调次数计数器+1
if(CaptureDataMon(&humiBat, &tempBpm) == 0) return;//未成功采集到温湿度数据立即返回
tempBpm %= 512;//初步判断温度数据大小
humiBat /= 10;//初步判断湿度数据大小
if (notiCnt >= 20) {//每进入该回调函数20次才发送一次温度数据
notiCnt = 0;
cur_notifyhandle = 0x12;//温度数据回复句柄值
if (tempBpm < 0x100){
DHTData[0] = 0; //1Byte
DHTData[1] = tempBpm;
sconn_notifydata(DHTData,2);//换算处理好温度数据后通过蓝牙发出
}
else {
DHTData[0] = 1; //2Byte
DHTData[1] = tempBpm;
DHTData[2] = tempBpm>>8;
sconn_notifydata(DHTData,3);//换算处理好温度数据后通过蓝牙发出
}
}
else if (10 == notiCnt) {//每进入该回调函数10次才发送一次湿度数据
SimBatt = humiBat; //0~100
cur_notifyhandle = 0x18;//湿度数据回复句柄值
sconn_notifydata(&SimBatt,1);//换算处理好湿度数据后通过蓝牙发出
}
}
除了上述关键的蓝牙数据发送函数外,下面再简单介绍一些与蓝牙相关的特征值定义:
手机操作流程如下:
- 打开手机蓝牙并打开App,选择HRM进入,点击Connect按钮开始搜索温湿度蓝牙设备。
- 选择对应名称(MM32W0\_DHT)的蓝牙设备并进行配对,等待连接成功。连接成功后会有相应提示,按钮Connect名字会变成Disconnect。
- 连接成功后,在App界面上电池图标会显示从DHT11传感器获取的湿度信息(百分比)Finger和图表会显示从DHT11传感器获取的温度信息(原始数据,温度值x10)。
图2 手机APP图