Smart Eye Based on DWIN Circular Screen

——From DWIN Developer Forum

The DWIN developer forum open source project recommended for everyone this time is a very interesting routine for simulating the movement of human eyes. The engineer used several human eye picture materials to realize functions such as eyeball movement, blinking, face recognition and following. 

Introduction to open source solutions:

1. UI image material

Editor’s note: DWIN smart screen is based on pictures to complete UI development, which can easily realize various display effects.

dytrgf (1)

2. Interface development

It is relatively simple to develop the interface through DGUS software, and only two graphic controls are needed. In this routine, the engineer chose a 2.1-inch round smart screen.

dytrgf (2)

3. Realize blink animation

Let the pictures of the eyelids be displayed in turn at intervals:

//Blink animation

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(0×3000, (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. Realize the eyeballs look left and right naturally.

This is similar to blinking, but it needs to compare the time of the crystal oscillator to control the eye movement. After many times of debugging, the engineer designed the following set of codes.

//Eyeball animation

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;

    }

//Move left and right

//    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] = 0×00;

        eyeball_pos[1] = eyeball_cnt;

    }

    else

    {

        eyeball_pos[0] = 0xFF;

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

    }    

    write_dgus_vp(0×3111, (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. Add ESP32 face recognition to realize the movement of eyes following the face.

The processing method here is that when the face is detected, the eyes do not move by themselves, and a variable is defined to increment in the while loop. When the increment reaches a certain value, the eyeballs will move by themselves. When the serial port receives data, this variable will be cleared, and then only move the eyes according to the position of the face. The main code is as follows:

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;

    }

}


Post time: Jun-26-2023