STM32 Project Share: Air Purifier

STM32 Project Share: Air PurifierSTM32 Project Share: Air Purifier

Bilibili video link:

https://www.bilibili.com/video/BV1bndfYfEhM/?share_source=copy_web&vd_source=097fdeaf6b6ecfed8a9ff7119c32faf2

01

Project Overview

1. Function Details

STM32 Air Purifier

The functions are as follows:

  1. MQ-2 detects smoke, triggers sound and light alarm, and activates the purifier

  2. PM2.5 module detects dust

  3. MQ-7 detects carbon monoxide gas

  4. MQ-135 detects air quality

  5. MS1100 detects formaldehyde levels

  6. Smoke, gas, air quality, dust, and formaldehyde exceedance triggers buzzer and indicator light alarms and activates the purifier

  7. DHT11 detects environmental temperature and humidity, with voice prompts when temperature or humidity exceeds thresholds

  8. OLED displays current environmental data in real-time

  9. Buttons can adjust thresholds and manually control the purifier switch

  10. Data is sent to a mobile device via Bluetooth, allowing control of the fan and purifier, and mode switching

2. Bill of Materials

  • STM32F103C8T6 microcontroller

  • OLED screen

  • DHT11 temperature and humidity sensor

  • MQ2 smoke sensor

  • MQ7 carbon monoxide sensor

  • MQ135 air quality sensor

  • PM2.5 dust sensor

  • MS1100 formaldehyde sensor

  • BT04A Bluetooth module

  • Active buzzer

  • Relay

  • Fan module

  • Humidifier module

02

Schematic Design

STM32 Project Share: Air Purifier

03

PCB Hardware Design

PCB Diagram

STM32 Project Share: Air PurifierSTM32 Project Share: Air Purifier

04

Program Design

