基于RT-Thread与英飞凌Psoc6-evaluationkit-062S2的智能触摸与手势系统 | 技术集结

描述

目录

 


 

电容触摸界面


 

手势识别


 

网络同步


 

RTduino使用


 

使用方法


 

项目源码

1 电容触摸界面 


 

利用 Psoc6-evaluationkit-062S2 的 CapSense 模块设计一个交互式触摸面板。

可以通过触摸面板调 整PWM的频率使蜂鸣器播放不同的音调(需要映射do (1), re (2), mi (3), fa (4) 音符)+ 调整 PWM 信号的占空比控制 LED 指示灯。

1.1 Capsense触控

在Slider例程上修改,根据触摸位置(x)判断音符、手势

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

  slider_touch_info = CyCapSense_GetTouchInfo(CY_CAPSENSE_LINEARSLIDER0_WDGT_ID, &cy_capsense_context);  slider_touch_status = slider_touch_info->numPosition;  slider_pos = slider_touch_info->ptrPosition->x;  int x=slider_pos;  if (RT_NULL != slider_touch_status)  {      int senor_id=detect_sensor_id();      char *gesture=detect_gesture(x);      int now_note_id=detect_note(x);      screen_show_info(now_note_id,senor_id,gesture);      rt_event_send(&buzzer_event, EVENT_TOUCH);      message_json(senor_id, gesture);  }

获取sensor id,逐个判断是否激活,返回id

  •  

Cy_CapSense_IsSensorActive(CY_CAPSENSE_LINEARSLIDER0_WDGT_ID,i,&cy_capsense_context

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

intdetect_sensor_id(){    for(int i=0;i<4;i++)    {        if(Cy_CapSense_IsSensorActive\(CY_CAPSENSE_LINEARSLIDER0_WDGT_ID,i,&cy_capsense_context))        {            return i;        }    }  }

10ms扫描一次

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

voidloop(void){    /* put your main code here, to run repeatedly: */    rt_sem_take(trans_done_semphr, RT_WAITING_FOREVER);    /* Process all widgets */    Cy_CapSense_ProcessAllWidgets(&cy_capsense_context);    /* Process touch input */    process_touch();    /* Establishes synchronized operation between the CapSense     * middleware and the CapSense Tuner tool.     */    Cy_CapSense_RunTuner(&cy_capsense_context);    /* Initiate next scan */    Cy_CapSense_ScanAllWidgets(&cy_capsense_context);    rt_thread_mdelay(10);}

1.2 音调播放

英飞凌

改变pwm设置播放音调,求出周期,设置20%的占空比

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

int notes[] = {1, 262, 294, 330, 349, 392, 440, 494};structrt_eventbuzzer_event;//int pre_note=0;voidset_notes(int i){    uint32_t period_ns = 1000000000 / notes[i]; // ns    uint32_t pulse_ns = period_ns * 0.2;        // 20%        rt_pwm_set(buzzer_pwm, PWM_DEV_CHANNEL, period_ns, pulse_ns);    rt_pwm_enable(buzzer_pwm, PWM_DEV_CHANNEL);}

没触摸0.2s后停止播放

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

voidbuzzer_entry(void *parament){    rt_uint32_t e;    while (1)    {        if(rt_event_recv(&buzzer_event, EVENT_TOUCH,RT_EVENT_FLAG_AND|RT_EVENT_FLAG_CLEAR, 0,&e)!=RT_EOK)        {            rt_pwm_disable(buzzer_pwm, PWM_DEV_CHANNEL);        }        rt_thread_mdelay(200);    }}

1.3 屏幕显示

英飞凌

触摸响应时间必须≤100ms,并且触发的命令须显示在 OLED 屏幕上(分辨率≥128x64 像素),并清晰标识触摸区域和操作。

使用ssd1306软件包,分别显示了音符,触摸区域id,手势

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

voidscreen_show_info(int note,int id,char *gesture){  rt_mutex_take(screen_mutex, RT_WAITING_FOREVER);  ssd1306_SetCursor(2, 15);  ssd1306_WriteString(note_str[note], Font_7x10, White);  ssd1306_SetCursor(20, 15);  ssd1306_WriteChar(id+'0', Font_7x10, White);  ssd1306_SetCursor(2, 30);  ssd1306_WriteString(gesture, Font_7x10, White);  ssd1306_UpdateScreen();  rt_mutex_release(screen_mutex);}

显示时间
 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

voidscreen_show_time(char *time){  rt_mutex_take(screen_mutex, RT_WAITING_FOREVER);  ssd1306_SetCursor(2, 0);  ssd1306_WriteString(time, Font_6x8, White);  ssd1306_UpdateScreen();  rt_mutex_release(screen_mutex);}

1.4 LED随滑动控制

可以通过触摸面板调整PWM的占空比控制 LED 指示灯的亮度。

使用pwm

  •  
  •  

rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, 1 * 1000 * 1000, GET_DUTY_CYCLE(brightness));  }

