共计 2949 个字符,预计需要花费 8 分钟才能阅读完成。
背景与痛点
传统的温湿度显示通常依赖于 LCD 屏幕或 LED 数码管,这种方式在以下场景存在明显不足:

- 需要近距离查看,不适用于远距离监控
- 在光线不足环境下可视性差
- 无法满足视力障碍用户的需求
- 交互方式单一,缺乏智能化体验
语音交互系统则完美解决了这些问题:
- 实现自然的人机交互方式
- 不受环境光线条件限制
- 可远距离获取信息
- 特别适合智能家居等应用场景
硬件选型
语音识别模块对比
市场上常见的语音识别方案主要有以下几种:
- ASRPRO:国产芯片,支持离线识别,成本低,识别率高
- LD3320:需要外接 Flash 存储语音库,开发复杂
- 科大讯飞在线方案:需要网络支持,有云端费用
我们选择 ASRPRO 的主要原因:
- 完全离线工作,不依赖网络
- 支持自定义唤醒词和指令
- 内置音频解码器,可直接驱动喇叭
- 开发工具链完善,文档丰富
STM32 型号选择
考虑因素包括:
- 需要至少 1 个 UART 接口与 ASRPRO 通信
- 需要 I2C 或单总线接口连接温湿度传感器
- 足够的 GPIO 资源
- 性价比
推荐型号:STM32F103C8T6(蓝色 pill 开发板)
系统架构
整体系统由三大模块组成:
- 传感器模块:DHT11/DHT22
- 主控模块:STM32
- 语音模块:ASRPRO
连接关系如下:
- STM32 PA0-PA7 -> DHT11 数据线
- STM32 USART1_TX(PA9) -> ASRPRO RX
- STM32 USART1_RX(PA10) -> ASRPRO TX
- 共用 3.3V 电源
核心实现
STM32 读取 DHT11 代码
// DHT11 驱动代码(基于 HAL 库)#define DHT11_PORT GPIOA
#define DHT11_PIN GPIO_PIN_0
void DHT11_Start(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};
// 配置为输出模式
GPIO_InitStruct.Pin = DHT11_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStruct);
// 发送开始信号
HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_RESET);
HAL_Delay(18); // 保持低电平至少 18ms
HAL_GPIO_WritePin(DHT11_PORT, DHT11_PIN, GPIO_PIN_SET);
// 切换为输入模式等待响应
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(DHT11_PORT, &GPIO_InitStruct);
}
uint8_t DHT11_Read(void)
{
uint8_t data = 0;
for(int i=0; i<8; i++) {while(HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_RESET);
uint32_t start = HAL_GetTick();
while(HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_SET);
if((HAL_GetTick() - start) > 40) {data |= (1 << (7-i));
}
}
return data;
}
void DHT11_GetData(float *temp, float *humi)
{uint8_t data[5] = {0};
DHT11_Start();
// 检查响应信号
if(HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_RESET) {while(HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_RESET);
while(HAL_GPIO_ReadPin(DHT11_PORT, DHT11_PIN) == GPIO_PIN_SET);
// 读取 40 位数据
for(int i=0; i<5; i++) {data[i] = DHT11_Read();}
// 校验和验证
if(data[4] == (data[0]+data[1]+data[2]+data[3])) {*humi = data[0];
*temp = data[2];
}
}
}
ASRPRO 语音识别配置
- 使用官方 SDKTool 配置唤醒词和指令
- 设置串口通信参数:9600bps, 8N1
- 定义语音播报内容模板
关键配置示例:
[唤醒词]
小度小度
[指令集]
当前温度 -> $TEMP$
当前湿度 -> $HUMI$
[播报模板]
$TEMP$ -> "当前温度为 %.1f 度"
$HUMI$ -> "当前湿度为 %d%%"
串口通信协议设计
采用简单的 ASCII 协议格式:
格式:$[命令][数据]\n
示例:$T25.5\n // 温度 25.5℃
$H60\n // 湿度 60%
STM32 发送代码:
void USART_SendTempHumidity(float temp, float humi)
{char buf[32];
// 发送温度
sprintf(buf, "$T%.1f\n", temp);
HAL_UART_Transmit(&huart1, (uint8_t*)buf, strlen(buf), 100);
// 发送湿度
sprintf(buf, "$H%d\n", (int)humi);
HAL_UART_Transmit(&huart1, (uint8_t*)buf, strlen(buf), 100);
}
性能优化
采样频率控制
- DHT11 传感器要求采样间隔≥1s
- 实际设置 2s 采样一次,避免频繁操作影响传感器寿命
- 采用定时器中断触发采样,保证时序精确
语音响应优化
- 设置 200ms 的语音指令消抖时间
- 在 STM32 端实现简单的命令缓存队列
- 采用非阻塞式串口通信,避免主循环卡顿
避坑指南
常见问题及解决方案
- 供电不稳导致识别失败
- 为 ASRPRO 单独增加 1000μF 电容
-
电源走线尽量短粗
-
环境噪声干扰
- 调整 ASRPRO 的麦克风增益
- 增加唤醒词识别阈值
-
远离风扇等噪声源
-
串口通信乱码
- 检查两端波特率是否一致
- 确保共地连接
-
添加 120Ω 终端电阻
-
DHT11 数据异常
- 检查上拉电阻(4.7KΩ)
- 确保时序严格符合规格书
- 避免长距离布线(建议 <20cm)
进阶建议
扩展更多传感器
- 光照传感器(BH1750,I2C 接口)
- 空气质量传感器(SGP30,I2C 接口)
- 气压传感器(BMP280,I2C/SPI 接口)
增加语音指令
- 组合查询:” 当前环境状况 ”
- 阈值报警:” 温度过高时提醒我 ”
- 历史查询:” 昨天最高温度 ”(需增加 RTC 和存储)
系统集成
- 通过 ESP8266 增加 Wi-Fi 联网功能
- 开发手机 APP 实现远程监控
- 接入智能家居平台(如 Home Assistant)
总结
本方案实现了低成本、高可靠性的语音交互温湿度监测系统,具有以下优势:
- 硬件成本低于 100 元
- 完全离线工作,隐私性好
- 响应速度快(<500ms)
- 可扩展性强
建议初学者先完整实现基础功能,再逐步添加扩展模块。在实际部署时,注意做好防潮处理和电磁兼容设计。
正文完
