1. 项目背景与设计初衷
凌晨三点的办公室,咖啡杯已经见底,我正和一段顽固的代码死磕。随手把外卖盒扔向垃圾桶的瞬间,突然闪过一个念头:要是垃圾桶能听懂人话该多省事?这个看似荒诞的想法,最终催生出了这个基于STM32的语音交互智能垃圾桶。
传统垃圾分类面临三大痛点:分类标识不直观、投放过程无引导、满溢状态难察觉。市面上的智能垃圾桶要么功能单一,要么价格昂贵。我的设计目标很明确:用最经济的方案实现语音交互+垃圾分类引导+状态监控的全套功能,整套硬件成本控制在200元以内。
2. 硬件架构解析
2.1 核心控制器选型
选用STM32F103C8T6作为主控,江湖人称"蓝色药丸"的这款芯片性价比极高:
- 72MHz主频足够处理多传感器数据
- 内置12位ADC满足模拟量采集需求
- 多达5个USART接口方便外设扩展
- 最低1μA的停机模式电流符合低功耗要求
实测发现:芯片的PA0引脚内部上拉较弱,接按键时需要外接10kΩ上拉电阻,否则会出现误触发
2.2 语音识别模块设计
采用LD3320非特定人语音识别芯片,相比传统方案有三大优势:
- 无需训练即可识别50条指令
- 支持动态词条更新(通过SPI接口)
- 自带MP3解码功能节省外围电路
硬件连接注意事项:
c复制// 典型接线配置
#define LD3320_RST_PIN PC13
#define LD3320_CS_PIN PA4
#define LD3320_WR_PIN PA7
#define LD3320_RD_PIN PA6
// 初始化时序必须严格遵循datasheet要求
void LD3320_Reset(){
HAL_GPIO_WritePin(LD3320_RST_PIN, GPIO_PIN_RESET);
HAL_Delay(50);
HAL_GPIO_WritePin(LD3320_RST_PIN, GPIO_PIN_SET);
HAL_Delay(120); // 必须大于100ms
}
2.3 传感器网络搭建
2.3.1 人体检测模块
采用HC-SR501红外热释电传感器,其探测角度可达120度。安装时要注意:
- 离地高度建议80-100cm
- 避免正对空调出风口
- 灵敏度电位器调至中间档位
2.3.2 垃圾量检测方案
使用GP2Y0A21红外测距传感器,其非线性输出特性需要通过分段线性化处理:
c复制float GetDistanceCM(uint16_t adc_val){
float voltage = adc_val * 3.3f / 4096.0f;
if(voltage > 2.8) return 5.0; // 饱和值
else if(voltage > 1.5) return 30.2 - 9.8*voltage;
else return 80.4 - 47.6*voltage;
}
2.3.3 环境光检测电路
光敏电阻与10kΩ电阻组成分压电路,采用滑动滤波算法消除突变干扰:
c复制#define LIGHT_HISTORY_SIZE 8
uint16_t light_history[LIGHT_HISTORY_SIZE];
uint8_t light_index = 0;
uint16_t GetLightLevel(){
light_history[light_index] = ADC_Read();
light_index = (light_index+1) % LIGHT_HISTORY_SIZE;
uint32_t sum = 0;
for(int i=0; i<LIGHT_HISTORY_SIZE; i++){
sum += light_history[i];
}
return sum / LIGHT_HISTORY_SIZE;
}
3. 软件系统实现
3.1 主程序流程图
plaintext复制START → 外设初始化 → 进入低功耗模式
↑ ↓
[中断唤醒] ← 人体检测
↓
语音识别处理 → 垃圾分类引导
↓
状态检测更新 → 返回低功耗
3.2 语音交互逻辑实现
关键词识别采用模糊匹配算法,核心代码如下:
c复制void ASR_Callback(uint8_t cmd){
switch(cmd){
case CMD_KITCHEN_WASTE:
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET);
PlaySound(SOUND_KITCHEN);
break;
case CMD_RECYCLABLE:
HAL_GPIO_WritePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin, GPIO_PIN_SET);
PlaySound(SOUND_RECYCLE);
break;
// 其他分类处理...
}
// 5秒后自动关闭指示灯
osTimerStart(led_off_timer, 5000);
}
3.3 低功耗优化策略
通过以下措施将待机功耗降至8mA以下:
- 关闭未用外设时钟
c复制
__HAL_RCC_TIM1_CLK_DISABLE(); __HAL_RCC_ADC2_CLK_DISABLE(); - 配置GPIO为模拟输入模式
- 使用STOP模式+中断唤醒
- OLED屏采用动态刷新(仅当检测到人体时激活)
4. 电源管理系统
4.1 太阳能充电电路
采用TP4056充电管理芯片,关键参数配置:
- 充电电流:Rprog=1.2kΩ → 1000mA
- 电池过放保护:DW01+8205A方案
- 太阳能输入:6V/5W面板
实测数据:晴天条件下4小时可充满2000mAh锂电池
4.2 电源路径管理
实现无缝切换的电路设计:
plaintext复制太阳能 → TP4056 → 锂电池 → MT3608升压 → 5V系统
↓
低压报警电路 → STM32 ADC检测
电池电压检测算法:
c复制#define BAT_DIV_RATIO 2.0f // 分压比
float GetBatteryVoltage(){
uint16_t adc = ADC_Read(BAT_ADC_CHANNEL);
return adc * 3.3f / 4096 * BAT_DIV_RATIO;
}
5. 机械结构与外壳设计
5.1 3D打印部件清单
- 主壳体(200×200×400mm)
- 分类隔板(可拆卸设计)
- 传感器支架
- 太阳能板固定座
5.2 防水防尘处理
- 麦克风开孔处加装防水膜
- 所有接缝处涂抹704硅橡胶
- 底部增加20mm垫高脚
6. 调试与优化实录
6.1 语音识别抗干扰方案
遇到的环境噪声问题及解决方案:
- 空调风噪 → 增加500ms起始静音检测
- 回声干扰 → 在MIC输入端并联100pF电容
- 误触发 → 加入双重关键词验证机制
6.2 传感器数据校准
垃圾量检测的标定方法:
- 空桶状态记录ADC基准值
- 每增加100ml水记录一次数据
- 用Matlab进行曲线拟合得到转换公式
6.3 典型故障排查表
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 语音无响应 | 麦克风偏置电压异常 | 检查MIC_BIAS电路 |
| 距离检测不准 | 传感器镜面污染 | 用酒精棉清洁 |
| LED频闪 | PWM频率设置不当 | 调整TIM基频至1kHz |
7. 功能扩展方向
7.1 无线通信模块
可添加ESP-01S实现:
- 微信推送垃圾满提醒
- 远程语音指令更新
- 使用统计数据分析
7.2 自动开盖机构
采用SG90舵机+连杆机构:
c复制void OpenLid(uint8_t type){
uint16_t angle = type * 30 + 60; // 不同分类不同开盖角度
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, angle);
HAL_Delay(1000);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);
}
7.3 智能学习功能
通过记录用户投放习惯:
- 自动优化关键词识别优先级
- 预测高频垃圾投放时段
- 生成个性化语音提示
这个项目最让我惊喜的是LD3320的识别准确率,实测日常垃圾名称识别率能达到90%以上。当然也有翻车时刻——有次它把"香蕉皮"识别成了"相片机",看来在语音库优化上还有很长的路要走。