问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

基于STM32的光照度自动调节系统

创作时间:
作者:
@小白创作中心

基于STM32的光照度自动调节系统

引用
CSDN
1.
https://blog.csdn.net/weixin_43469377/article/details/124102495

本文介绍了一个基于STM32的光照度自动调节系统,详细描述了硬件器材、PCB绘制、STM32CubeMX配置以及代码实现等步骤。通过光照度传感器和蓝牙模块,用户可以通过手机设定目标光照度,系统会自动调节LED灯的亮度以达到设定值。

基于STM32的光照度自动调节系统

1、硬件器材

  • STM32F103C8T6
  • HC-05
  • 光照度传感器BH1750
  • 一个LED灯(作为被调节对象)
  • 一个限流电阻(1k~10k)

2、硬件PCB绘制

这个硬件电路其实很简单,直接用洞洞板焊也很快,但是毕竟是我的课设作业,我还是画了一下PCB,显得高级hhh

最终效果:

需要PCB文件的话可以私信我(免费),画的比较简陋

3、stm32cubeMX配置

时钟和下载方式配置:

定时器1kHZ(72M/72/1000)不用定时器中断:

I2C(光照传感器需要):

串口通信(蓝牙需要)注意波特率一致:
要开串口中断:
勾选这三项,然后生成代码:

4、自己添加的代码

添加光照度传感器的代码,基本上就是普通的I2C通信,不细说了(下图不完整,完整的参考https://blog.csdn.net/weixin_43469377/article/details/120923774?spm=1001.2014.3001.5501 或者在我的资源里下载):

串口通信在usart.c添加下面的代码重定向printf函数:
记得添加头文件#include stdio.h

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
 
  return ch;
}

主函数:

头文件需要添加这些
一些参数:
靠调节PWM占空比来调节LED亮度:
初始化串口、LED灯亮度为50%,读取当前光照度:
主要逻辑(注释复制过来乱码了,下面有截图):

  /* USER CODE BEGIN WHILE */
  while (1)
  {
        /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
        Set_Value=0;
        Now_Value=0;
        if(Flag==1)      //接收一次命令参数
        {
            Set_Value=strtoul((char *)Light_Buffer,NULL,10); //设置值保存
            HAL_Delay(500);
            printf("SET:%lu lx\r\n",Set_Value);          //反馈给手机设置值
            Now_Value=Value_GY30();
            HAL_Delay(500);
            printf("NOW:%d lx\r\n",Now_Value);          //反馈给手机当前照度
            if(Set_Value>Now_Value)                     //设置照度>当前照度
            {
                printf("lighter");                        //反馈给手机调节
                while(Set_Value>Value_GY30())
                {
                    pwmVal+=15;
                    __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, pwmVal);  //增大LED亮度直到当前照度达到设置值
                }
                printf("NOW:%d lx\r\n",Value_GY30());         //反馈给手机当前照度 
            }
            else if(Set_Value<Now_Value)                 //设置照度<当前照度
            {
                printf("Darker");                         //反馈给手机调节
                while(Set_Value<Value_GY30())
                {
                    pwmVal-=15;
                    __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, pwmVal); //减小LED亮度直到当前照度达到设置值
                }
                printf("NOW:%d lx\r\n",Value_GY30());         //反馈给手机当前照度
            }
            Flag=0;                    //一次调节完成,等待下一次命令
        }
  }
  /* USER CODE END 3 */

串口的中断回调函数:

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    UNUSED(huart);
    if(huart->Instance==USART1)
    {
        RxLine++;  //接收到的数据加一
        Light_Buffer[RxLine-1]=RecieveBuffer[0];  //保存收到的正确数据
        if(RxLine==3)
        {
//			HAL_UART_Transmit_IT(&huart1, (uint8_t *)Light_Buffer, sizeof(Light_Buffer));
            Flag=1;
        }
        RecieveBuffer[0]=0;
        HAL_UART_Receive_IT(&huart1, (uint8_t *)RecieveBuffer, 1);
    }
}
/* USER CODE END 4 */

有个使用的BUG就是,手机给单片机发送指定光照度时需要发三位数,例如设定为25LX,需要发送025
如果需要使光照度快速达到要求,可以更改这个值,让占空比改变速度变大(下图中的15),但是可能会调过了:

成果展示

光照度调节-演示视频

整个工程已上传到我的资源,需要的朋友可以看看

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号