自制智能镜之——化妆灯和人体感应篇

Posted 三明治开发社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自制智能镜之——化妆灯和人体感应篇相关的知识,希望对你有一定的参考价值。


​ ​ ​ ​ 上一节 《自制智能镜之——屏幕显示时间日期篇》给大家介绍了一下屏幕显示日期时间的实现方式,现在来说一说智能镜重要的化妆灯功能和人体感应功能。
​ ​ ​ ​
​ ​ ​ ​

PWM驱动灯板

​ ​ ​ ​ demo使用了一冷一暖两种LED灯,通过输出两路 PWM 驱动,实现灯光亮度可调和冷暖色的切换。例程中有关pwm的初始化和启动、占空比设置等相关代码都实现在 tuya_mirror_pwm.c 文件中。

OPERATE_RET mirror_pwm_init(VOID);

OPERATE_RET mirror_pwm_set(UCHAR_T color, USHORT_T duty);

OPERATE_RET mirror_pwm_off(VOID);

mirror_pwm_set() 可以改变控制连接冷暖两路的PWM的开启和停止以及各自的占空比,直接输入灯色传参和占空比即可实现灯板的冷暖光切换和亮度调整:

OPERATE_RET mirror_pwm_set(UCHAR_T color, USHORT_T duty)
{
  FLOAT_T percent = 0.0;

  if(user_pwm_init_flag != TRUE){
      PR_ERR("user pwm not init!");
      return OPRT_INVALID_PARM;
  }

  percent = (FLOAT_T)(duty/1000.0);

  bk_pwm_stop(pChannelList[0]);
  bk_pwm_stop(pChannelList[1]);

  switch (color)
  {
  case 0:
      PR_NOTICE("set light cold");
      bk_pwm_update_param(pChannelList[0], pwm_period, (UINT32)(percent * pwm_period), 0, 0);
      bk_pwm_start(pChannelList[0]);
      break;
  case 1:
      PR_NOTICE("set light medium");
      bk_pwm_update_param(pChannelList[0], pwm_period, (UINT32)((percent * pwm_period)/2), 0, 0);
      bk_pwm_update_param(pChannelList[1], pwm_period, (UINT32)((percent * pwm_period)/2), 0, 0);
      bk_pwm_start(pChannelList[0]);
      bk_pwm_start(pChannelList[1]);
      break;
  case 2:
      PR_NOTICE("set light warm");
      bk_pwm_update_param(pChannelList[1], pwm_period, (UINT32)(percent * pwm_period), 0, 0);
      //bk_pwm_update_param(pChannelList[0], pwm_period, 0, 0, 0);
      bk_pwm_start(pChannelList[1]);
      break;
  default:
      break;
  }

  return OPRT_OK;
}

封装好这几个接口后,接下来就需要在应用代码中合适的地方调用来控制灯板。

人体感应

​ ​ ​ ​ 本demo还有一个人体感应开关灯光和屏幕的功能,是通过一个PIR传感器来简单实现的。该传感器会在检测到人体运动的时候输出高电平,简单易用。

​ ​ ​ ​ 直接写一个读取连接传感器IO的电平的函数,然后把它放到线程里周期运行,并在读到高电平的时候保存PIR状态在设备数据结构体当中:

STATIC VOID mirror_pir_detect(VOID)
{    
    if(tuya_gpio_read(PIR_IN_PORT)) {
        PR_NOTICE("-----------SOMEONE HERE-------------");
        mirror_ctrl_data.PIR_state = trigger;
    }
}

VOID mirror_data_get_handle(VOID)
{   
 	......
 	// Detect pir IO port
 	mirror_pir_detect();
}
STATIC VOID sensor_data_get_thread(PVOID_T pArg)
{   
 	 while(1) {
 	
 	     mirror_data_get_handle();
 	
 	     tuya_hal_system_sleep(TASKDELAY_SEC);
 	 }
}

​ ​ ​ 然后另一个线程对设备数据结构体中PIR的状态进行判定,当设备打开人体感应功能,且设备总开关处于打开的情况下,PIR检测到有人的时候将会打开灯光开关,同时启动定时器。当定时器触发进入中断时将会关闭灯光开关。

VOID pir_data_handle(VOID)
{
 MIRROR_CTRL_DATA_T *p;

 p = &mirror_ctrl_data;

 if(p->PIR_state == trigger) {
     p->PIR_state = none;

     if((p->PIR_switch != TRUE)||(p->Mirror_switch != TRUE)) {

         return;
     }

     if(IsThisSysTimerRun(off_timer) == TRUE) {
         sys_stop_timer(off_timer);
         sys_start_timer(off_timer, 1000*600, TIMER_ONCE);
     }else {
         sys_start_timer(off_timer, 1000*600, TIMER_ONCE);
     }

     p->Light_switch = TRUE;

 }
}

这样就实现了人来即亮,延时熄灭的效果。

其他功能

​ ​ ​ 经过上面的步骤,我们的智能镜demo就只剩下电池电量检测及显示功能没实现了,这个功能通过ADC采样得到电池电压,再根据电压值预估电池剩余电量,同时把之前屏幕素材收集阶段准备的几张电池图案显示在屏幕上。这个实现起来非常简单,这里就不加赘述了。
​ ​ ​ 把所有功能的运行逻辑加以整合和修改,同时引入涂鸦云dp功能点下发控制逻辑,一个可用手机APP控制的智能镜嵌入式demo代码就完成了。

编译和烧录

​ ​ ​ 在linux终端输入指令运行SDK环境目录下的build_app.sh脚本来编译代码生成固件,指令格式为 sh build_app.sh APP_PATH APP_NAME APP_VERSION
在这里插入图片描述
若出现下图所示提示,则表示编译成功,固件已经生成:在这里插入图片描述
固件生成路径为:apps->APP_PATH->output

将固件烧录至模组即可开始功能调试阶段,有关烧录和授权方式可以参照文档: WB系列模组烧录授权

以上是关于自制智能镜之——化妆灯和人体感应篇的主要内容,如果未能解决你的问题,请参考以下文章

自制智能镜之——功能逻辑分析篇

自制智能镜之——应用入口及触摸按键实现篇

自制智能镜之——屏幕显示时间日期篇

自制智能镜之——硬件&结构设计篇

自制智能镜之——产品创建及开发环境搭建篇(限时活动进行中)

红外线人体感应灯