【开源】基于STM32的智能垃圾桶
项目编号:STM32-T004
项目名称:基于STM32的智能垃圾桶
【摘要】
本项目设计了一种基于STM32F103C8T6单片机的智能垃圾桶系统,融合语音识别、环境监测、自动分类与物联网功能,旨在提升垃圾分类的智能化与便捷性。系统采用ASRPRO语音识别模块,实现对“有害垃圾”和“生活垃圾”的语音指令识别,并通过双舵机分别控制两个垃圾桶盖的自动开启。红外传感器用于监测垃圾桶内垃圾满度,DHT11模块采集环境温湿度信息,相关数据通过OLED屏幕实时显示。当检测到垃圾桶已满时,蜂鸣器发出报警提示,提醒用户及时清理。系统还配备ESP8266-01S模块,实现Wi-Fi通信,将垃圾桶状态、环境参数等信息上传至云平台,用户可通过手机APP实时查看垃圾分类情况与满度状态。该系统功能完善,操作智能,适用于家庭、学校、办公楼等多种生活场景,有助于推动垃圾分类与智能环保理念的推广。
【所用硬件】
1、STM32F103C8T6最小系统板
STM32F103C8T6最小系统板是基于意法半导体(ST)Cortex-M3内核的微控制器开发板,核心芯片为STM32F103C8T6,主频72MHz,具有64KB Flash和20KB SRAM,满足中等复杂度的嵌入式应用需求。该板集成USB、USART、SPI、I2C等通信接口,支持多种外设扩展。最小系统板包含必要的外围电路,如8MHz晶振、复位电路、电源管理(3.3V稳压),并提供GPIO引脚引出,方便连接传感器、显示屏等模块。其低功耗、高性能特性使其广泛应用于智能硬件、工业控制等领域。在本设计中,它作为主控单元,负责数据采集、处理及外设控制,确保电子秤系统的稳定运行。
2、天问ASRPRO语音模块
天问ASRPRO语音模块是一款集成度较高的离线语音识别与语音合成一体化模块,能够实现本地语音指令识别和实时语音播报功能。它内置多种常用语音指令库,支持用户自定义关键词,识别速度快且准确率高,不依赖网络即可运行,适合应用在对响应速度和稳定性要求较高的嵌入式系统中。模块采用串口通信方式,与单片机、STM32或其他主控设备连接简单,开发门槛低,用户只需通过指令配置即可完成识别与播报功能。
3、舵机模块
SG90舵机是一款常见的小型直流伺服电机,体积小巧、重量轻,广泛应用于各类电子制作和机器人控制中。它采用PWM信号控制转动角度,通常可实现0°到180°的范围,定位精度较高,响应速度快,适合需要角度调节的场景。SG90内部带有减速齿轮和位置反馈电位器,能稳定控制输出角度,同时保持较好的力矩输出。由于价格低廉、使用方便,SG90常被用于Arduino、单片机和各种嵌入式实验项目中。
4、红外传感器
TCRT5000红外传感器是一种集发射与接收一体的光电传感器,主要由红外发射二极管和光敏三极管组成,能通过检测反射光的强弱来判断物体的存在与否或表面颜色的差异。该传感器对黑白反差较为敏感,因此常用于巡线小车、计数器以及接近检测等场合。它体积小巧,响应速度快,使用时只需配合简单的电路即可输出稳定信号,便于与单片机等控制器连接,具有低成本和易于集成的特点。
5、OLED显示模块
OLED(有机发光二极管)显示屏模块是一种自发光显示器件,无需背光,具有高对比度、宽视角和快速响应的特点。本设计采用的OLED模块通常为0.96英寸或1.3英寸,分辨率为128×64像素,支持I2C或SPI通信协议,可直接与STM32等微控制器连接。其工作电压为3.3V~5V,功耗低,适合便携式设备。
6、ESP8266-01S WIFI模块
ESP8266-01S是一款基于ESP8266芯片的紧凑型无线通信模块,支持802.11 b/g/n协议,工作频率2.4GHz,内置32位Tensilica处理器和片上WiFi堆栈,可独立运行或作为从机与主控MCU(如STM32)协同工作。模块通过UART(AT指令)或SPI接口通信,支持STA(客户端)、AP(热点)和混合模式,便于接入互联网或组建本地无线网络。其Flash容量为1MB,提供GPIO引脚用于基础控制,工作电压3.3V,功耗低且成本低廉。
7、蜂鸣器模块
鸣器模块是一种常见的声音报警装置,广泛应用于电子设备中用于提示或报警功能。该模块通常由一个蜂鸣器和驱动电路组成,能发出高频的蜂鸣声。按照驱动方式可分为有源蜂鸣器和无源蜂鸣器两种类型。有源蜂鸣器只需提供直流电压即可发声,控制简单,适用于固定频率提示场景;无源蜂鸣器则需要外部提供特定频率的驱动信号才能工作,适用于需要调节音调或生成特定声音模式的场合。模块通常采用5V或3.3V供电,可通过三极管或专用驱动芯片控制启停,响应速度快,可靠性高,常用于智能设备、安防系统、工业仪表等场景中。
8、DHT11模块
DHT11模块是一款常用的温湿度传感器模块,内部集成了电容式湿度测量元件和NTC温度测量元件,并配备专用信号处理芯片,可输出经过校准的数字信号。该模块通过单总线方式与单片机通信,具有响应速度快、数据传输简洁的特点。DHT11在0℃至50℃范围内能测量温度,在20%至90%范围内测量湿度,精度适中,功耗较低,价格便宜,适合应用于家居环境监测、气象站和智能控制等场景。
【系统框架图】
【软件流程图】
【核心代码展示】
#include "app_task.h"
#include "Encoder.h"
#include "key.h"
#include "oled.h"
#include "beep.h"
#include "timer.h"
#include "DTH11.h"
#include "io.h"
#include "esp8266.h"u8 str[50];
PAGE page;
POINT point;
u8 clear_flag;BUCKET bucket;TaskControlBlock TaskList[MAX_TASKS] = {0};
uint8_t RegisteredTasks = 0; // 已注册任务数
uint32_t SystemTick = 0; // 系统时间基准// 任务注册函数
int8_t Task_Register(uint8_t id, uint32_t interval, void (*task_func)(void *), void *param)
{if (RegisteredTasks >= MAX_TASKS)return -1;TaskList[RegisteredTasks].TaskID = id;TaskList[RegisteredTasks].PollingInterval = interval;TaskList[RegisteredTasks].TimerCounter = 0;TaskList[RegisteredTasks].RunFlag = 0;TaskList[RegisteredTasks].EnableFlag = 1;TaskList[RegisteredTasks].TaskHook = task_func;TaskList[RegisteredTasks].TaskParam = param;TaskList[RegisteredTasks].Delay = 0;RegisteredTasks++;return 0;
}// 任务使能控制
void Task_Enable(uint8_t id, uint8_t enable)
{for (int i = 0; i < RegisteredTasks; i++){if (TaskList[i].TaskID == id){TaskList[i].EnableFlag = enable;break;}}
}/*** @brief 桶盖控制任务** @param pt*/
void Cap1_Control(void *pt)
{static u8 delay;if (bucket.other.lid == OPEN){Servo_SetAngle_PB1(60);/**打开5s后关闭 */delay++;if (delay == 50){delay = 0;bucket.other.lid = CLOSE;}}else if (bucket.other.lid == CLOSE){Servo_SetAngle_PB1(170);}}void Cap2_Control(void *pt)
{static u8 delay;if (bucket.harmful.lid == OPEN){Servo_SetAngle_PB0(60);/**打开5s后关闭 */delay++;if (delay == 50){delay = 0;bucket.harmful.lid = CLOSE;}}else if (bucket.harmful.lid == CLOSE){Servo_SetAngle_PB0(170);}
}
/*** @brief LED闪烁任务** @param pt*/
void Led_Task(void *pt)
{LED1 = !LED1;
}/*** @brief 蜂鸣器任务** @param pt*/
void Beep_Task(void *pt)
{if(DHT11_data[2] >= bucket.dht11.temp || DHT11_data[0] >= bucket.dht11.humi || bucket.harmful.capacity == FULL || bucket.other.capacity == FULL){BEEP = 0;}else{BEEP = 1;}}/*** @brief 语音任务** @param pt*/
void Asrpro_Task(void *pt)
{
}/*** @brief 温湿度任务** @param pt*/
void Dht11_Task(void *pt)
{DHT11_READ_DATA();
}/*** @brief WIFI任务** @param pt*/
void Esp8266_Task(void *pt)
{sprintf(str,"#%d.%d#%d.%d#%d#%d#", DHT11_data[2], DHT11_data[3], DHT11_data[0], DHT11_data[1],bucket.harmful.capacity,bucket.other.capacity);ESP8266_SendData(str);
}/*** @brief 红外检测任务** @param pt*/
void HongWai_Task(void *pt)
{if (HongWai1 == 0 || HongWai2 == 0){if (HongWai1 == 0){bucket.harmful.capacity = FULL;}if (HongWai2 == 0){bucket.other.capacity = FULL;}// BEEP = 0;}else{if (HongWai1 == 1){bucket.harmful.capacity = UNDER;}if(HongWai2 == 1){bucket.other.capacity = UNDER;}// BEEP = 1;}
}/*** @brief 按键处理任务** @param pt*/
void Key_Task(void *pt)
{switch (KEY_Scan(0)){case KEY1_PRICE:{};break;case KEY2_PRICE:{};break;case KEY3_PRICE:{};break;case KEY4_PRICE:{};break;}
}/*** @brief OLED显示任务** @param pt*/
void OLED_Task(void *pt)
{if (page == HOME){/**智能垃圾桶**/OLED_ShowChinese(32, 0, 0, 16, 1);OLED_ShowChinese(48, 0, 1, 16, 1);OLED_ShowChinese(64, 0, 2, 16, 1);OLED_ShowChinese(80, 0, 3, 16, 1);OLED_ShowChinese(96, 0, 4, 16, 1);/*温度:*/OLED_ShowChinese(0, 16, 5, 16, 1);OLED_ShowChinese(16, 16, 6, 16, 1);OLED_ShowChinese(32, 16, 9, 16, 1);sprintf(str, "%2d.%2dC", DHT11_data[2], DHT11_data[3]);OLED_ShowString(48, 16, str, 16, 1);/*湿度:*/OLED_ShowChinese(0, 32, 7, 16, 1);OLED_ShowChinese(16, 32, 8, 16, 1);OLED_ShowChinese(32, 32, 9, 16, 1);sprintf(str, "%2d.%2d%%", DHT11_data[0], DHT11_data[1]);OLED_ShowString(48, 32, str, 16, 1);}OLED_Refresh();
}void Task_Init(void)
{Task_Register(1, 1000, Led_Task, NULL);Task_Register(2, 1, Key_Task, NULL);Task_Register(3, 20, OLED_Task, NULL);Task_Register(4, 200, Beep_Task, NULL);Task_Register(5, 500, Asrpro_Task, NULL);Task_Register(6, 500, Dht11_Task, NULL);Task_Register(7, 100, HongWai_Task, NULL);Task_Register(8, 2000, Esp8266_Task, NULL);Task_Register(9, 100, Cap1_Control, NULL);Task_Register(10, 100, Cap2_Control, NULL);
}void Task_Run(void)
{for (int i = 0; i < RegisteredTasks; i++){if (TaskList[i].RunFlag && TaskList[i].EnableFlag){// 执行任务函数if (TaskList[i].TaskHook != NULL){TaskList[i].TaskHook(TaskList[i].TaskParam);}// 清除运行标志TaskList[i].RunFlag = 0;}}
}void TaskTime(void)
{static u32 tick_time = 0;tick_time++;// 遍历任务列表更新计数器for (int i = 0; i < RegisteredTasks; i++){if (TaskList[i].EnableFlag){TaskList[i].TimerCounter++;// 达到时间间隔时设置运行标志if (TaskList[i].TimerCounter >= TaskList[i].PollingInterval){TaskList[i].RunFlag = 1;TaskList[i].TimerCounter = 0;}}}
}
【原理图】
【硬件实物图】
【实物演示】
STM32-T004-智能垃圾桶