Código para OMRON HVC em Python

Lembra da OMRON? Bem, faz parte da minha atual tarefa compará-lo a outros dispositivos e por acaso ele não possui nenhum código que não para Windows. Pior ainda, por se tratar de um componente para integração com outros sensores biométricos e/ou senhas para se tornar um produto, a comunicação com esse dispositivo é realmente de baixo nível. Mas justamente por ser tão baixo nível resolvi compartilhar o código para poder comentar a respeito. Quem é de baixo nível não verá novidade mas quem ainda não teve esse tipo de contato verá algo novo, que normalmente não temos no dia-a-dia maker.

Folha de comandos da OMRON

Primeiramente, eu não encontrei esse documento na Internet. Quando você compra o produto, recebe um link para fazer o download dos PDFs e dos códigos de exemplo (tudo pra Windows em Visual Studio). Estou disponibilizando os comandos mas infelizmente não posso disponibilizar o documento porque está escrito “confidencial” e não lí nada a respeito do acordo de confidencialidade, mas se não tem esse documento publico na Internet, certamente não é aberto.

Os comandos que implementei foram somente os necessários para o meu teste. Tem mais uma série deles, mas irrelevantes para meu propósito.

Comunicação com o dispositivo OMRON

A comunicação é serial, mas os comandos devem ser enviados em hexadecimal; não uma string hexa, mas um emcapsulamento que em Python é feito com o módulo struct.

Para fazer a comunicação serial em Python, deve-se instalar o python-serial. Por fim, para visualizar algumas saídas sem ter que fazer o caminho reverso, instale o hexdump para Python:

Código para o OMRON HVC





Vou mostrar apenas algumas partes do documento pra poder exclarecer como os comandos são montados e vou exemplificar alguns trechos. Se tudo o que você quer é o código, pegue-o completo ao final desse post. Mas eu recomendo a leitura.

A primeira parte é fazer os devidos imports e estabelecer a comunicação serial que no caso, deve ser um dispositivo identificado como “/dev/ttyUSB0”, se não houver outro conectado à sua máquina:

Essa conexão serial é a mesma que você faz com um Arduino, ESP8266 etc. A diferença é que você não tem uma interface gráfica para fazer a interação. O segundo ponto de diferenciação aqui é a velocidade. Repare que esse dispositivo tem um baud rate que vai até 921600, mas claro, ele precisa estar configurado para suportar isso. Para tal, ele possui 4 seletores que representam 4 bits e conforme a conbinação, vai de 9600 até 921600.

Exemplo de código para fazer face detection

O OMRON é um dispositivo passivo, de modo que seu programa precisa estar em execução continuamente para auto-detectar faces ou então estar ligado a um trigger para fazer detecção apenas em determinado momento. Essas características são implementadas pela empresa que integra o OMRON em seu hardware. O programa que escrevi apenas executa conforme a chamada feita por linha de comando shell. Veja a seguinte página do documento para o face detection:

Especificação de comandos
Especificação de comandos

Comando

Como você pode notar, o cabeçalho indica 4 partes, como uma barra de chocolate que tem seus quadradinhos. Olhe onde está escrito “Command (Host->HVC-P)”. Ele diz que o cabeçalho de envio deve conter o “synchronous code”, o “Command number”, o “Data length” e os dados. Vejamos; o syncCode já sabemos, o número do comando para executar detecção também. O comprimento dos dados é de 3 hexadecimais. Então, no campo data deveremos colocar esses 3 hexas. Mas quais são eles? Repare que em “Data” está escrito “Por favor, veja abaixo para detalhes”. Um pouco mais abaixo da página você encontra “Command Data” e lá está especificado cada um dos bits de cada Byte. Como o intuito é fazer face detection, qual bit deve ser levantado? – Exato, o bit 2, que representa o valor hexa 0x04. Vamos para o segundo Byte

Ora, veja. No segundo Byte não queri usar nada. É só a detecção que me interessa, portanto, o segundo Byte dos dados é 0x00. Agora o terceiro Byte, que pode ser apenas 0x00 para não devolver a imagem, 0x01 para devolver a imagem em formato 320×240 ou 0x02 para devolver a imagem em 160×120. Para não ficar complicado, vamos ignorar a imagem, portanto, mais uma vez 0x00.

Agora vamos montar o comando completo. Mas primeiro, uma coisa precisa ser considerada; não basta escrever os hexadecimais na serial porque eles não passarão de caracteres ASCII. O comando precisa ser enviado no modo binário e para fazermos isso no Python, utilizamos o struct, importado no início do código. Pra finalizar a explicação dessa linha, o início do método struct.pack possui um campo ‘<7B’, que significa “7 Bytes alinhados à esquerda”. Lembrando: FEh, 04h, 03h, 00h, 04h, 00h, 00h – dando o total de 7 Bytes.

Agora precisamos ler a resposta.

Resposta





Mais uma vez no início da página, em verde temos o formato da resposta. Mais uma fez o SyncCode é FEh e o código de saída normal é 00h. Ponto. O comprimento dos dados pode ser de até 04h. Não poderei explicar mais detalhes porque a área de dados está em outra página do documento, mas adianto que do mesmo modo que no envio, selecionei apenas o valor que corresponde ao face detection. Lembra aquela analogia boba com o chocolate lá em cima do texto? Agora vamos dividir esse chocolate:

Desse modo temos o syncCode em uma variável, respCode em outra e o dataLen em outra. Não se preocupe, todos os detalhes você poderá contemplar no código adiante. Nessa linha estamos fazendo o unpack da resposta binária. O valor ‘<BBl’ significa 2 Bytes e um long (positivo ou negativo) alinhados à esquerda. O header é a leitura da resposta de escrita. O dataLen pode variar, por isso pegamos o tamanho. Agora faz-se uma segunda leitura para obter os valores que importam:

O que queremos é o número de faces detectadas, que deve ser no mínimo 1, de outro modo, 0. A variável numFaces guarda esse valor, de resto é código comum. Baseado nisso, você já conseguirá interpretar razoavelmente o que significa cada função dentro desse código:

Para executar, apenas chame o script seguido do parâmetro “help” para ver o menu, então execute o script novamente com a execução pretendida. Repare que se for executado o face detection do exemplo acima, em seguida ele tenta fazer o face recognition, caso contrário, simplesmente sai. Legal, hum?

Inscreva-se no nosso newsletter, alí em cima à direita e receba novos posts por email.

Siga-nos no Do bit Ao Byte no Facebook.

Prefere twitter? @DobitAoByte.

Inscreva-se no nosso canal Do bit Ao Byte Brasil no YouTube.

Nossos grupos:

Arduino BR – https://www.facebook.com/groups/microcontroladorarduinobr/
Raspberry Pi BR – https://www.facebook.com/groups/raspberrybr/
Orange Pi BR – https://www.facebook.com/groups/OrangePiBR/
Odroid BR – https://www.facebook.com/groups/odroidBR/
Sistemas Embarcados BR – https://www.facebook.com/groups/SistemasEmbarcadosBR/
MIPS BR – https://www.facebook.com/groups/MIPSBR/
Do Bit ao Byte – https://www.facebook.com/groups/dobitaobyte/

Próximo post a caminho!

Comments

comments

Djames Suhanko

Djames Suhanko é Perito Forense Digital. Já atuou com deployer em sistemas de missão critica em diversos países pelo mundão. Programador Shell, Python, C, C++ e Qt, tendo contato com embarcados ( ora profissionalmente, ora por lazer ) desde 2009.