基于STM32红外计数的灯光照明

小作品简介

  这个小作品通过两个红外计数模块来检测物体运动的方向,从而计算出“房间”的人数。同时通过一个光敏电阻检测环境光线的强度。若光线较暗且房间有人时,则打开LED照明。否则,熄灭LED。如果有需要可以在文章的末尾下载到完整的工程,此外笔者会给出实物清单和接线方法。

基于STM32红外计数的灯光照明_第1张图片

  • 实物清单:

    • 24灯LED(12V)
    • XL6009 DC-DC 升压模块
    • 1路继电器
    • 红外对射计数传感器 (2个)
    • 光敏电阻传感器
    • STM32最小系统板
  • 接线

    • GPIOA.0–>光敏电阻A0(数字输出口)
    • GPIOA.1–>继电器信号端
    • GPIOA.2–>红外计数传感器(上)
    • GPIOA.3–>红外计数传感器(下)

硬件部分

模块简介

  24灯LED由24个食人鱼LED灯组成,按正负极给模块接入12V即可点亮LED。
  XL6009升压模块可以将3-32V的模块升压到5-35V。通过板载的电位器即可调节输出电压。
  1路继电器通过信号端的高低电平来控制吸合或断开,以此控制导线的连通或断开。其中高电平吸和或低电平吸合通过模块上的短路帽决定。
  红外对射传感器含有一个发射和接收段,当有物体遮挡红外时,模块输出高电平(逻辑1),否则输出低电平(逻辑0)
  光敏电阻传感器的A0是模拟量输出,其中电压的大小取决于光敏电阻阻值,而其阻值又取决于光照强度,所以可以通过模数转化(DAC)检测A0电压以检测光照的强弱。D0则是一个简单的数字输出,当光照强度低于某个值(取决于电位器)的时候,D0输出高电平(模块指示灯暗),否则输出低电平(模块指示灯亮)。

硬件原理

  LED灯的负极连接升压模块的负极,正级连接继电器的COM端口。升压模块的正级连接继电器ON端,这样若信号为高电平(或低电平,取决于短路帽的短路方式)时,升压模块的正级就会和LED模块的正级连接,完成一次LED的12V接入。反之,LED正极与升压模块正极断开,灯熄灭。
  光敏电阻模块使用A0口MCU的IO连接,通过读取输入的值判断光线的强弱。
  两个红外计数的分别连接MCU的两个中断。

软件设计

程序原理

  首先,标记一次上两个传感器的是否被遮挡过,读者可以使用一个bool类型的变量,在前面传感器发生遮挡时,判断后面传感器是否被遮挡过,若是,则表示物体从后往前通过,此时笔者认为有人“走出房间”,然后清空标志。将房间人数-1。若没有,则标记前门有物体遮挡过。
  同理,若后面有物体遮挡,通过判断前面是否被制遮挡过,来判断是否有人进入。若有,则需要将房间人数+1,并清空标志。
  其次,由于我们控制了灯的开关,若光线强的环境下,是不需要开灯的,故最后需要结合光照来决定继电器是否吸合。
  

主要程序

  
这里贴出与程序设计有关的部分,不含外设初始化或其他。读者可以在文章末尾的工程中查看完整的初始化部分。其中system文件夹由正点原子提供,其具体其功能可参考原子官方给出的教程。

void EXTI2_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line2)!=RESET)
    {
        if(front&&behind)                     //前面后面都被遮挡过              
        {
            people--;
            behind = front = false;           //清空标志
            printf("人数%d\r\n",people);
        }
        else
        {
            front = true;                     //标记前一个被遮挡
            printf("前面检测\r\n");            //输出调试信息
        }
        LED0 = !LED0;

        EXTI_ClearITPendingBit(EXTI_Line2);
    }
}

  笔者程序中,中断是上下沿检测的(尽管配置为下降沿检测 - -),即物体通过某一红外传感器,会触发两次。假设读者为上升沿或下降沿触发,则需要在进入中断就标志检测到遮挡。
  这是一个前面传感器中断服务子程序,首先若检测到后面都有物体遮挡过,则表示物体运动是又后往前。人数减1。后面传感器原理一直。在本程序中,笔者使用一个全局变量来存储房间的人数。
  

int main(void)
{   
    delay_init();
    NVIC_Configuration();
    uart_init(9600);
    LED_Init();
    EXTIX_Init();
    while(1)
    {
        if(dark&&people)            
        { 
           LED1 = 1;
        }
        else 
        {
            LED1 = 0;
        }
        delay_ms(100);
    } 
}

主函数很简单,其中dark是读取IO得到的值,如果dark为1,这表示传感器输出高电平,既环境光线弱。

源码下载

链接: http://pan.baidu.com/s/1i3Uvhfn 密码: 8bju

你可能感兴趣的:(电子制作)