在物联网中,有很多场景下都需要用到这种功能,我之所以做这个功能主要是因为公司正在做一个智能灯项目,而灯最常见的配网方式就是开关电源5次,常见的流程是 “ 开关5次,指示灯闪烁,清除原有热点信息,进入配网状态”。
定时器
定时器主要有2个任务,第一,当按键开关按下后,在一定时间内(3s或5s)如果没有再次按下,表示不是连按系统正常运行,第二,当连续开关5次后,启用定时器来控制指示灯闪烁。
void timer_handler(void *arg) //定时器中断函数
{
timescaler++;
printf("timescaler = %d\r\n",timescaler);
if(bringflag == 2) //value等于3,黄灯闪,进入配网
{
led_white_off();
if(timescaler >= 60){ //60s内不配网,则取消配网
entertimerflag = 1;
bringflag = 0;
}
if(timescaler%2 == 0){ //灯闪烁
led_yellow_off();
}
else{
led_yellow_on();
}
}
if(entertimerflag == 1)
{
if(timescaler >= 3) //3s内没有按下,正常运行
{
timescaler = 0;
entertimerflag = 0;
hal_timer_stop(&timer1); //停止定时器
value = 0; //计数次数归零
aos_kv_del("key");
printf(">>>dingshi aos_kv_set:%d\r\n", aos_kv_set(key, &value, strlen(value), 1));//写入次数
}
}
}
void timer1_init(void) //定时器初始化
{
int ret=-1;
timer1.port = 1;//定时器1
timer1.config.period = 1000000; /* 1s */
timer1.config.reload_mode = TIMER_RELOAD_AUTO;//自动重装载
timer1.config.cb = timer_handler;//定时器中断函数名
hal_timer_init(&timer1);
if (ret == 0) {
printf("timer1 init successful !\n");
}
/* start timer1 */
ret = hal_timer_start(&timer1); //启动定时器
if (ret == 0) {
printf("timer1 start successful !\n");
}
timescaler = 0;//定时计数
}
读取flash次数以及次数写入
int read_and_write_switchs_to_flash(void)
{
int ret = 0;
ret = aos_kv_get(key, &value, strlen(value));//读次数
if (ret != 0)//读取失败,出厂第一次开机,里面没开始存值
{
value=1;
aos_kv_del(key);
printf(">>>shibai aos_kv_set:%d\r\n", aos_kv_set(key, &value, strlen(value), 1));
}
else //读取成功,次数加1
{
value++;
aos_kv_del(key);
printf(">>>chenggong aos_kv_set:%d\r\n", aos_kv_set(key, &value, strlen(value), 1));
if(value>3)//进入配网,系统会重启,为保证重启后系统仍然进入配网状态,保存上一次重启前的value值
{
printf(">>>chongqiflag aos_kv_set:%d\r\n",aos_kv_get("chongqiflag", &chongqiflag, strlen(chongqiflag)));//读次数
if(chongqiflag == 1) //配网后,清除热点信息后,再次配网准备
{
value = 3;
chongqiflag =0;
aos_kv_del(key);
printf(">>>dayu5 aos_kv_set:%d\r\n", aos_kv_set(key, &value, strlen(value), 1));
printf(">>>write flag =: %d\r\n", aos_kv_set("chongqiflag", &chongqiflag, strlen(chongqiflag), 1));
}else{
value=1;
aos_kv_del(key);
printf(">>>dayu5 aos_kv_set:%d\r\n", aos_kv_set(key, &value, strlen(value), 1));
}
}
}
printf("value = %d\r\n",value);
return value;
}
主程序需要调用的接口
void timer1init_and_Distribution_network(void)
{
int ret=0;
if(flag == 1)//每次开机只运行一次
{
timer1_init();
ret = read_and_write_switchs_to_flash();//读取flash中次数
Normal_operation_light_mode(ret);
if(ret>=3)//次数大于进入配网
{
printf(">>>read flag =: %d\r\n", aos_kv_get("connflag", &connflag, strlen(connflag)));
printf("enter reset connflag = %d\r\n",connflag);
do_awss_active();
do_awss_active();
if(connflag == 1)//如果第一次连不用清除热点信息,之后再次连接清除之前热点信息
{
do_awss_reset();//清除全部缓存,相当于第一次开机
chongqiflag =1;
connflag =0;
printf(">>>write flag =: %d\r\n", aos_kv_set("connflag", &connflag, strlen(connflag), 1));
printf(">>>write flag =: %d\r\n", aos_kv_set("chongqiflag", &chongqiflag, strlen(chongqiflag), 1));
}
}
flag = 0;
}
}
对了,此次项目中使用alios things中的kv组件,关于kv组件的使用,大家不会的可以看看。再此次项目中其实比较有价值的功能暂时就是这个了,其实整个项目中总共遇到两个难点,当时我们使用的是庆科EMW3080模块,这个模块当时阿里的在alios things2.1.0上没有PWM的驱动,不过最后还是解决了,最终实现了开关5次配网、调冷暖色光、调灯光明亮度等,最后还是有些遗憾,公司没有找到wifi灯的驱动厂商,项目没得进行下去。