前言

本文主要内容是实现烧水壶的触摸按键驱动,触摸按键芯片选用TS02N。

一、智能烧水壶按键功能设定

  • 智能烧水壶的按键功能设定如下,实现功能之前,我们首先要实现按键采集芯片的驱动。
功能 说明
煮沸 触摸按键1,触发方式:轻触。默认煮沸。
触摸按键控制煮沸键 按下开启,再按关闭
app控制:煮沸
保温键 触摸按键1,触发方式:轻触
轻触进入默认的自来水模式下的55度保温模式,按下开启,再按关闭
长按5s进入配网模式
不操作,app也无操作,默认凉白开模式

二、按键采集的方案制定

1.硬件电路图

  • 按键采集电路如下:

  • TS02N使用说明

     输入P1\P2:低电平触发

     P1触发后OUT1输出低电平

     P2触发后OUT2输出低电平

    通信引脚设定:

OUT1 | P7    煮沸键
OUT2    | P8    保温键

2.嵌入式方案设定

为了后期的程序扩展,采用回调函数注册的方式实现按键控制。

1.按键按下时,按键指示灯亮,按键松开,按键指示灯灭;按一次按键蜂鸣器响一下
2.可以使用注册函数直接注册所用IO口,以及注册按键按下触发的回调函数
3.可以设置长按时间,配置按键长按触发的回调函数

三、功能实现

1.代码实现

  • 在之前开发的基础上增加程序,增加ts02n_key.c文件和其头文件,目前整个工程的文件结构如下:
├── src
|    ├── tuya_drive
|    |      └── b3950
|    |          └── b3950.c           //温度传感器驱动相关
|    |      └── gpio_control
|    |          └── gpio_control.c           //gpio 控制相关
|    |      └── ts02n_key
|    |          └── ts02n_key.c           //按键驱动
|    |      └── timer
|    |          └── timer.c           //定时器相关
|    ├── tuya_device.c             //应用层入口文件
|    └── kettle_app.c            //智能烧水壶主要应用文件
|
├── include             //头文件目录
|    ├── tuya_drive_h
|    |      └── b3950_h
|    |          └── b3950.h
|    |      └── gpio_control_h
|    |          └── gpio_control.h
|    |      └── ts02n_key_h
|    |          └── ts02n_key.h           //按键驱动
|    |      └── timer_h
|    |          └── timer.h           //定时器相关
|    ├── tuya_device.h
|    └── kettle_app.h
|
└── output              //编译产物

ts02n_key.c中函数实现如下:主要内容是实现扫描函数,根据传入的配置参数进行初始化

