开源 | 基于迪文圆形屏的智能眼

——来自迪文开发者论坛

本次为大家推荐的迪文开发者论坛开源项目是一个很有意思的模拟人眼跟随运动的例程工程师使用几张人眼图片素材,实现了眼珠运动、眨眼、人脸识别和跟随等功能,让我们一睹为快:

演示视频


    完整开发资料含迪文屏DGUS工程资料与代码,可前往迪文开发者论坛获取:http://inforum.dwin.com.cn:20080/forum.php?mod=viewthread&tid=8175&extra=page%3D1

 

【开源方案简介】

1. UI图片素材

编者注:迪文智能屏是基于图片来完成UI开发的,可以便捷的实现各类显示效果。

1.(智能眼)

2. 界面的开发

通过DGUS软件开发界面比较简单,只需要两个图形控件即可。在该例程中,工程师选择了一款2.1寸圆形智能屏

2.(智能眼)

3. 实现眨眼动画

隔一段时间让眼皮的图片轮流显示一下:

 

//眨眼动画

void blink_animat(void)

{

    if(blink_flag == 0)

    {

        blink_cnt++;

        if(blink_cnt >= 4)

        {

            blink_flag = 1;

        }

    }

    else

    {

        blink_cnt--;

        if(blink_cnt <= 0)

        {

            blink_flag = 0;

        }

    }

   

    write_dgus_vp(0x3000, (u8 *)&blink_cnt, 2);

}

 

void blink_run()

{

    static u32 run_timer_cnt = 0;

    run_timer_cnt++;

    if(run_timer_cnt >= 2000000)

    {

        run_timer_cnt = 0;

        blink_animat();

        Delay_ms(30);

        blink_animat();

        Delay_ms(30);

        blink_animat();

        Delay_ms(30);

        blink_animat();

        Delay_ms(30);

        blink_animat();

        Delay_ms(30);

        blink_animat();

        Delay_ms(30);

        blink_animat();

        Delay_ms(30);

        blink_animat();

        Delay_ms(30);  

    }

}


4. 实现眼珠自然左右看

这里和眨眼类似,但是需要比较晶振的控制眼球运动的时间,这里经过多次调试,工程师设计出了下面这套代码。

 

//眼珠动画

void eyeball_animat(void)

{

    eyeball_timer_cnt++;

 

    if(eyeball_timer_cnt < 50)

    {

        eyeball_cnt = 20;

    }

    else if(eyeball_timer_cnt < 51)

    {

        eyeball_cnt = 50;

    }

    else if(eyeball_timer_cnt < 52)

    {

        eyeball_cnt = 80;

    }

    else if(eyeball_timer_cnt < 53)

    {

        eyeball_cnt = 94;

    }

    else if(eyeball_timer_cnt < 103)

    {

        eyeball_cnt = 94;

    }

    else if(eyeball_timer_cnt < 104)

    {

        eyeball_cnt = 80;

    }

    else if(eyeball_timer_cnt < 105)

    {

        eyeball_cnt = 50;

    }

    else if(eyeball_timer_cnt < 106)

    {

        eyeball_cnt = 20;

    }

    else if(eyeball_timer_cnt < 107)

    {

        eyeball_cnt = -10;

    }

    else if(eyeball_timer_cnt < 108)

    {

        eyeball_cnt = -40;

    }

    else if(eyeball_timer_cnt < 158)

    {

        eyeball_cnt = -54;

    }

    else if(eyeball_timer_cnt < 159)

    {

        eyeball_cnt = -40;

    }

    else if(eyeball_timer_cnt < 160)

    {

        eyeball_cnt = -10;

    }

    else if(eyeball_timer_cnt < 161)

    {

        eyeball_cnt = 20;

        eyeball_timer_cnt = 0;

    }

    //左右移动

//    if(eyeball_flag == 0)

//    {

//        eyeball_cnt++;

//        if(eyeball_cnt >= 94)

//        {

//            eyeball_flag = 1;

//        }

//    }

//    else

//    {

//        eyeball_cnt--;

//        if(eyeball_cnt <= -54)

//        {

//            eyeball_flag = 0;

//        }

//    }

 

    if(eyeball_cnt >= 0)

    {

        eyeball_pos[0] = 0x00;

        eyeball_pos[1] = eyeball_cnt;

    }

    else

    {

        eyeball_pos[0] = 0xFF;

        eyeball_pos[1] = (eyeball_cnt & 0xFF);

    }

   

   

    write_dgus_vp(0x3111, (u8 *)&eyeball_pos, 2);

}

 

void eyeball_run()

{

    static u32 run_timer_cnt = 0;

    run_timer_cnt++;

    if(run_timer_cnt >= 20000)

    {

        run_timer_cnt = 0;

        eyeball_animat();

    }

}

 

3. 加入ESP32人脸识别,实现眼珠跟随人脸运动

这里的处理方法是,检测到人脸的时候眼睛自己不运动了,定义一个变量在while循环中自增,当自增到一定数值时,眼珠就自己运动。当串口收到数据时,这个变量就清零,然后只根据人脸的位置进行眼睛的移动。主要代码如下:

 

if(rec_data_timer_cnt < 1000000)

        {

            rec_data_timer_cnt++;

        }

        else

        {

            eyeball_run();

        }

 

extern u32 rec_data_timer_cnt;

extern u16 eyeball_timer_cnt;

void Communication_CMD(u8 st)

{

        if((uart[st].Rx_F==1 )&&(uart[st].Rx_T==0))

    {

        rec_data_timer_cnt = 0;

        eyeball_timer_cnt = 0;                                                       

#if(Type_Communication==1)               

        Describe_8283(st);

#elif(Type_Communication==2)               

        Describe_Modbus(st);

#endif                                       

        uart[st].Rx_F=0;

        uart[st].Rx_Num=0;

    }

}