Design of a Vision Protection System Based on STM32 Microcontroller

System Overview

This design develops an intelligent vision protection system based on the STM32 microcontroller, effectively preventing myopia and poor posture through functions such as ultrasonic distance measurement, ambient light detection, and timed reminders. The system adopts a modular design, including modules for sensor data acquisition, threshold judgment, alarm prompts, and user interaction, characterized by strong practicality and low cost.

Hardware Design

Core Controller Selection

The system uses the STM32F103C8T6 as the main controller, which is a 32-bit microcontroller based on the ARM Cortex-M3 core, featuring rich peripheral interfaces and high processing capability, making it very suitable for embedded application scenarios. If you need the circuit schematic for this design, you can follow my public account

and contact me via private message to obtain it.

This chip has the following advantages:

  • 72MHz main frequency, meeting real-time requirements
  • Rich peripheral interfaces (ADC, PWM, USART, etc.)
  • Low power design, suitable for battery power supply
  • Low cost, with abundant development resources

Sensor Module

1. Ultrasonic Distance Measurement Module (HC-SR04)

Used to detect the distance between the user’s face and the desktop to prevent reading too closely. The HC-SR04 ultrasonic sensor has the following characteristics:

  • Measurement range: 2cm-400cm
  • Accuracy: 3mm
  • Operating voltage: 5V DC
  • Operating current: 15mA

This module triggers distance measurement through the Trig pin, and the Echo pin receives the echo, with measurement time proportional to distance.

2. Light Sensor Module

Used to detect ambient light intensity to prevent eye strain in overly dark or bright environments. It uses a light-dependent resistor combined with the STM32’s internal ADC:

  • Light-dependent resistor GL5516
  • Measurement range: 10-20K Lux
  • ADC resolution: 12 bits (0-4095)
  • Connected to the STM32’s ADC pin via a voltage divider circuit

Display and Interaction Module

1. OLED Display

Using a 0.96-inch OLED12864 display (IIC interface) to display in real-time:

  • Current measured distance
  • Ambient light intensity
  • Set threshold
  • Remaining time

2. Key Input

Utilizing four independent keys to implement function settings:

  • Distance threshold adjustment
  • Light intensity threshold adjustment
  • Timer setting
  • Mode switching

Alarm Module

1. Buzzer Alarm

Triggered when poor eye usage is detected:

  • Active buzzer (5V)
  • NPN transistor drive
  • Supports different alarm modes (distance/light intensity/timer)

2. LED Indicator

RGB LED for status indication:

  • Green: Normal
  • Yellow: Warning
  • Red: Alarm

Power Module

The system uses USB 5V power supply, with the AMS1117-3.3V voltage regulator chip providing power to the STM32 and other 3.3V devices.

Software Design

Main Program Flowchart

The system software adopts a modular design, with the main program flow as follows:

  1. System initialization (clock, peripherals, variables)
  2. Sensor data acquisition (distance, light intensity)
  3. Threshold comparison and state judgment
  4. Control alarm and display based on state
  5. Process user input
  6. Return to step 2 for loop execution

Core Code Implementation

Below is the code implementation of the system’s main function and key functional modules, including detailed comments:

#include "stm32f10x.h"
#include "delay.h"
#include "oled.h"
#include "hcsr04.h"
#include "key.h"
#include "timer.h"
#include "led.h"
#include "adc.h"

// Global variable definition
uint16_t current_distance = 0;    // Current measured distance (cm)
uint16_t current_light = 0;       // Current light intensity (0-100)
uint16_t distance_threshold = 30; // Distance threshold (cm)
uint16_t light_threshold = 40;    // Light intensity threshold (0-100)
uint16_t timer_count = 0;         // Timer counter (minutes)
uint16_t timer_set = 45;          // Timer setting (minutes)