可以更改其它引脚

英飞凌英飞凌英飞凌

2 手势识别


 

使用 CapSense 模块实现 2 种不同手势的识别(向左滑动、向右滑动)。

由于本开发板上的是slider线性滑条,在CapSense组件中,只有触摸板widget支持手势功能。所以通过记录最近3次触摸位置(x),简单判断是否为手势

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

char *detect_gesture(int num){    staticint val[3] = {0};    val[0] = val[1];    val[1] = val[2];    val[2] = num;    rt_kprintf("val: %d %d %d\n", val[0], val[1], val[2]);    char *gesture = "";        if (ORDER(val[0], val[1], val[2]))    {        rt_kprintf("left\n");                gesture = "left ";    }    elseif (ORDER(val[2], val[1], val[0]))    {        rt_kprintf("right\n");        gesture = "right";            }    else    {        gesture = "     ";    }    return gesture;}

3  网络同步


 

通过网络模块使用MQTT协议同步NTP时间并显示到OLED上(格式:YYYY-MM-DD HHMMSS)。并将触摸和手势数据(包括:触摸区域 ID、手势类型)传输到服务器端显示。

3.1 rw007

英飞凌

英飞凌

3.2 mqtt

使用pahomqtt软件包, 使用参考样例的mqtt_start函数

设置好topic等宏

  •  
  •  
  •  
  •  
  •  
  •  

#define MQTT_URI "tcp://broker.emqx.io:1883"#define MQTT_SUBTOPIC "abc/sub"#define MQTT_PUBTOPIC "abc/pub"#define MQTT_WILLMSG "Goodbye!"#define MQTT_USERNAME "name"#define MQTT_PASSWORD "password"

英飞凌

可以等待网络连接后再连接mqtt

  •  
  •  
  •  
  •  
  •  

intcheck_network(void){  structnetdev *netdev = netdev_get_by_family(AF_INET);  return (netdev && netdev_is_link_up(netdev) /* && netdev_is_internet_up(netdev) */);}

用RyanJson软件包生成json数据,mqtt发送到相应的topic

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

char *message_json(int touch_area_id, char *gesture_type)
{    RyanJson_t root;    root = RyanJsonCreateObject();    RyanJsonAddIntToObject(root, "Touch area ID", touch_area_id);    RyanJsonAddStringToObject(root, "Gesture type",gesture_type );    rt_uint32_t len;    tmp_json = RyanJsonPrint(root, 650, RyanJsonTrue, &len);    int ret = paho_mqtt_publish(&client, QOS1, MQTT_PUBTOPIC, tmp_json);        rt_kprintf("json:%s\n",tmp_json);        RyanJsonDelete(root);    return tmp_json;}

3.3 ntp

在netutils软件包中使能ntp

每秒更新时间

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

staticvoidtime_thread_entry(void *parameter){   structtm *tm;   while (1)   {       // 获取当前时间        time_t now =time(NULL);                tm = localtime(&now); // 使用UTC时间                strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", tm);        screen_show_time(time_buf);       // 线程睡眠1秒钟       rt_thread_mdelay(1000);   }}

4 RTduino使用


 

4.1 RT-Thread多任务集成

利用 Psoc6 的 RTduino 支持(RT-Thread 的 Arduino 兼容生态系统)来实现实时触摸和手势处理

英飞凌

4.2 使用.c文件中的函数

  •  

applications/arduino_main.cpp: : undefined reference to `'

在arduino_main.cpp中调用其它文件的函数时,提示说未定义,要在对应头文件中添加extern "C"

  •  
  •  
  •  
  •  
  •  
  •  
  •  

#ifdef __cplusplusextern"C"{#endif#ifdef __cplusplus}#endif

5 使用方法


 

5.1 线程使用

buzzer线程,用于停止播放音调

 time线程,用于更新屏幕显示时间

 rtduino loop,用于触摸识别,与数据处理显示

mqtt线程,用于等待网络连接和启动mqtt客户端

5.2 软件包使用

英飞凌

6 项目源码


 

Gitee仓库地址(https://gitee.com/dgjames/psoc6project

RT-Thread Github 开源仓库,欢迎撒个星(Star)支持,更期待你的代码贡献: https://github.com/RT-Thread/rt-thread

 

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分