#include "sys.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "math.h"
#include "delay.h"
#include "gpio.h"
#include "key.h"
#include "oled.h"
#include "usart.h"
#include "adc.h"
#include "dht11.h"
#include "pm25.h"
/**********************************Variable Definitions**********************************/
uint8_t key_num = 0; // Key scan flag
uint8_t flag_display = 0; // Display interface flag
uint32_t time_num = 0; // 10ms timer
char display_buf[32]; // Display buffer
_Bool flag_mode = 0; // Current mode flag
extern uint8_t usart1_buf[256]; // USART1 receive array
u16 smog_value = 0; // Smoke value
u16 smog_max = 80; // Maximum smoke value
u16 trq_value = 0; // Natural gas value
u16 trq_max = 80; // Maximum natural gas value
u16 har_value = 0; // Harmful gas value
u16 har_max = 80; // Maximum harmful gas value
u16 jq_value = 0; // Formaldehyde gas value
u16 jq_max = 80; // Maximum formaldehyde gas value
u16 temp_value = 0; // Temperature value
u16 temp_max = 35; // Maximum temperature value
_Bool flag_yy_temp = 0; // Voice flag
u16 humi_value = 0; // Humidity value
u16 humi_max = 70; // Maximum humidity value
_Bool flag_yy_humi = 0; // Voice flag
u16 pm_value = 0; // PM2.5 value
u16 pm_max = 300; // Maximum PM2.5 value
/**********************************Function Declarations**********************************/
void Key_function(void); // Key function
dvoid Monitor_function(void); // Monitoring function
void Display_function(void); // Display function
void Manage_function(void); // Processing function
/*********** Main Function ************/
int main(void) {
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // Configure interrupt priority group
    Delay_Init(); // Delay initialization
    Gpio_Init(); // IO initialization
    Key_Init(); // Key initialization
    Oled_Init(); // OLED initialization
    Oled_Clear_All(); // Clear screen
    Usart1_Init(9600); // USART1 initialization
    Usart2_Init(9600); // USART2 initialization
    Adc_Init(); // ADC initialization
    DHT11_Init(); // Temperature initialization
    PM25_Init(); // PM2.5 initialization
    UsartPrintf(USART2,"AF:30");
    Delay_ms(1000);
    UsartPrintf(USART2,"A7:00001");
    while(1) {
        Key_function(); // Key function
        Monitor_function(); // Monitoring function
        Display_function(); // Display function
        Manage_function(); // Processing function
        time_num++; // Timer variable +1
        Delay_ms(10);
        if(time_num % 10 == 0) LED_SYS = ~LED_SYS;
        if(time_num >= 5000) {
            time_num = 0;
        }
    }
}
/*********** Key Function ************/
void Key_function(void) {
    key_num = Chiclet_Keyboard_Scan(0); // Key scan
    if(key_num != 0) { // If a key is pressed
        switch(key_num) {
            case 1: // Key 1, switch to settings interface
                flag_display++;
                if(flag_display >= 8) flag_display = 0;
                Oled_Clear_All(); // Clear screen
                break;
            case 2: // Key 2
                switch(flag_display) {
                    case 0: // Interface 0:
                        flag_mode = 1;
                        RELAY_FS = ~RELAY_FS;
                        RELAY_JH = ~RELAY_JH;
                        break;
                    case 1: // Interface 1: Set maximum smoke value +1
                        if(smog_max < 300) smog_max++;
                        break;
                    case 2: // Interface 2: Set maximum PM2.5 value +1
                        if(pm_max < 600) pm_max++;
                        break;
                    case 3: // Interface 3: Set maximum natural gas value +1
                        if(trq_max < 300) trq_max++;
                        break;
                    case 4: // Interface 4: Set maximum harmful gas value +1
                        if(har_max < 300) har_max++;
                        break;
                    case 5: // Interface 5: Set maximum formaldehyde gas value +1
                        if(jq_max < 300) jq_max++;
                        break;
                    case 6: // Interface 6: Set maximum temperature value +1
                        if(temp_max < 100) temp_max++;
                        break;
                    case 7: // Interface 7: Set maximum humidity value +1
                        if(humi_max < 100) humi_max++;
                        break;
                    default: break;
                }
                break;
            case 3: // Key 3
                switch(flag_display) {
                    case 0: // Interface 0:
                        flag_mode = 0;
                        break;
                    case 1: // Interface 1: Set maximum smoke value -1
                        if(smog_max > 0) smog_max--;
                        break;
                    case 2: // Interface 2: Set maximum PM2.5 value -1
                        if(pm_max > 0) pm_max--;
                        break;
                    case 3: // Interface 3: Set maximum natural gas value -1
                        if(trq_max > 0) trq_max--;
                        break;
                    case 4: // Interface 4: Set maximum harmful gas value -1
                        if(har_max > 0) har_max--;
                        break;
                    case 5: // Interface 5: Set maximum formaldehyde gas value -1
                        if(jq_max > 0) jq_max--;
                        break;
                    case 6: // Interface 6: Set maximum temperature value -1
                        if(temp_max > 0) temp_max--;
                        break;
                    case 7: // Interface 7: Set maximum humidity value -1
                        if(humi_max > 0) humi_max--;
                        break;
                    default: break;
                }
                break;
            default: break;
        }
    }
}
/*********** Monitoring Function ************/
void Monitor_function(void) {
    if(flag_display == 0) // Measurement interface
    {
        if(time_num % 2 == 0) // Get data
        {
            if(CHECK_S == 0) // If smoke triggers
                smog_value = 90*(Get_Adc_Average(0,3)*3.3/4096.0);
            else
                smog_value = 0;
            if(CHECK_T == 0) // If natural gas triggers
                trq_value = 90*(Get_Adc_Average(1,3)*3.3/4096.0);
            else
                trq_value = 0;
            if(CHECK_H == 0) // If harmful gas triggers
                har_value = 90*(Get_Adc_Average(4,3)*3.3/4096.0);
            else
                har_value = 0;
            if(CHECK_JQ == 0) // If formaldehyde gas triggers
                jq_value = 90*(Get_Adc_Average(5,3)*3.3/4096.0);
            else
                jq_value = 0;
            pm_value = Pm25_Get_Value(3);
            if(pm_value < 200) pm_value = 0;
            Dht11_Get_Temp_Humi_Value(&temp_value,&humi_value);
        }
        if(time_num % 10 == 0) // Send data
        {
            UsartPrintf(USART1,"\r\nAir Quality: %dPPM",har_value);
            UsartPrintf(USART1,"\r\nPM2.5: %dPPM",pm_value);
            UsartPrintf(USART1,"\r\nCombustible Gas: %dPPM",trq_value);
            UsartPrintf(USART1,"\r\nFormaldehyde Gas: %dPPM",jq_value);
            UsartPrintf(USART1,"\r\nSmoke: %dPPM",smog_value);
            UsartPrintf(USART1,"\r\nTemperature: %d.%dC Humidity: %d.%d%%",temp_value/10,temp_value%10,humi_value/10,humi_value%10);
            if(flag_mode == 0) UsartPrintf(USART1,"   Mode: Automatic");
            else UsartPrintf(USART1,"   Mode: Manual");
        }
        if(temp_value > temp_max*10) {
            if(flag_yy_temp == 0) {
                UsartPrintf(USART2,"A7:00002");
                flag_yy_temp = 1;
            }
        } else {
            flag_yy_temp = 0;
        }
        if(humi_value > humi_max*10) {
            if(flag_yy_humi == 0) {
                UsartPrintf(USART2,"A7:00003");
                flag_yy_humi = 1;
            }
        } else {
            flag_yy_humi = 0;
        }
        if(USART1_WaitRecive() == 0) // If Bluetooth data is received
        {
            switch(usart1_buf[0]) {
                case 'A': // A: Switch to automatic mode
                    flag_mode = 0;
                    break;
                case 'B': // B: Start purification
                    flag_mode = 1;
                    RELAY_JH = 1;
                    RELAY_FS = 1;
                    break;
                case 'C': // C: Stop purification
                    flag_mode = 1;
                    RELAY_JH = 0;
                    RELAY_FS = 0;
                    break;
                default: break;
            }
            USART1_Clear();
        }
    }
}
/*********** Display Function ************/
void Display_function(void) {
    switch(flag_display) // Display different interfaces based on display mode flag
    {
        case 0: // Interface 0:
            Oled_ShowCHinese(1,0,"Temperature");
sprintf(display_buf,":%d",temp_value/10); // Display temperature value
            Oled_ShowString(1, 4, display_buf);
            Oled_ShowCHinese(1,4,"Humidity");
sprintf(display_buf,":%d%%",humi_value/10); // Display humidity value
            Oled_ShowString(1, 12, display_buf);
            Oled_ShowCHinese(2,0,"Smoke");
            if(smog_value!=0) {
sprintf(display_buf,":%d",smog_value); // Display harmful gas value
                Oled_ShowString(2, 4, display_buf);
            } else Oled_ShowString(2, 4, ":0  ");
            Oled_ShowCHinese(3,0,"Gas");
            if(trq_value!=0) {
sprintf(display_buf,":%d",trq_value); // Display combustible gas value
                Oled_ShowString(3, 4, display_buf);
            } else Oled_ShowString(3, 4, ":0  ");
            Oled_ShowCHinese(3,4,"Air");
            if(har_value!=0) {
sprintf(display_buf,":%d",har_value); // Display smoke value
                Oled_ShowString(3, 12, display_buf);
            } else Oled_ShowString(3, 12, ":0  ");
            Oled_ShowCHinese(4,0,"Formaldehyde");
sprintf(display_buf,":%d ",jq_value); // Display formaldehyde value
            Oled_ShowString(4, 4, display_buf);
            Oled_ShowCHinese(2,4,"Particles");
            if(pm_value!=0) {
sprintf(display_buf,":%d",pm_value); // Display PM2.5 value
                Oled_ShowString(2, 12, display_buf);
            } else {
                Oled_ShowString(2, 12, ":0  ");
            }
            if(flag_mode == 0) Oled_ShowCHinese(4,4,"Automatic");
            else Oled_ShowCHinese(4,4,"Manual");
            break;
        case 1: // Interface 1:
            Oled_ShowCHinese(1,0,"Set Maximum Smoke Value");
            if(time_num % 5 == 0) {
sprintf(display_buf,"%d  ",smog_max);
                Oled_ShowString(2, 7, display_buf);
            }
            if(time_num % 10 == 0) {
                Oled_ShowString(2, 7, "    ");
            }
            break;
        case 2: // Interface 2:
            Oled_ShowCHinese(1,0,"Set Maximum PM2.5 Value");
            if(time_num % 5 == 0) {
sprintf(display_buf,"%d  ",pm_max);
                Oled_ShowString(2, 7, display_buf);
            }
            if(time_num % 10 == 0) {
                Oled_ShowString(2, 7, "    ");
            }
            break;
        case 3: // Interface 3:
            Oled_ShowCHinese(1,0,"Set Maximum Gas Value");
            if(time_num % 5 == 0) {
sprintf(display_buf,"%d  ",trq_max);
                Oled_ShowString(2, 7, display_buf);
            }
            if(time_num % 10 == 0) {
                Oled_ShowString(2, 7, "    ");
            }
            break;
        case 4: // Interface 4:
            Oled_ShowCHinese(1,0,"Set Air Quality");
            if(time_num % 5 == 0) {
sprintf(display_buf,"%d  ",har_max);
                Oled_ShowString(2, 7, display_buf);
            }
            if(time_num % 10 == 0) {
                Oled_ShowString(2, 7, "    ");
            }
            break;
        case 5: // Interface 5:
            Oled_ShowCHinese(1,0,"Set Maximum Formaldehyde Value");
            if(time_num % 5 == 0) {
sprintf(display_buf,"%d  ",jq_max);
                Oled_ShowString(2, 7, display_buf);
            }
            if(time_num % 10 == 0) {
                Oled_ShowString(2, 7, "    ");
            }
            break;
        case 6: // Interface 6:
            Oled_ShowCHinese(1,0,"Set Maximum Temperature Value");
            if(time_num % 5 == 0) {
sprintf(display_buf,"%d  ",temp_max);
                Oled_ShowString(2, 7, display_buf);
            }
            if(time_num % 10 == 0) {
                Oled_ShowString(2, 7, "    ");
            }
            break;
        case 7: // Interface 7:
            Oled_ShowCHinese(1,0,"Set Maximum Humidity Value");
            if(time_num % 5 == 0) {
sprintf(display_buf,"%d  ",humi_max);
                Oled_ShowString(2, 7, display_buf);
            }
            if(time_num % 10 == 0) {
                Oled_ShowString(2, 7, "    ");
            }
            break;
        default: break;
    }
}
/*********** Processing Function ************/
void Manage_function(void) {
    if(flag_display == 0) // Measurement interface
    {
        if(flag_mode == 0) {
            if(smog_value > smog_max || har_value > har_max || trq_value > trq_max || jq_value > jq_max || pm_value > pm_max) // If any value exceeds the set maximum, ventilate, purify, and trigger alarm
            {
                RELAY_FS = 1;
                RELAY_JH = 1;
                if(time_num % 2 == 0) {
                    LED = ~LED;
                    BEEP = ~BEEP;
                }
            } else {
                RELAY_FS = 0;
                RELAY_JH = 0;
                LED = 1;
                BEEP = 0;
            }
        } else {
            LED = 1;
            BEEP = 0;
        }
    } else // Settings interface
    {
        RELAY_FS = 0;
        RELAY_JH = 0;
        LED = 1;
        BEEP = 0;
    }
}

05

Experimental Results

STM32 Project Share: Air Purifier

Leave a Comment