← 返回

基于STM32的光强测量仪

基于STM32的光强测量仪

开发时间:2024年5月

使用技术:STM32, U8g2, OPT3001

项目介绍

这是一款基于STM32F103的高精度光强测量仪,采用TI公司的OPT3001数字光强传感器,具有高精度、低功耗的特点。通过U8g2图形库实现了美观的用户界面,支持实时显示光强值和等级指示。

项目目标

  • 测量精度:< 5 Lux
  • 光强分级:8级显示
  • 成本控制:< 50元
  • 测量范围:0.01LUX ~ 83000LUX

界面特点

  • 实时显示光强数值(LUX)
  • 8级光强等级指示
  • LED阵列实时显示光强等级
  • 进度条式启动动画
  • 图形化光强等级显示

技术实现

  • 采用U8g2图形库实现GUI界面
  • OPT3001数字光强传感器,I2C通信
  • STM32F103C8T6作为主控
  • 0.96寸OLED显示屏
  • 8个LED指示灯动态显示

硬件成本明细

器件 价格(¥)
电阻电容套件 2.252
OPT3001 2.1
STM32F103C8T6 3.5
0.96寸OLED 8.9
其他配件(晶振/LED等) 2.248

软件功能

  • 启动界面带进度条动画效果
  • 主界面实时显示光强数值
  • 8级光强等级动态显示
  • LED阵列同步显示光强等级
  • 图形化界面显示光强高低

电源设计

  • TypeC接口与锂电池混合供电
  • TP4056充电管理,500mA充电电流
  • ASM1117-3.3稳压设计

代码实现

进度条显示代码

void testDrawProcess(u8g2_t *u8g2)
{
  for(int i=10;i<=80;i=i+2)
  {
    u8g2_ClearBuffer(u8g2); 
      
    char buff[20];
    sprintf(buff,"%d%%",(int)(i/80.0*100));
    
    u8g2_SetFont(u8g2,u8g2_font_ncenB12_tf);
    u8g2_DrawStr(u8g2,16,32,"Lux meter");//字符显示
    
    u8g2_SetFont(u8g2,u8g2_font_ncenB08_tf);
    u8g2_DrawStr(u8g2,100,49,buff);//当前进度显示
    
    u8g2_DrawRBox(u8g2,16,40,i,10,4);//圆角填充框矩形框
    u8g2_DrawRFrame(u8g2,16,40,80,10,4);//圆角矩形
    if(i%10==0)
    {
      HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_0<<(i/10-1));
    }
    u8g2_SendBuffer(u8g2);
  }
  HAL_Delay(250);
  HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_All);
  HAL_Delay(250);
  HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_All);
  HAL_Delay(250);
  HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_All);
}
主界面显示代码

void MainGUI(u8g2_t *u8g2)
{
  char buff[20];
  u8g2_SetFont(u8g2,u8g2_font_ncenB08_tf);
  u8g2_ClearBuffer(u8g2);
  u8g2_DrawStr(u8g2,5, 15, "Light Intensity");
  u8g2_DrawStr(u8g2,95, 15, "High");
  u8g2_DrawStr(u8g2,95, 60, "Low");
  u8g2_DrawRFrame(u8g2, 0, 0, 92, 23,6);
  B_LUX_40_GetLux(&Lux);
  u8g2_SetFont(u8g2, u8g2_font_ncenB12_tr);
  
  // 光强等级判断
  if(Lux<1000)
    Level = 1;
  else if(Lux < 7000)
    Level = 2;
  else if(Lux < 15000)
    Level = 3;
  else if(Lux <33000)
    Level = 4;
  else if(Lux <78000)
    Level = 5;
  else if(Lux <170000)
    Level = 6;
  else if(Lux <290000)
    Level = 7;
  else
    Level = 8;
  
  // 显示光强值和等级
  sprintf(buff,"%6.0luLux",(long)Lux);
  u8g2_DrawStr(u8g2,0,40,buff);
  sprintf(buff,"LeveL:%d",Level);
  u8g2_DrawStr(u8g2,7,60,buff);
  
  // 光强等级指示器绘制
  if(Level>=8)
  {
    u8g2_DrawBox(u8g2, 104, 21, 8, 5);
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|
                     GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7,1);
  }
  else
  {
    u8g2_DrawFrame(u8g2, 104, 21, 8, 5);
  }
  // ... 其他等级的指示器绘制 ...
}

关于U8g2库

U8g2是一个用于嵌入式系统的开源图形库,特别适用于OLED、LCD等显示屏。主要特点:

  • 支持多种显示屏(SSD1306、SH1106等)
  • 支持I2C、SPI等多种通信接口
  • 提供丰富的字体库和图形绘制功能
  • 支持全缓冲和页面缓冲两种模式
  • 适用于Arduino、STM32等多种平台