STM32 Project Sharing: Smart Greenhouse (Bluetooth Version)

Project Product Images:

STM32 Project Sharing: Smart Greenhouse (Bluetooth Version)

Bilibili Video Link:

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

(Material sharing can be found at the end of the article)

01

Project Overview

1. Function Details

STM32 Smart Greenhouse (Bluetooth Version)

The functions are as follows:

  1. STM32F103C8T6 microcontroller as the main controller

  2. Waterproof DS18B20 detects soil temperature. When the temperature exceeds the set maximum value, an audible and visual alarm is triggered, and the fan is turned on for cooling; when the temperature is below the set minimum value, an audible and visual alarm is triggered, and the heating element is turned on for heating.

  3. The soil moisture module detects soil moisture. When the moisture is below the set minimum value, an audible and visual alarm is triggered, and the water pump is turned on to add water until the moisture exceeds the set maximum value;

  4. The light-dependent resistor detects light intensity. When the light intensity is below the set minimum value, supplementary lighting is activated.

  5. Threshold values can be set via buttons.

  6. The OLED display shows measurement values.

  7. The Bluetooth module sends measurement data to the mobile phone.

2. Bill of Materials

  • STM32F103C8T6 microcontroller

  • OLED screen

  • DS18B20 temperature sensor

  • Light sensor

  • Soil moisture sensor

  • BT04A Bluetooth module

  • Relay

  • Active buzzer

  • Heating element

  • Water pump

  • Fan module

  • LED lighting module

02

Schematic Design

STM32 Project Sharing: Smart Greenhouse (Bluetooth Version)

03

PCB Hardware Design

PCB Diagram

