【开源】基于迪文屏的智能眼

描述

——来自迪文开发者论坛

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

01

方案简介

1. UI图片素材

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

迪文屏

2.界面开发

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

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();

 

        }

 

}

5.加入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;

 

      }

 

}

 

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

全部0条评论

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

×
20
完善资料,
赚取积分