int main(void) {
    // 1. System initialization
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // Set interrupt priority group
    Delay_Init();                                   // Delay function initialization
    OLED_Init();                                    // OLED initialization
    HCSR04_Init();                                  // Ultrasonic module initialization
    KEY_Init();                                     // Key initialization
    TIM3_Init(4999, 7199);                         // Timer initialization (10ms interrupt)
    LED_Init();                                     // LED initialization
    ADC1_Init();                                    // ADC initialization

    // 2. Display initial information
    OLED_ShowString(0, 0, "Distance:   cm");
    OLED_ShowString(0, 2, "Light:      %");
    OLED_ShowString(0, 4, "Timer:  /  min");
    OLED_ShowString(0, 6, "STM32 Vision Guard");

    // 3. Main loop
    while(1) {
        // 3.1 Get sensor data
        current_distance = HCSR04_GetDistance();    // Get distance (cm)
        current_light = 100 - (ADC_GetValue()/40); // Get light intensity (0-100%)

        // 3.2 Update display
        OLED_ShowNum(72, 0, current_distance, 3);   // Display distance
        OLED_ShowNum(48, 2, current_light, 3);      // Display light intensity
        OLED_ShowNum(48, 4, timer_count, 2);        // Display current timer
        OLED_ShowNum(72, 4, timer_set, 2);          // Display set time

        // 3.3 State judgment and alarm
        if(current_distance < distance_threshold) {
            LED_SetColor(LED_RED);                  // Set LED to red
            BEEP_On();                              // Turn on buzzer
            OLED_ShowString(90, 0, "!");          // Display warning sign
        } else if(current_light < light_threshold) {
            LED_SetColor(LED_YELLOW);               // Set LED to yellow
            BEEP_On();                              // Turn on buzzer
            OLED_ShowString(90, 2, "!");          // Display warning sign
        } else {
            LED_SetColor(LED_GREEN);                // Set LED to green
            BEEP_Off();                             // Turn off buzzer
            OLED_ShowString(90, 0, " ");          // Clear warning sign
            OLED_ShowString(90, 2, " ");          // Clear warning sign
        }

        // 3.4 Process key input
        KEY_Process();                              // Key processing function

        Delay_Ms(100);                             // Delay 100ms
    }
}

// Timer interrupt service function (triggered every 10ms)
void TIM3_IRQHandler(void) {
    if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) {
        static uint16_t count = 0;
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update); // Clear interrupt flag

        count++;
        if(count >= 6000) { // 6000*10ms = 60s = 1 minute
            count = 0;
            timer_count++;
            if(timer_count >= timer_set) {
                BEEP_On();                          // Timer time reached, turn on buzzer
                LED_SetColor(LED_RED);              // Set LED to red
            }
        }
    }
}

Key Functional Modules

1. Ultrasonic Distance Measurement Module

// HC-SR04 initialization
void HCSR04_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(HCSR04_TRIG_RCC | HCSR04_ECHO_RCC, ENABLE);

    // Trig pin configuration (output)
    GPIO_InitStructure.GPIO_Pin = HCSR04_TRIG_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(HCSR04_TRIG_PORT, &GPIO_InitStructure);

    // Echo pin configuration (input)
    GPIO_InitStructure.GPIO_Pin = HCSR04_ECHO_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_Init(HCSR04_ECHO_PORT, &GPIO_InitStructure);

    HCSR04_TRIG_OFF(); // Initial state Trig low
}

// Get distance (cm)
uint16_t HCSR04_GetDistance(void) {
    uint32_t time = 0;

    HCSR04_TRIG_ON();              // Send 10us high pulse
    Delay_Us(10);
    HCSR04_TRIG_OFF();

    while(GPIO_ReadInputDataBit(HCSR04_ECHO_PORT, HCSR04_ECHO_PIN) == RESET); // Wait for Echo to go high
    while(GPIO_ReadInputDataBit(HCSR04_ECHO_PORT, HCSR04_ECHO_PIN) != RESET) { // Measure high level time
        time++;
        Delay_Us(1);
        if(time > 23529) break; // Timeout (400cm)
    }

    return time / 58;              // Calculate distance (cm)
}

2. Light Sensor Module

// ADC initialization
void ADC1_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    ADC_InitTypeDef ADC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);

    // Configure ADC pin (PA1)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // ADC configuration
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 1;
    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_Cmd(ADC1, ENABLE);
    ADC_ResetCalibration(ADC1);
    while(ADC_GetResetCalibrationStatus(ADC1));
    ADC_StartCalibration(ADC1);
    while(ADC_GetCalibrationStatus(ADC1));
}

// Get ADC value (0-4095)
uint16_t ADC_GetValue(void) {
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
    return ADC_GetConversionValue(ADC1);
}

3. Key Processing Module