STM32 Project Sharing: Smart Greenhouse (Bluetooth Version)STM32 Project Sharing: Smart Greenhouse (Bluetooth Version)

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 "ds18b20.h"
#include "adc.h"

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); // Serial port 1 initialization
  DS18B20_Init(); // DS18B20 initialization
  Adc_Init(); // ADC initialization
  Delay_ms(1000);
  Delay_ms(1000);

  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, switch to settings interface
          flag_display++;
          if(flag_display >= 6)
            flag_display = 0;
          Oled_Clear_All(); // Clear screen
          break;
        case 2: // Key 2
          switch(flag_display) {
            case 1: // Interface 1: Temperature maximum value +1
              if(temp_max < 99)
                temp_max++;
              break;
            case 2: // Interface 2: Temperature minimum value +1
              if(temp_min < temp_max-1)
                temp_min++;
              break;
            case 3: // Interface 3: Humidity maximum value +1
              if(soil_max < 99)
                soil_max++;
              break;
            case 4: // Interface 4: Humidity minimum value +1
              if(soil_min < soil_max-1)
                soil_min++;
              break;
            case 5: // Interface 5: Light minimum value
              if(light_min < 99)
                light_min++;
              break;
            default:
              break;
          }
          break;
        case 3: // Key 3
          switch(flag_display) {
            case 1: // Interface 1: Temperature maximum value -1
              if(temp_max > temp_min+1)
                temp_max--;
              break;
            case 2: // Interface 2: Temperature minimum value -1
              if(temp_min > 0)
                temp_min--;
              break;
            case 3: // Interface 3: Humidity maximum value -1
              if(soil_max > soil_min+1)
                soil_max--;
              break;
            case 4: // Interface 4: Humidity minimum value -1
              if(soil_min > 0)
                soil_min--;
              break;
            case 5: // Interface 5: Light minimum value -1
              if(light_min > 0)
                light_min--;
              break;
            default:
              break;
          }
          break;
        default:
          break;
      }
    }
    if(flag_display == 0) { // Measurement interface
      if(time_num % 5 == 0) { // Get data
        temp_value = DS18B20_Get_Temp();
        light_value = 99-30*(Get_Adc_Average(0,3)*3.3/4096.0);
        soil_value = 99-30*(Get_Adc_Average(1,3)*3.3/4096.0);
      }
      if(time_num % 30 == 0) { // Send data
        UsartPrintf(USART1,"Temperature: %d.%dC\r\n",temp_value/10,temp_value%10);
        UsartPrintf(USART1,"Humidity: %d%%\r\n",soil_value);
        UsartPrintf(USART1,"Light: %dLux\r\n",light_value);
      }
    }
    switch(flag_display) { // Display different interfaces based on the display mode flag
      case 0: // Interface 0: Display temperature, humidity, and light values
        Oled_ShowCHinese(1,1,"Soil Environment Monitoring");
        Oled_ShowCHinese(2,0,"Temperature:");
        sprintf(display_buf,"%d.%dC  ",temp_value/10,temp_value%10);
        Oled_ShowString(2,6,display_buf);
        Oled_ShowCHinese(3,0,"Humidity:");
        sprintf(display_buf,"%d%%  ",soil_value);
        Oled_ShowString(3,6,display_buf);
        Oled_ShowCHinese(4,0,"Light:");
        sprintf(display_buf,"%dLux  ",light_value);
        Oled_ShowString(4,6,display_buf);
        break;
      case 1: // Interface 1: Set maximum temperature
        Oled_ShowCHinese(1,0,"Set Maximum Temperature");
        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 2: // Interface 2: Set minimum temperature
        Oled_ShowCHinese(1,0,"Set Minimum Temperature");
        if(time_num % 5 == 0) {
          sprintf(display_buf,"%d  ",temp_min);
          Oled_ShowString(2, 7, display_buf);
        }
        if(time_num % 10 == 0) {
          Oled_ShowString(2, 7, "    ");
        }
        break;
      case 3: // Interface 3: Set maximum humidity
        Oled_ShowCHinese(1,0,"Set Maximum Humidity");
        if(time_num % 5 == 0) {
          sprintf(display_buf,"%d  ",soil_max);
          Oled_ShowString(2, 7, display_buf);
        }
        if(time_num % 10 == 0) {
          Oled_ShowString(2, 7, "    ");
        }
        break;
      case 4: // Interface 4: Set minimum humidity
        Oled_ShowCHinese(1,0,"Set Minimum Humidity");
        if(time_num % 5 == 0) {
          sprintf(display_buf,"%d  ",soil_min);
          Oled_ShowString(2, 7, display_buf);
        }
        if(time_num % 10 == 0) {
          Oled_ShowString(2, 7, "    ");
        }
        break;
      case 5: // Interface 5: Set minimum light
        Oled_ShowCHinese(1,0,"Set Minimum Light");
        if(time_num % 5 == 0) {
          sprintf(display_buf,"%d  ",light_min);
          Oled_ShowString(2, 7, display_buf);
        }
        if(time_num % 10 == 0) {
          Oled_ShowString(2, 7, "    ");
        }
        break;
      default:
        break;
    }
    if(flag_display == 0) { // Measurement interface
      if(temp_value < temp_min*10) { // Temperature below minimum, turn on heating and alarm
        flag_temp_min = 1;
        flag_temp_max = 0;
        FS = 0;
        JR = 1;
      } else if(temp_value > temp_max*10) { // Temperature above maximum, turn on fan and alarm
        flag_temp_min = 0;
        flag_temp_max = 1;
        FS = 1;
        JR = 0;
      } else { // Temperature between both, turn off fan, heating, and alarm
        flag_temp_min = 0;
        flag_temp_max = 0;
        FS = 0;
        JR = 0;
      }
      if(soil_value < soil_min) { // Humidity below minimum, turn on water pump and alarm
        flag_soil_min = 1;
        JS = 1;
      } else if(soil_value > soil_max) { // Humidity above maximum, turn off water pump and alarm
        flag_soil_min = 0;
        JS = 0;
      } else { // Humidity between both, turn off alarm
        flag_soil_min = 0;
      }
      if(light_value < light_min) // Light below minimum, turn on supplementary lighting
        BG = 1;
      else // Light above minimum, turn off supplementary lighting
        BG = 0;
      if(flag_temp_min == 1 || flag_temp_max == 1 || flag_soil_min == 1) {
        if(time_num % 3 == 0) { // Turn on alarm
          LED = ~LED;
          BEEP = ~BEEP;
        }
      } else { // Turn off alarm
        LED = 1;
        BEEP = 0;
      }
    } else { // Settings interface
      LED = 1;
      BEEP = 0;
      FS = 0;
      JS = 0;
      JR = 0;
      BG = 0;
    }
    time_num++; // Increment timer variable
    Delay_ms(10);
    if(time_num %10 == 0)
      LED_SYS = ~LED_SYS;
    if(time_num >= 5000) {
      time_num = 0;
    }
} 

05

Experimental Results

STM32 Project Sharing: Smart Greenhouse (Bluetooth Version)STM32 Project Sharing: Smart Greenhouse (Bluetooth Version)

Material Sharing (Baidu Cloud)

https://pan.baidu.com/s/13ZlmGxD4WajGlw1-is9YmQ?pwd=ksn4 Extraction Code: ksn4

(Or scan the QR code below to obtain)STM32 Project Sharing: Smart Greenhouse (Bluetooth Version)For physical purchases, scan the QR code belowSTM32 Project Sharing: Smart Greenhouse (Bluetooth Version)

Leave a Comment