自制智能镜之——化妆灯和人体感应篇
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系列模组烧录授权
以上是关于自制智能镜之——化妆灯和人体感应篇的主要内容,如果未能解决你的问题,请参考以下文章