UNIVERSIDADE ESTADUAL DO RIO GRANDE DO SUL
UNIDADE EM GUAÍBA
CURSO DE ENGENHARIA DE SISTEMAS DIGITAIS
HENRIQUE GABRIEL RODRIGUES CORDEIRO
DISPOSITIVO PERIFÉRICO PARA CAPTURA DE MOVIMENTOS DAS MÃOS
GUAÍBA
2012
HENRIQUE GABRIEL RODRIGUES CORDEIRO
DISPOSITIVO PERIFÉRICO PARA CAPTURA DE MOVIMENTOS DAS MÃOS
Trabalho de Conclusão de Curso apresentado como requisito parcial para obtenção do título de Bacharel em Engenharia de Sistemas Digitais na Universidade Estadual do Rio Grande do Sul.
Orientador: Profa. Dra. Letícia Vieira Guimarães
GUAÍBA
2012
HENRIQUE GABRIEL RODRIGUES CORDEIRO
DISPOSITIVO PERIFÉRICO PARA CAPTURA DE MOVIMENTOS DAS MÃOS
Trabalho de Conclusão de Curso aprovado como requisito parcial para obtenção do título de Bacharel em Engenharia de Sistemas Digitais na Universidade Estadual do Rio Grande do Sul.
Aprovado em ....../....../......
BANCA EXAMINADORA:
Profa. Dra. Letícia Vieira Guimarães
Prof. Dr. Daniel Sander Hoffmann
Prof. Dr. Fernando Gonçalves Pilotto
A minha filha, Yumi.
AGRADECIMENTOS
À Professora Dra. Letícia Vieira Guimarães, minha orientadora, por todo o apoio,
paciência e dedicação.
A minha amada filha, Yumi, pelo simples fato de existir e ser a razão da minha vida.
A minha esposa, Caroline, pelos puxões de orelha nos meus momentos de preguiça,
por me motivar sempre e ainda por me ajudar na soldagem dos acelerômetros nas
placas.
Aos colegas de curso, de trabalho e amigos, pelo apoio e sugestões dadas.
Ao ex-colega de curso, colega de trabalho e, acima de tudo, amigo, Leonardo
Bordignon Ceolin, com sua imprescindível colaboração no projeto e manufatura das
PCBs dos acelerômetros.
Aos meus pais, Jorge e Nara, um agradecimento especial, por todas as noites de
sono perdidas, dores de cabeça que lhes causei e por terem dedicado grande parte
de suas vidas ao objetivo de me dar uma vida melhor do que a que puderam ter.
"Educai as crianças e não será preciso punir os homens."
Pitágoras de Samos
RESUMO
O presente trabalho aborda o desenvolvimento de um dispositivo periférico
composto por sensores de aceleração, que permite a interação com o computador
por meio de movimentos da mão humana. Este dispositivo é responsável por
detectar os movimentos da mão e dos dedos, através de acelerômetros
posicionados em locais específicos. Os sinais detectados são enviados para uma
interface microcontrolada responsável por realizar o condicionamento e
processamento dos mesmos e disponibilizá-los para o computador através de uma
interface de comunicação serial. Além disso, foi desenvolvido um software que
interpreta e exibe graficamente os movimentos realizados.
Palavras-chave: Captura de Movimentos, Movimentos das Mãos, Acelerômetros,
Microcontroladores, Comunicação Serial.
ABSTRACT
The present work addresses the development of a peripheral device composed by
acceleration sensors, that allows interaction with the computer througout human
hand gestures. This device is responsible for detecting hand gestures and finger
moves, through accelerometers placed in specific locations. The detected signals are
sent to a microcontrolled interface, responsible for perform the conditioning and
processing of the signals and make them available to a computer via serial
communication interface. Also, a software was developed that translates and shows
graphically the performed gestures.
Key-words: Motion Capture, Hand Gestures, Accelerometers, Microcontrollers,
Serial Communication.
LISTA DE ILUSTRAÇÕES
Figura 1 - Sistema massa-mola..................................................................................17
Figura 2 - Estrutura básica de um acelerômetro.........................................................19
Figura 3 - Estrutura básica de um acelerômetro com a posição da massa e do
encapsulamento..........................................................................................................19
Figura 4 - Estrutura interna de um acelerômetro capacitivo.......................................21
Figura 5 - Configuração comb-drive de um micro-acelerômetro capacitivo...............22
Figura 6 - Material piezoelétrico antes (a) e durante (b) a aplicação de pressão, a
qual gera uma tensão elétrica.....................................................................................23
Figura 7 - Diagrama de blocos de um microcontrolador.............................................24
Figura 8 - Estrutura interna da CPU............................................................................25
Figura 9 - Esquema básico de uma memória de 16 posições....................................26
Figura 10 - Ossos da mão humana.............................................................................34
Figura 11 - Dedos da mão esquerda...........................................................................35
Figura 12 - Movimento de flexão e extensão do dedo indicador da mão direita........36
Figura 13 - Movimentos de adução e abdução do dedo indicador da mão direita.....37
Figura 14 - Movimentos de pronação e supinação da mão direita.............................37
Figura 15 - Diagrama de blocos simplificado do projeto.............................................38
Figura 16 - Disposição dos acelerômetros na luva (mão direita)...............................39
Figura 17 – Vista superior e inferior do acelerômetro MMA7260...............................42
Figura 18 - Pinagem do MMA7260 (visão do topo)...................................................43
Figura 19 - Sentido da aceleração em cada um dos eixos........................................44
Figura 20 - Aceleração estática nos eixos do acelerômetro MMA7260 em
posicionamentos diferentes.........................................................................................45
Figura 21 - Diagrama de conexões do acelerômetro MMA7260QT...........................46
Figura 22 - PCB para o acelerômetro MMA7260, vista superior (esquerda) e inferior
(direita).........................................................................................................................47
Figura 23: Arduino Uno...............................................................................................48
Figura 24 - Ambiente de Desenvolvimento Arduino....................................................49
Figura 25 - Pinagem do multiplexador CD4051B.......................................................50
Figura 26 - Setup para teste do acelerômetro............................................................51
Figura 27 - Sinal observado no osciloscópio ao causar movimento em um dos eixos
do acelerômetro...........................................................................................................52
Figura 28 - Acelerômetro com conector fêmea soldado.............................................52
Figura 29 - Conexão do acelerômetro com o Arduino (fios de GND e VDD ainda não
soldados).....................................................................................................................53
Figura 30 - Dados recebidos do Arduino pelo programa Terminal, com o
acelerômetro em repouso...........................................................................................55
Figura 31 - Dados recebidos do Arduino pelo programa Terminal, com o
acelerômetro sendo movimentado e com o valor lido convertido em tensão.............56
Figura 32 - Gráfico gerado pelo código Processing relativo a tensão observada nas
saídas dos acelerômetros...........................................................................................57
Figura 33 - Luva com acelerômetro fixado..................................................................57
Figura 34 - Aceleração lida nos eixos dos acelerômetros da mão e dos dedos........59
Figura 35 - Movimento de rotação do eixo x. .............................................................60
Figura 36 - Gráfico Tensão versus Aceleração para o eixo do acelerômetro MM7260.
.....................................................................................................................................60
Figura 37 - Ângulos lidos nos eixos dos acelerômetros da mão e dos dedos...........61
Figura 38 - Modelo tridimensional de uma mão com esqueleto para animação........62
Figura 39 – Diagrama de classes do programa HandCube.......................................63
Figura 40 - Dispositivo conectado ao computador......................................................65
Figura 41 - Tela inicial do software HandCube...........................................................66
Figura 42 - Cubos sendo movimentados com os movimentos da mão no HandCube.
.....................................................................................................................................67
LISTA DE TABELAS
Tabela 1 - Sinal digital com resolução de 2 bits, correspondente a um sinal analógico
de 0 à 5 volts...............................................................................................................31
Tabela 2 - Resolução por bit e valor máximo para uma faixa dinâmica de 5V em
conversores de 8, 10 e 16 bits....................................................................................31
Tabela 3 - Descrição dos pinos do acelerômetro MMA7260......................................42
Tabela 4 - Descrição dos pinos g-Select.....................................................................43
LISTA DE ABREVIATURAS E SIGLAS
A/D – Analógico/Digital
API – Application Programming Interface
CI – Circuito Integrado
CPU – Central Processing Unit
EPROM – Erasable Programmable Read Only Memory
EEPROM – Eletrically Erasable Programmable Read Only Memory
GND – Ground
I/O – Input/Output
PCB – Printed Circuit Board
PVDF – Polyvinylidene Fluoride
PWM – Pulse-Width Modulation
QFN – Quad-Flat no-Leads
RAM – Random Access Memory
ROM – Read Only Memory
RS-232 – Recommended Standard 232
SI – Sistema Internacional de Unidades
UC – Unidade de Controle
UCP – Unidade Central de Processamento
ULA – Unidade Lógica e Aritmética
USB – Universal Serial Bus
SUMÁRIO
1 INTRODUÇÃO...............................................................................................14
2 REFERENCIAL TEÓRICO............................................................................16
2.1 ACELERAÇÃO...............................................................................................16
2.2 ACELERÔMETROS.......................................................................................16
2.2.1 Princípio de Funcionamento.......................................................................17
2.2.2 Estrutura de um Acelerômetro....................................................................18
2.2.3 Resposta em Frequência do Acelerômetro...............................................19
2.2.4 Tipos de Acelerômetros...............................................................................21
2.2.4.1 Acelerômetro Capacitivo................................................................................21
2.2.4.2 Acelerômetro Piezoresistivo..........................................................................22
2.2.4.3 Acelerômetro Piezoelétrico............................................................................23
3 MICROCONTROLADORES..........................................................................24
3.1 CPU (CENTRAL PROCESSING UNIT).........................................................24
3.2 MEMÓRIA......................................................................................................25
3.2.1 ROM (Read Only Memory)...........................................................................27
3.2.2 EPROM (Erasable Programmable Read Only Memory)...........................27
3.2.3 EEPROM (Eletrically Erasable Programmable Read Only Memory)......27
3.2.4 Flash..............................................................................................................28
3.2.5 RAM (Random Access Memory).................................................................28
3.3 ENTRADA E SAÍDA (I/O)...............................................................................28
3.4 COMUNICAÇÃO SERIAL..............................................................................29
3.5 CONVERSOR A/D (ANALÓGICO/DIGITAL)..................................................29
3.5.1 Faixa Dinâmica.............................................................................................30
3.5.2 Resolução.....................................................................................................30
3.5.3 Tempo de Conversão...................................................................................32
3.5.4 Erro de Linearidade......................................................................................32
3.6 CLOCK...........................................................................................................33
3.7 TEMPORIZADOR...........................................................................................33
4 ANATOMIA DA MÃO.....................................................................................34
4.1 DEDOS...........................................................................................................35
4.2 MOVIMENTOS ARTICULARES.....................................................................35
4.2.1 Flexão, Extensão e Hiperextensão.............................................................36
4.2.2 Abdução........................................................................................................36
4.2.3 Adução...........................................................................................................37
4.2.4 Pronação e Supinação.................................................................................37
5 DEFINIÇÃO DO PROJETO...........................................................................38
5.1 ESPECIFICAÇÕES INICIAIS.........................................................................38
5.2 METODOLOGIA.............................................................................................40
5.3 SELEÇÃO DE COMPONENTES...................................................................41
5.3.1 Acelerômetro MMA7260...............................................................................41
5.3.2 Arduino..........................................................................................................47
5.3.2.1 Arduino Uno...................................................................................................48
5.3.2.2 Ambiente De Desenvolvimento Arduino........................................................49
5.3.3 Multiplexador CD4051B...............................................................................50
6 IMPLEMENTAÇÃO DO PROJETO...............................................................51
7 RESULTADOS OBTIDOS..............................................................................65
8 IMPLEMENTAÇÕES FUTURAS...................................................................68
9 CONCLUSÃO................................................................................................69
REFERÊNCIAS................................................................................................70
APÊNDICE A – PROGRAMA TESTESERIAL.INO.............................................74
APÊNDICE B – PROGRAMA TESTESERIAL2.INO...........................................75
APÊNDICE C – PROGRAMA TESTESERIAL3.INO...........................................76
APÊNDICE D – PROGRAMA TESTEACEL.INO................................................78
APÊNDICE E – PROGRAMA TESTEACELANGULOS.INO...............................80
APÊNDICE F – PROGRAMA ACELEROMETRO.INO.......................................82
APÊNDICE G – CLASSE COMMUNICATOR.JAVA...........................................85
APÊNDICE H – CLASSE HANDCUBE.JAVA.....................................................90
14
1 INTRODUÇÃO
O computador, em suas diversas formas, pode ser visto basicamente como
uma máquina capaz de resolver problemas através de cálculos matemáticos. Porém
sua função vai muito além da resolução de problemas propriamente ditos, sendo
muitas vezes usado também para entretenimento, além de auxiliar nas mais diversas
tarefas do dia-a-dia. Para que o uso do computador seja possível, ou seja, para que
o homem possa "dizer" ao computador o que este deve fazer e, para que o
computador, por sua vez, seja capaz de dar-lhe algum tipo de resposta, é necessário
que haja algum mecanismo de interação entre os dois. Este mecanismo de interação
se dá por meio dos dispositivos periféricos chamados de interface homem máquina
(Human Machine Interface).
Atualmente, nos deparamos com os mais diversos tipos de periféricos, que
determinam as mais diversas formas de interação entre o homem e a máquina. Os
periféricos mais básicos e largamente difundidos, quando se trata de computadores
de mesa (os desktops), são o teclado, o monitor de vídeo e o mouse. Porém,
levando-se em conta outros sistemas computacionais, tais como telefones celulares,
video games, tablets, entre outros, encontram-se diversas outras formas de
interação com os sistemas computacionais.
Um exemplo que pode-se destacar é o do joystick utilizado no Nintendo Wii,
console da empresa de entretenimento japonesa Nintendo. O Wiimote (contração de
Wii Remote), como é chamado, além de possuir os botões encontrados nos joysticks
tradicionais, é também capaz de captar os movimentos que o jogador faz com o
mesmo. Dessa forma, a pessoa é capaz de interagir com os jogos imitando
movimentos do mundo real, como o balançar de um taco de golfe, o brandir de uma
espada ou socos em uma luta de boxe. Isso é possível graças aos sensores
contidos no joystick, que na verdade não são capazes de captar movimentos, mas
sim a aceleração a que são submetidos. A estes sensores dá-se o nome de
acelerômetros. O entendimento do seu funcionamento bem como a sua utilização
serão imprescindíveis para o desenvolvimento deste trabalho.
15
O presente trabalho visa o emprego de acelerômetros no desenvolvimento de
um periférico de entrada em forma de luva, capaz de captar movimentos simples
feitos pela mão humana. Os sensores serão conectados à uma interface
responsável por tratar os sinais captados pelos sensores e enviá-los a uma porta
serial do computador. Não será um objetivo deste trabalho definir uma aplicação
específica para o dispositivo, pois a ideia é desenvolver um periférico que possa ser
usado nas mais diversas aplicações possíveis, seja em entretenimento, controle
remoto ou até mesmo em fisioterapia.
16
2 REFERENCIAL TEÓRICO
2.1 ACELERAÇÃO
De acordo com a Primeira Lei de Newton, quando a força resultante sobre um
corpo é igual a zero – as forças que atuam sobre o corpo se anulam –, este está em
repouso ou se desloca em velocidade constante (movimento retilíneo uniforme). Já a
Segunda Lei de Newton afirma que quando a força resultante sobre um corpo não é
nula, este corpo está sofrendo uma aceleração. A aceleração determina a que taxa a
velocidade de um corpo varia, em m/s² (metros por segundo ao quadrado) no SI.
A aceleração, assim como a velocidade, é uma grandeza vetorial, portanto
possui um sentido. Pode ser positiva, acarretando em aumento da velocidade, ou
negativa, quando existe uma força que se opõe ao movimento, acarretando na
diminuição da velocidade, até que o corpo pare ou altere o sentido do seu
movimento.
2.2 ACELERÔMETROS
Acelerômetros são dispositivos capazes de medir aceleração. Isto é feito
convertendo-se a energia mecânica – neste caso, a aceleração – em um sinal de
tensão elétrica proporcional, podendo este ser digital ou analógico, dependendo do
acelerômetro.
Os acelerômetros são usados nos mais diversos tipos de aplicações, podendo
ser usados para detectar impacto (air bags), queda livre (sistema de detecção de
queda em discos rígidos de notebooks), vibrações (sismógrafos), ângulos
(inclinômetros), mudança de posição (alteração de referência da tela de celulares e
tablets) etc.
17
2.2.1 Princípio de Funcionamento
O princípio de funcionamento de um acelerômetro baseia-se no sistema
massa-mola (figura 1). Um sistema massa-mola é constituído de uma massa m,
chamada massa de prova ou sísmica, presa por uma de suas extremidades a uma
mola, sendo que a outra extremidade da mola é presa a um ponto fixo. Este sistema
é governado pelo princípio físico da Lei de Hooke, a qual descreve uma força
restauradora exibida pela mola, quando comprimida ou esticada, ou seja, ao sofrer
uma deformação.
Figura 1 - Sistema massa-mola.Fonte: https://ccrma.stanford.edu/CCRMA/Courses/252/sensors/node9.html
A força restauradora age no sentido de restaurar o formato original da mola
sendo, portanto, oposta à força que a comprime ou estica. Esta força é dada pela
equação
F=−kx , (1)
onde k é a constante de elasticidade da mola e x é a deformação (deslocamento)
sofrido pela mesma. A fórmula possui o sinal negativo devido ao fato de a força
restauradora da mola atuar no sentido oposto ao da força que a estica ou comprime.
Outro princípio que fundamenta o funcionamento dos acelerômetros é a
Segunda Lei de Newton, a qual afirma que um corpo de massa m submetido a uma
aceleração a, possui uma força agindo sobre ele dada pela fórmula F=ma.
Substituindo F por kx da Lei de Hooke, obtém-se a seguinte equação 2.
18
(2)
Uma vez que a massa m e k são constantes, observa-se que a aceleração é
diretamente proporcional à deformação sofrida pela mola, podendo-se então medi-la
em função desta deformação.
O deslocamento x pode ser detectado e convertido em sinal elétrico através
de diversas técnicas de sensoreamento, sendo este o princípio que rege o
funcionamento de todos os tipos de acelerômetro.
É importante destacar que este método é capaz de medir aceleração em uma
única direção. No entanto, existem acelerômetros capazes de medir aceleração em
dois e até mesmo três eixos. Neste caso, o acelerômetro possui um sistema massa-
mola para cada eixo, medindo a aceleração em cada um destes eixos
independentemente.
2.2.2 Estrutura de um Acelerômetro
A estrutura básica de um acelerômetro é ilustrada na figura 2. Um
acelerômetro é composto por uma massa de prova m conectada a base do sensor
através de uma mola de coeficiente k. Além disso, existe o coeficiente de
amortecimento λ, devido a perdas mecânicas da mola e à viscosidade do meio
(RIPKA & TIPEK, 2007), pois os acelerômetros podem conter algum tipo de gás ou
líquido (KAAJAKARI, 2009).
Quando o acelerômetro é submetido a uma aceleração a, é produzido, devido
à inércia, um movimento relativo x da massa de prova, o qual é detectado por um
transdutor, responsável por transformar o movimento em um sinal elétrico de saída.
a=km
x
19
Figura 2 - Estrutura básica de um acelerômetro.Fonte: RIPKA & TIPEK, 2007.
2.2.3 Resposta em Frequência do Acelerômetro
De acordo com Kaajakari (2009, p. 35), a equação do movimento em função
do tempo, para a massa de prova m, é dada por:
, (3)
onde xm e xf (figura 3) são as posições da massa de prova e do encapsulamento do
acelerômetro, respectivamente, γ é o coeficiente de amortecimento e k é o
coeficiente de elasticidade da mola. FE é a força externa que age sobre a massa.
Figura 3 - Estrutura básica de um acelerômetro com a posição da massa e do encapsulamento.Fonte: KAAJAKARI, 2009.
md 2 xm
dt2+γ
d (xm−x f )
dt+k ( xm−x f )=F E
20
A equação (3) pode ser simplificada, subtraindo d2xf /dt2 de ambos os lados:
(4)
Levando-se em conta que é x=x f −xm a diferença entre a posição do
encapsulamento do acelerômetro e a posição da massa, têm-se:
, (5)
onde F é a soma das forças inercial e externa, como ilustrado na equação 6.
F=md 2 x f
dt 2−F E=m x f −F E (6)
Resolvendo a equação 5 usando a transformada de Laplace, definindo o fator
de qualidade mecânica Q=ω0m/γ e assumindo que não há forças externas (FE=0)
(KAJAKAARI, 2009), obtém-se:
x= F /m
s2+sω0/Q+ω0
2=
x f
s2+sω0 /Q+ω0
2≡H (s) x f (7)
Logo, a resposta em frequência do acelerômetro é dada pela seguinte
equação:
H (s)≡ xx f
=1
s2+sω0/Q+ω0
2 (8)
md 2
(xm−x f )
dt 2+γ
d ( xm−x f )
dt+k ( xm−x f )=−m
d 2 x f
dt2+F E
m d 2 x
dt2+γ dx
dt+kx=F
21
2.2.4 Tipos de Acelerômetros
Os acelerômetros podem ser construídos usando diferentes tecnologias.
Algumas delas serão brevemente descritas a seguir.
2.2.4.1 Acelerômetro Capacitivo
Os acelerômetros capacitivos são o tipo mais comumente empregado. Isso se
deve em grande parte ao seu baixo custo, pouca suscetibilidade a ruídos e baixo
consumo de energia (KAAJAKARI, 2009, tradução nossa). Seu funcionamento
baseia-se na detecção da alteração na capacitância – alteração esta proporcional à
aceleração sofrida pelo acelerômetro –, devido ao movimento relativo entre as
placas da massa de prova e as placas fixas à estrutura de suporte do acelerômetro
(figura 4).
Figura 4 - Estrutura interna de um acelerômetro capacitivo.Fonte: http://www.jera.com.br/hardware/hardware-acelerometro/.
22
As placas ou eletrodos encontram-se em uma disposição conhecida como
comb-drive, pelo fato de assemelharem-se aos dentes de dois pentes intercalados
(figura 5).
Figura 5 - Configuração comb-drive de um micro-acelerômetro capacitivo.
Podem ser citados como exemplos de acelerômetros capacitivos o ADXL150,
da Analog Devices, e o MMA7260, da Freescale.
2.2.4.2 Acelerômetro Piezoresistivo
São transdutores que convertem a aceleração numa variação de resistência
devido à deformação de um strain-gage num dos braços de uma ponte de
Wheatstone (THOMAZINI, 2010). A força exercida pela massa de prova faz variar a
resistência do material piezoresistivo, sendo esta variação detectada pela ponte de
Wheatstone.
23
2.2.4.3 Acelerômetro Piezoelétrico
Acelerômetros piezoelétricos baseiam-se na propriedade existente em
determinados cristais naturais, como o quartzo, por exemplo, materiais cerâmicos e
alguns polímeros, como o PVDF, chamada de piezoeletricidade. Materiais
piezoelétricos são capazes de gerar um campo elétrico quando submetidos à
deformações, sendo que este campo pode ser medido em forma de tensão elétrica
(figura 6). A alteração do sentido da força aplicada sobre o material (tração para
compressão) causa a inversão do sentido deste campo.
Figura 6 - Material piezoelétrico antes (a) e durante (b) a aplicação de pressão, a qual gera uma tensão elétrica.
Fonte: CALLISTER, 2002.
Nos acelerômetros que baseiam-se nesse princípio, uma massa de prova
quando acelerada comprime um material piezoelétrico, o qual gera uma tensão
elétrica proporcional a aceleração sofrida. Estes acelerômetros são capazes de
operar em frequências baixas como 2Hz e frequências acima de 5KHz e suportam
temperaturas acima de 120°C.
24
3 MICROCONTROLADORES
Um microcontrolador é um computador em um único chip, otimizado para
controlar dispositivos externos enfatizando a autossuficiência e baixo custo (CESAR
FILHO, 2007). É composto por uma Unidade Central de Processamento (CPU,
Central Processing Unit), memória de programa, memória de dados, entradas e
saídas para ligação com elementos externos, temporizadores, conversor A/D
(analógico/digital), entre outros componentes, como ilustra a figura 7.
Alguns destes componentes serão brevemente descritos a seguir.
Figura 7 - Diagrama de blocos de um microcontrolador.Fonte: http://www.pictutorials.com/what_is_microcontroller.htm.
3.1 CPU (CENTRAL PROCESSING UNIT)
A CPU – ou UCP, de Unidade Central de Processamento – é o componente
principal e mais importante de um microcontrolador, pois é ela a responsável pela
execução do programa e processamento de todos os dados recebidos pelo
microcontrolador. É muitas vezes chamada simplesmente de processador.
A CPU é composta por diversos componentes. De acordo com Stallings
(2003, p. 11) seus principais componentes são os seguintes:
• Unidade de Controle (UC): controla a operação da CPU e, portanto, do
25
microcontrolador;
• Unidade Lógica e Aritmética (ULA): desempenha as funções de
processamento de dados do microcontrolador;
• Registradores: fornecem o armazenamento interno de dados para a CPU;
• Interconexão da CPU (barramentos): mecanismo que possibilita a
comunicação entre a unidade de controle, a ULA e os registradores.
Figura 8 - Estrutura interna da CPU.Fonte: STALLINGS, 2003.
3.2 MEMÓRIA
A memória tem por função armazenar dados. Fazendo uma analogia, a
memória pode ser vista como um armário, contendo uma série de gavetas, onde
cada gaveta pode conter uma informação. Informações podem ser colocadas ou
consultadas em uma gaveta específica. Na memória, cada "gaveta" é chamada
posição de memória e as operações de "colocar" e "consultar" dados são chamadas
de escrita e leitura, respectivamente. Além disso, para se ler ou escrever em uma
determinada posição de memória, é necessário conhecer o endereço daquela
posição.
26
Cada posição de memória possui um endereço único, possibilitando sua
localização. Dessa forma, toda vez que se deseja realizar uma operação sobre a
memória é necessário informar qual operação será realizada (leitura ou escrita), em
qual endereço e, no caso da escrita, qual dado será armazenado. Caso a operação
seja de leitura, o dado lido deverá ser armazenado em algum local, como um
registrador do microcontrolador, para ser usado posteriormente. A figura 9 ilustra o
esquemático simplificado de uma memória com 16 posições, com endereços de 0 à
15. Estão ilustradas na figura as linhas de dados, de endereço e de controle – de
seleção da operação: leitura (read) ou escrita (write).
Figura 9 - Esquema básico de uma memória de 16 posições.Fonte: CESAR FILHO, 2007.
Os microcontroladores geralmente são baseados na arquitetura Harvard,
tendo a memória de programa separada da memória de dados. Para a memória de
programa, podem ser usadas memórias não-voláteis, ou seja, memórias ROM,
EPROM, EEPROM e Flash, enquanto que para a memória de dados é utilizada a
memória RAM, que é uma memória volátil. Essa diferenciação ocorre pois a
memória de programa não deve ser perdida enquanto que a memória de dados deve
27
ser mantida somente enquanto o programa está em execução. A seguir será dada
uma descrição sobre cada um destes tipos de memória.
3.2.1 ROM (Read Only Memory)
As memórias deste tipo permitem apenas a leitura dos dados, como o seu
próprio nome indica (Read Only Memory, ou seja, Memória Somente Leitura). Esta
memória possui seus dados gravados pelo fabricante e possui a vantagem de ter
baixo custo em relação às outras. Geralmente é utilizada na fabricação em massa
de produtos finais, onde não é necessária a alteração de código.
Apesar das suas vantagens, as memórias ROM vem sendo amplamente
substituídas por memórias FLASH, por estas permitirem a modificação dos dados
mesmo em um produto final. Desta forma o fabricante pode disponibilizar correções
e atualizações de firmware para o seu produto, podendo até mesmo incluir novas
funcionalidades.
3.2.2 EPROM (Erasable Programmable Read Only Memory)
As memórias deste tipo podem ter seu conteúdo apagado através da
incidência de raios ultravioleta sobre elas, podendo, desta forma, ser programadas
novamente.
3.2.3 EEPROM (Eletrically Erasable Programmable Read Only Memory)
As memórias EEPROM podem ser apagadas diversas vezes, eletricamente.
Podem ser lidas um número ilimitado de vezes, porém podem ser reprogramadas
28
um número limitado de vezes, sendo que este número varia entre cem mil e um
milhão de vezes. Esta limitação se deve a deterioração do chip de memória durante
o processo de apagamento os dados, o qual necessita de uma tensão elétrica mais
elevada.
3.2.4 Flash
A memória Flash é considerada uma evolução da memória EEPROM. Ela se
diferencia desta pelo fato de permitir escrita de dados em bloco, enquanto que a
memória EEPROM permite apenas escrita bit à bit. Além disso, as memórias Flash
ocupam uma área menor do CI, permitindo desenvolver chips de maior capacidade
em espaços menores.
A memória Flash está sendo amplamente utilizada nos mais diversos
dispositivos, tais como pen drives, câmeras fotográficas digitais e celulares.
3.2.5 RAM (Random Access Memory)
A memória RAM é caracterizada por ser uma memória volátil – os dados nela
armazenados são perdidos quando não há alimentação elétrica nos seus circuitos.
Esta memória é utilizada no microcontrolador para armazenar dados ao longo da
execução do programa, tais como constantes e variáveis.
3.3 ENTRADA E SAÍDA (I/O)
A entrada e saída (ou I/O, de input/output) é o meio de comunicação do
microcontrolador com o mundo exterior. Através dela, o microcontrolador pode
29
receber e enviar dados para dispositivos externos. Um microcontrolador geralmente
possui várias entradas e saídas, as quais correspondem a pinos do CI. Estes pinos
são agrupados em portas, geralmente em agrupamentos de 8 bits, podendo variar
de acordo com as características do microcontrolador.
Cada pino de uma porta pode ter seu fluxo de dados definido como de
entrada ou de saída. Pinos de entrada permitem a leitura de dados de sensores e
outros dispositivos externos ao microcontrolador, enquanto que pinos de saída
permitem o envio (escrita) de dados para atuadores e outros dispositivos.
As portas de entrada e saída podem ser digitais ou analógicas.
3.4 COMUNICAÇÃO SERIAL
Através de pinos específicos, pode-se realizar uma transferência serial
bidirecional de dados com outro periférico.
Normalmente são previstas duas linhas independentes de comunicação a
partir de dois pinos específicos, um para transmissão (Tx) e outro para recepção
(Rx). A linha de transmissão é elétrica e fisicamente independente da linha de
recepção, o que permite transmitir um dado e receber outro simultaneamente
(CESAR FILHO, 2007).
Alguns microcontroladores possuem portas seriais físicas, padrão RS-232,
prontas para realizar comunicação com um PC ou outro microcontrolador. Em
modelos mais recentes, pode-se encontrar também pinos para comunicação via
USB.
3.5 CONVERSOR A/D (ANALÓGICO/DIGITAL)
O conversor A/D é um dispositivo que, dado um sinal de entrada analógico, é
capaz de gerar um sinal de saída digital correspondente. Desta forma, o
microcontrolador, que trabalha apenas com dados digitais, pode processar dados
30
oriundos de sensores que geram apenas saídas analógicas.
É importante observar que um sinal digital é apenas uma representação de
um sinal analógico. O sinal analógico é contínuo no tempo, enquanto que o sinal
digital é discreto. Se um sinal de tensão analógica varia de 0 a 5 volts, por exemplo,
esse sinal poderá assumir infinitos valores dentro deste intervalo. Já um sinal digital
equivalente poderá apenas assumir alguns valores dentro deste intervalo. Isso
significa que sempre haverá erro ou distorções na conversão de um sinal analógico
para digital.
As características de um conversor A/D que devem ser levadas em conta são
a faixa dinâmica, a resolução, o tempo de conversão e o erro de linearidade.
3.5.1 Faixa Dinâmica
A faixa dinâmica é a faixa de amplitude de operação do sinal analógico (em
geral uma tensão) dentro da região de trabalho (linear) do conversor. O sinal de
entrada deve ser condicionado de forma a possibilitar sua máxima utilização dentro
dessa faixa dinâmica. Os conversores A/D apresentam na prática uma faixa
dinâmica de 0,1 a 10V (BONFIM, 2002).
3.5.2 Resolução
A resolução corresponde a menor quantidade que pode ser convertida
(resolvida) dentro da faixa dinâmica do sinal de entrada. É especificada pelo número
de bits do conversor. Considerando o exemplo anterior do sinal analógico que varia
de 0 a 5V, se a resolução do conversor utilizado para gerar o sinal digital
correspondente fosse de 2 bits, a menor amplitude de tensão que pode ser resolvida
é dada por 5V/2² = 1,25V. Ou seja, o degrau entre os valores representados ou
resolução de tensão por bit é de 1,25V. Na tabela 1, observa-se os valores de tensão
que poderão ser representados pelo sinal digital. É importante observar que o valor
31
máximo de tensão (5V) não pode ser representado. O valor máximo que se pode
representar, neste caso, é dado por 1,25x(2²-1)=3,75V. Sendo assim, as fórmulas
para determinar resolução de tensão por bit (Vres) para uma dada resolução e o valor
máximo (Vmax) são, respectivamente:
V res=V ent
2n , (9)
V max=V res×(2n−1) , (10)
onde Vent é a faixa dinâmica do sinal analógico e n é o número de bits da resolução
do conversor.
Tabela 1 - Sinal digital com resolução de 2 bits, correspondente a um sinal analógico de 0 à 5 volts.
bits Tensão (V)
00 0,00
01 1,25
10 2,50
11 3,75
Para a mesma faixa dinâmica de 5V citada anteriormente, considerando a
utilização de conversores A/D com resolução de 8, 10 e 16 bits, foi construída a
tabela 2, com valores de resolução por bit e valor de tensão máximo para cada
resolução.
Tabela 2 - Resolução por bit e valor máximo para uma faixa dinâmica de 5V em conversores de 8, 10 e 16 bits.
Resolução (bits) Resolução por bit (mV) Valor Máximo (V)
8 19,531 4,980469
10 4,883 4,995117
16 0,076 4,999924
32
Conforme pode-se observar na tabela 2, quanto maior a resolução do
conversor A/D, menor será o degrau entre os valores representáveis e mais próximo
estará o valor máximo representável digitalmente do valor máximo do sinal
analógico. Dessa forma conclui-se que quanto maior a resolução do conversor, mais
próximo o sinal digital estará do sinal analógico.
São encontrados na prática conversores com resoluções de 8 a 20 bits
(BONFIM, 2002).
3.5.3 Tempo de Conversão
É o tempo necessário para se obter o valor na saída digital a partir do
momento em que o sinal de entrada foi lido pelo conversor e foi iniciado o processo
de conversão. Este tempo irá depender do circuito utilizado pelo conversor e da sua
resolução. De modo geral, quanto maior a resolução, maior o tempo de conversão.
Este tempo é importante para definir a máxima frequência possível a ser convertida
a partir de um sinal de entrada variante no tempo (BONFIM, 2002).
3.5.4 Erro de Linearidade
O erro de linearidade representa o desvio do resultado de conversão de uma
reta ideal. É expresso em ± uma porcentagem do valor total ou em número de bits
(BONFIM, 2002).
33
3.6 CLOCK
É necessário que haja uma base de tempo constante e independente de
forma que os sinais digitais no interior da memória e da CPU sejam enviados e
recebidos corretamente. Esta base de tempo é fornecida por um oscilador onde, a
cada ciclo, um evento é realizado. A velocidade de realização destes eventos
depende da frequência do oscilador.
Como este oscilador fornece a base de tempo de funcionamento dos
dispositivos eletrônicos, recebe o nome técnico de CLOCK (relógio) (CESAR FILHO,
2007).
3.7 TEMPORIZADOR
O temporizador é um registrador existente no microcontrolador, cujo valor
numérico incrementa em uma unidade em intervalos de tempo definidos, de acordo
com o sinal de relógio (clock).
Alguns microcontroladores podem incluir mais de um temporizador e o sinal
de relógio de cada um destes pode ser de origem interna ou externa.
Caso a origem do sinal de relógio seja configurada como externa, o módulo
temporizador pode ser utilizado como um contador de eventos externos,
incrementando o registrador com cada pulso recebido mediante o pino
correspondente. Se a origem do sinal de relógio é interna, o temporizador
incrementa com cada ciclo do oscilador.
34
4 ANATOMIA DA MÃO
A mão humana pode ser dividida em três partes: carpo, metacarpo e falanges
(figura 10). O carpo é a porção proximal1 da mão, correspondente ao conjunto de
ossos que articula com os ossos do antebraço – articulação esta também conhecida
como punho e vulgarmente chamada de pulso – e do metacarpo. É formado por oito
ossos, dispostos em duas fileiras de quatro ossos cada.
O metacarpo é a porção média da mão, região esta conhecida como palma
da mão. Corresponde ao conjunto de 5 ossos que articulam com os ossos do carpo
e com as falanges proximais.
As falanges são os ossos que compõem os dedos. Cada dedo é composto
por três falanges, exceto o polegar, que possui apenas duas. As falanges possuem
nomes diferentes, de acordo com sua posição:
• Falanges proximais: articulam com os ossos metacarpais;
• Falanges médias: articulam com as falanges proximais e as falanges
distais;
• Falange distais: articulam com as falanges médias e correspondem às
extremidades dos dedos.
Figura 10 - Ossos da mão humana.Fonte: http://www.mundoeducacao.com.br/biologia/ossos-membro-superior.htm.
1 Mais próximo do centro do corpo.
35
4.1 DEDOS
Os dedos da mão humana são também conhecidos como quirodáctilos. Cada
mão possui um total de 5 dedos, os quais são identificados através de um nome e
um número, a saber: polegar (1), indicador (2), médio (3), anular (ou anelar) (4) e
mínimo (5), como ilustra a figura 11.
Figura 11 - Dedos da mão esquerda.Fonte: http://www.oragoo.net/quais-os-nomes-dos-dedos-da-mao/.
4.2 MOVIMENTOS ARTICULARES
As articulações das mãos, punhos e dedos podem realizar uma série de
movimentos. Os tipos de movimentos possíveis são: flexão, extensão,
hiperextensão, abdução, adução, pronação e supinação.
36
4.2.1 Flexão, Extensão e Hiperextensão
A flexão é o movimento de dobra de um osso sobre outro, causando uma
diminuição do ângulo da articulação entre estes ossos. A extensão, por sua vez,
ocorre inversamente à flexão, causando um aumento do ângulo da articulação,
geralmente trazendo uma parte do corpo à sua posição anatômica após esta ser
flexionada. Se uma articulação for estendida além da posição anatômica, ocorre a
chamada hiperextensão.
Estes movimentos são realizados pelas articulações dos dedos e do punho. A
figura 12 ilustra os movimentos de flexão e extensão do dedo indicador da mão
direita.
Figura 12 - Movimento de flexão e extensão do dedo indicador da mão direita.Fonte: http://www.bioeng.nus.edu.sg/compbiolab/projects/hand-biomechanics.html.
4.2.2 Abdução
Movimento de afastamento em relação a linha média do corpo. Este
movimento é realizado pela articulação do punho e dos dedos. Quando relacionado
ao movimento do punho, também é chamado de desvio radial. No caso dos dedos, o
ponto de referência é o dedo médio e não a linha média do corpo. É uma tendência
natural abduzir os dedos durante a extensão mesmos. A figura 13 ilustra o
movimento de abdução do dedo indicador da mão direita.
37
4.2.3 Adução
Movimento de aproximação da linha média do corpo. Este movimento é
realizado pela articulação do punho e dos dedos. Quando relacionado ao movimento
do punho, também é chamado de desvio ulnar. No caso dos dedos, o ponto de
referência é o dedo médio e não a linha média do corpo. É uma tendência natural
aduzir os dedos durante a flexão dos mesmos. A figura 13 ilustra o movimento de
adução do dedo indicador da mão direita.
Figura 13 - Movimentos de adução e abdução do dedo indicador da mão direita.Fonte: http://www.bioeng.nus.edu.sg/compbiolab/projects/hand-biomechanics.html.
4.2.4 Pronação e Supinação
A pronação e supinação são movimentos no plano horizontal, sendo que a
pronação é um movimento para longe da linha média do corpo, enquanto que a
supinação é um movimento em direção a linha média do corpo. A pronação faz com
que a palma da mão fique virada para baixo, enquanto que a supinação faz com que
a palma da mão fique virada para cima.
A figura 14 ilustra os movimentos de pronação e supinação da mão direita.
Figura 14 - Movimentos de pronação e supinação da mão direita.Fonte: http://www.bioeng.nus.edu.sg/compbiolab/projects/hand-biomechanics.html.
38
5 DEFINIÇÃO DO PROJETO
5.1 ESPECIFICAÇÕES INICIAIS
O projeto consiste no desenvolvimento de um dispositivo periférico capaz de
capturar movimentos simples de uma mão humana. Para isso, serão utilizados
sensores de aceleração (acelerômetros) dispostos em uma luva, os quais serão
responsáveis por detectar os movimentos articulares dos cinco dedos e também o
movimento da articulação da própria mão. Os sensores, por sua vez, serão
conectados a uma interface microcontrolada, responsável por tratar os sinais
adquiridos dos acelerômetros e enviá-los para um computador. O diagrama de
blocos do projeto pode ser observado na figura 15.
Figura 15 - Diagrama de blocos simplificado do projeto.
Alguns detalhes devem ser observados, tais como:
• Quantidade de acelerômetros;
• Graus de liberdade do acelerômetro;
• Disposição dos acelerômetros na luva;
• Características desejáveis do microcontrolador;
• Comunicação entre microcontrolador e computador.
A quantidade de acelerômetros a ser utilizada será de seis sensores. Este
número foi escolhido de forma a utilizar a menor quantidade de sensores possível,
por razões de custo, e ao mesmo tempo poder captar os movimentos articulares
básicos de uma mão. Dos seis acelerômetros empregados, cinco deles estarão
posicionados nas falanges distais dos dedos, a fim de captar o movimento de cada
39
um destes, enquanto que o sensor restante ficará posicionado sobre a mão. A figura
16 ilustra a disposição dos sensores sobre a luva.
Até o presente momento, o autor considera que esta é a melhor configuração
para os sensores. Os acelerômetros posicionados nas falanges distais, ou seja, nas
extremidades dos dedos, têm por objetivo detectar os movimentos de flexão e
extensão dos mesmos (dobrar e esticar, respectivamente). Já o acelerômetro
posicionado no centro da mão visa captar os movimentos de flexão, extensão e
hiperextensão do punho, bem como os movimentos de pronação e supinação da
mão. Apenas com os testes ao longo do desenvolvimento prático do projeto poder-
se-á determinar se essa configuração é realmente a mais adequada.
Quanto aos graus de liberdade do acelerômetro, considera-se que os
acelerômetros utilizados em cada dedo deverão realizar medidas em 2 eixos
enquanto que o sensor posicionado sobre a mão necessitará de 3 eixos. Isso se
deve aos movimentos que se deseja detectar. No caso dos dedos, deseja-se
detectar apenas os movimentos de flexão e extensão, ignorando os movimentos de
adução e abdução. Dessa forma o movimento a ser detectado ocorrerá apenas em
dois eixos. Para o movimento da mão, serão detectados flexão, extensão,
hiperextensão, pronação e supinação. Serão ignorados os movimentos de desvio
ulnar e radial. Essa escolha foi tomada com a finalidade de reduzir o nível de
complexidade do projeto.
Figura 16 - Disposição dos acelerômetros na luva (mão direita).
40
Em relação ao microcontrolador a ser utilizado, é desejável que este possua
algumas características, a saber:
• Conversor A/D, para o caso de o acelerômetro escolhido possuir saídas
analógicas, com tantos canais quanto for possível, a fim de converter as
diversas saídas dos acelerômetros, e uma resolução de 8 ou 10 bits;
• Interface RS-232 ou USB, para comunicação com o computador e
também para programação externa;
• Memória de programa do tipo Flash, permitindo fácil reprogramação;
• Fácil programação, permitindo o uso de linguagem de alto nível.
No que diz respeito à comunicação entre o microcontrolador e o computador,
considera-se a possibilidade da interface serial RS-232 ou USB. A interface RS-232
possibilita um meio de comunicação simples, eficiente e presente na grande maioria
dos microcontroladores, porém muitos desktops e notebooks mais novos não
possuem uma porta de comunicação deste tipo. Já a porta USB é amplamente
encontrada nos computadores modernos e nos microcontroladores mais completos,
porém sua utilização é mais complexa, se comparada com a RS-232.
5.2 METODOLOGIA
O projeto foi dividido em 8 etapas:
• Etapa 1: escolha dos componentes (acelerômetros, microcontrolador e
outros elementos que podem vir a ser necessários) que serão utilizados
no projeto, tendo em vista o custo, acessibilidade e correspondência com
as especificações do projeto. Estudo das particularidades e operação dos
componentes.
• Etapa 2: estudo da comunicação entre os acelerômetros e o
microcontrolador, método de aquisição e conversão dos dados (se
necessário). Realização de testes de aquisição de dados dos
acelerômetros por parte do microcontrolador.
• Etapa 3: escolha do método de comunicação entre o microcontrolador e o
41
computador (a princípio RS-232 ou USB).
• Etapa 4: desenvolvimento do software de captura de movimentos dos
acelerômetros.
• Etapa 5: comunicação entre microcontrolador e computador através da
tecnologia escolhida.
• Etapa 6: realização de testes funcionais.
• Etapa 7: correção de problemas encontrados na etapa 6 e realização de
novo teste para verificação das correções.
• Etapa 8: coleta e análise dos resultados obtidos e apresentação do
trabalho.
5.3 SELEÇÃO DE COMPONENTES
Num primeiro momento, foi realizada uma pesquisa com o objetivo de
selecionar os componentes para o desenvolvimento do projeto. Foram utilizados
como critério para a seleção de componentes a adequação com os requisitos
estabelecidos na definição do projeto e também o custo de cada elemento. Portanto,
nem sempre o componente escolhido é o que melhor atende aos requisitos, mas sim
o que possui o melhor custo-benefício.
5.3.1 Acelerômetro MMA7260
O acelerômetro MMA7260, da Freescale Semiconductor, é um acelerômetro
capacitivo de baixo custo que permite detectar aceleração em três eixos, além de
possuir 4 níveis de sensibilidade selecionáveis (1.5g, 2g, 4g e 6g). Suas principais
características são:
• Baixo consumo de corrente (500µA);
• Modo sleep, para reduzir consumo (3µA);
42
• Baixa tensão de operação, entre 2,2V e 3,6V;
• 4 níveis de sensibilidade (1.5g, 2g, 4g e 6g);
A escolha deste modelo se deu principalmente devido ao seu baixo custo e
também devido a sua alta sensibilidade. A figura 17 mostra o acelerômetro visto de
cima e por baixo.
Figura 17 – Vista superior e inferior do acelerômetro MMA7260.Fonte: http://www.voti.nl/shop/catalog.html?IC-MMA7260.
O MMA7260 possui 16 pinos, dos quais apenas 8 são utilizados. A tabela 3
contém a relação de pinos do acelerômetro, enquanto que a figura 18 ilustra a
disposição dos mesmos no chip.
Tabela 3 – Descrição dos pinos do acelerômetro MMA7260.
Nº Pino Nome Pino Descrição
1 g-Select1 Entrada lógica para seleção de sensibilidade.
2 g-Select2 Entrada lógica para seleção de sensibilidade.
3 Vdd Entrada de alimentação.
4 Vss Entrada de terra.
12 Sleep Mode Entrada lógica que habilita/desabilita o Sleep Mode.
13 Zout Saída de tensão do eixo Z.
14 Yout Saída de tensão do eixo Y.
15 Xout Saída de tensão do eixo X.
Fonte: Tradução livre do autor da tabela 4 do Data sheet do Acelerômetro.
43
Figura 18 - Pinagem do MMA7260 (visão do topo).Fonte: MMA7260QT Data sheet Rev 5.
Os pinos lógicos g-Select1 e gSelect2 permitem a seleção entre quatro níveis
de sensibilidade, podendo este nível ser alterado durante a operação. A tabela 4
apresenta os estados dos pinos g-Select, a faixa de aceleração e a sensibilidade
para cada seleção.
O pino de Sleep Mode permite a redução no consumo de energia do
acelerômetro, o que é um ponto forte para aplicações que utilizem bateria,
aumentando sua autonomia. Quando o Sleep Mode esta ativado (nível lógico alto,
pois sua entrada é negada), todas as saídas do acelerômetro são desativadas,
reduzindo o consumo de corrente para cerca de 3μA. Ao receber um sinal em nível
lógico alto, o acelerômetro volta a operar normalmente, reativando as saídas. Para
um consumo ainda menor, há uma recomendação no data sheet do acelerômetro
para colocar o g-Select para o nível de sensibilidade de 1,5g.
Tabela 4 - Descrição dos pinos g-Select.
g-Select2 g-Select1 g-Range Sensibilidade
0 0 1.5g 800mV/g
0 1 2g 600mV/g
1 0 4g 300mV/g
1 1 6g 200mV/g
Fonte: MMA7260QT Data sheet Rev 5.
44
Os pinos Zout, Yout e Xout exibem uma saída de tensão proporcional a
aceleração sofrida nos eixos Z, Y e X do acelerômetro, respectivamente. Observa-se
na figura 19 os sentidos positivo e negativo em cada um dos eixos do acelerômetro.
Isso significa que se o acelerômetro for movimentado no sentido positivo do eixo x,
por exemplo, o valor de aceleração medido no acelerômetro é positivo, enquanto
que no sentido negativo, o valor será, portanto, negativo.
Quando em repouso, o acelerômetro sofre apenas a ação da aceleração da
gravidade. Os eixos do acelerômetro MMA7260, quando em gravidade zero - ou
seja, formando um ângulo de 90 graus com a aceleração da gravidade -, exibem em
seus pinos de saída uma tensão de 1,65V, o que representa a metade do valor
máximo de tensão de saída nos eixos (3,3/2V). Quando sob ação direta da
gravidade, ou seja, quando encontram-se em paralelo com a aceleração da
gravidade, os eixos exibem uma tensão de 2,45V quando com o mesmo sentido, e
uma tensão de 0,85V quando com sentido contrário à gravidade, como pode-se
observar na figura 20.
Figura 19 - Sentido da aceleração em cada um dos eixos.Fonte: MMA7260QT Data sheet Rev 5.
Conclui-se que o acelerômetro pode ser utilizado de duas formas distintas:
captando a aceleração resultante de um movimento de translação (aceleração
decorrente de um movimento como, por exemplo, um soco) e a ação da força g
45
sobre os eixos do acelerômetro quando este é rotacionado (movimento de rotação),
de forma que o acelerômetro pode ser utilizado como um inclinômetro.
Figura 20 - Aceleração estática nos eixos do acelerômetro MMA7260 em posicionamentos diferentes.Fonte: MMA7260QT Data sheet Rev 5.
Como pode-se observar na figura 17, o acelerômetro MMA7260 possui um
encapsulamento QFN, o que dificulta a sua soldagem de forma manual. Encontram-
se à venda placas com o acelerômetro já soldado e pronto para uso, porém seu
custo é relativamente alto.
Após uma longa procura, o componente MMA7260 foi encontrado em
quantidade suficiente e a custo razoável. Os componentes obtidos encontravam-se
já soldados em uma placa, porém esta não pôde ser aproveitada para o projeto, pois
seu circuito utilizava apenas um eixo e seu tamanho era grande para a aplicação no
projeto. Uma vez que tentar remover o acelerômetro da placa poderia resultar na
inutilização do mesmo, optou-se por cortar a placa, deixando apenas a parte
embaixo do chip do acelerômetro e uma pequena parte ao redor do mesmo, com os
contatos para soldagem.
Uma vez que a placa na qual o acelerômetro se encontrava não pôde ser
46
aproveitada, fez-se necessário projetar uma. No próprio data sheet do acelerômetro
encontra-se um diagrama de conexão para o mesmo, que pode ser utilizado como
guia para a criação da placa. Este diagrama está ilustrado na figura 21.
Com base nesse diagrama, foi projetada uma PCB para abrigar o
acelerômetro. O projeto da placa não será abordado no trabalho, pois não foi
realizado pelo autor. A placa já pronta pode ser observada na figura 22.
Com a placa pronta, foi necessário soldar os componentes SMD (capacitores
e resistores) e o acelerômetro. A placa foi projetada de forma que os componentes
ficarão embaixo do acelerômetro. Isso foi feito com o intuito de deixar a PCB com o
menor tamanho possível, uma vez que a placa deverá ser posicionada sobre o dedo.
Devido ao tamanho da placa e ao fato de sua fabricação ser caseira,
possuindo apenas uma camada, fez-se necessário a utilização de jump wires na
placa.
Figura 21 - Diagrama de conexões do acelerômetro MMA7260QT.Fonte: MMA7260QT Data sheet Rev 5.
Com relação a soldagem do acelerômetro a placa, convém fazer as seguintes
observações:
• O pino de Sleep Mode foi soldado diretamente ao Vcc, de forma que nunca
será habilitado este modo;
• Os pinos de g-Select foram conectados direto ao GND, ou seja, o
acelerômetro estará sempre na sensibilidade de 1,5g.
47
Figura 22 - PCB para o acelerômetro MMA7260, vista superior (esquerda) e inferior (direita).
Estas decisões foram tomadas pois acredita-se que essas funcionalidades
não serão necessárias, por dois motivos: não pretende-se utilizar bateria no projeto,
portanto não há tanta preocupação em relação ao consumo; os movimentos
realizados pela mão encontram-se dentro da faixa de 0-1,5g, sendo desnecessário
acelerações maiores (MMA7260QFS Rev 0). Além disso, essas decisões ajudam a
simplificar o projeto.
5.3.2 Arduino
O Arduino é uma plataforma de prototipação open-source de desenvolvimento
fácil e rápido. Sua programação é feita através da linguagem de programação
Arduino, baseada no framework open-source Wiring, no ambiente de
desenvolvimento Arduino, sendo este baseado no ambiente Processing. As placas
do projeto podem ser construídas ou adquiridas já prontas. O ambiente de
desenvolvimento pode ser adquirido via download gratuitamente. Existem vários
modelos diferentes do Arduino, cada qual com um microcontrolador diferente e com
componentes específicos. Para este projeto, foi escolhido o Arduino Uno, devido ao
seu baixo custo e tamanho relativamente reduzido, além das características que
48
serão descritas a seguir.
5.3.2.1 Arduino Uno
O Arduino Uno é um kit que possui como microcontrolador o Atmega328, da
Atmel. Dentre suas características, pode-se destacar:
• 14 entradas/saídas digitais, das quais 6 podem ser utilizadas para PWM;
• 6 entradas analógicas;
• Oscilador de cristal de 16MHz;
• Conector de 2.1mm para alimentação DC
• Conector USB tipo B fêmea, para alimentação (seleção automática entre
alimentação USB ou fonte externa) e comunicação serial (utiliza o
Atmega16U2 como conversor USB para serial).
• Conversor AD de 10 bits de resolução e 6 canais.
A figura 23 ilustra uma foto da placa do kit.
Figura 23: Arduino Uno.Fonte: http://arduino.cc/en/uploads/Main/ArduinoUno_R3_Front.jpg.
49
5.3.2.2 Ambiente de Desenvolvimento Arduino
O Arduino possui um ambiente de desenvolvimento, composto por um editor
de texto, um área de mensagens, um console de texto uma barra de ferramentas
com botões para diversas funções, além de uma série de menus, como pode-se
observar na figura 24. O ambiente pode ser utilizado para a escrita de programas e
além disso é através dele que os programas são enviados para o hardware do
arduino.
Os programas criados para o Arduino são chamados de sketches, e seu
código possui a extensão .ino (em versões antigas do ambiente a extensão utilizada
era a .pde). Estes programas são escritos em linguagem própria do Arduino,
linguagem esta baseada no framework Wiring, muito semelhante a sintaxe das
linguagens C e Java.
Figura 24 - Ambiente de Desenvolvimento Arduino.
50
A escolha do Arduino Uno deu-se devido ao seu baixo custo e simplicidade,
porém essa escolha acarretou uma modificação no projeto: o número de canais é
menor que o numero de sinais de entrada dos eixos dos acelerômetros. No entanto,
este problema pode ser resolvido com a utilização de um multiplexador para
selecionar as saídas dos acelerômetros que serão lidas.
5.3.3 Multiplexador CD4051B
O CD4051B é um multiplexador de 8 canais, com 3 entradas binárias para
seleção do canal, além de um entrada para inibição, impedindo a saída do sinal de
todas as entradas. Este multiplexador opera na faixa de tensão de 0,5V a 20V,
permitindo leitura de sinais analógicos de até 20V pico a pico. A pinagem do
multiplexador pode ser observada na figura 25.
Figura 25 - Pinagem do multiplexador CD4051B.Fonte: CD4051B, CD4052B, CD4053B (Rev. G) [28].
51
6 IMPLEMENTAÇÃO DO PROJETO
Inicialmente foi realizado um teste para verificar o funcionamento dos
acelerômetros. Para tal, foram utilizados os seguintes componentes: uma fonte de
alimentação estabilizada 0-30V, um osciloscópio e um protoboard, sendo este último
utilizado para conectar todos os demais componentes. A fonte foi utilizada para
alimentar a placa do acelerômetro com 3,3V, enquanto que o osciloscópio foi
conectado às saídas do acelerômetro, a fim de verificar o sinal gerado por este. A
figura 26 ilustra o setup utilizado para o teste.
Com o setup preparado foram realizados movimentos com o acelerômetro,
nos seus três eixos, a fim de observar as alterações nas suas saída por meio do
osciloscópio. Durante a movimentação pôde-se observar alterações no sinal (figura
27) semelhantes às de um sistema oscilante com amortecimento, como um sistema
massa-mola, conforme o comportamento esperado.
Figura 26 - Setup para teste do acelerômetro.
52
Figura 27 - Sinal observado no osciloscópio ao causar movimento em um dos eixos do acelerômetro.
Após o teste, assumindo que o acelerômetro estava funcionando
corretamente, foi dado início ao processo de comunicação entre o acelerômetro e o
kit do Arduino. Para tal, foi utilizado um cabo flat para fazer a ligação entre a placa
do kit e o acelerômetro e conectores latch - removidos de uma PCB inutilizada -
foram soldados ao cabo e à placa do acelerômetro (figuras 28 e 29), a fim de
permitir que os elementos sejam desconectados.
Figura 28 - Acelerômetro com conector fêmea soldado.
53
Figura 29 - Conexão do acelerômetro com o Arduino (fios de GND e VDD ainda não soldados).
Concluída a conexão física entre a placa do acelerômetro e o arduino, foi
dado início ao desenvolvimento do software para leitura dos dados do acelerômetro.
Para o desenvolvimento deste programa, tomou-se como base um exemplo já
existente no ambiente do Arduino, chamado AnalogInput.ino. O programa
desenvolvido, que encontra-se no apêndice A, lê os dados dos pinos analógicos e
os envia para a porta serial à qual o Arduino está conectado. Como ainda não foi
desenvolvido o programa para receber os dados no computador, foi utilizado um
software gratuito chamado Terminal, o qual lê dados da porta serial, para testar a
comunicação com o Arduino. Ao clicar no botão Connect do software Terminal, o
mesmo passou a exibir as informações vindas do Arduino, como pode-se observar
na figura 30.
Como pode ser observado na figura, os valores dos eixos x e y variam entre
331 e 337, enquanto que o valor do eixo z variou entre 492 e 503. Levando em conta
que o conversor AD do ATMega328 do Arduino possui uma resolução de 10 bits e
uma tensão de referência de 5V – enquanto que a tensão de alimentação do
acelerômetro é de 3,3V – o valor observado faz sentido. Aplicando a fórmula 9
obtêm-se:
V res=5
210=0,0048828125 .
54
Multiplicando esse valor pela média dos valores encontrados nos pinos do
acelerômetro temos para os eixos x e y
V x e y=335+331+336+334+337
5×0,0048828125=1,6337890625 ,
e para o eixo z
V z=492+498+503+496+500
5×0,0048828125=2,4306640625 .
É importante observar que durante esta leitura, o acelerômetro encontrava-se
em repouso, ou seja, a placa do acelerômetro estava na posição horizontal. Com
isso, infere-se que em repouso e em gravidade zero, o valor esperado na saída do
pino de um eixo do acelerômetro – neste caso os eixos x e y – é de uma tensão de
1,65V (de acordo com a figura 20). Já o eixo z, que encontra-se diretamente sobre a
ação da gravidade, espera-se um valor equivalente a uma tensão de 2,45V. Sendo
assim, os valores lidos pelo Arduino e exibidos no terminal estão satisfatoriamente
próximos do esperado. Foram realizadas leituras com o acelerômetro em diversas
posições diferentes, de modo a deixar sempre um eixo sob ação da aceleração da
gravidade (em ambos os sentidos) e os demais em gravidade zero. Em todos os
casos, os valores lidos aproximaram-se do valor esperado.
55
Figura 30 - Dados recebidos do Arduino pelo programa Terminal, com o acelerômetro em repouso.
De posse dos resultados, foi dado andamento ao software de leitura do
acelerômetro, no sentido de converter o valor lido em um valor real de tensão, para
ser exibido no terminal. Esse passo pode ser considerado bastante simples, pois
basta multiplicar os valores lidos pela tensão de resolução, como feito anteriormente.
O código resultante pode ser observado no apêndice B. A saída exibida no Terminal,
resultante da execução do programa pode ser observada na figura 31.
Para uma melhor visualização dos resultados, foi utilizado um código escrito
em Processing, linguagem idêntica à do Arduino e na qual esta é baseada, com a
diferença de que o código será executado no computador, não no microcontrolador.
Esse código foi desenvolvido por Daniel Gonçalves e pode ser encontrado no
endereço http://lusorobotica.com/index.php/topic,902.0.html. O código é responsável
por receber do microcontrolador via serial os dados lidos do acelerômetro e exibi-los
graficamente. Para isso, também foi necessário alterar o programa contido no
Arduino, que lê os dados do acelerômetro, o qual também foi obtido no mesmo
endereço. Apenas uma pequena alteração foi realizada no código Processing, a fim
de deixar o plano de fundo do gráfico na cor branca, em vez da cor preta do código
original.
56
Figura 31 - Dados recebidos do Arduino pelo programa Terminal, com o acelerômetro sendo movimentado e com o valor lido convertido em tensão.
Ao executar o código Processing - assumindo que o código Arduino já foi
carregado para o kit e já está em execução – uma janela onde será exibido o gráfico
se abre. Ao serem pressionadas as teclas x, y ou z, o programa passa a exibir o
gráfico correspondente ao eixo da letra, nas cores vermelha, verde e azul,
respectivamente. A figura 32 contém o gráfico gerado durante a movimentação dos
eixos do acelerômetro. No gráfico, uma crista significa que o acelerômetro foi
inclinado de forma que a aceleração da gravidade possui o mesmo sentido do eixo e
um vale representa uma inclinação no sentido contrário ao eixo em relação à
gravidade. A região em vermelho corresponde ao eixo x, a região em verde
corresponde ao eixo y e a região em azul corresponde ao eixo z.
Os testes apresentaram resultados que representam de forma satisfatória o
comportamento do acelerômetro MMA7260 nas condições especificadas no projeto.
Sendo assim, foi dado início a montagem dos demais acelerômetros necessários ao
projeto em suas respectivas placas. Após a soldagem nas PCBs, cada acelerômetro
foi testado da mesma forma que o primeiro, de forma a garantir seu funcionamento.
57
Figura 32 - Gráfico gerado pelo código Processing relativo a tensão observada nas saídas dos acelerômetros.
Após certificar-se de que os acelerômetros se encontravam em pleno
funcionamento, iniciou-se a fixação dos mesmos sobre uma luva. Foi utilizada a mão
direita de um par de luvas de algodão comum, utilizando-se cola quente para fixar os
acelerômetros sobre a mesma. A figura 33 mostra a luva com um dos
acelerômetros já fixado.
Figura 33 - Luva com acelerômetro fixado.
Com todos os acelerômetros fixados à luva e devidamente conectados ao
Arduino, foi realizada uma modificação no programa do Arduino (apêndice C) para
incorporar os eixos x dos dedos polegar, indicador e médio nos pinos 2, 1 e 0,
58
respectivamente. As saídas dos eixos x dos acelerômetros dos dedos anelar e
mínimo foram conectadas ao multiplexador CD4051B, nos pinos 1 e 2 do mesmo,
sendo que a saída do multiplexador foi conectada ao pino analógico 0 do Arduino. A
variável que representa o eixo x do acelerômetro do polegar foi chamada de x1,
enquanto que a do indicador foi chamada de x2, e assim por diante, em referência a
numeração utilizada na anatomia (polegar é o dedo 1, indicador é o 2, médio é o 3
etc.). Em seguida executou-se o código e, com o auxílio do software Terminal,
verificou-se os dados recebidos da serial, com a finalidade de verificar se os dados
exibidos pelos demais acelerômetros eram semelhantes ao do primeiro acelerômetro
utilizado. O teste mostrou que os demais acelerômetros mostravam os mesmos
valores nas mesmas condições impostas (repouso, movimento, aceleração sobre
um determinado eixo no sentido positivo/negativo etc).
Apesar de todos os testes realizados indicarem o funcionamento correto dos
acelerômetros consoante as informações disponíveis no data sheet, os valores lidos
estão na forma de tensão, enquanto que deseja-se obter a aceleração nos eixos.
Portanto, é necessário realizar a conversão desse valor para aceleração. O valor da
aceleração em g pode ser obtido dividindo-se o valor de tensão lido pela
sensibilidade do acelerômetro (que não configuração de 1,5g é de 800mV/g). É
importante lembrar que os valores de tensão lidos do acelerômetro são sempre
positivos, portanto é necessário subtrair destes o valor tensão lido em zero g, a fim
de se obter os valores positivos e negativos da aceleração. A fórmula resultante é
observada na equação 11.
g=V OUT−V OFFSET
S 1,5g(11)
Onde:
g é a aceleração observada em um eixo do acelerômetro, medida em
unidades g;
VOUT é a tensão de saída de um eixo do acelerômetro, medida em volts (V);
VOFFSET é a tensão de saída a zero g, medida em volts (V);
59
S1,5g é a sensibilidade do acelerômetro na configuração para 1,5g (medida em
mV/g).
O código do Arduino foi então modificado para realizar a conversão da tensão
em aceleração, conforme a equação 11, podendo ser observado no apêndice D. No
programa, a tensão VOFFSET é obtida através de uma função que calcula uma média
entre 50 amostras, sendo o cálculo feito individualmente para cada eixo de cada
acelerômetro. A leitura dos valores de aceleração pelo programa Terminal para os
acelerômetros pode ser observada na figura 34.
Figura 34 - Aceleração lida nos eixos dos acelerômetros da mão e dos dedos.
Em seguida, o código do apêndice D foi ligeiramente alterado, de forma a
exibir apenas o valor da aceleração no eixo x de um dos dedos e, além disso,
mostrar o valor de tensão para cada valor de aceleração. Utilizando o código
alterado, foram capturados os movimentos do eixo x do acelerômetro durante um
movimento de rotação, iniciado com o eixo x do acelerômetro com o mesmo sentido
da força g e finalizado com o eixo x com sentido inverso à força g, conforme ilustra a
figura 35. Os valores obtidos foram transportados para uma planilha do software
OpenOffice.org Calc, a fim de plotá-los em um gráfico. O gráfico gerado pode ser
observado na figura 36.
60
Figura 35 - Movimento de rotação do eixo x.
Figura 36 - Gráfico Tensão versus Aceleração para o eixo do acelerômetro MM7260.
O movimento realizado no teste assemelha-se ao movimento de flexão e
extensão. Diferente do que se considerava no início do projeto, não serão
necessários dois eixos para capturar estes movimentos, mas apenas um (neste caso
o eixo x) pois, como pode-se observar, a aceleração altera-se de acordo com o
ângulo de inclinação do acelerômetro. Pode-se, portanto, obter o ângulo de
inclinação do eixo do acelerômetro em função da força g, fazendo com que o
acelerômetro comporte-se com um inclinômetro. O mesmo vale para os movimentos
de pronação e supinação do punho da mão, que são essencialmente movimentos
rotacionais. Neste caso, pode-se usar apenas os eixos x e y do acelerômetro
61
posicionado sobre a mão, excluindo-se o eixo z, utilizando o eixo x para captar os
movimentos de flexão e extensão e o eixo y para os movimentos de pronação e
supinação. Para obter-se o angulo de inclinação de um eixo do acelerômetro em
função da aceleração da gravidade, calcula-se o arco seno sobre o valor de
aceleração experimentado no eixo [12]:
θ=arcsin (V OUT−V OFFSET
S 1,5g
) (12)
O código do Arduino foi novamente alterado, de forma a aplicar o cálculo para
obter o ângulo de inclinação. O programa modificado encontra-se no apêndice E. A
figura 37 mostra a leitura dos valores em graus através do Terminal.
Figura 37 - Ângulos lidos nos eixos dos acelerômetros da mão e dos dedos.
Com o objetivo de demonstrar o funcionamento do dispositivo de uma forma
mais intuitiva, foi utilizada a jMonkey Engine, um motor gráfico feito em Java que
permite a manipulação de modelos tridimensionais. A ideia inicial era desenvolver o
modelo de uma mão em um software de modelagem. Em seguida, esse modelo
seria exportado para o jMonkey, onde seria desenvolvido um programa que leria os
dados da serial enviados pelo Arduino e os traduziria para movimentos no modelo
62
tridimensional da mão.
Para a modelagem da mão foi utilizado o software de modelagem Blender, o
qual foi escolhido por ser open source e gratuito. Usando o Blender e, com o auxílio
de tutoriais em vídeo na internet ([29], [30] e [31]), foi criado o modelo de uma mão,
o qual está ilustrado na figura 38. Após a criação do modelo é necessário que o
mesmo seja exportado para o formato utilizado pelo jMonkey. Várias tentativas de
exportar o modelo foram realizadas, mas não se obteve sucesso, pois o modelo não
era corretamente exportado, faltando sempre o esqueleto necessário para fazer a
movimentação. As falhas talvez possam ser relacionadas a falta de familiaridade
com este tipo de software, porém optou-se por uma solução mais simples: utilizar
um dos modelos tridimensionais já existentes no jMonkey.
Figura 38 - Modelo tridimensional de uma mão com esqueleto para animação.
O jMonkey possui formas geométricas tridimensionais básicas. Dentre elas,
foi escolhido o cubo para demonstrar o funcionamento do dispositivo. O objetivo é
fazer com que o cubo se movimente de acordo com o movimento da mão,
traduzindo no espaço virtual tridimensional os movimentos reais da mão. É
importante lembrar que até o momento, todos os testes de leitura dos dados foram
realizados através do software Terminal ou de código Processing. Sendo assim,
63
para o programa desenvolvido no jMonkey, será necessário estabelecer uma
comunicação serial com o Arduino através da linguagem Java. Portanto o software
deve ser dividido em pelo menos duas camadas: a camada gráfica, a qual será
responsável por exibir o objeto tridimensional – neste caso um cubo – e traduzir os
valores recebidos em movimentos do mesmo; a camada de comunicação,
responsável por estabelecer uma comunicação através da porta serial a qual o
Arduino está conectado, lendo os dados enviados por este e enviando-os para a
camada gráfica. Para satisfazer esse requisito, foram criadas duas classes Java: a
classe HandCube, que utiliza a API do jMonkey para exibir um cubo tridimensional
na tela, e a classe Communicator, que utiliza a API RXTX para comunicação serial.
O diagrama de classes da aplicação pode ser observado na figura 39.
Figura 39 – Diagrama de classes do programa HandCube.
64
O código do Arduino foi mais uma vez modificado, para permitir a
comunicação com o programa desktop. Algumas das mudanças realizadas foram a
diminuição do delay entre os ciclos de leitura dos dados dos dados dos
acelerômetros, além de remover os textos que eram enviados juntos com estes
dados para fins de debug. O código resultante encontra-se no apêndice F. As
classes da implementação do programa gráfico que executará no desktop,
Communicator e HandCube, encontram-se no apêndice G e H, respectivamente.
65
7 RESULTADOS OBTIDOS
O dispositivo foi testado utilizando o software desenvolvido. Para tal, os
acelerômetros foram conectados à placa do arduino, a qual foi conectada ao
computador utilizando-se de um cabo USB A/B (figura 40). O teste foi executado em
um computador com processador Intel Pentium Dual Core de 3GHz, com 1GB de
memória, placa de vídeo ATI Radeon HD 4650 e sistema operacional Windows 7 32
bits. É importante observar porém que tanto o dispositivo quanto o software podem
ser executados em outras plataformas, como o Linux, por exemplo, pois o dispositivo
independe de recursos específicos de plataforma e o software foi desenvolvido em
Java, de forma que também é independente de plataforma. Após conectar o
dispositivo no computador, foi carregado o software para o Arduino, o qual passa a
executá-lo imediatamente após a carga.
Figura 40 - Dispositivo conectado ao computador.
O programa HandCube foi executado no desktop, abrindo sua tela inicial,
padrão do jMonkey, que pode ser observada na figura 41. Nesta tela pode-se definir
algumas opções, tais como resolução da tela do programa e modo de tela cheia,
entre outras.
66
Figura 41 - Tela inicial do software HandCube.
Clicando na opção ”Ok”, o programa abre uma janela na resolução
selecionada, com seis cubos de cores distintas. Cada um dos cubos move-se de
acordo com os movimentos da mão e dos dedos, a saber:
• Movimento de flexão do dedo 1 (polegar) faz com que o cubo vermelho gire
para cima, enquanto que a extensão deste mesmo dedo faz com que este
cubo gire para baixo.
• Movimento de flexão do dedo 2 (indicador) faz com que o cubo verde gire
para cima, enquanto que a extensão deste mesmo dedo faz com que este
cubo gire para baixo.
• Movimento de flexão do dedo 3 (médio) faz com que o cubo azul gire para
cima, enquanto que a extensão deste mesmo dedo faz com que este cubo
gire para baixo.
• Movimento de flexão do dedo 4 (anelar) faz com que o cubo amarelo gire
para cima, enquanto que a extensão deste mesmo dedo faz com que este
cubo gire para baixo.
• Movimento de flexão do dedo 5 (mínimo) faz com que o cubo rosa gire para
cima, enquanto que a extensão deste mesmo dedo faz com que este cubo
gire para baixo.
• Movimento de flexão da mão faz com que o cubo branco gire para cima,
enquanto que a extensão faz com que este cubo gire para baixo.
• Movimento de pronação da mão faz com que o cubo branco gire no sentido
anti-horário, enquanto que a supinação faz com que este cubo gire no sentido
67
horário.
Na figura 42, pode-se observar o programa HandCube em execução, com os
cubos em movimentação.
Figura 42 - Cubos sendo movimentados com os movimentos da mão no HandCube.
68
8 IMPLEMENTAÇÕES FUTURAS
Novas funcionalidades e melhorias poderão ser implementadas futuramente
no dispostivo, tais como:
• Introdução de um módulo de comunicação sem fio (Bluetooth, ZigBee ou
Xbee), para substituir a comunicação serial, dando maior liberdade nos
movimentos.
• Utilização de um número maior de acelerômetros como, por exemplo, um
acelerômetro por falange, para captar movimentos com maior precisão.
• Captação de movimentos da mão decorrentes de movimentos do braço, tais
como acenar, arremessar, entre outros. Para tal, seria necessário dois
sensores sobre a mão: um fazendo o papel de inclinômetro (tal como o
acelerômetro atual o faz), captando movimentos de rotação, enquanto o outro
captaria movimentos de translação. O ideal seria a utilização de um
giroscópio para rotação e o acelerômetro para rotação.
• Projetar uma PCB mais elaborada, que permita que o acelerômetro seja
soldado diretamente na mesma, sem adaptações, afim de reduzir erros.
• Projetar um módulo de controle específico para o dispositivo, substituindo o
Arduino, a fim de obter uma redução de tamanho e um hardware otimizado
para a aplicação.
• Desenvolvimento de um protocolo de comunicação mais elaborado e robusto
para o dispositivo, com o objetivo de reduzir o acoplamento entre este e as
aplicações para ele desenvolvidas.
69
9 CONCLUSÃO
O presente trabalho teve por objetivo desenvolver um dispositivo que
permitisse a interação com o computador através de movimentos da mão. Para
atingir este objetivo foram utilizados sensores capazes de detectar aceleração, os
acelerômetros. Quando este projeto foi idealizado, os acelerômetros ainda eram
pouco difundidos e restritos a poucos aparelhos. Atualmente são encontrados em
diversos dispositivos, principalmente smartphones e tablets, onde são utilizados para
definir a orientação da tela e para diversas outras aplicações, dependendo da
criatividade dos desenvolvedores.
Com o desenvolvimento deste trabalho, foi dado um pequeno passo no
sentido de utilizar os acelerômetros num dispositivo periférico para interagir com o
computador. Espera-se que as informações nele contidas possam ser úteis para que
outros estudantes e pesquisadores possam ter maiores avanços, aplicando este
conhecimento em áreas como robótica, fisioterapia, ou o que mais a criatividade dos
mesmos permitir.
Acredita-se que o objetivo do trabalho foi alcançado, que o mesmo permitiu a
aplicação de vários conceitos adquiridos ao longo do curso e que o aprendizado com
ele adquirido será importante no decorrer da carreira de engenharia.
70
REFERÊNCIAS
[1] Accelerometer. Disponível em: <http://www.diy-contractor.com/wiki/tool/332-
measuring-instruments/20175-accelerometer.html>. Acesso em: 22 mai. 2011.
[2] Accelerometer (Analog Devices ADXL50). Disponível em:
<https://ccrma.stanford.edu/CCRMA/Courses/252/sensors/node9.html>.
Acesso em: 4 jun. 2011.
[3] Arduino. Arduino Development Environment. Disponível em:
<http://arduino.cc/en/Guide/Environment>. Acesso em: 14 mai. 2012.
[4] Arduino. Arduino Uno. Disponível em:
<http://arduino.cc/en/Main/arduinoBoardUno>. Acesso em: 14 mai. 2012.
[5] Atmel Corporation. Atmega328 Data Sheet. Disponível em:
<http://www.atmel.com/Images/doc8161.pdf>. Acesso em: 14 mai. 2012.
[6] Biomechanics of the Hand. Disponível em:
<http://www.bioeng.nus.edu.sg/compbiolab/projects/hand-biomechanics.html>.
Acesso em: 20 jun. 2011.
[7] BONFIM, Marlio. Conversores Digital/Analógico (D/A) e Analógico/Digital
(A/D). Disponível em: <www.eletrica.ufpr.br/marlio/medidas/apostila/apostila3a.pdf>.
Acesso em: 26 jun. 2011.
[8] BRITO, Ana Júlia Cunha. Planos e Eixos e Nomenclatura dos Movimentos
Humanos. Disponível em: <http://www.nead.unama.br/site/bibdigital/pdf
%5Cartigos_revistas%5C111.pdf>. Acesso em: 11 jun. 2011.
[9] CALLISTER, William D. Ciência e Engenharia de Materiais: Uma Introdução.
Rio de Janeiro: LTC, 2002.
71
[10] CARNEIRO, Felipe Marcus. Levantamento Bibliográfico das Tecnologias
dos Acelerômetros Comerciais. 19f. Trabalho de Graduação (Graduação em
Engenharia Mecânica) - Departamento de Mecânica Computacional, Faculdade de
Engenharia Mecância, Universidade Estadual de Campinas, Campinas.
[11] CESAR FILHO, Bento Alves Cerqueira. Microcontrolador Básico. Disponível
em: <http://pt.scribd.com/doc/8339182/Microcontrolador-Basico>.
Acesso em: 26 jun. 2011.
[12] CLIFFORD, Michelle; GOMEZ, Leticia. Measuring Tilt with Low-g
Accelerometers.
Disponível em: <http://www.freescale.com/files/sensors/doc/app_note/AN3107.pdf>.
Acesso em: 9 jun. 2011.
[13] DUC, Tan Tran. Modeling and Simulation of the Capacitive Accelerometer:
Diploma Thesis. Nordestedt, Alemanha: GRIN Verlag, 2005.
[14] FIGUEIREDO, Lígia J. et al. Aplicações de Acelerómetros. 2007. 13f.
Monografia (Instrumentação e Aquisição de Sinais) – Lisboa, Portugal, 2007.
FRADEN, Jacob. Handbook of Modern Sensors: Physics, Designs, and
Applications. 4. ed. Nova Iorque: Springer, 2004.
[15] HALLIDAY, David; RESNICK, Robert; WALKER, Jearl. Fundamentals of
Physics. 8. ed. LTC, 2009
[16] KAAJAKARI, Ville. Practical MEMS: Analysis and design of microsystems.
Small Gear Publishing, 2009.
[17] Freescale Inc. MMA7260QFS Rev 0. Disponível em:
<http://www.freescale.com/files/sensors/doc/fact_sheet/MMA7260QFS.pdf >. Acesso
em: 3 abr. 2011.
[18] Freescale Inc. MMA7260QT Data Sheet Rev 5. Disponível em:
<http://www.freescale.com/files/sensors/doc/data_sheet/MMA7260QT.pdf>. Acesso
72
em: 26 abr. 2011.
[19] GRANDI, C. et al. Orientações para elaboração e apresentação de trabalhos e
relatórios acadêmicos. Porto Alegre: UERGS, 2010. 96 p.
[20] JmonkeyEngine 3.0 | Java OpenGL Game Engine. Disponível em:
<http://jmonkeyengine.com/>. Acesso em: 17 jun. 2011.
[21] Microcontroladores. Disponível em:
<http://roboticafacil.blogspot.com/2010/04/microcontroladores.html>.
Acesso em: 26 jun. 2011.
[22] OKI, Nobuo. Microcontroladores e Microprocessadores. Disponível em:
<http://www.dee.feis.unesp.br/graduacao/disciplinas/ele0671/curso_robo%20aula
%20microcontrol_rec_.pdf>. Acesso em: 25 jun. 2011.
[23] RIPKA, Pavel; TIPEK, Alois. Modern Sensors Handbook. Londres: ISTE, 2007.
[24] ROSA FILHO, Blair José. Biomecânica Global. Disponível em:
<http://www.wgate.com.br/conteudo/medicinaesaude/fisioterapia/biomecanica.htm>.
Acesso em: 20 jun. 2011.
[25] RXTX: The Prescription for Trasmission. Disponível em:
<http://users.frii.com/jarvi/rxtx>. Acesso em: 17 jun. 2011.
[26] SILVA, Emilio Carlos Nelli; IBRAHIM, Ricardo Cury. Projeto e Fabricação de
Sistemas Microeletromecânicos (MEMS). 2009. 8f. Departamento de Engenharia
Mecatrônica e de Sistemas Mecânicos, Escola Politécnica da Universidade de São
Paulo, São Paulo, 2009.
[27] STALLINGS, William. Arquitetura de Computadores. 5 ed. São Paulo: Prentice
Hall, 2003.
[28] Texas Instruments. CD4051B, CD4052B, CD4053B (Rev. G). Disponível em:
<http://www.ti.com/lit/ds/symlink/cd4051b.pdf>. Acesso em: 21 abr. 2012;
73
[29] THOMAZINI, Daniel; ALBUQUERQUE, Pedro Urbano Braga de. Sensores
Industriais: Fundamentos e Aplicações. 7. ed. São Paulo: Érica, 2010.
[30] Tutorial Blender 2.59 - Mão Parte 1. Disponível em:
<http://www.youtube.com/watch?v=NfjNg_fZ73o>. Acesso em: 27 mai. 2012.
[31] Tutorial Blender 2.59 - Mão Parte 2. Disponível em:
<http://www.youtube.com/watch?v=c4DNMffXW3M>. Acesso em: 27 mai. 2012.
[32] Tutorial Blender 2.59 - Bone Mão Parte 3. Disponível em:
<http://www.youtube.com/watch?v=pUQxknts0rw>. Acesso em: 27 mai. 2012.
74
APÊNDICE A – PROGRAMA TESTESERIAL.INO
/* TesteSerial * Teste de leitura de eixos do acelerometro. * */
// Pinos analogicos conectados aos eixos do acelerometroint x = A5;int y = A4;int z = A3;
void setup() { Serial.begin(9600); // Seta o baud rate da comunicacao serial }
void loop() { // Leitura dos valores dos pinos analogicos float xValue = analogRead(x); float yValue = analogRead(y); float zValue = analogRead(z); // Escreve os dados na serial Serial.print("x = "); Serial.println(xValue); Serial.print("y = "); Serial.println(yValue); Serial.print("z = "); Serial.println(zValue); // Delay alto para possibilitar visualizacao dos valores delay(1000); }
75
APÊNDICE B – PROGRAMA TESTESERIAL2.INO
/* TesteSerial2 * Teste de leitura de eixos do acelerometro, * convertendo os dados lidos para tensao em volts. */
// Pinos analógicos conectados aos eixos do acelerômetroint x = A5;int y = A4;int z = A3;
// Resolucao do conversorconst double vRes = 5.0 / 1024.0;
void setup() { Serial.begin(9600); // Seta o baud rate da comunicação serial }
void loop() { // leitura dos valores dos pinos analógicos double xValue = analogRead(x); double yValue = analogRead(y); double zValue = analogRead(z); // Obtém o valor em Volts do sinal lido double xVoltage = xValue * vRes; double yVoltage = yValue * vRes; double zVoltage = zValue * vRes; // Escreve os dados na serial Serial.print("x = "); Serial.print(xVoltage); Serial.print(" V ("); Serial.print(xValue); Serial.println(")"); Serial.print("y = "); Serial.print(yVoltage); Serial.print(" V ("); Serial.print(yValue); Serial.println(")"); Serial.print("z = "); Serial.print(zVoltage); Serial.print(" V ("); Serial.print(zValue); Serial.println(")"); // Delay alto para possibilitar visualização dos valores delay(1000); }
76
APÊNDICE C – PROGRAMA TESTESERIAL3.INO
/* TesteSerial3 * Teste de leitura de eixos do acelerometro, * convertendo os dados lidos para tensao em volts. */
// Pinos analogicos conectados aos eixos do acelerometroint x = A5;int y = A4;int z = A3;int x1 = A2;int x2 = A1;
// Resolucao do conversorconst double vRes = 5.0 / 1024.0;
void setup() { Serial.begin(9600); // Seta o baud rate da comunicacao serial}
void loop() { // Leitura dos valores dos pinos analogicos double xValue = analogRead(x); double yValue = analogRead(y); double zValue = analogRead(z); double x1Value = analogRead(x1); double x2Value = analogRead(x2); // Obtém o valor em Volts do sinal lido double xVoltage = xValue * vRes; double yVoltage = yValue * vRes; double zVoltage = zValue * vRes; double x1Voltage = x1Value * vRes; double x2Voltage = x2Value * vRes; // Escreve os dados na serial Serial.print("x = "); Serial.print(xVoltage); Serial.print(" V ("); Serial.print(xValue); Serial.println(")"); Serial.print("y = "); Serial.print(yVoltage); Serial.print(" V ("); Serial.print(yValue); Serial.println(")"); Serial.print("z = "); Serial.print(zVoltage); Serial.print(" V ("); Serial.print(zValue); Serial.println(")"); Serial.print("x1 = "); Serial.print(x1Voltage); Serial.print(" V ("); Serial.print(x1Value); Serial.println(")"); Serial.print("x2 = "); Serial.print(x2Voltage);
77
Serial.print(" V ("); Serial.print(x2Value); Serial.println(")"); delay(1000); // Delay alto para possibilitar visualizacao dos // valores }
78
APÊNDICE D – PROGRAMA TESTEACEL.INO
/* TesteAcel * Teste de leitura de eixos do acelerometro, * convertendo os dados lidos para aceleração em g. */
const float ZOUT_1G = 850.0; // Tensão em mV em Zout a 1G
const float V_OFFSET = 1650.0; // Tensão em mV em a 0G
const int N_AM = 50; // numero de amostras
// Entradas analógicas conectadas aos pinos dos acelerômetrosconst int xaxis = A5; // Eixo x do acelerômetro do punhoconst int yaxis = A4; // Eixo y do acelerômetro do punhoconst int zaxis = A3; // Eixo z do acelerômetro do punhoconst int x1axis = A2; // Eixo x do acelerômetro do dedo 1 (polegar)const int x2axis = A1; // Eixo x do acelerômetro do //dedo 2 (indicador)const float MV_RES = 5000.0 / 1024.0; // resolução do conversor, //em mVconst float SENSIBILITY = 800.0; // Sensibilidade do acelerometro a //1,5g, em milivolts/g// Offset de tensão em zero g float xOffset, yOffset, zOffset, x1Offset, x2Offset;
// Valores lidos dos pinos analógicosfloat x, y, z, x1, x2;
// Aceleração nos eixos (em g)float gx, gy, gz, gx1, gx2;
/* Função que realiza a media entre 50 amostras * de um eixo para calcular o offset. */float AccelAdjust(int axis){ float acc = 0.0, readValue = 0.0; int j; for (j = 0; j < N_AM; j++) { readValue = analogRead(axis); acc = acc + ((readValue * 5000) / 1024.0); delay(11); //número primo para evitar ciclos de leitura } return acc / N_AM;}
/* Configuração dos pinos, do baud rate e cálculo * do erro dos acelerômetros */void setup(){ Serial.begin(9600); // Seta o baud rate da comunicacao serial, // em bps // Configura os pinos para entrada pinMode(xaxis,INPUT);
79
pinMode(yaxis,INPUT); pinMode(zaxis,INPUT); pinMode(x1axis,INPUT); pinMode(x2axis,INPUT); // Leitura do offset para os eixos dos acelerômetros xOffset = AccelAdjust(xaxis); yOffset = AccelAdjust(yaxis); zOffset = AccelAdjust(zaxis); zOffset = zOffset - ZOUT_1G; x1Offset = AccelAdjust(x1axis); x2Offset = AccelAdjust(x2axis);} // Programa principalvoid loop(){ // Leitura dos valores dos pinos analógicos x = analogRead(xaxis); y = analogRead(yaxis); z = analogRead(zaxis); x1 = analogRead(x1axis); x2 = analogRead(x2axis); // Converte o valor lido para g float gx = (x * MV_RES - xOffset) / SENSIBILITY; float gy = (y * MV_RES - yOffset) / SENSIBILITY; float gz = (z * MV_RES - zOffset) / SENSIBILITY; float gx1 = (x1 * MV_RES - x1Offset) / SENSIBILITY; float gx2 = (x2 * MV_RES - x2Offset) / SENSIBILITY; // Envia os dados pela serial Serial.print("xMao = "); Serial.print(gx); Serial.println(); Serial.print("yMao = "); Serial.print(gy); Serial.println(); Serial.print("zMao = "); Serial.print(gz); Serial.println(); Serial.print("xDedo1 = "); Serial.print(gx1); Serial.println(); Serial.print("xDedo2 = "); Serial.print(gx2); Serial.println(); // Delay entre cada ciclo de leitura delay(2000); // Delay alto para possibilitar visualizacao dos
valores }
80
APÊNDICE E – PROGRAMA TESTEACELANGULOS.INO
/* TesteAcelAngulos * Teste de leitura de eixos do acelerometro, * convertendo os dados lidos para angulos em graus. */
const float ZOUT_1G = 850.0; // Tensão em mV em Zout a 1G
const float V_OFFSET = 1650.0; // Tensão em mV em a 0G
const int N_AM = 50; // numero de amostras
// Entradas analógicas conectadas aos pinos dos acelerômetrosconst int xaxis = A5; // Eixo x do acelerômetro do punhoconst int yaxis = A4; // Eixo y do acelerômetro do punho//const int zaxis = A3; // Eixo z do acelerômetro do punhoconst int x1axis = A2; // Eixo x do acelerômetro do dedo 1 (polegar)const int x2axis = A1; // Eixo x do acelerômetro
// do dedo 2 (indicador)
const float MV_RES = 5000.0 / 1024.0; // resolução do conversor, // em mV
const float SENSIBILITY = 800.0; // Sensibilidade do acelerometro a // 1,5g, em milivolts/g
// Offset de tensão em zero g float xOffset, yOffset, zOffset, x1Offset, x2Offset;
// Valores lidos dos pinos analógicosfloat x, y, z, x1, x2;
// Aceleração nos eixos (em g)float gx, gy, gz, gx1, gx2;
/* Calcula a media entre 50 amostras * de um eixo para calcular o offset. */float AccelAdjust(int axis){ float acc = 0.0, readValue = 0.0; int j; for (j = 0; j < N_AM; j++) { readValue = analogRead(axis); acc = acc + ((readValue * 5000) / 1024.0); delay(11); //número primo para evitar ciclos de leitura } return acc / N_AM;}
/* Configuração dos pinos, do baud rate e cálculo do erro dos * acelerômetros */void setup(){ // Seta baudrate para 9600 Serial.begin(9600); // Seta o baud rate da comunicacao serial,
81
// em bps // Configura os pinos para entrada pinMode(xaxis,INPUT); pinMode(yaxis,INPUT); //pinMode(zaxis,INPUT); pinMode(x1axis,INPUT); pinMode(x2axis,INPUT); // Leitura do offset para os eixos dos acelerômetros xOffset = AccelAdjust(xaxis); yOffset = AccelAdjust(yaxis); //zOffset = AccelAdjust(zaxis); //zOffset = zOffset;// - ZOUT_1G; x1Offset = AccelAdjust(x1axis); x2Offset = AccelAdjust(x2axis);} // Programa principalvoid loop(){ // Leitura dos valores dos pinos analógicos x = analogRead(xaxis); y = analogRead(yaxis); //z = analogRead(zaxis); x1 = analogRead(x1axis); x2 = analogRead(x2axis); // Converte o valor lido para g gx = (x * MV_RES - xOffset) / SENSIBILITY; gy = (y * MV_RES - yOffset) / SENSIBILITY; //gz = (z * MV_RES - zOffset) / SENSIBILITY; gx1 = (x1 * MV_RES - x1Offset) / SENSIBILITY; gx2 = (x2 * MV_RES - x2Offset) / SENSIBILITY;
// Calcula o arco seno e envia os dados pela serial Serial.print("xMao ="); Serial.print((int)(asin(gx) * RAD_TO_DEG)); Serial.println(); Serial.print("yMao ="); Serial.print((int)(asin(gy) * RAD_TO_DEG)); Serial.println(); //Serial.print("zMao ="); //Serial.print((int)(asin(gz) * RAD_TO_DEG)); //Serial.println(); Serial.print("xDedo1 ="); Serial.print((int)(asin(gx1) * RAD_TO_DEG)); Serial.println(); Serial.print("xDedo2 ="); Serial.print((int)(asin(gx2) * RAD_TO_DEG)); Serial.println(); // Delay entre cada ciclo de leitura delay(2000);}
82
APÊNDICE F – PROGRAMA ACELEROMETRO.INO
/* Acelerometro * Le dados do acelermetro, convertendo-os para graus * e enviando pela serial. */const float V_OFFSET = 1650.0; // Tensão em mV em a 0G
const int N_AM = 50; // numero de amostras
// pinos digitais para seletor do muxconst int s0 = 8;const int s1 = 9;const int s2 = 10;
// Entradas analógicas conectadas aos pinos dos acelerômetrosconst int xaxis = A5; // Eixo x do acelerômetro do punhoconst int yaxis = A4; // Eixo y do acelerômetro do punhoconst int x1axis = A2; // Eixo x do acelerômetro do dedo 1 (polegar)const int x2axis = A1; // Eixo x do acelerômetro do // dedo 2 (indicador)const int x3axis = A0; // Eixo x do acelerômetro do dedo 3 (médio)const int x4x5axis = A3;
const float MV_RES = 5000.0 / 1024.0; // resolução do conversor, // em mV
const float SENSIBILITY = 800.0; // Sensibilidade do acelerometro // a 1,5g, em milivolts/g// Offset de tensão em zero g float xOffset, yOffset, x1Offset, x2Offset, x3Offset, x4Offset, x5Offset;
// Valores lidos dos pinos analógicosfloat x, y, x1, x2, x3, x4, x5;
// Aceleração nos eixos (em g)float gx, gy, gx1, gx2, gx3, gx4, gx5;
/* Calcula a media entre 50 amostras * de um eixo para calcular o offset. */float AccelAdjust(int axis){ float acc = 0.0, readValue = 0.0; int j; for (j = 0; j < N_AM; j++) { readValue = analogRead(axis); acc = acc + ((readValue * 5000) / 1024.0); delay(11); //número primo para evitar ciclos de leitura } return acc / N_AM;}
// Configuração dos pinos, do baud rate e // cálculo do erro dos acelerômetrosvoid setup()
83
{ // Seta baudrate para 9600 Serial.begin(9600); // Seta o baud rate da comunicacao // serial, em bps // Configura pinos para saída pinMode(s0, OUTPUT); pinMode(s1, OUTPUT); pinMode(s2, OUTPUT); // Configura os pinos para entrada pinMode(xaxis,INPUT); pinMode(yaxis,INPUT); pinMode(x1axis,INPUT); pinMode(x2axis,INPUT); pinMode(x3axis,INPUT); pinMode(x4x5axis,INPUT); // Leitura do offset para os eixos dos acelerômetros xOffset = AccelAdjust(xaxis); yOffset = AccelAdjust(yaxis); x1Offset = AccelAdjust(x1axis); x2Offset = AccelAdjust(x2axis); x3Offset = AccelAdjust(x3axis); // Seleciona pino do dedo 4 // (seleciona entrada 6 do MUX) digitalWrite(s0, LOW); digitalWrite(s1, HIGH); digitalWrite(s2, HIGH); delay(10); x4Offset = AccelAdjust(x4x5axis); // Seleciona pino do dedo 5 // (seleciona entrada 4 do MUX) digitalWrite(s0, LOW); digitalWrite(s1, LOW); digitalWrite(s2, HIGH); delay(10); x5Offset = AccelAdjust(x4x5axis);} // Programa principalvoid loop(){ // Leitura dos valores dos pinos analógicos x = analogRead(xaxis); y = analogRead(yaxis); x1 = analogRead(x1axis); x2 = analogRead(x2axis); x3 = analogRead(x3axis); // Seleciona pino do dedo 4 // (seleciona entrada 6 do MUX) digitalWrite(s0, LOW); digitalWrite(s1, HIGH); digitalWrite(s2, HIGH); delay(10); x4 = analogRead(x4x5axis); // Seleciona pino do dedo 5 // (seleciona entrada 4 do MUX) digitalWrite(s0, LOW); digitalWrite(s1, LOW); digitalWrite(s2, HIGH);
84
delay(10); x5 = analogRead(x4x5axis); // Converte o valor lido para g gx = (x * MV_RES - xOffset) / SENSIBILITY; gy = (y * MV_RES - yOffset) / SENSIBILITY; gx1 = (x1 * MV_RES - x1Offset) / SENSIBILITY; gx2 = (x2 * MV_RES - x2Offset) / SENSIBILITY; gx3 = (x3 * MV_RES - x3Offset) / SENSIBILITY; gx4 = (x4 * MV_RES - x4Offset) / SENSIBILITY; gx5 = (x5 * MV_RES - x5Offset) / SENSIBILITY;
/* Calcula o arco seno, envia os dados pela serial e, * entre o dado de cada eixo, envia um caracter de * nova linha */ Serial.print((int)(asin(gx) * RAD_TO_DEG)); Serial.print("\n"); Serial.print((int)(asin(gy) * RAD_TO_DEG)); Serial.print("\n"); Serial.print((int)((asin(gx1) - asin(gx)) * RAD_TO_DEG)); Serial.print("\n"); Serial.print((int)((asin(gx2) - asin(gx)) * RAD_TO_DEG)); Serial.print("\n"); Serial.print((int)((asin(gx3) - asin(gx)) * RAD_TO_DEG)); Serial.print("\n"); Serial.print((int)((asin(gx4) - asin(gx)) * RAD_TO_DEG)); Serial.print("\n"); Serial.print((int)((asin(gx5) - asin(gx)) * RAD_TO_DEG)); Serial.print("\n"); // Delay entre cada ciclo de leitura delay(200);}
85
APÊNDICE G – CLASSE COMMUNICATOR.JAVA
package henriquetcc2.serialcom;
import gnu.io.CommPort;import gnu.io.CommPortIdentifier;import gnu.io.PortInUseException;import gnu.io.SerialPort;import gnu.io.SerialPortEvent;import gnu.io.SerialPortEventListener;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.util.ArrayList;import java.util.Enumeration;import java.util.HashMap;import java.util.TooManyListenersException;
/** Classe Communicator, responsável por ler os dados da serial * enviados pelo Arduino */public class Communicator implements SerialPortEventListener { //Contém as portas encontradas private Enumeration ports = null; // Mapeia os nomes das portas para CommPortIdentifiers private HashMap portMap = new HashMap(); //Contém a porta aberta private CommPortIdentifier selectedPortIdentifier = null; private SerialPort serialPort = null;
//Stream para receber e enviar dados private InputStream input = null; private OutputStream output = null;
//Flag que informa se há ou não conexão private boolean bConnected = false;
//Timeout para conexão com a porta private final static int TIMEOUT = 2000;
//Valor ASCII para nova linha private final static int NEW_LINE_ASCII = 10; private int serialCount = 0; private float aax; private float aax1; private float aax2; private float aax3; private float aax4; private float aax5; private float aay; private String data = ""; //Armazena as portas encontradas private ArrayList<String> comPorts = new ArrayList<String>(); public float getAax() { return aax; } public float getAax1() {
86
return aax1; } public float getAax2() { return aax2; }
public float getAax3() { return aax2; }
public float getAax4() { return aax2; }
public float getAax5() { return aax2; } public float getAay() { return aay; }
/** Procura pelas portas seriais e coloca as portas no * ArrayList comPorts */ public void searchForPorts() { ports = CommPortIdentifier.getPortIdentifiers(); while (ports.hasMoreElements()) { CommPortIdentifier curPort = (CommPortIdentifier) ports.nextElement(); // Pega apenas portas seriais if (curPort.getPortType() == CommPortIdentifier.PORT_SERIAL) { comPorts.add(curPort.getName()); portMap.put(curPort.getName(), curPort); } } }
/** Conecta à porta selecionada */ public void connect() { // Porta inserida hardcoded "COM3" String selectedPort = (String)comPorts.get(1); selectedPortIdentifier = (CommPortIdentifier)portMap.get(selectedPort); CommPort commPort = null;
try { //Retorna um objeto do tipo CommPort CommPort = selectedPortIdentifier.open( "TigerControlPanel", TIMEOUT);
//É feito um cast no objeto CommPort para SerialPort serialPort = (SerialPort)commPort;
//Seta a flag conectado setConnected(true);
87
//Logs System.out.println(selectedPort + " opened successfully."); //TODO add logs } catch (PortInUseException e) { //Porta já está em uso System.out.println(selectedPort + " is in use. (" + e.toString() + ")"); } catch (Exception e) { //Problema durante a abertura da porta System.out.println("Failed to open " + selectedPort + "(" + e.toString() + ")"); } }
/** Abre os streams de input e output para comunicação */ public boolean initIOStream() { //Valor de retorno em caso de sucesso ou falha na abertura boolean successful = false;
try { input = serialPort.getInputStream(); output = serialPort.getOutputStream(); successful = true; return successful; } catch (IOException e) { // Falha na abertura System.out.println("I/O Streams failed to open. (" + e.toString() + ")"); return successful; } }
/** Inicia o eventListener para saber quando houver dados * para serem lidos */ public void initListener() { try { serialPort.addEventListener(this); serialPort.notifyOnDataAvailable(true); } catch (TooManyListenersException e) { System.out.println("Too many listeners. (" + e.toString() + ")"); } }
/** Desconecta da porta serial e fecha os streams */ public void disconnect() { try { serialPort.removeEventListener(); serialPort.close(); input.close(); output.close(); setConnected(false); }
88
catch (Exception e) { System.out.println("Failed to close " + serialPort.getName() + "(" + e.toString() + ")"); } }
final public boolean getConnected() { return bConnected; }
public void setConnected(boolean bConnected) { this.bConnected = bConnected; } /** Evento disparado quando há dados na serial */ @Override public void serialEvent(SerialPortEvent evt) { if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE) { try { // Lê o stream de input byte singleData = (byte)input.read(); /* Pega o dado caso não seja um caracter de nova * linha */ if (singleData != NEW_LINE_ASCII) { data += new String(new byte[] {singleData}); } else { if (!(data.isEmpty() || data.equals(""))) {
switch(serialCount) { case 0: aax = Float.parseFloat(data); serialCount++; break; case 1: aay = Float.parseFloat(data); serialCount++; break;
case 2: aax1 = Float.parseFloat(data); serialCount++; break;
case 3: aax2 = Float.parseFloat(data); serialCount = 0; break;
case 4: aax1 = Float.parseFloat(data); serialCount = 0; break;
case 5: aax1 = Float.parseFloat(data); serialCount = 0; break;
case 6: aax1 = Float.parseFloat(data); serialCount++; break; }
89
data = ""; } } } catch (Exception e) { //Erro ao ler o dado da serial System.out.println("Failed to read data. (" + e.toString() + ")"); } } }
}
90
APÊNDICE H – CLASSE HANDCUBE.JAVA
package heriquetcc2; import com.jme3.app.SimpleApplication;import com.jme3.material.Material;import com.jme3.math.Vector3f;import com.jme3.scene.Geometry;import com.jme3.scene.shape.Box;import com.jme3.math.ColorRGBA;import com.jme3.math.Quaternion;import com.jme3.system.AppSettings;import henriquetcc2.serialcom.Communicator; /** Classe HandCube. Cria uma janela de aplicação * com cubos 3D que se movem de acordo com os dados * lidos da serial pela classe Communicator. */public class HandCube extends SimpleApplication { // Objeto da comunicação serial Communicator communicator = null; // Geometry para cada parte da mão protected Geometry hand; protected Geometry finger1; protected Geometry finger2; protected Geometry finger3; protected Geometry finger4; protected Geometry finger5; // Ângulos lidos pela serial private float xAngle; private float x1Angle; private float x2Angle; private float x3Angle; private float x4Angle; private float x5Angle; private float yAngle; private Quaternion qHand, qFinger1, qFinger2, qFinger3, qFinger4, qFinger5; /** Define configurações da aplicação:
* -setFrameRate: define frame rate * no valor especificado. * -setTitle: define um título na * barra de títulos da aplicação. */ public static void main(String[] args) { HandCube app = new HandCube(); AppSettings settings = new AppSettings(true); settings.setFrameRate(60); settings.setTitle("HandCube TCC II"); settings.setUseInput(false); app.setSettings(settings);
app.start(); } /** Método executado na inicialização do app.
91
* Cria um objeto communicator para estabelecer * comunicação. * Cria os cubos que serão exibidos na tela. */ @Override public void simpleInitApp() {
communicator = new Communicator(); communicator.searchForPorts(); communicator.connect();
if (communicator.getConnected() == true) { if (communicator.initIOStream() == true) { communicator.initListener(); } }
Box bHand = new Box(Vector3f.ZERO, 1, 1, 1); Box bFinger1 = new Box(new Vector3f(-6, 3, 0), 1, 1, 1); Box bFinger2 = new Box(new Vector3f(-3, 3, 0), 1, 1, 1); Box bFinger3 = new Box(new Vector3f(0, 3, 0), 1, 1, 1);
Box bFinger4 = new Box(new Vector3f(3, 3, 0), 1, 1, 1); Box bFinger5 = new Box(new Vector3f(6, 3, 0), 1, 1, 1);
hand = new Geometry("Player", bHand); finger1 = new Geometry("Player1", bFinger1); finger2 = new Geometry("Player2", bFinger2); finger3 = new Geometry("Player3", bFinger3); finger4 = new Geometry("Player4", bFinger4); finger5 = new Geometry("Player5", bFinger5);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
Material mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
Material mat4 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
Material mat5 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.White); mat1.setColor("Color", ColorRGBA.Red); mat2.setColor("Color", ColorRGBA.Green); mat3.setColor("Color", ColorRGBA.Blue); mat4.setColor("Color", ColorRGBA.Yellow); mat5.setColor("Color", ColorRGBA.Pink);
hand.setMaterial(mat); finger1.setMaterial(mat1); finger2.setMaterial(mat2);
finger3.setMaterial(mat3); finger4.setMaterial(mat4); finger5.setMaterial(mat5);
rootNode.attachChild(hand); rootNode.attachChild(finger1); rootNode.attachChild(finger2); rootNode.attachChild(finger3);
92
rootNode.attachChild(finger4); rootNode.attachChild(finger5); } /** Método que realiza a movimentação dos cubos * com base nos dados lidos da serial */ @Override public void simpleUpdate(float tpf) {
// Lê ângulo do eixo x da mão xAngle = communicator.getAax() * tpf; // Lê ângulo do eixo y da mão yAngle = communicator.getAay() * tpf; // Lê ângulo do eixo x do dedo 1 x1Angle = communicator.getAax1() * tpf; // Lê ângulo do eixo x do dedo 2 x2Angle = communicator.getAax2() * tpf; // Lê ângulo do eixo x do dedo 3 x3Angle = communicator.getAax3() * tpf; // Lê ângulo do eixo x do dedo 4 x4Angle = communicator.getAax4() * tpf; // Lê ângulo do eixo x do dedo 5 x5Angle = communicator.getAax5() * tpf; // Estabelece os eixos de rotação dos cubos // Obs.: o sinal negativo foi utilizado pois o // sistema de coordenadas no jMonkey estão em uma // posição diferente. qHand = new Quaternion().fromAngles(-xAngle, 0, -yAngle); qFinger1 = new Quaternion().fromAngles(-x1Angle, 0, 0); qFinger2 = new Quaternion().fromAngles(-x2Angle, 0, 0); qFinger3 = new Quaternion().fromAngles(-x3Angle, 0, 0); qFinger4 = new Quaternion().fromAngles(-x4Angle, 0, 0); qFinger5 = new Quaternion().fromAngles(-x5Angle, 0, 0); // Executa a rotação dos cubos hand.setLocalRotation(qHand); finger1.setLocalRotation(qFinger1); finger2.setLocalRotation(qFinger2); finger3.setLocalRotation(qFinger3); finger4.setLocalRotation(qFinger4); finger5.setLocalRotation(qFinger5); } /** Desconecta da serial ao fechar a janela */ @Override public void stop() { communicator.disconnect(); super.stop(); } }