/*使用时只需要通过ts02n_key_init(TS02N_KEY_DEF_S* user_key_def)函数进行注册,注册后会自动开启一个定时扫描任务去采集按键信息,按键触发后也会自动调用注册的回调函数*/
typedef VOID(* KEY_CALLBACK)();
typedef struct {   // user defineunsigned int key_pin1; //ts02n CH1 PINunsigned int key_pin2; //ts02n CH2 PINKEY_CALLBACK key1_cb;  //normal press key1 callback functionKEY_CALLBACK key2_cb;  //normal press key2 callback functionKEY_CALLBACK key1_long_press_cb;  //normal press key1 callback functionKEY_CALLBACK key2_long_press_cb;  //normal press key2 callback functionKEY_CALLBACK key1_Low_level_cb;  //Key1 low level process callback functionKEY_CALLBACK key2_Low_level_cb;  //Key2 low level process callback functionunsigned int long_time_set; //long press key time setunsigned int scan_time; //Scan cycle set   unit: ms}TS02N_KEY_DEF_S;typedef struct {unsigned int down_time; //记录按键按下的时间unsigned char status;   }KEY_PRESS_STATUS_S;typedef struct {TS02N_KEY_DEF_S* ts02n_def_s;//用户注册的相关信息,回调函数,pin口等KEY_PRESS_STATUS_S key_status;
}TS02N_KEY_MANAGE_S;
/* Private function prototypes -----------------------------------------------*/
static int key_scan();
static void key_timer_cb();/* Private variables ---------------------------------------------------------*/
static TIMER_ID key_timer;
static TS02N_KEY_MANAGE_S *key_mag = NULL;
enum KEY_STAT_E{KEY1_UP = 0,KEY1_DOWN,KEY1_FINISH,KEY2_UP,KEY2_DOWN,KEY2_FINISH,
};enum KEY_PRESS_STAT{KEY1_NORMAL_PRESS = 0,KEY2_NORMAL_PRESS, KEY1_LONG_PRESS,KEY2_LONG_PRESS,NO_KEY_PRESS,
};/* Private functions ---------------------------------------------------------*/
/*** @Function: ts02n_key_init* @Description: key init * @Input: none* @Output: none* @Return: none* @Others: */
int ts02n_key_init(TS02N_KEY_DEF_S* user_key_def)
{int op_ret = 0;key_mag = (TS02N_KEY_MANAGE_S *)Malloc(SIZEOF(TS02N_KEY_MANAGE_S));memset(key_mag, 0, SIZEOF(TS02N_KEY_MANAGE_S));//No callback function is registered    key init errif((user_key_def->key1_cb == NULL) && (user_key_def->key2_cb == NULL) && \(user_key_def->key1_long_press_cb == NULL) && (user_key_def->key2_long_press_cb == NULL)){return KEY_INIT_ERR;}//key pin init tuya_pin_init(user_key_def->key_pin1, TUYA_PIN_MODE_IN_PU);tuya_pin_init(user_key_def->key_pin2, TUYA_PIN_MODE_IN_PU);//get user definekey_mag->ts02n_def_s = user_key_def;//creat key scan handle timerop_ret = sys_add_timer(key_timer_cb,NULL,&key_timer);if(op_ret != KEY_INIT_OK) {return KEY_INIT_ERR;PR_ERR("add timer err");}op_ret = sys_start_timer(key_timer,key_mag->ts02n_def_s->scan_time,TIMER_CYCLE);if(op_ret != KEY_INIT_OK) {return KEY_INIT_ERR;PR_ERR("start timer err");}}
/*** @Function: key_timer_cb* @Description: Timing key scan processing function* @Input: none* @Output: none* @Return: none* @Others: */
static void key_timer_cb()
{int ret = -1;//get key press statusret = key_scan();switch (ret) {case KEY1_NORMAL_PRESS: {key_mag->ts02n_def_s->key1_cb();}break;case KEY1_LONG_PRESS: {key_mag->ts02n_def_s->key1_long_press_cb();}break;case KEY2_NORMAL_PRESS: {key_mag->ts02n_def_s->key2_cb();}break;case KEY2_LONG_PRESS: {key_mag->ts02n_def_s->key2_long_press_cb();}break;default:break;}
}
/*** @Function: key_scan* @Description: key scan handle function* @Input: none* @Output: none* @Return: none* @Others: */
static int key_scan()
{if((tuya_pin_read(key_mag->ts02n_def_s->key_pin1) == 0) && (tuya_pin_read(key_mag->ts02n_def_s->key_pin2) == 0 )) {return NO_KEY_PRESS;}if(tuya_pin_read(key_mag->ts02n_def_s->key_pin1) == 0 ) {key_mag->ts02n_def_s->key1_Low_level_cb();key_mag->key_status.status = KEY1_DOWN;key_mag->key_status.down_time += key_mag->ts02n_def_s->scan_time;if(key_mag->key_status.down_time >= key_mag->ts02n_def_s->long_time_set) {key_mag->key_status.status = KEY1_FINISH;}}else {if(key_mag->key_status.status == KEY1_DOWN) {key_mag->key_status.status = KEY1_FINISH;}}if(tuya_pin_read(key_mag->ts02n_def_s->key_pin2) == 0 ) {key_mag->ts02n_def_s->key2_Low_level_cb();key_mag->key_status.status = KEY2_DOWN;key_mag->key_status.down_time += key_mag->ts02n_def_s->scan_time;if(key_mag->key_status.down_time >= key_mag->ts02n_def_s->long_time_set) {key_mag->key_status.status = KEY2_FINISH;}}else {if(key_mag->key_status.status == KEY2_DOWN) {key_mag->key_status.status = KEY2_FINISH;}}switch (key_mag->key_status.status) {case (KEY1_FINISH): {if(key_mag->key_status.down_time >= key_mag->ts02n_def_s->long_time_set) {PR_DEBUG("key_pin1 long press");key_mag->key_status.down_time = 0;key_mag->key_status.status = KEY1_UP;return KEY1_LONG_PRESS;}else {key_mag->key_status.status = KEY1_UP;key_mag->key_status.down_time = 0;PR_DEBUG("key_pin1 press");return KEY1_NORMAL_PRESS;}}break;case (KEY2_FINISH): {if(key_mag->key_status.down_time >= key_mag->ts02n_def_s->long_time_set) {PR_DEBUG("key_pin2 long press");key_mag->key_status.down_time = 0;key_mag->key_status.status = KEY2_UP;return KEY2_LONG_PRESS;}else {key_mag->key_status.status = KEY2_UP;key_mag->key_status.down_time = 0;PR_DEBUG("key_pin2 press");return KEY2_NORMAL_PRESS;}}break;default:return NO_KEY_PRESS;break;}}
  • kettle_app.c文件中初始化按键,并注册回调函数,其中一些设置烧水壶状态的函数可以先不看,后面文章会说明
TS02N_KEY_DEF_S kettle_key_def_s = {.key_pin1 = TY_GPIOA_8,.key_pin2 = TY_GPIOA_7,.key1_cb = key1_cb_fun,.key2_cb = key2_cb_fun,.key1_long_press_cb = NULL,.key2_long_press_cb = key2_long_press_cb_fun,.key1_Low_level_cb = key1_Low_level_cb_fun,.key2_Low_level_cb = key2_Low_level_cb_fun,.long_time_set = 5000,.scan_time = 100,
};
VOID_T kettle_init()
{b3950_init();thread_init();kettle_gpio_init();ts02n_key_init(&kettle_key_def_s);//注册按键并初始化
}//煮沸键按下再松开后触发
void key1_cb_fun()
{   //Button press promptled1_set(OFF);buzzer_flag = 1;//Button press promptif(get_kettle_work_status() == boil) { //if current status is boil, close boiling set_kettle_work_status(nature);set_dp_boil_value(FALSE);report_one_dp_status(DP_BOIL);}else {set_kettle_work_status(boil);set_dp_boil_value(TRUE);report_one_dp_status(DP_BOIL);}}
//保温键按下再松开后触发
void key2_cb_fun()
{//Button press promptled2_set(OFF);buzzer_flag = 1;//Button press promptif(get_kettle_work_status() == keep_warm_mode1) {//if current status is keep_warm_mode1,turn off insulation functionset_kettle_work_status(nature);set_dp_keep_warm_switch(0);report_one_dp_status(DP_KEEP_WARM);}else {set_kettle_work_status(keep_warm_mode1);//tap water warm mode :1.boil -> 2.keep warmset_kettle_keep_warm_temper(Default_Warm_Temperature);set_dp_keep_warm_switch(1);report_one_dp_status(DP_KEEP_WARM);report_one_dp_status(DP_TEMP_SET);}}
//保温键长按5s触发,进行配网模式
void key2_long_press_cb_fun()
{led2_set(OFF);tuya_iot_wf_gw_unactive();buzzer_flag = 1;}
//按键按下时触发
void key1_Low_level_cb_fun()
{PR_DEBUG("key1_Low_level_cb");led1_set(ON);if(buzzer_flag) {timer_init();//蜂鸣器响一下buzzer_flag = 0;}}
//按键按下时触发
void key2_Low_level_cb_fun()
{led2_set(ON);PR_DEBUG("key2_Low_level_cb");if(buzzer_flag) {timer_init();//蜂鸣器响一下buzzer_flag = 0;}
}
  • 此时智能烧水壶的按键驱动功能已经实现了,其他功能实现请见后续文章。

下篇文章快速入口:
智能烧水壶(WIFI版)05——水温调节和灯光提示功能实现篇

技术支持

您可以通过以下方法获得涂鸦的支持:

  • 涂鸦智能IoT平台
  • Demo中心
  • 涂鸦智能开发者平台

智能烧水壶(WIFI版)04——TS02N触摸按键驱动篇相关推荐

  1. 智能烧水壶(WIFI版)01——硬件设计篇

    一.概述 烧可饮用热水应该是大部分人生活中必不可少的一部分,但往往会发生想喝的时候来不及烧,烧完之后长时间未饮用,水变凉的尴尬情况.这时候如果拥有一款智能恒温烧水壶,可远程控制,支持保温模式还可支持预 ...

  2. 智能烧水壶(WIFI版)05——水温调节和灯光提示功能实现篇

    前言 前面我们已经实现了烧水壶的按键功能,本文将实现烧水壶的煮沸.保温功能.灯光提示功能,同时实现按键触发烧水和煮沸. 一.智能烧水壶功能设定 智能烧水壶的煮沸功能.保温功能.灯光指示以及按键控制功能 ...

  3. 智能烧水壶(Bluetooth LE版)——硬件设计篇

    一.概述 前面已经设计了一款Wi-Fi控制的智能烧水壶,为了满足不同使用群体的需求,又设计了一款蓝牙控制的智能烧水壶,硬件电路上兼容,只需要把Wi-Fi模块换成Bluetooth LE模块即可. 1. ...

  4. wifi卡慢延迟高_健康生活好助手:华为智能体脂秤 WiFi 版 体验评测

    点击右上角关注我们,每天给您带来最新最潮的科技资讯,让您足不出户也知道科技圈大事! 为了让自己严格执行减肥计划,一台体脂秤是肯定少不了的,只有时刻记住那个沉重的数字,管住嘴.迈开腿才会有动力. 不过随 ...

  5. 十分钟开发物联网:智能加湿器(Wifi版)

    智能加湿器设备集成了温湿度传感器.加湿器控制单元.以及Wifi传输模块,ShineBlink万能核心板采集温湿度传感器数据,并将它们上传至机智云,然后我们就可以在远程通过手机App或者Web网页端来访 ...

  6. 微型计算机智能体重评测,荣耀智能体脂秤WiFi版评测:17项身体指标 比你更懂你...

    本帖最后由 艾玛伍兹122 于 2019-8-16 16:45 编辑 2.不正经搞机社-660x200.jpg (104.36 KB, 下载次数: 0) 2019-8-16 16:25 上传 现代生活 ...

  7. 微型计算机智能体重评测,华为智能体脂秤WiFi版评测:17项身体指标秒知道 与肥胖生活断舍离...

    压力测试 现代人正处于高压的社会工作环境下,作为曾经体验过华为手环压力测试的小编我,惊喜的发现华为智能体脂秤WiFi版竟然支持压力检测! 这项功能是华为与中国科学院心理研究所联合研发,基于心率变异性( ...

  8. 智能恒温水壶系统设计_如何安装和设置Ecobee智能恒温器

    智能恒温水壶系统设计 A smart thermostat is a great accessory to have in your house, not only to be able to adj ...

  9. WT588F02KD-24SS语音芯片(数码管显示驱动ic)在多功能烧水壶的应用设计方案

    WT588F02KD-24SS语音芯片(数码管显示驱动ic)在多功能烧水壶的应用设计方案 现代人除了写字楼及个别家庭在使用饮水机消费纯净水或蒸馏水外,大多数的家庭仍然是饮用烧开的自来水.而早前流行于欧 ...

最新文章

  1. 网络营销外包期间站长如何挖掘用户真实需求探索网络营销外包真谛
  2. administrator没有管理员权限_网络安全 之 NTFS安全权限
  3. 10.1.3 标签分类与嵌套
  4. 20 CO配置-控制-产品成本控制-产品成本计划编制-定义成本核算变式
  5. Google I/O 2019 行纪 —— Google 要让 AI 消除偏见
  6. 视频编解码(八):264/265解码器小结
  7. java之StringBuffer
  8. sap 打印预览界面点击打印时记录打印次数_9个Excel打印神技巧!从此打印不求人!...
  9. java web 上传图片_java web图片上传和文件上传实例
  10. native数据类型 react_React-Native 之 数据持久化
  11. 部分 MP4 视频在谷歌浏览器无法播放
  12. 华为云的云计算比阿里云的云计算认证好吗?
  13. oracle 同义词public,oracle中private同义词跟public同义词
  14. C语言初学者环境配置
  15. 利用装饰器模拟博客园登陆
  16. html5鼠标悬停图片放大的原理,jQuery当鼠标悬停时放大图片的效果实例
  17. 树上统计——基于树的搜索
  18. 上海交大校长张杰院士:大学,重新定义你的人生
  19. Could not set property 'xxxxxx' of 'xxxxxx' with value 'xxxxx'
  20. 小米平板4能装Linux系统吗,终于迎来它!小米平板4进行重大更新

热门文章

  1. ogre for wind7的自我娱乐
  2. 第十七届全国大学生智能车竞赛华南赛区比赛成绩
  3. Android图片加载Glide框架使用详解
  4. 【校园卡】最后一周!校园卡最近消息:2020校园卡10月底停售!
  5. mysql中如何调整列的顺序,SQL Server 数据库调整表中列的顺序操作
  6. android常驻型广播,Android 常驻广播和非常驻广播
  7. 快速排序 算法 详解 及 深度优化
  8. redis当成数据库使用,时间范围查询
  9. tp5结合es6.x的基本用法
  10. 计算机英语ppt演讲稿,英语ppt演讲稿