目录
写在前面
小小屏幕
魔改之路
裁出官方Sample的驱屏代码
保存手势识别结果
在主函数中根据手势结果进行屏显控制
效果
在上一章节《CSK6开发分享1-视觉开发套件初体验篇》,我分享了聆思推出的一款视觉AI开发套件的初步体验,体验后也仔细了看下官方文档中的工程讲解和代码,了解到CSK6011芯片具备SPI接口可以用来驱SPI屏幕,且官方SDK也提供了例程,于是心里有了个想法,如果能把手势识别的一些结果在屏幕上做呈现岂不乐哉。于是尝试联系官方活动方,要到了他们一块还是内测验证的屏幕来玩一玩。
跟聆思活动方“借”到的这个屏幕是当前他们还在测试的一个原型机,使用了SPI接口(屏显)+I2C接口(触摸),且官方针对这个屏幕的也提供了一个名为display&kscan的例程和配套的文档讲解。参照文档讲解以及官方提供的屏幕板子硬件引脚定义,我在display_kscan例程的工程目录下增加了一个名为 csk6011a_nano.overlay 的文件,在文件中对屏幕板所用到的引脚进行定义。官方答复说板子正式发布后,对应例程会提供可直接使用的overlay文件的,因此这里我就不陈述如何修改了。因为CSK6的系统用的是Zephyr RTOS,而这个系统通过设备树对硬件进行配置,有兴趣的伙伴可以参考官方关于设备树语法的讲解。
烧录display&kscan例程固件后,可以看到屏幕如期显示出了色块:
OK,屏幕已有,开启魔改。
官方的视觉AI(头肩检测&手势识别)Sample需要连接USB,打开预览工具才可以对手势识别结果进行查看,如果可以通过屏幕直接显示对应的识别结果呢?行,既然始于“色块”,那就先沿用“色块”,改一个根据不同手势显示不同颜色的色块吧!
官方文档中心对display&kscan例程进行了讲解,参照文档阅读下代码,基本很快可以清楚整个例程的流程,官方提供的流程图如下:
我们可以在视觉AI Sample的main.c中增加驱屏所需的一些依赖代码:
// display驱动头文件
#include
// 设备树定义
#if DT_NODE_HAS_STATUS(DT_INST(0, sitronix_st7789v), okay)
#define DISPLAY_DEV_NAME DT_LABEL(DT_INST(0, sitronix_st7789v))
#endif
void main(){
……
// 一些屏显功能变量定义
uint8_t *buf;
int32_t grey_scale_sleep;
const struct device *display_dev;
struct display_capabilities capabilities;
struct display_buffer_descriptor buf_desc;
size_t buf_size = 0;
……
}
在往视觉Sample加入驱屏相关定义时,可以尝试在main中运行起屏显例程中的色块,已检查依赖的代码已移植完毕。
新增了一个全局变量 gesture_status,用于记录视觉AI Sample中 on_receive_hsd_result 回调函数的的手势识别结果
void on_receive_hsd_result(…){
……
else if (event == HSD_EVENT_GESTURE_RECOGNIZE){
……
gesture_status = result->gesture_state;// 保存识别结果,用于下文处理
}
}
在主函数的while(1)循环中,我们判断手势的切换状态,为避免未识别到手势时带来的抖动,我们对未识别到手势时(手势状态=other)进行过滤:
// 检测到手势发生变化,且属于被识别到的有效手势
if((gesture_status != GESTURE_OTHER) && (gesture_status != recently_gesture))
{
recently_gesture = gesture_status;
printk("changge!!!!!!!!!!%d \n",recently_gesture);
// 根据不同手势,将屏显buffer填充为不同的颜色
switch (recently_gesture) {
case GESTURE_LIKE:
(void)memset(buf, 0xFF00u, buf_size);// 黑
break;
case GESTURE_OK:
(void)memset(buf, 0xFF77u, buf_size);// 绿
break;
case GESTURE_STOP:
(void)memset(buf, 0x3388u, buf_size);// 粉
break;
case GESTURE_YES:
(void)memset(buf, 0x5511u, buf_size);// 蓝
break;
case GESTURE_SIX:
(void)memset(buf, 0x00FFu, buf_size);// 白
break;
}
buf_desc.buf_size = buf_size;
buf_desc.pitch = capabilities.x_resolution;
buf_desc.width = capabilities.x_resolution;
buf_desc.height = h_step;
// 绘制整块屏幕
for (int idx = 0; idx < capabilities.y_resolution; idx += h_step) {
display_write(display_dev, 0, idx, &buf_desc, buf);
}
这样我们就实现了根据不同手势,实时控制屏幕显示不同的颜色。