Manual

do

Maker

.

com

Urna eletrônica com display Nextion

Urna eletrônica com display Nextion

Melhor já começar esclarecer antes que se inicie uma celeuma por aí. O propósito desse artigo é mostrar uma comunicação com dados recebidos pela serial de forma passiva. Essa simulação tem fim exclusivo de tutorial do display e a urna eletrônica simulada aqui passa a milhares de anos luz do funcionamento de uma urna real.

Primeira coisa importante: Não importa o que escolhi para o design. Isso é relacionado ao conhecimento técnico. Use o político que quiser, os alunos do grêmio estudantil, votação da flor mais bonita ou o que quiser. Tenha foco no conhecimento técnico.

Iniciando o design da urna eletrônica

Para fazer o visual exibido no display, fiz um screenshot de uma imagem da urna que peguei no Google Images. Depois, copiei só a frente da urna e trabalhei em cima dela utilizando o programa Gimp, que possui versões para Linux, Windows e MAC. Você pode conferir no site do Gimp.

No arquivo primário, fui criando camadas, uma para cada botão. Isso foi o suficiente para simular o pressionamento dos botões da urna eletrônica. Também peguei a foto de 2 candidatos e um desejoso, mas a próxima vez que ele estará em uma urna será em seu enterro.

Não pretendo fazer tutoriais de Gimp, mas acho que nem é necessário para um tutorial tão simplório. O primeiro passo será pegar a frente da urna e dimensionar para o tamanho do display. No meu caso, 400x240, que é o display de 3.2".

nextion-gimp-e1605940598137.webp

 

Foram separados os botões em camadas simplesmente para modificar o contraste dele. Faz-se um com maior luminosidade, depois faz-se um com a cor natural. Isso é necessário porque o widget de botão requer 2 imagens; a natural e a de reação ao clique.

Na área do display dessa imagem, um retângulo do tamanho das fotos dos candidatos também foi gerado para iniciar o display Nextion como se não houvesse nada, mas sim, já há uma imagem na região do display.

Na urna eletrônica real, dois quadrados ficam acima da imagem para comportar os números. Também, aparece o nome do candidato quando selecionado. Um som é emitido nesse momento e outro ao clicar em confirma ou em branco. só coloquei o som em Confirma.

Projeto no Nextion Editor

Cria-se um novo projeto, rotaciona-se a tela à 90 graus e seleciona-se o display que será utilizado. A composição da tela ficou assim:

urna.webp

 

 

t0

Um label foi adicionado para fazer uma brincadeira, que você vê no vídeo. A lógica para o label é simples; não exibe nada no início. Se clicar em "Branco", um texto é exibido. Clicando em corrige, o texto é retirado novamente.

p0

Incluí o widget Picture para exibir a imagem do candidato selecionado. Esse widget está sendo iniciado com um crop do background, de modo que a tela inicial parece estar vazia. Mas não está.

n0 e n1

Utilizando o widget Number, criei as caixas referentes aos números digitados no teclado virtual. Não fiz os quadrados que envolvem os números na urnaeletrônica real. Todos os eventos estão fora destes widgets supracitados.

Button

Adicionei 13 botões, apesar de estar utilizando apenas 8 deles. O código de interação com a interface está disposto neles. O botão Confirmar tem uma instrução extra para enviar ao dispositivo remoto o resultado de cada transação da urna eletrônica de brinquedo.

va0 e va1

Incluí 2 widgets Variable, sendo um deles para coletar e atribuir os números digitados e o outro, para concatenar os valores que serão enviados ao dispositivo remoto.

tm0

Esse timer é responsável por colocar na tela a imagem do respectivo candidato selecionado.

Código utilizado no display

Agora a parte mais deliciosa da brincadeira; o dispositivo remoto não tem nenhuma tarefa relacionada à interface, sua função exclusiva é tratar os valores da conclusão de um voto! Não é fascinante a capacidade desse display? Toda a interface e todo o código de interação feito no Nextion Editor. Tente imaginar a complexidade que seria fazer algo parecido com uma MCU qualquer. E para fazer igual? A chance disso acontecer seria infinitesimal.

Botões

Todos os botões numéricos recebem o mesmo código, mudando apenas o valor que para o widget Number é variável. Os botões ficam assim:

if(n0.val==0)
{
  n0.val=1
}else
{
  n1.val=1
}
tm0.en=1

O primeiro passo é saber se n0 está com o valor 0. Se sim, será nele que o número escolhido será incluído. Se não, vai para o n1. Se fosse um projeto sério, uma coisa que deveria ser considerada aqui é a interrupção dessa funcionalidade após alimentar o segundo valor. Também, nenhum candidato começa com 0, senão seria necessário criar uma variável para ser usado como índice do posicionamento.

