Product images of the project:

Bilibili video link:
https://www.bilibili.com/video/BV1mcUWYgE3d/?share_source=copy_web&vd_source=097fdeaf6b6ecfed8a9ff7119c32faf2
(See the end of the article for resource sharing)
01
—
Project Introduction
1. Function Details
STM32 Smart Voice-Activated Waste Sorting Bin
The functions are as follows:
1. STM32F103C8T6 microcontroller system board as the main control unit
2. Servo drives to open and close the waste bin lid
3. Button control for the opening and closing of four categorized waste bins
4. Voice recognition controls the opening and closing of the waste bins
5. Photoelectric infrared sensors monitor whether the bins are full and indicate with lights
6. OLED display shows the status of the waste bins
7. Mobile Bluetooth app receives notifications when the waste bins are full
2. Bill of Materials
-
STM32F103C8T6 microcontroller
-
OLED screen
-
Photoelectric infrared sensor
-
SNR8016 voice recognition module
-
BT04A Bluetooth module
-
Servo
02
—
Schematic Design

03
—
PCB Hardware Design
PCB Diagram


04
—
Program Design
#include "sys.h"
#include "stdio.h"
#include "string.h"
#include "delay.h"
#include "gpio.h"
#include "key.h"
#include "usart.h"
#include "motor_duoji.h"
#include "oled.h"
/**********************************Variable Definitions**********************************/
uint8_t key_num = 0; // Key scan flag
uint32_t time_num = 0; // 10ms timer
uint8_t flag_waste_1 = 0; // Recyclable waste bin flag
uint8_t flag_waste_2 = 0; // Kitchen waste bin flag
uint8_t flag_waste_3 = 0; // Hazardous waste bin flag
uint8_t flag_waste_4 = 0; // Other waste bin flag
extern uint8_t usart2_buf[64]; // Serial port 2 receive array
/**********************************Function Declarations**********************************/
void Key_function(void); // Key function
void Monitor_function(void); // Monitoring function
void Manage_function(void); // Processing function
/*********** Main Function *****/
int main(){
Delay_Init(); // Delay initialization
Gpio_Init(); // IO initialization
Key_Init(); // Key initialization
Motor_Duoji_Init(); // Servo initialization
Motor_Duoji2_Init(); // Servo initialization
OLED_Init();
Usart1_Init(9600); // Serial port 1 initialization
Usart2_Init(9600); // Serial port 2 initialization
TIM_SetCompare1(TIM1,1830); // PWM output
Delay_ms(100); // Delay 100ms
TIM_SetCompare4(TIM1,1830); // PWM output
Delay_ms(100); // Delay 100ms
TIM_SetCompare1(TIM2,1830); // PWM output
Delay_ms(100); // Delay 100ms
TIM_SetCompare2(TIM2,1830); // PWM output
Delay_ms(100); // Delay 100ms
OLED_Clear();
OLED_ShowChinese(0,0,0,16,1);
OLED_ShowChinese(16,0,1,16,1);
OLED_ShowChinese(32,0,2,16,1);
OLED_ShowChinese(48,0,15,16,1);
OLED_ShowChinese(64,0,16,16,1);
OLED_ShowChar(80,0,':',16,1);
OLED_ShowChinese(96,0,11,16,1);
OLED_ShowChinese(112,0,12,16,1);
OLED_ShowChinese(0,16,3,16,1);
OLED_ShowChinese(16,16,4,16,1);
OLED_ShowChinese(32,16,15,16,1);
OLED_ShowChinese(48,16,16,16,1);
OLED_ShowChar(80,16,':',16,1);
OLED_ShowChinese(96,16,11,16,1);
OLED_ShowChinese(112,16,12,16,1);
OLED_ShowChinese(0,32,5,16,1);
OLED_ShowChinese(16,32,6,16,1);
OLED_ShowChinese(32,32,15,16,1);
OLED_ShowChinese(48,32,16,16,1);
OLED_ShowChar(80,32,':',16,1);
OLED_ShowChinese(96,32,11,16,1);
OLED_ShowChinese(112,32,12,16,1);
OLED_ShowChinese(0,48,7,16,1);
OLED_ShowChinese(16,48,8,16,1);
OLED_ShowChinese(32,48,15,16,1);
OLED_ShowChinese(48,48,16,16,1);
OLED_ShowChar(80,48,':',16,1);
OLED_ShowChinese(96,48,11,16,1);
OLED_ShowChinese(112,48,12,16,1);
while(1) {
key_num = Chiclet_Keyboard_Scan(0); // Key scan
if(key_num != 0) { // If a key is pressed
switch(key_num) {
case 1: // Key 1: Control recyclable waste bin opening
OLED_ShowChinese(96,0,9,16,1);
OLED_ShowChinese(112,0,10,16,1);
TIM_SetCompare1(TIM2,1920); // Open
Delay_ms(1000); // Delay 2s
Delay_ms(1000);
TIM_SetCompare1(TIM2,1830); // Close
OLED_ShowChinese(96,0,11,16,1);
OLED_ShowChinese(112,0,12,16,1);
break;
case 2: // Key 2: Control kitchen waste bin opening
OLED_ShowChinese(96,16,9,16,1);
OLED_ShowChinese(112,16,10,16,1);
TIM_SetCompare2(TIM2,1920); // Open
Delay_ms(1000); // Delay 2s
Delay_ms(1000);
TIM_SetCompare2(TIM2,1830); // Close
OLED_ShowChinese(96,16,11,16,1);
OLED_ShowChinese(112,16,12,16,1);
break;
case 3: // Key 3: Control hazardous waste bin opening
OLED_ShowChinese(96,32,9,16,1);
OLED_ShowChinese(112,32,10,16,1);
TIM_SetCompare1(TIM1,1920); // Open
Delay_ms(1000); // Delay 2s
Delay_ms(1000);
TIM_SetCompare1(TIM1,1830); // Close
OLED_ShowChinese(96,32,11,16,1);
OLED_ShowChinese(112,32,12,16,1);
break;
case 4: // Key 4: Control other waste bin opening
OLED_ShowChinese(96,48,9,16,1);
OLED_ShowChinese(112,48,10,16,1);
TIM_SetCompare4(TIM1,1920); // Open
Delay_ms(1000); // Delay 2s
Delay_ms(1000);
TIM_SetCompare4(TIM1,1830); // Close
OLED_ShowChinese(96,48,11,16,1);
OLED_ShowChinese(112,48,12,16,1);
break;
default:
break;
}
}
if(USART2_WaitRecive() == 0) { // If data is received
if(usart2_buf[0] == 0x01) { // Received voice command "waste paper|plastic bottle|recyclable waste", control recyclable waste bin opening
OLED_ShowChinese(96,0,9,16,1);
OLED_ShowChinese(112,0,10,16,1);
TIM_SetCompare1(TIM2,1920); // Open
Delay_ms(1000); // Delay 2s
Delay_ms(1000);
TIM_SetCompare1(TIM2,1830); // Close
USART2_Clear(); // Clear buffer
OLED_ShowChinese(96,0,11,16,1);
OLED_ShowChinese(112,0,12,16,1);
} else if(usart2_buf[0] == 0x02) // Received voice command "leftovers|bones|kitchen waste", control kitchen waste bin opening
{
OLED_ShowChinese(96,16,9,16,1);
OLED_ShowChinese(112,16,10,16,1);
TIM_SetCompare2(TIM2,1930); // Open
Delay_ms(1000); // Delay 2s
Delay_ms(1000);
TIM_SetCompare2(TIM2,1820); // Close
USART2_Clear(); // Clear buffer
OLED_ShowChinese(96,16,11,16,1);
OLED_ShowChinese(112,16,12,16,1);
} else if(usart2_buf[0] == 0x03) // Received voice command "light bulb|hazardous waste", control hazardous waste bin opening
{
OLED_ShowChinese(96,32,9,16,1);
OLED_ShowChinese(112,32,10,16,1);
TIM_SetCompare1(TIM1,1920); // Open
Delay_ms(1000); // Delay 2s
Delay_ms(1000);
TIM_SetCompare1(TIM1,1830); // Close
USART2_Clear(); // Clear buffer
OLED_ShowChinese(96,32,11,16,1);
OLED_ShowChinese(112,32,12,16,1);
} else if(usart2_buf[0] == 0x04) // Received voice command "wood|other waste", control other waste bin opening
{
OLED_ShowChinese(96,48,9,16,1);
OLED_ShowChinese(112,48,10,16,1);
TIM_SetCompare4(TIM1,1920); // Open
Delay_ms(1000); // Delay 2s
Delay_ms(1000);
TIM_SetCompare4(TIM1,1830); // Close
USART2_Clear(); // Clear buffer
OLED_ShowChinese(96,48,11,16,1);
OLED_ShowChinese(112,48,12,16,1);
}
}
if(IR_1 == 0) { // Recyclable waste bin full, red light on, and send "Recyclable waste bin full" via Bluetooth
Delay_ms(100);
if(IR_1 == 0) {
LED1_G = 0;
LED1_R = 1;
if(flag_waste_1) {
UsartPrintf(USART1,"Recyclable waste bin full\r\n");
flag_waste_1 = 0;
}
}
} else { // Not full, green light on
LED1_G = 1;
LED1_R = 0;
flag_waste_1 = 1;
}
if(IR_2 == 0) { // Kitchen waste bin full, red light on, and send "Kitchen waste bin full" via Bluetooth
Delay_ms(100);
if(IR_2 == 0) {
LED2_G = 0;
LED2_R = 1;
if(flag_waste_2) {
UsartPrintf(USART1,"Kitchen waste bin full\r\n");
flag_waste_2 = 0;
}
}
} else { // Not full, green light on
LED2_G = 1;
LED2_R = 0;
flag_waste_2 = 1;
}
if(IR_3 == 0) { // Hazardous waste bin full, red light on, and send "Hazardous waste bin full" via Bluetooth
Delay_ms(100);
if(IR_3 == 0) {
LED3_G = 0;
LED3_R = 1;
if(flag_waste_3) {
UsartPrintf(USART1,"Hazardous waste bin full\r\n");
flag_waste_3 = 0;
}
}
} else { // Not full, green light on
LED3_G = 1;
LED3_R = 0;
flag_waste_3 = 1;
}
if(IR_4 == 0) { // Other waste bin full, red light on, and send "Other waste bin full" via Bluetooth
Delay_ms(100);
if(IR_4 == 0) {
LED4_G = 0;
LED4_R = 1;
if(flag_waste_4) {
UsartPrintf(USART1,"Other waste bin full\r\n");
flag_waste_4 = 0;
}
}
} else { // Not full, green light on
LED4_G = 1;
LED4_R = 0;
flag_waste_4 = 1;
}
}}
05
—
Experimental Results


Resource Sharing (Baidu Cloud)
https://pan.baidu.com/s/1jWq7jc8qLExB4N5vFU4sfQ?pwd=pmpv Extraction code: pmpv
(Or scan the QR code below to obtain)
Scan the QR code below for physical purchase