Olho inteligente baseado em tela circular DWIN

——Do Fórum de Desenvolvedores DWIN

O projeto de código aberto DWIN, recomendado desta vez para todos no fórum de desenvolvedores, é uma rotina muito interessante para simular o movimento dos olhos humanos. O engenheiro utilizou diversas imagens de olhos humanos para implementar funções como movimento ocular, piscadas, reconhecimento facial e seguimento de olhares.

Introdução às soluções de código aberto:

1. Material de imagem da interface do usuário

Nota do editor: A tela inteligente DWIN utiliza imagens para desenvolver a interface do usuário, o que facilita a criação de diversos efeitos de exibição.

dytrgf (1)

2. Desenvolvimento de interface

É relativamente simples desenvolver a interface através do software DGUS, sendo necessários apenas dois controles gráficos. Nesta rotina, o engenheiro optou por uma tela inteligente redonda de 2,1 polegadas.

dytrgf (2)

3. Implementar animação de piscar

Que as imagens das pálpebras sejam exibidas em intervalos regulares:

//Animação de piscar

void blink_animat(void)

{

se(blink_flag == 0)

{

blink_cnt++;

se(contagem_piscada >= 4)

{

blink_flag = 1;

}

}

outro

{

piscar_cnt–;

se(contagem_piscada

{

blink_flag = 0;

}

}

write_dgus_vp(0×3000, (u8 *)&blink_cnt, 2);

}

void blink_run()

{

static u32 run_timer_cnt = 0;

run_timer_cnt++;

se (run_timer_cnt >= 2000000)

{

run_timer_cnt = 0;

piscar_animado();

Atraso_ms(30);

piscar_animado();

Atraso_ms(30);

piscar_animado();

Atraso_ms(30);

piscar_animado();

Atraso_ms(30);

piscar_animado();

Atraso_ms(30);

piscar_animado();

Atraso_ms(30);

piscar_animado();

Atraso_ms(30);

piscar_animado();

Atraso_ms(30);

}

}

4. Perceba que os olhos se movem naturalmente para a esquerda e para a direita.

Isso é semelhante ao piscar de olhos, mas requer a comparação do tempo do oscilador de cristal para controlar o movimento dos olhos. Após várias tentativas de depuração, o engenheiro desenvolveu o seguinte conjunto de códigos.

//Animação de globo ocular

vazio eyeball_animat(vazio)

{

eyeball_timer_cnt++;

se(contagem_temporizador_olho

{

contagem_de_olhos = 20;

}

senão se(eyeball_timer_cnt

{

contagem_de_olhos = 50;

}

senão se(eyeball_timer_cnt

{

contagem_de_olhos = 80;

}

senão se(eyeball_timer_cnt

{

contagem_de_olhos = 94;

}

senão se(eyeball_timer_cnt

{

contagem_de_olhos = 94;

}

senão se(eyeball_timer_cnt

{

contagem_de_olhos = 80;

}

senão se(eyeball_timer_cnt

{

contagem_de_olhos = 50;

}

senão se(eyeball_timer_cnt

{

contagem_de_olhos = 20;

}

senão se(eyeball_timer_cnt

{

contagem_olho = -10;

}

senão se(eyeball_timer_cnt

{

contagem_de_olhos = -40;

}

senão se(eyeball_timer_cnt

{

contagem_de_olhos = -54;

}

senão se(eyeball_timer_cnt

{

contagem_de_olhos = -40;

}

senão se(eyeball_timer_cnt

{

contagem_olho = -10;

}

senão se(eyeball_timer_cnt

{

contagem_de_olhos = 20;

eyeball_timer_cnt = 0;

}

//Mover para a esquerda e para a direita

// se(eyeball_flag == 0)

// {

// eyeball_cnt++;

// se(contagem_de_olhos >= 94)

// {

// eyeball_flag = 1;

// }

// }

// outro

// {

// eyeball_cnt–;

// se (contagem_de_olhos

// {

// eyeball_flag = 0;

// }

// }

se(contagem_de_olhos >= 0)

{

eyeball_pos[0] = 0×00;

posição_olho[1] = contagem_olho;

}

outro

{

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++;

se (run_timer_cnt >= 20000)

{

run_timer_cnt = 0;

animações_do_olho();

}

}

5. Adicionar reconhecimento facial ESP32 para realizar o movimento dos olhos seguindo o rosto.

O método de processamento aqui é o seguinte: quando o rosto é detectado, os olhos não se movem automaticamente. Uma variável é definida para ser incrementada dentro de um laço while. Quando o incremento atinge um determinado valor, os olhos se movem automaticamente. Quando a porta serial recebe dados, essa variável é zerada e, então, os olhos se movem apenas de acordo com a posição do rosto. O código principal é o seguinte:

se(rec_data_timer_cnt

{

rec_data_timer_cnt++;

}

outro

{

eyeball_run();

}

externo u32 rec_data_timer_cnt;

externo u16 eyeball_timer_cnt;

void Communication_CMD(u8 st)

{

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

{

rec_data_timer_cnt = 0;

eyeball_timer_cnt = 0;

#if(Type_Communication==1)

Descreva_8283(st);

#elif(Type_Communication==2)

Descrever_Modbus(st);

#fim

uart[st].Rx_F=0;

uart[st].Rx_Num=0;

}

}


Data da publicação: 26/06/2023