No final da atribuição, o tm0 é iniciado e então seu código (exibido mais adiante) é executado.

O botão Branco simplesmente alimenta o t0 com uma string. Não faz a votação em branco, de propósito.

O botão Corrigir só atribui valores a algumas variáveis:

t0.txt=""
p0.pic=31
n0.val=0
n1.val=0

No botão Branco, invés do valor "", está sendo incluído o texto, mas o formato é exatamente o mesmo.

O botão Confirmar é o mais elaborado desses 3.

va1.val=n0.val*10+n1.val
t0.txt=""
p0.pic=31
n0.val=0
n1.val=0
prints va1.val,2

val1 recebe a soma dos valores de n0 e n1. n0 é multiplicado por 10 por se tratar da posição das dezenas. Quando um voto é confirmado, a urna eletrônica deve voltar ao estado inicial. Na urna eletrônica de verdade é exibida uma mensagem FIM, que deve permanecer lá até que o mesário libere a urna para o próximo eleitor.

A última linha (prints) envia a mensagem para o dispositivo remoto via comunicação serial.

O tm0 recebe o seguinte código:

if(n0.val==1)
{
  if(n1.val==7)
  {
    p0.pic=7
  }else if(n1.val==3)
  {
    p0.pic=8
  }
}else if(n0.val==4)
{
  if(n1.val==5)
  {
    p0.pic=1
  }
}
tm0.en=0

Aqui estou usando uma lógica que poderia ser simplificada, se fizesse nos botões numéricos a soma das variáveis n0 e n1, mas só pensei nisso depois de ter escrito esse código. Como está funcional, preferi não reescrever, afinal, é só uma brincadeira.

A última linha interrompe o timer.

Código utilizado para recepção dos dados advindos da serial

Fiz a comunicação com o desktop mesmo. Eu não sabia qual era o formato que viria, não sabia  o tipo também, então foi um bocado trabalhoso descobrir. Não achei nenhum exemplo pronto, então fui na tentativa e erro para descobrir a forma ideal de fazer essa comunicação. Estou deixando um exemplo prontinho pra você compreender como é feita a comunicação a partir do display.

Chamei de urna.py:

import serial #para fazer a comunicação serial
import sys    #só foi utilizado para pegar parâmetros do STDOUT
from time import sleep #como o delay do Arduino
from os import system #usei a chamada system para tocar o áudio

#instância da porta serial no Linux
nx = serial.Serial("/dev/ttyUSB0",9600,timeout=2)

#Formato da mensagem:
#101 - msg
#0   - 
#13  - ID do componente (Confirma)
#0   -
#255 - Termino
#255 - Termino
#255 - Termino
#17  - valor do candidato
#0   - 

#Funcão para ficar aguardando dados
def readForever():
    comm      = [] #Em python isso é uma lista, como um array
    count     = 0  #counter
    lula      = 0  #candidato
    bolsonaro = 10 #candidato
    alckmin   = 0  #candidato

    #Simulação da zerésima
    print("Zeresima:")
    print("Lula: 0")
    print("Bolsonaro: 0")
    print("Alckmin:   0")

    while True:
        nxByte = nx.read()
        #conversão do tipo byte para int
        val    = int.from_bytes(nxByte,byteorder='little')
        #checa se a mensagem é válida
        if val == 101:
            while count < 9:
                #adiciona a leitura à lista (array)
                comm.append(val)
                count+=1
                nxByte = nx.read()                                                                                                                     
                val    = int.from_bytes(nxByte,byteorder='little')                                                                                     
                                                                                                                                                       
            if count == 9:                                                                                                                             
                print(comm)                                                                                                                            
            count = 0                                                                                                                                  
            if comm[2] == 13:                      
                #limpa o array                                                                                                    
                comm.clear()  
                #toca o som de finalização                                                                                                                         
                system("play /home/djames/img/urna/fim.wav")                                                                                           
        sleep(0.005)                                                                                                                                   

#executa a funcão                                                                                                                                                       
readForever()

Só isso, o projeto está pronto! Faz-se o upload, então inicia-se o script Python no console e o resto você vê no video, que estará disponível em algumas horas no nosso canal DobitAoByteBrasil no Youtube. Se inscreva, deixe seu like e clique no sininho para receber notificações, para motivar a produção de mais conteúdos.

Os materiais utilizados em artigos são em sua grande maioria, dos parceiros nacionais, dos quais os links ser encontrarão no carrossel ao início do artigo.

Inscreva-se no nosso canal Manual do Maker no YouTube.

Também estamos no Instagram.

Nome do Autor

Djames Suhanko

Autor do blog "Do bit Ao Byte / Manual do Maker".

Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.