// Key initialization
void KEY_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(KEY1_RCC | KEY2_RCC | KEY3_RCC | KEY4_RCC, ENABLE);
    GPIO_InitStructure.GPIO_Pin = KEY1_PIN | KEY2_PIN | KEY3_PIN | KEY4_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(KEY1_PORT, &GPIO_InitStructure);
}

// Key processing function
void KEY_Process(void) {
    static uint8_t key_up = 1;

    if(key_up && (KEY1_PRES || KEY2_PRES || KEY3_PRES || KEY4_PRES)) {
        Delay_Ms(10); // Debounce
        key_up = 0;

        if(KEY1_PRES) { // Increase distance threshold
            distance_threshold += 5;
            if(distance_threshold > 60) distance_threshold = 60;
        } else if(KEY2_PRES) { // Decrease distance threshold
            distance_threshold -= 5;
            if(distance_threshold < 20) distance_threshold = 20;
        } else if(KEY3_PRES) { // Increase light intensity threshold
            light_threshold += 5;
            if(light_threshold > 80) light_threshold = 80;
        } else if(KEY4_PRES) { // Decrease light intensity threshold
            light_threshold -= 5;
            if(light_threshold < 20) light_threshold = 20;
        }
    } else if(KEY1_PRES==0 && KEY2_PRES==0 && KEY3_PRES==0 && KEY4_PRES==0) {
        key_up = 1;
    }
}

System Schematic

The system hardware connection schematic is as follows:

+-------------------+       +-------------------+       +-------------------+
|   STM32F103C8T6   |       |     HC-SR04       |       |     OLED12864      |
|                   |       |                   |       |                   |
| PA0  <---------   |<-----| Trig              |       |                   |
| PA1  <---------   |<-----| Echo              |       |                   |
|                   |       |                   |       |                   |
| PA2  <---------   |<-----| VCC (5V)          |       |                   |
| PA3  <---------   |<-----| GND               |       |                   |
|                   |       |                   |       |                   |
| PB6  <---------   |<-----| SCL               |       |                   |
| PB7  <---------   |<-----| SDA               |       |                   |
|                   |       |                   |       |                   |
| PB8  <---------   |<-----| +                 |       |                   |
| PB9  <---------   |<-----| -                 |       |                   |
|                   |       |                   |       |                   |
| PC13 <---------   |<-----| Buzzer            |       |                   |
|                   |       |                   |       |                   |
| PA4  <---------   |<-----| Light Sensor      |       |                   |
|                   |       |                   |       |                   |
| PB0  <---------   |<-----| KEY1              |       |                   |
| PB1  <---------   |<-----| KEY2              |       |                   |
| PB10 <---------   |<-----| KEY3              |       |                   |
| PB11 <---------   |<-----| KEY4              |       |                   |
+-------------------+       +-------------------+       +-------------------+

Function Testing and Optimization

Testing Plan

  1. Distance Detection Test:

    • Test the accuracy of the ultrasonic module at different distances (20cm-50cm)
    • Verify the alarm threshold setting function
  2. Light Intensity Detection Test:

    • Test the response of the light sensor using an adjustable light source
    • Verify the accuracy of the alarm under different lighting conditions
  3. Timing Function Test:

    • Test the accuracy of the timed alarm
    • Verify the timer setting function
  4. Comprehensive Test:

    • Simulate actual usage scenarios for long-term stability testing
    • Test the interaction of multiple modules working simultaneously

Optimization Suggestions

  1. Algorithm Optimization:

    • Add sensor data filtering algorithms to improve stability
    • Implement dynamic threshold adjustment to adapt to different user needs
  2. Function Expansion:

    • Add a Bluetooth module for mobile app control
    • Add data logging functionality to track eye usage habits
    • Support multi-user mode to store personalized settings
  3. User Experience Optimization:

    • Add voice prompt functionality
    • Optimize alarm methods (vibration, light, etc.)
    • Improve user interface to include more status displays

Conclusion

This article provides a detailed introduction to a vision protection system design based on the STM32 microcontroller, including hardware selection, circuit design, software implementation, and functional testing. The system achieves intelligent alarms through ultrasonic distance measurement and ambient light detection, characterized by strong practicality and low cost, especially suitable for students and office workers. The complete source code and detailed comments provided can serve as a reference for related project development and can also be further developed based on this foundation!

Leave a Comment