Smart Touch and Gesture System Based on RT-Thread and Infineon Psoc6-evaluationkit-062S2 | Technical Collection
This article is contributed by ljcjames.
1 Capacitive Touch Interface
Using the CapSense module of Psoc6-evaluationkit-062S2 to design an interactive touch panel.
Through the touch panel, the PWM frequency can be adjusted to make the buzzer play different tones (need to map do (1), re (2), mi (3), fa (4) notes) + adjust the PWM signal duty cycle to control the LED indicator.
1.1 Capsense Touch
Modified based on the Slider example, determine notes and gestures according to the touch position (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);
}Get sensor id, determine one by one whether it is activated, and return the 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;
}
}
}Scan every 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 Tone Playback
Change PWM settings to play tones, calculate the period, set 20% duty cycle.
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);
}Stop playing 0.2s after no touch.
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 Screen Display
The touch response time must be ≤100ms, and the triggered command must be displayed on the OLED screen (resolution ≥128x64 pixels), clearly marking the touch area and operation.
Using the ssd1306 software package, displaying note, touch area id, gesture respectively.
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);
}Display time
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 Control with Sliding
The duty cycle of PWM can be adjusted through the touch panel to control the LED indicator brightness.
Using PWM
rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, 1 * 1000 * 1000, GET_DUTY_CYCLE(brightness));
}Other pins can be changed.
2 Gesture Recognition
Use the CapSense module to recognize 2 different gestures (swipe left, swipe right).
Since this development board uses a slider linear bar, in the CapSense component, only the touchpad widget supports gesture function. Therefore, by recording the last 3 touch positions (x), simply judge whether it is a gesture.
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 Network Synchronization
Use the MQTT protocol through the network module to synchronize NTP time and display it on the OLED (format: YYYY-MM-DD HHMMSS). And transmit touch and gesture data (including: touch area ID, gesture type) to the server for display.
3.1 rw007
3.2 mqtt
Using the pahomqtt package, refer to the mqtt_start function in the sample.
Set macros such as 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"You can connect mqtt after waiting for network connection.
intcheck_network(void)
{
structnetdev *netdev = netdev_get_by_family(AF_INET);
return (netdev && netdev_is_link_up(netdev) /* && netdev_is_internet_up(netdev) */);
}Use the RyanJson package to generate json data and send via mqtt to the corresponding 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
Enable ntp in the netutils package.
Update time every second.
staticvoidtime_thread_entry(void *parameter)
{
structtm *tm;
while (1)
{
// Get current time
time_t now =time(NULL);
tm = localtime(&now); // Use UTC time
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", tm);
screen_show_time(time_buf);
// Thread sleep 1 second
rt_thread_mdelay(1000);
}
}4 RTduino Usage
4.1 RT-Thread Multitasking Integration
Use Psoc6’s RTduino support (Arduino compatible ecosystem of RT-Thread) to implement real-time touch and gesture processing.
4.2 Use Functions in .c File
applications/arduino_main.cpp: : undefined reference to ` ‘
When calling functions from other files in arduino_main.cpp, an undefined error is reported. You need to add extern “C” in the corresponding header file.
#ifdef __cplusplus
extern"C"
{
#endif
#ifdef __cplusplus
}
#endif5 Usage Method
5.1 Thread Usage
● buzzer thread, used to stop playing tones
● time thread, used to update screen display time
● rtduino loop, used for touch recognition and data processing display
● mqtt thread, used to wait for network connection and start mqtt client
5.2 Software Package Usage
6 Project Source Code
Gitee repository address(https://gitee.com/dgjames/psoc6project)
RT-Thread Github open-source repository, welcome to give a star (Star) support, and look forward to your code contribution: https://github.com/RT-Thread/rt-thread
