Trabalho de Final de Curso do Guincho com Bluetooth - EMC

Propaganda
UNIVERSIDADE FEDERAL DE GOIÁS
ESCOLA DAS ENGENHARIAS MECÂNICA ELÉTRICA E DE COMPUTAÇÃO
Marcelo Pereira Barros
Murillo de Lima Inomata
MÓDULO DE COMUNICAÇÃO BLUETOOTH UTILIZANDO O
MICROCONTROLADOR 8051 PARA MANIPULAR UM GUINCHO
Goiânia
2013
Marcelo Pereira Barros
Murillo de Lima Inomata
MÓDULO DE COMUNICAÇÃO BLUETOOTH UTILIZANDO O
MICROCONTROLADOR 8051 PARA MANIPULAR UM GUINCHO
Trabalho
de
Conclusão
de
Curso
apresentado à Coordenadoria do Curso
de
Engenharia
de
Computação
da
Universidade Federal de Goiás para a
obtenção do título de Engenheiro de
Computação.
Orientador: Prof. Dr. José Wilson Lima Nerys
Goiânia
2013
Marcelo Pereira Barros
Murillo de Lima Inomata
MÓDULO DE COMUNICAÇÃO BLUETOOTH UTILIZANDO O
MICROCONTROLADOR 8051 PARA MANIPULAR UM GUINCHO
Trabalho
de
Conclusão
de
Curso
apresentado à Coordenadoria do Curso
de
Engenharia
de
Computação
da
Universidade Federal de Goiás para a
obtenção do título de Engenheiro de
Computação.
Aprovado em __/__/____
BANCA EXAMINADORA
Prof. Dr. José Wilson Lima Nerys
Prof. Dr. Marcelo Stehling de Castro
Ms. Gustavo Souto de Sá e Souza
1 RESUMO
O presente trabalho visa desenvolver um manipulador robótico de baixo
custo, fazendo uso do microcontrolador 8051 que é o núcleo de toda a família MSC51. O sistema baseado em microcontrolador deverá receber sinais de um dispositivo
móvel através do protocolo de comunicação Bluetooth, e realizar os movimentos
solicitados pelo usuário que está controlando o guindaste. A interface deverá ser
simples e intuitiva, e os sensores de posição deverão ter um controle rígido de
posição.
Palavras-chaves: Microcontrolador, guindaste, 8051, Bluetooth, braço
mecânico, dispositivos móveis, motores de passo.
2 ABSTRACT
This work aims to develop a low-cost robotic manipulator, using the 8051
microcontroller which is the core of the whole family MSC-51. The microcontroller
based system will receive signals from a mobile device via Bluetooth communication
protocol, and perform the movements required by the user who is controlling the
crane. The interface should be simple and intuitive, and the position sensors should
have tight control of the crane position.
Keywords: Microcontroller, crane, 8051, Bluetooth, mechanical arm, mobile
devices, stepper motors.
3 AGRADECIMENTOS
Agradeço, acima de tudo, a Deus, que me deu a vida e a força. Aos meus
filhos, por serem minha inspiração, e a minha esposa, por todo apoio. Mas em
especial agradeço aos meus pais, por tudo, e dedico a eles essa conquista.
Marcelo Pereira Barros
Agradeço primeiramente a Deus que sempre me deu forças para alcançar
vitórias, a minha família pelo apoio e aos meus companheiros de curso que me
motivaram
Agradeço a todos os professores e servidores da UFG pela paciência e
competência no exercício de suas atividades.
Murillo de Lima Inomata
"É preciso que o discípulo da sabedoria
tenha o coração grande e corajoso. O
fardo é pesado e a viagem longa."
Confúncio
"O grau mais elevado da sabedoria
humana é saber adaptar o seu caráter às
circunstâncias e ficar interiormente calmo
apesar das tempestades exteriores."
Daniel Defoe
SUMÁRIO
1
RESUMO .............................................................................................................. 4
2
ABSTRACT........................................................................................................... 5
3
AGRADECIMENTOS ............................................................................................ 6
4
Índice de Figuras ................................................................................................ 12
5
Índice de Tabelas ............................................................................................... 14
6
Símbolos e Siglas ............................................................................................... 15
7
CAPÍTULO 1 - INTRODUÇÃO............................................................................ 16
8
7.1
Descrição da Parte Física do Guincho ......................................................... 17
7.2
Fluxo de Desenvolvimento do Projeto .......................................................... 19
Capítulo 2 - Microcontroladores .......................................................................... 20
8.1
9
Aplicações de Microcontroladores ............................................................... 21
CAPÍTULO 3 – A FAMÍLIA MCS-51 ................................................................... 22
9.1
Introdução Histórica ..................................................................................... 22
9.2
Por que usar o 8051 ..................................................................................... 22
9.3
Principais Características Comuns da família 8051 ..................................... 23
9.4
Arquitetura Interna 8051............................................................................... 24
9.5
Configuração e descrição dos pinos do 8051 .............................................. 25
9.6
ORGANIZAÇÃO DA MEMÓRIA ................................................................... 28
9.6.1
Memória RAM Interna ............................................................................ 28
9.6.2
Memória RAM Externa .......................................................................... 29
9.7
REGISTRADORES DE FUNÇÕES ESPECIAIS .......................................... 29
9.8
CONJUNTO DE INSTRUÇÕES ................................................................... 31
10
CAPÍTULO 3 – BLUETOOTH .......................................................................... 32
10.1
11
Processo de estabelecimento de conexões .............................................. 34
DISPOSITIVOS UTILIZADOS ......................................................................... 36
11.1
AT89C52 ................................................................................................... 36
11.1.1
11.2
Memória de Dados ............................................................................. 37
MOTOR DE PASSO ................................................................................. 39
11.2.1
Definição ............................................................................................ 39
11.2.2
Parâmetros dos motores de passo: .................................................... 40
11.2.3
Ponte H .............................................................................................. 41
11.3
Módulo Bluetooth RS232 TTL ................................................................... 43
11.4
Conversor A/D (ADC0804)........................................................................ 44
11.4.1
Características: .................................................................................. 45
11.4.2
Funcionamento: .................................................................................. 46
11.4.3
Converter a entrada analógica e ler a saída do ADC0804. ................ 47
11.5
ULN2803 ................................................................................................... 48
11.6
Potenciômetro ........................................................................................... 49
11.7
L298N ....................................................................................................... 50
12
FERRAMENTAS E DISPOSITIVOS UTILIZADOS .......................................... 53
12.1
Proteus...................................................................................................... 53
12.2
PEQui........................................................................................................ 54
12.2.1
Funcionamento: .................................................................................. 54
12.3
ChipMax2 .................................................................................................. 55
12.4
MaxLoader ................................................................................................ 56
12.5
Eclipse e Android SDK .............................................................................. 57
13
RESULTADOS OBTIDOS ............................................................................... 58
13.1
Esquemático do circuito eletrônico ........................................................... 58
13.2
Placa de Circuito Impresso ....................................................................... 60
13.3
Processo de confecção da placa .............................................................. 61
13.4
Comunicação com os Dispositivos Bluetooth ........................................... 64
14
CONCLUSÃO E TRABALHOS FUTUROS...................................................... 67
15
BIBLIOGRAFIA................................................................................................ 69
16
APÊNDICE
A
–
CÓDIGO
EM
ASSEMBLY
DO
PROGRAMA
DO
MICROCONTROLADOR........................................................................................... 74
17
APÊNDICE B – CÓDIGO EM JAVA DO PROGRAMA ANDROID/BLUETOOTH
79
4 Índice de Figuras
Figura 1 - Etapas de funcionamento do projeto......................................................... 16
Figura 2 - Descrição e funcionamento do guincho .................................................... 18
Figura 3 - Conexão das engrenagens do guincho..................................................... 18
Figura 4 - Fluxo de desenvolvimento do projeto........................................................ 19
Figura 5 - Arquitetura típica de um microcontrolador ................................................ 20
Figura 6 - Características Especiais da Família MCS-51 .......................................... 24
Figura 7 - Arquitetura Interna do 8051 ...................................................................... 25
Figura 8 - Pinagem do 8051 ...................................................................................... 26
Figura 9 - Memória RAM do 8051. ............................................................................ 29
Figura 10 - Duas piconets formando uma scatternet, com um dispositivo escravo em
comum. ..................................................................................................................... 33
Figura 11 - Conjunto de estados dos dispositivos Bluetooth. .................................... 35
Figura 12 - Mapa dos SRF e seus valores de Reset ................................................. 38
Figura 13 - Ponte H chaveada................................................................................... 42
Figura 14 - ponte H automatizada. ............................................................................ 42
Figura 15 - Pinos usados do módulo Bluetooth. ........................................................ 44
Figura 16 - Cálculo de resolução do ADC. ................................................................ 45
Figura 17 - Interface do ADC 0804 com o 8051. ....................................................... 47
Figura 18 - CI ULN2803. ........................................................................................... 48
Figura 19 - Partes de um potenciômetro linear. ........................................................ 49
Figura 20 - Relação entre giro do cursor e as resistências. ...................................... 50
Figura 21 - Pinagem do L298N. ................................................................................ 51
Figura 22 - Ligação do L298N com motor de passo bipolar. ..................................... 52
Figura 23 - Ambientes ISIS (esquerda) e ARES (direita). ......................................... 54
Figura 24 - Ambiente do PEQui................................................................................. 55
Figura 25 - Dispositivo de gravação de chips ChipMax2. .......................................... 56
Figura 26 - Ambiente do MaxLoader. ........................................................................ 56
Figura 27 - Esquemático básico do guincho.............................................................. 58
Figura 28 - PCI do 8052. ........................................................................................... 62
Figura 29 - PCI da ponte H com L298N. ................................................................... 63
Figura 30 - PCI de ativação do eletroímã. ................................................................. 63
Figura 31 - Circuito eletrônico completo. ................................................................... 63
Figura 32 - Interface do dispositivo Bluetooth. .......................................................... 64
Figura 33 - Controle dos motores. ............................................................................. 65
Figura 34 - Tela de Configuração .............................................................................. 66
5 Índice de Tabelas
Tabela 1 - Principais modelos da família MCS-51 com especificação de ROM, RAM
e T/C. ........................................................................................................................ 22
Tabela 2 - Descrição e funcionamento da pinagem do 8051 .................................... 26
Tabela 3 - Função básica dos SFRs. ........................................................................ 30
Tabela 4 - Classificação dos dispositivos Bluetooth. ................................................. 34
Tabela 5 - Descrição da Pinagem do ADC0804 ........................................................ 45
6 Símbolos e Siglas
ADT: Android Development Tools
AFH: Adaptive Frequency Hopping
API: Application Programming Interface
CISC: Complex Instruction Set Computer
CLP: Controlador lógico programável
CMOS: Complementary metal-oxide-semiconductor
CPU: Central Processing Unit
DC: Direct Current
EPROM: Erasable Programmable Read-Only Memory
FCE: Força contra-eletromotriz
GFSK: Gaussian Frequency-Shift Keying
IDE: Integrated development environment
ISM: Industrial, Scientific and Medicine
LED: Light-emitting diode
PAN: Personal Area Networks
PC: Personal Computer
PCI: Placa de Circuito Impresso
PHP: Hypertext Preprocessor
RAM: Random Access Memory
ROM: Read Only Memory
SDK: Software Development Kit
SIG: Special Interest Group
SWT: Standard Widget Toolkit
TTL: Transistor–Transistor Logic
USB: Universal Serial Bus
ULA: Unidade lógica e aritmética
7 CAPÍTULO 1 - INTRODUÇÃO
Os
microcontroladores
estão
presentes no
cotidiano
da
população,
conquistando cada vez mais espaço em diversas aplicações e ganhando cada vez
mais espaço no mercado.
Nos sistemas eletrônicos, eles são responsáveis pela diminuição das
dimensões dos equipamentos, gerenciam e controlam as tarefas internas, facilitam a
manutenção, tornam alguns sistemas mais baratos e robustos, além de otimizar e
automatizar tarefas, facilitando a vida moderna.
Em questão de investimentos o microcontrolador fornece um excelente custobenefício, sendo um componente versátil que se adéqua a vários tipos de aplicações
diferentes, geralmente voltados para propósitos específicos.
Por possuir a maioria dos componentes necessários para o desenvolvimento
de um sistema em um único chip, torna muito mais viável sua utilização em vários
projetos, deixando o sistema mais simples, barato e reduzido. Cada vez mais os
sistemas microcontrolados ganham mais destaque e importância, sendo de suma
importância em sistemas de automação e controle.
Neste contexto, propomos o desenvolvimento de um sistema microcontrolado
que manipule e controle um guincho. Este sistema microcontrolado deverá
implementar um sistema de comunicação móvel baseado na tecnologia Bluetooth,
para que dispositivos móveis que possuam comunicação Bluetooth, enviem sinais
de controle para o sistema microcontrolado com o intuito de manipular um guincho.
A figura 1 resume as etapas de funcionamento do nosso projeto.
Figura 1 - Etapas de funcionamento do projeto.
16
Como podemos observar o projeto é composto pelas seguintes etapas:
1. Um dispositivo que possua capacidade de comunicação wireless utilizando
o protocolo Bluetooth, envia o sinal de controle para o módulo transceptor Bluetooth.
2. O módulo Bluetooth envia os sinais recebidos do dispositivo móvel para o
microcontrolador AT89C52.
3. O microcontrolador recebe o sinal do módulo Bluetooth e envia o sinal para
o L298N que irá movimentar o motor que passo para realizar os movimentos do
guincho. O motor de passo está acoplado ao guincho por engrenagens poderá
movimentar o guincho na direção horizontal (horário e anti-horário) e vertical (para
cima e para baixo). O microcontrolador poderá também ligar o eletroímã se for
solicitado.
4. Os movimentos do braço do guincho irão mover o cursor do potenciômetro,
variando a resistência entre suas extremidades e a derivação central.
5. O ADC0804 vai converter os dados de analógico para digital, devido a
variação da resistência dos potenciômetros (sensores).
6. O sinal convertido para digital será enviado pelo módulo transceptor
Bluetooth para o dispositivo móvel, informando os movimentos e a posição atual do
braço do guincho.
7.1
Descrição da Parte Física do Guincho
O guincho utilizado no nosso projeto consiste em um braço mecânico que
realiza movimentos horizontais e verticais. Tal braço possui seu eixo central fixo, um
motor de passo que controla o movimento horizontal e outro motor de passo
responsável pelo controle vertical. Foi adicionado um fim de curso no eixo vertical
para controlar a altura máxima do guincho.
Na extremidade do guincho está presente um eletroímã que quando
energizado passa a produzir os mesmos efeitos magnéticos de um ímã, com pólo
norte e sul definidos, podendo então atrair materiais ferromagnéticos.
17
Foram instalados dois potenciômetros lineares, sendo um para cada motor de
passo unipolar utilizado, com o intuito de controlar fielmente seus movimentos. O
microcontrolador da família MCS-51 utilizado, irá receber sinais de controle através
de um dispositivo móvel e irá movimentar o potenciômetro, que está acoplado ao
motor de passo através de engrenagens. A figura 2 descreve os componentes e o
funcionamento do guincho, e a figura 3 mostra a conexão das engrenagens do
guincho.
Figura 2 - Descrição e funcionamento do guincho
Figura 3 - Conexão das engrenagens do guincho
18
7.2
Fluxo de Desenvolvimento do Projeto
Após um estudo sobre a viabilidade do projeto, elaboramos um fluxo de
desenvolvimento a ser seguido, onde cada etapa posterior é dependende das
anteriores.
Figura 4 - Fluxo de desenvolvimento do projeto
19
8 Capítulo 2 - Microcontroladores
Um microcontrolador corresponde a um sistema computacional completo
alocado em um chip. Possui como componentes principais a Unidade Cental de
Processamento (CPU – Central Processor Unit), memória de dados (memória RAM)
e de programa (ROM/PROM/EPROM), linhas de entrada e saída.
É composto também por outros periféricos, que podem ou não ser utilizados
dependendo da aplicação, tais como, módulos de temporização, conversores A/D e
D/A, osciladores, codificadores, portas serial e paralela, modulação de largura de
pulso, entre outros.
A Figura 5 representa a arquitetura típica de um microcontrolador, em que
todos os componentes estão alocados em um único chip.
Figura 5 - Arquitetura típica de um microcontrolador
20
8.1
Aplicações de Microcontroladores
É bastante vasta a aplicação dos microcontroladores no mundo atualmente,
ele está presente nos mais diversos dispositivos eletro-eletrônicos.
Na indústria está presente em CLPs, equipamentos de medição, controle de
processos, esteira de chão de fábrica.
Nos automóveis estão presentes nos alarmes contra roubo, GPS,
computadores de bordo, injeção eletrônica, etc.
Nas residências, estão presentes nos fornos microondas, nas máquinas de
lavar, portão eletrônico, porta retrato digital, brinquedos, eletrônicos, etc.
No cotidiano está presente em elevadores, alarmes de incêndio, caixas
eletrônicos, leitores de código de barras, chaveiro localizador, celulares, sensores,
câmeras de segurança, etc.
21
9 CAPÍTULO 3 – A FAMÍLIA MCS-51
9.1
Introdução Histórica
A família MSC-51 teve sua origem a partir da MCS-48 (lançada pela INTEL
em 1976), que foi a primeira família de controladores lançada pela INTEL. Por não
ser tão limitada quanto seu antecessor e nem tão cara como é a MCS-96, é
praticamente a família de controladores mais usada e popular atualmente.
Atualmente diversos fabricantes produzem o 8051, tais como AMD, Atmel, Dallas,
OKI, Matra, Philips, Siemens, entre outros.
Tem como membro original o microcontrolador 8051, que também é o núcleo
para toda a MCS-51.
Seus principais modelos são:
Tabela 1 - Principais modelos da família MCS-51 com especificação de ROM, RAM e T/C.
Modelo
ROM
RAM
Temporizadores/
Contadores
8031
sem ROM (ROMLESS)
128 bytes de RAM
2 T/C
8051
com 4KB de ROM
128 bytes de RAM
2 T/C
8751
com 4KB de EPROM
128 bytes de RAM
2 T/C
8032
sem ROM (ROMLESS)
256 bytes de RAM
3 T/C
8052
com 8KB de ROM
256 bytes de RAM
3 T/C
8752
com 8KB de EPROM
256 bytes de RAM
3 T/C
9.2
Por que usar o 8051
Optamos pelo uso do 8051 devido às seguintes vantagens:
Por ser um microcontrolador de baixo custo e de alto nível de
integração, podendo assim montar um sistema completo funcional fazendo
uso de poucos componentes.
22
É o microcontrolador mais popular atualmente, oferecendo um
amplo suporte e de fácil aquisição.
Oferece um amplo conjunto de instruções por ser um
microcontrolador CISC (Computador com um Conjunto Complexo de
Instruções), sendo muito utilizado em inúmeras aplicações desde um simples
programa que faz piscar um LED, até programas mais complexos, como um
controlador robótico manipulado via Bluetooth.
Bastante usado no meio acadêmico, pois proporciona economia
real em termos de custo de ferramentas, treinamento além de possuir
softwares livres que compilam e simulam o funcionamento do circuito.
É rápido e eficaz, pois a sua arquitetura se correlaciona de perto
com o sistemas de controle, e menos bytes precisam ser buscados e menos
jumps
condicionais
são
processados,
por
suas
instruções
serem
especializadas.
Possui
aperfeiçoamentos
constantes,
como
aumento
da
velocidade e melhorias na manufatura, sendo produzido por diversos
fabricantes, e possui centenas de variedades, que são compatíveis por
possuírem o mesmo núcleo de arquitetura.
9.3
Principais Características Comuns da família 8051
CPU de 8 bits
128 bytes de RAM interna
4 portas bidirecionais de I/O de 8 bits cada (P0, P1, P2 E P3),
com bits individualmente endereçáveis.
Memória de dados externa e memória de programa externa com
capacidade de até 64KB cada.
23
Frequência de clock de 1 até 12MHz.
2 temporizadores /contadores de 16 bits
1 canal de comunicação serial
5 fontes de interrupção, com dois níveis de prioridade
selecionáveis por software. Das 5 fontes de interrupção, duas são
timers, duas externas e mais o canal de comunicação serial.
Oscilador de clock interno
Arquitetura CISC, que permite executar operações aritméticas e
lógicas mais complexas.
Os diversos fabricantes do 8051, adicionam algumas características
especiais, além das características comuns à todos modelos do 8051, de acordo
com a aplicação e o mercado que se destinam. As características especiais da
família 8051 que podem ser adicionadas estão especificadas na figura 6.
Figura 6 - Características Especiais da Família MCS-51
9.4
Arquitetura Interna 8051
O microcontrolador da família MCS-51 possui todos os componentes
relevantes para se obter um sistema em um único chip, como podemos observar
24
pela figura 7. A CPU de 8 bits controla as memórias, as portas bidirecionais, a parta
serial, os contadores/temporizadores, interrupções e barramentos.
O oscilador é responsável por gerar o clock que define a frequencia de
funcionamento do microcontrolador, já o controle de interrupção auxilia a CPU
quando for gerada uma interrupção externa, ou do canal serial, ou dos
contadores/temporizadores.
Figura 7 - Arquitetura Interna do 8051
9.5
Configuração e descrição dos pinos do 8051
A figura 8 demonstra a localização dos pinos do microcontrolador baseado na
família MCS-51, ela relaciona o nome do pino com a sua real localização nos pinos
do 8051. Já a tabela 2, descreve o funcionamento dos pinos típicos de qualquer chip
baseado no 8051.
25
Figura 8 - Pinagem do 8051
Tabela 2 - Descrição e funcionamento da pinagem do 8051
Nome do Pino
Numeração
Descrição / Funcionamento
Porta P0 (P0.0
a P0.7)
39 a 32
A porta P0 corresponde a uma porta bidirecional
de entrada e saída de 8 bits de dreno aberto.
Se escrever o nível lógico 1 nas em qualquer
pino da porta P0, eles flutuam, podendo assim esses
estados serem usados como entradas de alta
impedância.
Fornece
multiplexada
a
parte
menos
significativa do barramento de endereço (A0 a A7) e
do barramento de dados (D0 a D7) durante o acesso a
uma memória de programa ou de dados externa.
Portanto se estiver sendo usada como um
barramento de endereços, a porta P0 não poderá ser
usada como uma porta bidirecional de entrada e saída.
Porta P1 (P1.0
a P1.7)
1a8
A porta P1 corresponde a uma porta bidirecional
de 8 bits para entra e saída co pull-ups internos. O
resistor de pull-up fornece uma corrente de entrada em
nível baixo se aplicar um nível lógico zero.
Se colocarmos a porta P1 para funcionar como
entrada, os seus pinos são externamente elevados
para o nível lógico zero, que acaba fornecendo
corrente devido aos pull-upss internos dos pinos.
Porta P2 (P2.0
a P2.7)
21 a 28
A porta P2 corresponde a uma porta bidirecional
de 8 bits para entra e saída co pull-ups internos.
Pode ser usada como saída ou como parte mais
significativa do endereço que é necessário quando se
deseja acessar a memória externa. Recebe o byte
mais significativo do endereço durante a verificação da
ROM e da EPROM e durante a programação da
EPROM.
26
Porta P3 (P3.0
a P3.7)
10 a 17
A porta P3 também pode ser usada como uma
porta bidirecional de entrada e saída de 8 bits.
Porém, se o Latch da porta P3 estiver em nível
lógico um, a sua saída será controlada pelo sinal de
Função de Saída Alternativa. Assim a pinagem da
porta P3 passa a ter as seguintes funções especiais:
P3.0: Entrada Serial
P3.1: Saída Serial
P3.2: Interrupção 0
P3.3: Interrupção 1
P3.4: Contador 0
P3.5: Contador 1
P3.6: Sinal de Escrita
P3.7: Sinal de Leitura
Fonte de
alimentação Vcc
40
Entrada do positivo da fonte de alimentação
Terra - Vss
20
Entrada do Terra (GND)
Reset
9
Pino de entrada do Reset do circuito. Enquanto
o oscilador interno estiver sendo executado, se
mantivermos o nível lógico um no pino de reset por 2
ciclos de máquina, ele inicializa alguns registradores
internos com os valores predefinidos de fábrica,
resetando o dispositivo.
Adress Latch
Enable
30
Responsável por controlar a demultiplexação de
dados ou endereço da Porta P0.
Indica a um dispositivo externo quando ele deve
capturar o sinal de endereço e os dados que devem
ser multiplexados no tempo.
Pode ser utilizado para fins de clock ou de
temporizador externo.
Program Store
Enable
29
Sinal de leitura para a memória de programa
externa.
XTAL1 e
XTAL2
18 e 19.
Conexão do cristal para funcionamento do
oscilador de clock interno.
External
Access Enable
31
Se ligado ao terra, habilita a busca na memória
de programa externa (0000h a FFFFh).
Se estiver no nível lógico alto, executa apenas
os primeiros 4K na memória ROM interna.
27
9.6
ORGANIZAÇÃO DA MEMÓRIA
O 8051 não segue a arquitetura de Von Newmann em que a memória de
dados e de programa podem ser armazenadas no mesmo espaço de memória, ele
adota o modelo de arquitetura de Harward podendo assim ter dados e programas
alocados em memórias distintas.
As memórias de dados e de programa, que são denominadas memórias
externas, podem conter até 64KB cada. A utilização ou não dos 4KB da ROM interna
do microcontrolador vai ser definida pelo nivel lógico do pino EA (External Access
Enable). Se EA=0, então os 64KB de memória serão a de programa externa. Se
EA=1, então teremos 4KB de ROM interna mais 64KB de memória de programa
externa.
Para acessar a memória de programa externa, são emitidos endereços de 16
bits (0h – Fh), sacrificando então as porta P0 e P2 quando se deseja fazer uso da
memória de programa externa.
9.6.1 Memória RAM Interna
O 8051 fornece uma memória de dados interna com um mínimo de 128 bytes,
com isso para muitas aplicações que não necessitam de grande quantidade de
memória, não há a necessidade de fazer uso da RAM externa.
De acordo com a figura 8, a memória interna é dividida em três blocos
fisicamente distintos, sendo dois deles blocos de RAM de 128 bytes cada,
mapeados nos endereços 00H-7FH e 80H-FFH, também tem os registradores de
funções especiais, que estão endereçados na faixa de 80H-FFH. O modo de
endereçamento acessa de maneira distinta o bloco superior e o de registradores de
funções especiais, que possuem o mesmo endereço.
28
Figura 9 - Memória RAM do 8051.
9.6.2 Memória RAM Externa
Conforme explicado anteriormente, a memória de dados externa pode ocupar
até 64KB. Porém, como a faixa de endereço da memória de programa e da memória
de dados interna, que corresponde de 00h – FFh, é a mesma, há conflitos no
endereçamento.
Tal conflito pode ser resolvido de duas maneiras. Um corresponde a ativação
ou não do sinal PSEN (Program Store Enable), responsável pela leitura na memória
de programa. O hardware utiliza esse sinal para habilitar o banco de memória
correspondente. A outra forma corresponde à utilização das instruções MOV e
MOVX, sendo que a MOV é utilizada para acessar a memória de interna, e a MOVX
para acessas a memória externa.
9.7
REGISTRADORES DE FUNÇÕES ESPECIAIS
Os Registros de Função Especial (SFRs - Special Function Registers) são de
suma importância no do controle do 8051. Os registradores podem ser endereçados
29
a byte através do endereço correspondente (exemplo: MOV P0, #2FH), ou através
do nome (exemplo: MOV DPL, DPH).
Está descrito na tabela 3, os registradores especiais com seu endereço na
RAM ao lado, e a descrição de sua função básica.
Tabela 3 - Função básica dos SFRs.
Registrador de Função
Especial
Função básica
P0 (80H), P1 (90H), P2 Corresponde aos endereços na RAM que contém os
(A0H) e P3 (B0)
dados das 4 portas de I/O do micro, caso as mesmas
sejam utilizadas com essa finalidade. Ao realizar uma
escrita em um desses registros, o conteúdo presente na
saída do pino será automaticamente alterado.
Ao realizar uma leitura dos mesmos, coloca o estado atual
do pino em um desses registradores.
SP (81H)
É o apontador de pilha (Stack Pointer), que aponta para o
topo da pilha, ou seja, indica o último endereço que foi
armazenado na pilha.
DPL (82H) e DPH (83H) Em conjunto formam o DPTR,
endereçamento indireto de 16 bits.
utilizado
para
PCON (87H)
O registro PCON (Power Control) permite controlar o
consumo de energia do microcontrolador com segurança.
TCON (88H) e TMOD
(89H)
Registros responsáveis pelo Controle e de Modo de
Operação dos Temporizadores/Contadores, permitindo a
programação dos mesmos.
TL0 (8AH), TH0 (8CH), São os registros que contem os valores a serem contados
TL1 (8BH) e TH1 (8DH) dos Temporizadores/Contadores (T0 e T1).
SCON (98H) e SBUF
(99H)
SCON permite trabalhar com a porta de comunicação
serial e o SBUF armazena os dados recebidos e escreve
os dados transmitidos.
IE (A8H) e IP (B8H)
Registro para programação (habilitação/desabilitação,
prioridade etc.) das interrupções.
PSW (D0H)
O PSW (Program Status Word - palavra de status do
programa) é responsável pelo registro dos Flags do 8051,
indica as operações que ocorreram na ALU e o banco de
registradores que foi acessado por último.
ACC (E0H)
É o acumulador. É acessível como posição de memória.
B ( F0H)
Registro auxiliar B. É acessível como posição de memória.
30
9.8
CONJUNTO DE INSTRUÇÕES
A família MCS-51 apresenta um total de 111 instruções, sendo elas
aritméticas, lógicas, booleanas, transferência de dados e de desvios. As instruções
são otimizadas para melhorar o desempenho das aplicações de 8 bits. Abaixo estão
relacionados exemplos de instruções e o seu tipo correspondente.
MOV A, 20h; move para o acumulador o dado presente no endereço
20h - Instrução de transferência de dados.
INC 23h; incrementa o conteúdo da memória RAM de endereço 23h Instrução Aritmética.
ORL P1, A; seta os pinos de P1 segundo os valores dos bits do
acumulador - Instrução Lógica.
JB P3.4, T0_ON; testa se a entrada do temporizador 0 está setado Instrução booleana.
SJMP 00h; desvia para a próxima instrução (offset = 0) - Instrução de
desvio.
31
10 CAPÍTULO 3 – BLUETOOTH
Bluetooth é um padrão global para a comunicação sem fio de curto alcance,
automático e de baixo consumo de energia. Para isso ela usa ondas de rádio
freqüência, para substituir todo o cabeamento necessário para trocar dados entre
dispositivos eletrônicos.
Dentre suas principais vantagens citamos: elevados níveis de segurança,
baixo custo efetivo, baixo consumo de energia ao manter a potência de transmissão
em níveis bem baixos, comunicação simples e eficiente, além de fornecer serviços
síncronos (como voz sobre ip), e assíncronos (como transferências de arquivos).
A história do Bluetooth começa em 1994, quando a Ericsson estudava a
viabilidade de transmitir dados entre celulares usando rádio frequencia no lugar nos
cabos convencionais, resultando no MCLink que é um sistema de rádio de curto
alcance. Após o lançamento a Intel, IBM, Toshiba e Nokia se uniram a Ericsson e
criaram o consórcio Bluetooth SIG (Special Interest Group).
Com empresas das mais diversas tecnologias pertencentes ao consórcio SIG,
tornou-se possível a interoperabilidade da tecnologia nos mais diversos tipos de
aparelhos eletrônicos. O SIG é uma organização privada sem fins lucrativos, e é
responsável por proteger os direitos da marca Bluetooth, publicar especificações,
administrar a qualificação do programa e difundir o uso da tecnologia de
comunicação sem fio.
O Bluetooth opera na faixa ISM (Industrial, Scientific, Medical), que opera à
freqüência de 2,45 GHz, ela está livremente disponível e não é licenciada na maioria
dos países, a sua faixa de operação varia de 2,4 GHz a 2,5 GHz. Por operar em
uma banda que não é licenciada, ocorrem interferências com outros aparelhos
operantes na mesma faixa, por isso se utiliza a técnica de saltos adaptativos em
frequência (Adaptive frequency hopping – AFH)
com o intuito de diminuir tal
interferência.
32
O AFH detecta os outros dispositivos no espectro e evita as frequência que
eles estão utilizando, para isso ele divide a faixa em 79 canais e muda de canal
regularmente podendo mudar até 1600 vezes por
segundo. Com isso qualquer
interferência que ocorrer dura em fração de segundo.
Os sistemas Bluetooth podem, através dessas faixas de alcance,
formar
pequenas redes privadas conhecidas como PANS (Personal Area Networks – Redes
de Área Pessoal) ou piconets. Uma piconet é uma rede formada por até oito
dispositivos, assim cada aparelho dotado da tecnologia Bluetooth pode comunicar
com até outros 7 aparelhos da mesma piconet. A piconet é formada
automaticamente à medida que os aparelhos saem e entram na cobertura da
piconet.
O dispositivo Bluetooth que iniciar a conexão assume o papel de master
(mestre), enquanto que os demais dispositivos se tornam slave (escravos), com isso
em cada piconet deve haver um master e no máximo sete slaves.
Um dispositivo pode fazer parte de mais de uma piconet ao mesmo tempo,
como por exemplo na figura 10, o mesmo dispositivo é escravo na piconet A (slave
A3) e na piconet B(slaveB3). Desta forma ocorre a formação de uma scatternet,
onde uma piconet se comunica com outra dentro de um limite de alcance.
Figura 10 - Duas piconets formando uma scatternet, com um dispositivo escravo em comum.
33
O raio de operação da piconet vai depender dos dispositivos que estão sendo
utilizados. Tais dispositivos são classificados em três categorias, de acordo com a
tabela 4.
Tabela 4 - Classificação dos dispositivos Bluetooth.
Classe
Alcance
Potência
Classe 1
Longo alcance (100 m)
Entre 1 mW e 100 mW
Classe 2
Curto alcance (10 m)
Entre 0,25 mW e 2,5 mW
Classe 3
Curtíssimo (1 m)
Até 1 mW
10.1
Processo de estabelecimento de conexões
Assim que um dispositivo Bluetooth detectar outro, este assume o papel de
master e passa a gerenciar a conexão sobre o outro dispositivo que assume o papel
de slave. O master pode realizar a conexão de duas maneiras:
1. Comando Inquiry - é utilizado quando não é conhecido o número de
identificação ou endereço dos slaves. Permite que descubra quais os dispositivos
que estão ao alcance do master.
2. Comando Page - é utilizado assim que o endereço do slave for obtido e tem
a função de completar o estabelecimento da conexão. Quando for estabelecida a
conexão os dispositivos Bluetooth trocam pacotes entre si para sincronizar seus
relógios, definir a identificação de cada dispositivo e controlar a troca de mensagens.
Depois de estabelecida a conexão o dispositivo pode assumir os seguintes
estados:
Estado de Espera: Quando o dispositivo está ligado mas ainda
não se conectou a uma piconet.
Estado de Solicitação: Quando um dispositivo envia requisições
para encontrar outros que estejam ao seu alcance e que ele pode se
conectar.
Estado de Página: Estado onde há um envio de mensagens para
encontrar outros dispositivos que possam entrar ao alcance na sua piconet, e
apenas dispositivos mestres podem ficar neste estado de página.
34
Estado Conectado: Assim que for estabelecida a conexão, e um
dos dispositivos assumir o papel de mestre e o outro de escravo.
Estado de Transmissão: Estado em ocorre a transmissão de
dados de um dispositivo a outro. Depois da transmissão, retorna-se ao estado
conectado.
Estado de Escuta: Quando o escravo fica inativo por uma
quantidade definida de slots.
Estado bloqueado: Semelhante ao estado de escuta, porém não
ocorre transferência de dados.
Estado estacionado: Um dispositivo entra nesse estado quando
perde o seu endereço atual na piconet.
A figura 11 mostra o conjunto de estados que um dispositivo Bluetooth pode
encontrar, assim que for estabelecida a conexão.
Figura 11 - Conjunto de estados dos dispositivos Bluetooth.
35
11 DISPOSITIVOS UTILIZADOS
11.1
AT89C52
O AT89C52 é um microcontrolador baseado no 8051, que possui uma CPU
de 8 bits de alta performance baseado na tecnologia CMOS, possui baixo consumo
de energia, e 8 KB de EPROM.
O dispositivo é produzido usando a tecnologia de memória não-volátil de alta
densidade, e é compatível com os padrões de pinagem e conjunto de instruções do
80C51 e 80C52. O Flash on-chip permite a memória de programa ser reprogramada
no sistema, ou por um programador convencional de memória não-volátil.
Através da combinação de uma CPU de 8 bits versátil com flash em um chip
monolítico, o AT89C52 é um poderoso microcomputador que fornece uma solução
altamente flexível e de baixo custo para a maioria das aplicações de controle
embarcados.
O AT89C52 foi projetado com lógica estática para operar com freqüências
próximas de zero, e possui dois modos de economia de energia selecionáveis por
software. O modo de espera interrompe a CPU enquanto permite que a RAM,
temporizadores/contadores, a porta serial, e o sistema de interrupção permaneçam
funcionando. O modo de desligamento salva o conteúdo da RAM, mas congela o
oscilador, desabilitando todas as outras funções do chip, até o próximo sinal de reset
do hardware.
Características:
• Compatível com produtos de MCS-51
• 8KB de memória Flash reprogramável
• Operação inteiramente de estática: 0 hertz a 24 megahertz
• Fechamento em três níveis da memória do programa
• RAM interno de 8 bits de 256 x
36
• 32 linhas programáveis de entrada/saída
• Três temporizadores/contadores de 16 bits
• Oito fontes da interrupção
• Canal de comunicação serial programável
• Baixo consumo de potência no estado de espera e modo de desligamento
11.1.1 Memória de Dados
O AT89C52 implementa 256 bytes de RAM on-chip. Os 128 bytes superiores
ocupam um espaço de endereçamento paralelo ao dos registradores de função
especiais (Special Function Registers).
Isso significa que os 128 bytes superiores possuem o mesmo endereço que
os Registradores de Funções Especiais, mas estão fisicamente seprados no espaço
de memória.
Quando uma instrução acessa um endereço de memória interno abaixo do
endereço 7FH, o modo de endereçamento usado na instrução especifica se a CPU
deve acessar os 128 bytes superiores da memória RAM ou o espaço de
endereçamento dos registradores de função especiais.
Por exemplo a instrução seguinte que usa o modo de endereçamento direto
no endereço 0A0H (correspondente a P2)
MOV 0A0H, #data
Instruções que usam o modo de endereçamento indireto acessam os 128
bytes superior da RAM.
Por exemplo a instrução abaixo que usa endereçamento indireto, onde R0
contem 0A0H, que acessa os dados do endereço 0A0H em vez de P2 cujo endereço
também é 0A0H.
MOV @R0, #data
37
Podemos
observar
que
as
operações de
pilha
são
exemplos
de
endereçamento indireto, então os 128 bytes de dados da RAM estão disponíveis
como espaço de pilha.
A figura 12 representa o mapa dos Registradores de Função Especiais e os
valores de Reset do AT89C52.
Figura 12 - Mapa dos SRF e seus valores de Reset
38
11.2
MOTOR DE PASSO
11.2.1 Definição
Os Motores de Passo são dispositivos eletro-mecânicos síncronos, que
possuem a função de converter pulsos digital de algum sinal (geralmente sinais
elétricos) em movimentos mecânicos rotativos bem preciso, gerando variações
angulares discretas. Os motores de passo podem ser aplicados em sistemas de
malha aberta, ou seja, sem qualquer controle de realimentação, e possuem três
tipos básicos: de relutância variável, ímã permanente e híbridos.
Relutância Variável
Consiste de um rotor de ferro, com múltiplos dentes e um estator com uma
quantidade especifica de enrolamentos. Se energizarmos os enrolamentos do
estator com corrente DC os pólos ficam magnetizados. A rotação ocorre quando os
dentes do estator são atraídos para os pólos do estator energizado, para que o
sistema tenha o circuito com menor relutância.
Ímã Permanente
Possuem baixo custo e baixa resolução e baixo torque. O rotor é construído
com ímãs permanentes e não possui dentes. Os pólos magnetizados do rotor
provêm uma maior intensidade de fluxo magnético exibindo então uma melhor
característica de torque.
Híbrido
Mais caro do que os demais, porém possui melhor desempenho com respeito
à resolução de passo, torque e velocidade. O rotor é multi-dentado e contem um ímã
permanente ao redor do seu eixo. Para aplicações que exigem um controle bem
rígido e um ajuste fino de posicionamento, em máquinas de pequena e média
dimensão, os motores de passo híbrido são os mais utilizados devido à sua ótima
relação custo/benefício.
O motor de passo diferencia da maioria dos motores elétricos devido a sua
capacidade de controlar movimentos de forma bem precisa, sendo amplamente
usados em impressoras, robôs e na automação industrial.
39
A precisão de movimento aliado ao seu torque, a capacidade de atingir uma
boa velocidade, a boa resposta a aceleração e desaceleração, e por seguir uma
lógica digital, fez do motor de passo o mais viável para o nosso projeto de controle
do guincho.
Os motores de passo possuem como componentes o rotor e o estator. O rotor
é o conjunto eixo-imã que rodam solidariamente na parte móvel do motor, e o estator
correspondem a trave fica onde são enroladas as bobinas.
Se aplicarmos uma seqüência definida de pulsos elétricos nos terminais do
motor, o rotor de um motor de passo é rotacionado em incrementos angulares
específicos, denominados “passos”.
Abaixo especificamos os principais parâmetros dos motores de passo e com o
que estão relacionados.
11.2.2 Parâmetros dos motores de passo:
Rotação do motor: diretamente relacionado com os impulsos elétricos
recebidos.
Direção: relacionado com a seqüência que pulsos elétricos são
aplicados. Invertendo a seqüência dos pulsos, muda-se a direção de rotação
do motor.
Velocidade: relacionado com a freqüência de pulsos recebidos. Quanto
menor o intervalo entre os pulsos maior a velocidade, e vice-versa. O intervalo
não deve ser inferior a 10ms entre cada passo, pois geralmente o motor
perderá o torque e em vez de rodar, irá vibrar.
Ângulo rotacionado: relacionado com o número de pulsos aplicados.
O motor de passo utilizado é o 23LM-C004, que corresponde a um motor de
passo unipolar, com tensão de 6V/fase, corrente de 1,2A/fase e deslocamento
angular de 1,8graus/fase.
Por ser unipolar é caracterizado por ter 2 enrolamentos por fase sendo que a
corrente atravessa em um sentido em cada enrolamento, e possui uma derivação
central (center-tape) em cada uma das bobinas.
40
Essa derivação central é usada para alimentar o motor, e o motor de passo
basicamente é controlado aterrando seus enrolamentos. O aterramento é feito por
um circuito controlador e um driver, para que conforme acionado possa produzir uma
rotação contínua em alguma direção. O circuito de controle pode inverter o sentido
rotação do motor (horário/anti-horário) e até mesmo variar a sua velocidade.
Para que o motor de passo funcione corretamente, a alimentação deve ser de
forma seqüencial (energizando as bobinas em uma ordem específica) e repetida
(para que execute o movimento contínuo, definido pelo número de passos).
11.2.3 Ponte H
Os motores de passo podem ter seu sentido de rotação invertido, apenas
mudando o sentido dos pulsos elétricos aplicados no mesmo, ou seja se invertermos
o sentido da corrente elétrica que atravessa as bobinas do motor.
Poderíamos então inverter a polaridade dos terminais elétricos de um circuito,
que conseqüentemente inverteria o sentido da corrente. Para inverter a polaridade
elétrica poderíamos usar chaves, no qual se estiverem devidamente usadas para
este propósito controlariam facilmente o sentido do motor.
Porém como a maioria dos motores de passo são usados em processos
automatizados, o uso de chaves torna-se inadequado, para resolver este problema
podemos inserir transistores no circuito para poder controlar a corrente elétrica sem
o uso de partes móveis.
A Ponte H é um circuito transistorizado que visa controlar esse sentido de
corrente, permitindo que um determinado motor rode tanto no sentido horário quanto
no anti-horário, e o seu nome "ponte H" é devido ao formato do circuito quando
montado.
Para construir um circuito Ponte H chaveado, basta ligar conforme a figura 13,
na qual um par de chaves são acionadas de forma alternada (S1 e S4 ou S2 e S3)
para inverter o sentido da corrente.
De acordo com a figura 13, se as chaves S1 e S4 estiverem fechadas e as
chaves S2 e S3 abertas, uma tensão positiva será aplicada no motor, já se as
chaves S1 e S4 estiverem fechadas e S2 e S3 estiverem abertas, uma "tensão
negativa" será aplicada ao motor, invertendo o sentido da corrente. Nesta
41
configuração, as chaves S1 e S2 nunca poderão ser fechadas ao mesmo tempo,
pois isso ocasionaria um curto-circuito da fonte de tensão, de forma análoga as
chaves S3 e S4 não podem ser fechadas ao mesmo tempo.
Figura 13 - Ponte H chaveada
Para construir uma ponte H automatizada podemos utilizar qualquer
dispositivo que simule uma chave, como transistores, relés ou mosfets. No nosso
projeto usamos transistores que quando estiverem no corte funcionam como uma
chave fechada, e quando estiverem saturados funcionam como uma chave aberta.
A presença de diodos entre os transistores serve de proteção devido à FCE
(força contra eletromotriz) que é gerada pelo motor durante a partida e durante as
paradas, e serve também para controlar a circulação da corrente como no caso do
motor deixar de funcionar, fazendo com que a corrente volte para a fonte de
alimentação.
Capacitores podem ser adicionados para minimizar picos de tensão nas
bobinas do motor, evitando faiscamento nas escovas. Além disso, serve também
para filtrar ruídos de alta-freqüência e minimizar interferências em equipamentos de
RF.
Figura 14 - ponte H automatizada.
42
11.3
Módulo Bluetooth RS232 TTL
É um módulo transceptor criado para permitir a comunicação sem-fio entre
dispositivos utilizando o protocolo Bluetooth. É interessante para a comunicação de
um dispositivo como um guincho e outros dispositivos móveis para mandar
mensagens de controle, pois ele permite que o dispositivo de destino envie e receba
dados TTL (Lógica Transistor-Transistor) usando o protocolo Bluetooth sem a
necessidade de cabos seriais.
Características:
Fácil de usar e completamente encapsulado.
Chipset da CSR (empresa pioneira em projetos que usam Bluetooth).
Bluetooth de classe 2 (possui um alcance de até 10 metros e um
consumo de potência entre 0,25 mW e 2,5 mW) .
Modulação: GFSK (Gaussian Frequency Shift Keying), que é a técnica
de modulação mais usados nos sistemas Bluetooth, pois fornecem uma
melhor eficiência espectral.
Opções de Segurança: Autenticação e encriptação
Baud Rate definido pelo usuário: 1200, 2400, 4800, 9600, 19200,
38400, 57600, and 115200.
Tensão: de 3,6 até 6V.
No nosso projeto é necessário usar apenas 4 pinos do módulo Bluetooth, que
são: Vcc, Terra(GND), Tx (transferência de informação) e Rx (recebimento de
informação), conforme a figura 15.
43
Figura 15 - Pinos usados do módulo Bluetooth.
11.4
Conversor A/D (ADC0804)
Um conversor analógico-digital é um dispositivo eletrônico capaz de converter
grandezas analógicas em digital (zeros e uns).
O conversor ADC0804 usado em nosso projeto, é um circuito integrado
produzido pela National Semicondutor que é um dos maiores fabricantes de
semicondutores, circuitos integrados, processadores embutidos e softwares e
ferramentas de apoio, sediada na Califórnia – EUA.
O ADC0804 converte amostras analógicas (de 0 a 5 Voltz), em um valor
binário de 8 bits, baseado em CMOS, converte os valores por aproximação, baseado
em
uma
escada
diferencial
potenciométrica.
Não
é
necessário
nenhum
interfaceamento lógico, pois o conversor é visto como endereço de memória ou
portas de entrada/saída pelo microprocessador.
Entradas analógicas diferenciais de tensão permitem o aumento da rejeição
de modo comum e compensando o valor zero analógico da tensão de entrada. Em
compensação a tensão de referência pode ser ajustada para permitir a codificação
de qualquer tensão analógica para a sua respectiva resolução de 8 bits.
A sua saída poderá assumir valores entre 0 a 255 decimal (ou de 00000000
até 11111111 binário), sendo equivalente a 5V podendo ser convertidos em valores
44
múltiplos de 1*0,0195V=19,5mV até 255*0,0195V= 4,99V, conforme o esquema da
figura abaixo.
Figura 16 - Cálculo de resolução do ADC.
11.4.1 Características:
Interface fácil e simples com todos os microprocessadores, ou opera no
modo "stand alone". Interface lógica não requerida e tempo de acesso de 135
ns.
Entradas de tensão analógica diferencial
Funciona com 2.5V (tensão de referência), com máximo de 6,5V
Corrente de alimentação de 1,3mA (típica), 2,5mA (máxima)
Gerador de clock interno (on chip)
Chip moldado com 20 pinos
Nenhum ajuste zero.
Fornece de 0 até 5V a partir de uma única alimentação de 5V.
Características da Pinagem do ADC0804:
Tabela 5 - Descrição da Pinagem do ADC0804
Pinos
VIN(+) e VIN(-)
DB0 a DB7
Função/Descrição
Entradas analógicas diferenciais
Saídas digitais
45
/CS (entrada)
Seleção do Chip quando em nível "0"
/RD (entrada)
Habilita leitura disponibilizando os dados na saída quando em
nível "0"
/WR (entrada)
Comanda início de conversão quando em nível "0"
CLOCK IN
(entrada)
/INTR (saída)
Terminal de malha RC
Sinal indicando fim de conversão quando comutado para nível "0"
AGND
Terra analógico
DGND
Terra digital
VREF/2
Tensão de referência no valor da metade de V+, para correção
de fundo de escala
CLOCK R
(entrada)
V+ ou VREF
Segundo terminal para geração de clock interno
Tensão de alimentação
11.4.2 Funcionamento:
O conversor possui 2 entradas analógicas diferencias VIN(+) e VIN(-), fora do
modo livre uma ligação do pino 3 (/WR) com o pino 5 (/INTR) providencia um sinal
de início de conversão. Uma tensão de referência VRE/2 de precisão pode corrigir
um erro no fundo de escala do conversor. O seu terminal /CS é capaz de habilitar o
dispositivo em um endereçamento de I/O para dispositivos externos pela CPU.
O pino /RD habilita diretamente a saída colocando os dados no barramento
do sistema. O sinal de clock é gerado internamente bastando apenas a colocação de
um resistor e um capacitor externo, sua freqüência será determinado pela fórmula
abaixo.
Onde: R é o valor da resistência, C é o valor da capacitância.
Observação: O valor do resistor recomendado pelo fabricante é de 10K.
46
11.4.3 Converter a entrada analógica e ler a saída do ADC0804.
1. Faça CS = 0 e envie um pulso de alta para baixa o pino WR para iniciar a
conversão.
2. Continue monitorando o pino INTR. INTR será 1 se a conversão estiver concluída,
e será 0 se a conversão ainda não estiver terminada.
3. Se a conversão não está terminada (INTR = 0), aguarde até que esteja terminado.
4. Se a conversão for concluída (INTR = 1), vá para o passo seguinte.
5. Fazer CS = 0 e enviar um pulso de alta para baixa para o pino RD para ler os
dados a partir do ADC (trazer os dados convertidos para os pinos de saída).
Figura 17 - Interface do ADC 0804 com o 8051.
A figura 17 acima mostra o esquema usado para fazer o interfaceamento
ADC0804 com o 8051. Basicamente o circuito converte uma entrada analógica de
tensão (Vin) em dados digitais e exibe este resultado sobre os 8 LEDs que estão
ligados na porta P0 do microcontrolador.
47
Se a tensão de entrada Vin for 5V, todos os LEDs acenderão representando
255 em binário que equivale a 11111111, e a cada queda de tensão de 19,5mV
(referente ao cálculo da resolução) fará com que os LEDs representem uma unidade
a menos referente ao valor máximo de 255 em decimal.
Neste esquema a porta P1 do microcontrolador está funcionando como
entrada e a porta P0 está funcionando como saída. E os sinais de controle INTR,
WR, RD e CS, estão respectivamente conectados aos pinos P3.4 a P3.7 do
microcontrolador. O resistor R9 e o capacitor C1 estão associados com o circuito de
relógio interno do ADC, os resistores R1 a R8 são limitadores de corrente, já o
resistor R10 forma um divisor de tensão, que é aplicado aos pinos de entrada
analógica do ADC.
11.5
ULN2803
O CI ULN2803 tem 8 entradas que podem controlar até 8 saídas. Um CI
ULN2803 pode controlar até 2 motores de passo simultaneamente.
Figura 18 - CI ULN2803.
Como podemos observar na figura 18, o CI ULN2803 contêm 8 transistores
com emissores comum e diodos de supressão integral para cargas indutivas. Cada
transistor comporta uma corrente de carga de pico de 500mA contínuo, e pode
48
suportar pelo menos 50V no estado desligado. As saídas podem ser configuradas
em paralelo para suportarem uma corrente maior.
Possui um resistor de entrada 2.7kW para 5V TTL e CMOS. Apresentam um
pino de saída oposto ao de entrada para simplificar o layout da placa.
11.6
Potenciômetro
Potenciômetros são dispositivos elétricos formados por resistores variáveis
com uma derivação central, sendo que a resistência entre os terminais extremos
(valor nominal) é fixa, como por exemplo, 10KΩ (usado em nosso projeto).
Já a resistência entre a derivação central e um dos terminais extremos vai ser
definido pelo posicionamento do cursor, podendo ser ajustada de um valor muito
baixo de resistência (aproximadamente 0Ω) até o seu valor nominal. A figura 19
mostra as principais partes de um potenciômetro linear.
Figura 19 - Partes de um potenciômetro linear.
49
Os potenciômetros mecânicos possuem internamente uma pista de material
resistivo (carbono, cromo, níquel, etc) por onde desliza o cursor, se a resistência
entre a derivação central e uma das extremidades variar linearmente com relação ao
movimento do cursor, o potenciômetro é dito linear. A figura 20 mostra a relação
entra as resistências dos terminais (A e C) e o cursor (B), com o deslocamento do
cursor (giro).
Figura 20 - Relação entre giro do cursor e as resistências.
11.7
L298N
O Circuito Integrado L298N é um circuito integrado monolítico, constituído de
dupla Ponte-H e projetado para aceitar níveis lógicos TTL padrão e unidade de
cargas indutivas tais como relés, solenóides, DC e motores de passo. Internamente,
o L298N consiste de quatro amplificadores de potência independentes, com
entradas digitais de 5V, sendo que estes amplificadores de conduzir motores DC, ou
motores de passo unipolar e bipolar.
Os quatro amplificadores de são freqüentemente usados em pares, formando
uma ponte H para alternar a polaridade com o intuito de controlar a direção de um
motor DC.
50
Características:
Driver de ponte dupla
Corrente de saída: 2A
Voltagem de saída: 46V
N º de pinos: 15
N º de saídas: 4
Faixa de Tensão: 4.5V – 7V
Temperatura de Operação: -25 ° C a 130 ° C
Corrente máxima: 4A
Tensão máxima: 50V
A pinagem do L298N do modelo Multiwatt15 utilizado neste projeto está
descrita na figura 21.
Figura 21 - Pinagem do L298N.
Os pinos 1 e 15 são usados como sensor de corrente (current sensor). Eles
podem ser ligados diretamente ao terra do circuito, porém é aconselhável conectá-lo
51
a um resistor de baixo valor (até 0,5Ω) para não influenciar na corrente de saída, e
para que possa ser medido a tensão em cima do mesmo e calcular a corrente que
está sendo fornecida.
Os pinos ENA, ENB, e IN1-IN4 possuem o padrão de 5V lógica TTL para
fazer a conexão com a maioria dos microcontroladores de maneira simples e fácil.
O pino Supply voltage corresponde a tensão de alimentação para os motores
de passo, enquanto que o pino Logical Supply Voltage corresponde a tensão do
circuito de controle +5V do 8051. O pino 8, GND é ligado diretamente ao terra. Entre
as tensões de alimentação e o terra são inseridos capacitores de desacoplamento.
Os pinos Enable A e Enable B, podem ser colocados em nível alto
diretamente conectados ao Vs, ou podem ser usados por pinos de controle
provenientes do 8051. A figura 22 mostra o esquema de ligação do L298N com um
motor de passo bipolar.
Figura 22 - Ligação do L298N com motor de passo bipolar.
52
12 FERRAMENTAS E DISPOSITIVOS UTILIZADOS
12.1
Proteus
Proteus é um software de projeto e simulação de circuitos eletrônicos,
desenvolvido pela empresa inglesa Labcenter Electronics, é muito útil para
estudantes e profissionais que desejam desenvolver projetos com aplicações
analógicas e digitais.
O software possui dois ambientes (ISIS e ARES) para criar esquemáticos e
realizar simulações, e para posteriormente criar layout de placas de circuito impresso
se necessário.
Possui um entorno gráfico no qual podem inserir os símbolos representativos
dos componentes do circuito que desejamos projetar, podendo verificar a viabilidade
das conexões, e simular o funcionamento do circuito para evitar danos aos
componentes.
Durante a simulação podemos incluir instrumentos de medição e gráficos que
demonstrem os sinais obtidos durante a simulação do circuito. Ele pode simular
circuitos com os microcontroladores mais populares e usados atualmente, como
8051, PIC, ATMEL-AVR, Motorola, entre outros.
No
ambiente
ISIS
podemos
criar
esquemas
elétricos
utilizando
microcontrolador e componentes necessários para nosso projeto. Assim que for
criado o esquema podemos programar o microcontrolador e fazer simulações e
testes que verificam a viabilidade do projeto.
No ambiente ARES, podemos transformar o esquemático do circuito
eletrônico em um layout para a confecção de placas de circuito impresso. No ARES,
podemos definir as trilhas para uma correta comunicação entre os componentes,
evitar
cruzamento
e
proximidade
das
trilhas,
prevenindo
interferências
eletromagnéticas e possível mal funcionamento do circuito. A figura 23 mostra os
ambientes ISIS (esquerda) e ARES (direita).
53
Figura 23 - Ambientes ISIS (esquerda) e ARES (direita).
12.2
PEQui
O simulador PEQui é um software gratuito desenvolvido na Escola das
Engenharias Elétrica Mecânica e de Computação, da Universidade Federal de
Goiás, que auxilia estudantes e desenvolvedores que desejam projetar circuitos com
o microcontrolador 8051.
No ambiente do PEQui podemos digitar, compilar e simular o programa
escrito em Assembly a ser carregado no microcontrolador 8051. O PEQui é capaz
de simular as todas as funcionalidades do microcontrolador 8051, como
comunicação serial, fontes de interrupção, contadores/temporizadores, etc. Também
é capaz de transmitir os arquivos “hex” para o microcontrolador através da porta
serial do computador.
12.2.1 Funcionamento:
O programa digitado é gravado automaticamente com a extensão ".asm”. A
compilação do programa gera um arquivo com extensão “.hex”
e outro com
extensão ".lst". O programa “.lst” fornece a listagem do programa em assembly e o
código hexadecimal equivalente, além de possíveis mensagens de erro.
O kit didático é acompanhado de um programa que é usado para transferir o
arquivo ".hex" para o kit. O programa transferido inicia automaticamente sua
execução.
54
Figura 24 - Ambiente do PEQui.
O simulador permite visualizar os conteúdo dos principais registradores do
8051, além de poder depurar o programa passo a passo (por instrução), verificando
alterações na memória RAM, do conteúdo das portas de 8 bits e dos registradores.
12.3
ChipMax2
ChipMax2 é um dispositivo programador universal de baixo custo e alto
desempenho que utiliza a interface PC USB 2.0. Pode programar uma memória flash
de 64Mb em 42 segundos. Suporta mais de 13.000 dispositivos programáveis de
baixa tensão, oferece uma interface amigável e várias facilidades para programação
de chips. Suporta EPROM e microcontroladores, identifica se o chip foi corretamente
inserido antes de programar assim como pinos mal conectados.
55
Figura 25 - Dispositivo de gravação de chips ChipMax2.
12.4
MaxLoader
O maxloader é uma ferramenta da EETools. Apresenta uma interface simples
como podemos verificar na figura 26, que permite ler, apagar, verificar e programar
memórias e microcontroladores. Possui um catálogo variado de microcontroladores,
e trabalha com o dispositivo de gravação ChipMax2.
Figura 26 - Ambiente do MaxLoader.
56
12.5 Eclipse e Android SDK
O Eclipse é uma IDE (integrated development environment) desenvolvida em
JAVA, usada para facilitar o desenvolvimento de aplicações em várias linguagens de
programação, entre elas o JAVA, C++, PHP, entre outras. Formada por um
consórcio da IBM, é a IDE líder de mercado, e segue o modelo open source de
desenvolvimento de software. Suas principais características são:
Utiliza o SWT (The Standard Widget Toolkit) como biblioteca gráfica,
que usa componentes nativos do sistema operacional. Isso permite
criar
aplicações
gráficas
multiplataforma
sem
sacrificar
a
compatibilidade.
Orientação ao desenvolvimento baseado em plugins, que possuem
inúmeras funcionalidades diferentes, como: suporte a servidores de
aplicação, visualizadores de banco de dados, geradores de diagramas
UML, etc.
Portátil, ou seja, as aplicações desenvolvidas são compatíveis com
vários ambientes.
Permite a refatoração do código, permitindo melhorar o design sem
alterar a funcionalidade.
Juntamente com o Eclipse, foi preciso baixar e instalar o SDK (kit de
desenvolvimento de software) do Android. Depois de instalar o Android SDK, através
do Android SDK Manager, baixamos a API 2.3.3 para Android, escolhida como
versão mínima requerida para o aplicativo.
Após isso baixamos e instalamos o plugin de desenvolvimento Andoid para o
Eclipse, o Android Development Tools (ADT). O ADT possibilita criar mais
rapidamente novos projetos Android, construir uma interface do aplicativo, depurar o
aplicativo e exportar pacotes para distribuição.
57
13 RESULTADOS OBTIDOS
13.1 Esquemático do circuito eletrônico
A figura 27 mostra o esquemático que foi projetado e simulado no Proteus.
Figura 27 - Esquemático básico do guincho.
58
Após montar e simular o esquemático do projeto, com o programa em
assembly do Apêndice A, notou-se seu correto funcionamento, e esse circuito serviu
de base para a confecção da placa de circuito impresso.
Para facilitar a confecção do circuito impresso e para adaptá-lo melhor à
nossa necessidade, alteramos as seguintes características do circuito:
Os conversores analógico digitais (ADC0804) foram conectados nas
portas P1 e P2, e o driver L298N foi conectado na porta P0 do
microcontrolador.
O eletroímã foi conectado no pino T0 do microcontrolador.
Não foram necessárias as resistências dos pinos de sensor de
corrente do L298N. Visto que o mesmo fornece na porta uma tensão
de 6V e a resistência interna do motor de passos é de 6Ω, ele fornece
a corrente de aproximadamente 1A para o motor se desconsiderarmos
a queda de tensão dentro L298N. Nos resultados
práticos,
considerando a queda de tensão do L298N, a corrente que entra no
motor girou em torno de 750mA.
As entradas do L298N foram conectadas na porta P0 do microcontrolador, e
suas saídas ligadas às fases de cada motor. Visto que cada motor de passo possui
4 fases, foi necessário o uso de quatro pinos do microcontrolador por cada motor.
Os pinos sensA e sensB (sensor de corrente) do L298N foram ligados à porta GND
do mesmo (aterrados). O Vs é ligado à tensão de controle do micro e o Vss na
tensão de alimentação do motor de passo.
Os conversores analógico-digital de 8 bits (ADC0804), foram conectados na
porta P1 e P2 do microcontrolador, sendo que o bit menos significativo do conversor
foi ligado na .0 e o mais significativo na .7. Os pinos VIN(+) e VIN(-) que
correspondem às entradas analógicas diferenciais são conectados ao terminal de
derivação central do potenciômetro e no GND, respectivamente. Os pinos de escrita
(WR) e leitura (RD) do conversor foram ligados aos pinos de 16 e 17 do
microcontrolador. Os pinos CLK IN e CLK R são conectados ao gerador de clock do
59
micro e separados por um resistor e um capacitor em série para geração do clock
interno.
O pino Rx e o Tx do módulo Bluetooth são conectados respectivamente nos
pinos TxD(11) e RxD(10) do microcontrolador. A tensão de operação do módulo é
ligado à tensão de controle do microcontrolador, que corresponde a 5V. Já o
eletroímã foi ligado no pino T0 do microcontrolador.
Com o programa em assembly, usamos o software PEQui para emular e
depurar todo o funcionamento do micro, verificando alteração dos registradores e
envio de sinais. Para gravar o programa no chip usamos o software MaxLoader e o
dispositivo ChipMax2, que são compatíveis com os mais diversos fabricantes do
8051, inclusive o AT89C51 usado no projeto.
Convertemos o esquemático do ambiente ISIS, para o ambiente ARES do
Proteus, fizemos as modificações necessárias como trilhas cruzadas e correção das
mesmas, e otimizamos o espaço entre os componentes para deixar o circuito mais
simples e funcional.
13.2 Placa de Circuito Impresso
A Placa de Circuito Impresso é composta por camadas de materiais plásticos
e fibrosos, que contem finas películas de alguma substância metálica como cobre
níquel ou ouro. Essas películas serão responsáveis pela formação das trilhas nas
placas, onde irá fluir a corrente elétrica pelos componentes do circuito.
O desenho da placa foi feito depois de inúmeras simulações no ambiente do
PROTEUS e vários testes físicos, verificando a viabilidade do projeto. A construção
das placas veio tornar mais simples, eficaz e menos suscetível a erros os testes
físicos do sistema, pois foi reduzido drasticamente o número de fios e conexões
defeituosas.
60
Para o desenho da placa, visamos otimizar o espaço dos componentes na
placa, evitando trilhas abertas e cruzamentos, e também possíveis interferências
eletromagnéticas que poderiam ser causadas pelas proximidades das trilhas.
Deixamos também pinos para entrada de corrente e comunicação com outras
placas.
13.3
Processo de confecção da placa
1. Depois de gerado o layout da placa no ambiente ARES do PROTEUS,
imprimimos em uma impressora a laser de boa qualidade, usando papel fotográfico.
2. Lixamos a superfície da placa de circuito com uma esponja de aço para
tirar possíveis resíduos e a parte oxidada. Depois de lixada, limpamos com álcool
para retirar a gordura da placa.
3. Fixamos o layout da placa com uma fita isolante e deixamos o papel bem
firme e esticado para evitar defeitos no desenho do circuito.
4. Passamos um ferro já quente na região do desenho para transferi-lo para a
placa.
5. Deixamos a placa esfriar e retiramos o papel da placa.
6. Corroemos a placa de cobre usando percloreto de ferro, deixando de molho
em uma vasilha plástica. Depois de corroído lavamos a placa em água corrente, e
limpamos com tiner para tirar a tinta de cima das trilhas.
7. Fizemos os furos nas ilhas da placa para fixação dos componentes do
circuito. Soldamos os componentes na placa com cuidado para evitar curto circuito e
falhas nas trilhas.
As placas individuais podem ser vistas nas figuras 28, 29 e 30. Já a figura 31
mostra o circuito eletrônico completo necessário para o funcionando do projeto.
61
Figura 28 - PCI do 8052.
62
Figura 29 - PCI da ponte H com L298N.
Figura 30 - PCI de ativação do eletroímã.
Figura 31 - Circuito eletrônico completo.
63
13.4 Comunicação com os Dispositivos Bluetooth
Todo o programa para a comunicação com o Bluetooth foi feito na linguagem
de programação JAVA, e utilizando a SDK Android. O código do programa em JAVA
da comunicação Bluetooth, está no Apêndice B. Foi desenvolvido primeiramente a
interface gráfica que buscou ser simples e intuitiva, depois foi desenvolvido a
interface para a comunicação com o módulo Bluetooth. Depois foi desenvolvida toda
a estrutura lógica do sistema, que buscava adequar ao correto funcionamento de
todos os dispositivos usados no projeto, e suas respectivas limitações.
Com a conclusão do programa e em posse de um celular Android com
capacidade de comunicação Bluetooth, foi selecionado o módulo Bluetooth para
realizar a conexão. Após conectado, é mostrado uma interface simples e intuitiva, de
modo que o usuário possa operá-la sem grandes problemas. A figura 32 mostra a
interface do programa através da tela do celular.
Figura 32 - Interface do dispositivo Bluetooth.
64
Figura 33 - Controle dos motores.
Foi criada uma tela de configurações (figura 34), para possibilitar ao usuário
mudar, em tempo de execução, os valores de algumas constantes do sistema.
Através desta tela é possível limitar o curso do guincho e definir a precisão de
parada.
A definição de um valor limitador para o guincho não é só uma comodidade,
como também um fator de segurança, podendo evitar acidentes e danos nos
sensores.
Através das relações de engrenagens, e usando os limitadores de curso, foi
possível realizar a aferição dos sensores, para que indique uma posição
aproximada, traduzida em Graus, e mostrada em tempo real na tela do celular.
65
O funcionamento do programa está descrito abaixo:
- A barra de posição atual do motor pode ser vista como a porção de giro do
cursor do potenciômetro.
- A barra de posição desejada do motor é onde o usuário irá controlar o
movimento do motor, fazendo com que a barra de posição atual se locomova até a
posição desejada.
- A interface contém botões para ligar e desligar os motores, o ímã, e também
para conectar e desconectar os dispositivos Bluetooth.
Figura 34 - Tela de Configuração
66
14 CONCLUSÃO E TRABALHOS FUTUROS
O desenvolvimento deste projeto mostrou ser um grande desafio. E o principal
motivo foi a integração entre as várias áreas de conhecimento aplicadas durante seu
desenvolvimento. Durante seu processo foi necessário estudo de Mecânica,
Microcontroladores, Eletrônica e Linguagens de programação. Em cada uma dessas
áreas tivemos que realizar inúmeras pesquisas e aprofundar no conhecimento.
O processo de adequação da estrutura física para instalação de sensores e
adaptação dos motores foi bastante dispendioso. Vimos como pode ser difícil criar
um projeto baseando-se em algo já construído, em que não foi projetado para essas
mudanças. A instalação dos sensores demandou diversas horas na confecção de
engrenagens com apertos precisos, que coubessem em espaços curtos e que não
foram criados para esse propósito. Além das engrenagens diversos ajustes tiveram
que ser feitos na estrutura física, tendo em vista o desgaste sofrido com o tempo, de
forma que o funcionamento não deixasse a desejar.
O projeto eletrônico também foi de grande valor. O contato próximo com as
diversas ferramentas como conversores analógico-digital e transistores foram
fundamentais para agregar conhecimento. Nesse estudo temos que ressaltar a
importância de leitura minuciosa da documentação do fabricante, que detalha o
funcionamento de cada componente. Ainda sim, vimos que essa documentação vez
ou outra pode se apresentar confusa ou incompleta, onde se mostra importante a
troca de experiência e a orientação.
No trabalho pudemos concretizar, na prática, uma grande parte do
conhecimento aprendido nos diversos anos desta graduação. A confecção de
circuitos se mostrou um exemplo de algo que, apesar de aprendido em sua teoria,
mostra diversos desafios que só aparecem com a prática, e que agregam bastante
conhecimento.
Considerando o desafio com extensa área de conhecimento, o problema foi
enfrentado por partes. Essa abordagem foi fundamental para conseguir o resultado,
67
resolvendo problemas menores e juntando os resultados. Durante o trabalho, cada
um dos componentes foi estudado e conhecido a fundo seu funcionamento, e, só
então, iniciado o próximo, seguindo o nosso fluxo de desenvolvimento. O
componente de software também foi desenvolvido seguindo esta proposta, onde foi
desenvolvido sua interface gráfica, sua interface para comunicação Bluetooth e, por
fim, a lógica do programa.
Durante o desenvolvimento do projeto vimos também como os erros de
projeto podem atingir o andamento dos trabalhos. Com o projeto já na fase final
experimentamos um erro de cálculo em duas engrenagens no sistema, ao qual,
apesar de funcionarem, não estavam adequadas aos requisitos do projeto. Essas
modificações tiveram custo ao projeto e também serviram de aprendizado, onde
remodelamos a forma de trabalho para que não ocorresse novamente.
Por fim, o trabalho gera grandes expectativas para o futuro, tendo em vista
apresentar uma tecnologia que, apesar de não ser muito nova, ainda mostra um
enorme potencial para o mercado. Os dispositivos Bluetooth, considerando a
integração com dispositivos móveis, são uma tendência de mercado para os novos
dispositivos, e ainda não possuem um concorrente com abrangência comparável.
Isso significa que aplicações escritas para estes dispositivos podem atingir a um
número muito grande de usuários, com a provável tendência de que este quadro não
se altere nos próximos anos.
Assim, esta integração de componentes eletrônicos com dispositivos móveis
se mostra uma grande área de pesquisa, contendo inúmeros exemplos em que
podem ser trabalhados. Desde o conforto, como na automação residencial, quanto
na medicina, com sensores de saúde, até a área de segurança, as aplicações são
diversas e demanda uma mão de obra bem específica do Engenheiro de
Computação.
68
15 BIBLIOGRAFIA
[1] STALLINGS, W. Arquitetura e Organização de Computadores, Edição 5. Editora
Pearson Addison Wesley. 2005.
[2] TAUB, H.; Circuitos Digitais e Microprocessadores. São Paulo: Mc- Graw Hill,
1984.
[3] SILVA JÚNIOR , Vidal Pereira da . Microcontrolador 8051. São Paulo:Ática, 2. ed,
1999;
[4] NICOLOSI, D.E.C. Microcontrolador 8051 Detalhado. 2a. edição. São Paulo:
Editora Érica, 2000.
[5] Microcontrolador. Disponível em: <http://pt.wikipedia.org/wiki/Microcontrolador>
Acessado em 11 nov. 2012.
[6] Denardin, G.W. Apostila de microcontroladores. Disponível em:
<http://pessoal.utfpr.edu.br/gustavo/apostila_micro.pdf> Acessado em 11 nov. 2012.
[7] Lima, J.W. Notas das aulas de microcontroladores e microprocessadores.
Disponível em: <http://www.eeec.ufg.br/~jwilson/aulasmicro/ > Acessado em 11 nov.
2012.
[8] Brain, M. Como funcionam os microcontroladores. Disponível em:
<http://eletronicos.hsw.uol.com.br/microcontroladores.htm> Acessado em 17 nov.
2012.
[9] Zelenovsky, R. Mendonça, A. Arquitetura de Microcontroladores Modernos.
Disponível em: <http://www.mzeditora.com.br/artigos/mic_modernos.htm> Acessado
em 17 nov. 2012.
69
[10] Jucá, S. A apostila PIC e Periféricos. Disponível em:
<http://mecatronicananet.blogspot.com.br/2011/11/apostila-pic-e-perifericosatualizada.html> Acessado em 08 dez. 2012.
[11] Antônio, M. Apostila de:programação de microcontroladores usando linguagem
C. Disponível em: <http://www.pictronics.com.br/downloads/apostilas/Apostila-PicC.pdf> Acessado em 08 dez. 2012.
[12] Ruiz, W. Microcontroladores–Família MCS-51 Conceitos, Aplicações e Projetos.
Disponível em: <http://aragao.spo.ifsp.edu.br/files/apostilas/microcontroladores.pdf>
Acessado em 08 dez. 2012.
[13] Intel 8051. Disponível em: <http://pt.wikipedia.org/wiki/Intel_8051> Acessado em
09 dez. 2012.
[15] Neto, H.G. MICROCONTROLADORES MCS51. Disponível em:
<http://pessoal.utfpr.edu.br/hvieir/download/mcs51_1.pdf> Acessado em 09 dez.
2012.
[16] Aplicações de Microprocessadores II. Disponível em:
<http://iris.sel.eesc.sc.usp.br/sel337> Acessado em 09 dez. 2012.
[17] Aplicação de Microprocessadores I. Disponível em:
<http://iris.sel.eesc.usp.br/sel433/Aula8-i4.pdf> Acessado em 09 dez. 2012.
[18] Interfaciing ADC to 8051. Disponível em:
<http://www.circuitstoday.com/interfacing-ADC-to-8051> Acessado em 13 jan. 2013.
[19] Tateoki, G.T. Disponpivel em:
<http://www.getulio.eng.br/meusalunos/sad/ADC0804.pdf> Acessado em 13 jan.
2013.
70
[20] How to Interface Bluetooth with 8051. Disponível em:
<http://www.pantechsolutions.net/accessory-boards/Bluetooth-interfacing-with-8051>
Acessado em 27 jan. 2013.
[21] Brites, F.G. Santos, V.P. Disponível em:
<http://www.telecom.uff.br/pet/petws/downloads/tutoriais/stepmotor/stepmotor2k8111
9.pdf> Acessado em 02 fev. 2013.
[22] Controle de motor de passo através da porta paralela. Disponível em:
<http://www.rogercom.com/pparalela/IntroMotorPasso.htm> Acessado em 03 fev.
2013.
[23] O que são e como funcionam os potenciômetros digitais. Braga, N.C.Disponível
em: <http://www.sabereletronica.com.br/secoes/leitura/115> Acessado em 03 fev.
2013.
[24] Moraes, M. L298N Ponte H Dupla. Disponível em:
<http://arduinobymyself.blogspot.com.br/2013/02/l298n-ponte-h-dupla-breakoutboard.html> Acessado em 10 fev. 2013.
[25] L298 Dual H-Bridge Motor Driver. Disponível em:
<http://billwaa.wordpress.com/2012/06/06/arduino-l298-dual-h-bridge-motor-driver/>
Acessado em 10 fev. 2013.
[26]Patsko, L.F. Tutorial de Montagem da Ponte H. Disponível em:
<http://www.maxwellbohr.com.br/downloads/robotica/mec1000_kdr5000/tutorial_eletr
onica_-_montagem_de_uma_ponte_h.pdf> Acessado em 10 fev. 2013.
[27] L298 Dataseet. Disponível em:
<http://www.sparkfun.com/datasheets/Robotics/L298_H_Bridge.pdf> Acessado em
10 fev. 2013.
71
[28] Motores de passo (passo a passo). Disponível em:
<http://www.roboticasimples.com/artigos.php?acao=14> Acessado em 10 fev. 2013.
[29] Moraes,M. Ponte H - Controle de Motores DC. Disponível em:
<http://arduinobymyself.blogspot.com.br/2012/08/ponte-h-controle-de-motoresdc.html >Acessado em 10 fev. 2013.
[30] Manual em português do Proteus. Disponível em:
<http://mecatronicadegaragem.blogspot.com.br/2011/02/manual-em-portugues-doproteus-que.html> Acessado em 24 jan. 2013.
[31] Bluetooth - Camada Física e Camada de Acesso ao Meio. Disponível em:
<http://www.gta.ufrj.br/grad/09_1/Bluetooth/index.html> Acessado em 24 fev. 2013.
[32] Layton, J. Franklin, C. Como funciona o Bluetooth. Disponível em:
<http://informatica.hsw.uol.com.br/Bluetooth.htm> Acessado em 24 fev. 2013.
[33] Alecrim, E. Tecnologia Bluetooth. Disponível em:
<http://www.infowester.com/Bluetooth.php> Acessado em 24 fev. 2013.
[34] Kobayashi, C. Y. A Tecnologia Bluetooth e aplicações. Disponível em:
<http://grenoble.ime.usp.br/movel/monografia_Bluetooth.pdf> Acessado em 24 fev.
2013.
[35] Cavalheiro, L. Como fazer sua PCI (Placa de Circuito Impresso). Disponível em:
<http://lucascavalheiro.wordpress.com/2008/10/22/como-fazer-pci/> Acessado em
26 fev. 2013.
[36] Braga, N. Como funcionam potenciômetros e trimpots. Disponível em:
<http://www.newtoncbraga.com.br/index.php/como-funciona/3379-art472.html>
Acessado em 26 fev. 2013.
72
[37] Loflin, L. Connecting the Arduino to a L298N H-Bridge. Disponível em:
<http://www.bristolwatch.com/L298N/L298N_arduino.htm> Acessado em 27 fev.
2013.
73
16 APÊNDICE
A
–
CÓDIGO
EM
ASSEMBLY
DO
PROGRAMA
DO
MICROCONTROLADOR
$mod51
IMA equ T0;
MOTOR1 equ R1;
MOTOR2 equ R2;
MOTOR1_LIGADO equ 00h;
MOTOR1_SENTIDO equ 01h;
MOTOR2_LIGADO equ 02h;
MOTOR2_SENTIDO equ 03h;
IMA_LIGADO equ 04h;
RESULTADO_ENTRADA equ 20h;
RESULTADO_SAIDA equ R0;
MOTOR equ P0;
GIROMINIMO equ R3;
INTS1 equ P3.2;
INTS2 equ P3.3;
ADC_VAL1 equ R4;
ADC_VAL2 equ R5;
ADC_SENSOR1 equ P1;
ADC_SENSOR2 equ P2;
org 00h;
ajmp INICIALIZAR;
org 23h;
ajmp SERIAL;
org 40h;
INICIALIZAR:
74
mov
SP, #2Fh;
mov RESULTADO_ENTRADA, #0h;
mov RESULTADO_SAIDA, #0h;
mov MOTOR1, #0CCh;
mov MOTOR2, #0CCh;
mov GIROMINIMO, #0Fh;
mov IE, #10010000b;
mov SCON, #01010000b;
mov PCON, #00000000b;
mov TMOD, #00100000b;
mov TH1, #0FDh;
setb TR1;
INICIO:
acall APRESENTAR_RESULTADO;
acall AGUARDAR_TEMPO;
PROXIMO1:
jnb MOTOR1_LIGADO, PROXIMO2;
jnb MOTOR1_SENTIDO, INVERSO1;
mov A, MOTOR1;
rr A;
mov MOTOR1, A;
ajmp PROXIMO2;
INVERSO1:
mov A, MOTOR1;
rl A;
mov MOTOR1, A;
PROXIMO2:
jnb MOTOR2_LIGADO, PROXIMO3;
jnb MOTOR2_SENTIDO, INVERSO2;
mov A, MOTOR2;
rr A;
mov MOTOR2, A;
ajmp PROXIMO3;
75
INVERSO2:
mov A, MOTOR2;
rl A;
mov MOTOR2, A;
PROXIMO3:
jnb IMA_LIGADO, IMA_DESLIGADO;
setb IMA;
ajmp FIM;
IMA_DESLIGADO:
clr IMA;
FIM:
djnz GIROMINIMO, INICIO;
inc GIROMINIMO;
ajmp FIM;
APRESENTAR_RESULTADO:
mov A, MOTOR1;
clr C;
rrc A;
clr C;
rrc A;
clr C;
rrc A;
clr C;
rrc A;
mov RESULTADO_SAIDA, A;
mov A, MOTOR2;
clr C;
rlc A;
clr C;
rlc A;
clr C;
rlc A;
clr C;
rlc A;
76
add A, RESULTADO_SAIDA;
mov RESULTADO_SAIDA, A;
mov MOTOR, A;
ret;
AGUARDAR_TEMPO:
push B;
mov B,#0FAh;
Tempo2:
push B;
mov B,#0FFh;
Tempo1:
djnz B,Tempo1;
pop B;
djnz B,Tempo2;
pop B;
ret;
SERIAL:
mov GIROMINIMO,
#0Fh;
mov RESULTADO_ENTRADA, SBUF;
clr RI;
acall ADC_Converter;
mov SBUF, ADC_VAL1;
jnb TI, $;
clr TI;
mov SBUF, ADC_VAL2;
jnb TI, $;
clr TI;
reti;
ADC_Converter:
clr wr
77
nop
setb wr
jb INTS1,$
jb INTS2,$
clr rd
mov ADC_VAL1,ADC_SENSOR1
mov ADC_VAL2,ADC_SENSOR2
setb rd
ret;
end;
78
17 APÊNDICE B – CÓDIGO EM JAVA DO PROGRAMA ANDROID/BLUETOOTH
package ufg.eeec.guincho;
import java.io.IOException;
import ufg.eeec.guincho.BluetoothConnection.Motor;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
android.app.Activity;
android.app.Notification;
android.app.PendingIntent;
android.app.Service;
android.content.BroadcastReceiver;
android.content.Context;
android.content.Intent;
android.content.IntentFilter;
android.content.SharedPreferences;
android.os.AsyncTask;
android.os.Bundle;
android.os.IBinder;
android.preference.PreferenceManager;
android.view.Menu;
android.view.MenuItem;
android.view.View;
android.widget.Button;
android.widget.ProgressBar;
android.widget.SeekBar;
android.widget.TextView;
android.widget.ToggleButton;
android.widget.SeekBar.OnSeekBarChangeListener;
public class Principal extends Activity {
private
private
private
private
private
private
private
private
private
private
private
private
private
private
ToggleButton cmdLigaDeslMot1;
ToggleButton cmdLigaDeslMot2;
ToggleButton cmdLigaDeslIma;
ProgressBar pbPosMot1;
ProgressBar pbPosMot2;
SeekBar sbPosDesMot1;
SeekBar sbPosDesMot2;
TextView txtPosDesMot1;
TextView txtPosDesMot2;
TextView txtPosMot1;
TextView txtPosMot2;
Button cmdBluetooth;
Button cmdConnect;
Button cmdDisconnect;
private
private
private
private
private
private
private
private
static
static
static
static
static
static
static
static
final
final
final
final
final
final
final
final
int
int
int
int
int
int
int
int
numEngrenagemSup1
numEngrenagemSup2
numEngrenagemSup3
numEngrenagemSup4
numEngrenagemInf1
numEngrenagemInf2
numEngrenagemInf3
numEngrenagemInf4
=
=
=
=
=
=
=
=
90;
12;
42;
12;
40;
12;
36;
17;
79
private static final int numVoltasSensor = 10;
private
static
final
int
anguloMaxMotor1
=
(int)
(360
numVoltasSensor / ((((float) numEngrenagemInf1) / numEngrenagemInf2)
(((float) numEngrenagemInf3) / numEngrenagemInf4)));
private
static
final
int
anguloMaxMotor2
=
(int)
(360
numVoltasSensor / ((((float) numEngrenagemSup1) / numEngrenagemSup2)
(((float) numEngrenagemSup3) / numEngrenagemSup4)));
private static final int margemSeguranca = 1;
private
static
final
int
margemSegurancaMotor1
(margemSeguranca * ((float) anguloMaxMotor1) / numVoltasSensor);
private
static
final
int
margemSegurancaMotor2
(margemSeguranca * ((float) anguloMaxMotor2) / numVoltasSensor);
*
*
*
*
=
(int)
=
(int)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.guincho);
if (context == null)
context = getApplicationContext();
// Registra um BroadcastReciever para receber solicitacoes das
threads.
RegistrarReciever();
System.out.println(margemSegurancaMotor1);
System.out.println(margemSegurancaMotor2);
// Mantem uma referencia aos controles
cmdLigaDeslMot1
=
(ToggleButton)
findViewById(R.id.cmdLigaDeslMot1);
cmdLigaDeslMot2
=
(ToggleButton)
findViewById(R.id.cmdLigaDeslMot2);
cmdLigaDeslIma
=
(ToggleButton)
findViewById(R.id.cmdLigaDeslIma);
pbPosMot1 = (ProgressBar) findViewById(R.id.pbPosMot1);
pbPosMot2 = (ProgressBar) findViewById(R.id.pbPosMot2);
sbPosDesMot1 = (SeekBar) findViewById(R.id.sbPosDesMot1);
sbPosDesMot2 = (SeekBar) findViewById(R.id.sbPosDesMot2);
txtPosDesMot1 = (TextView) findViewById(R.id.txtPosDesMot1);
txtPosDesMot2 = (TextView) findViewById(R.id.txtPosDesMot2);
txtPosMot1 = (TextView) findViewById(R.id.txtPosMot1);
txtPosMot2 = (TextView) findViewById(R.id.txtPosMot2);
cmdBluetooth = (Button) findViewById(R.id.cmdBluetooth);
cmdConnect = (Button) findViewById(R.id.cmdConnect);
cmdDisconnect = (Button) findViewById(R.id.cmdDisconnect);
//Chama os valores padrao nas preferencias, caso o usuario nao as
tenha modificado.
PreferenceManager.setDefaultValues(this,
R.xml.preferences,
false);
CarregarValoresPreferencias();
// CRIA OS EVENTOS PARA OS BOTOES
cmdBluetooth.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
80
SelecionarDispositivoBluetooth();
}
});
cmdConnect.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
Conectar();
}
});
cmdDisconnect.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
Desconectar();
}
});
sbPosDesMot1.setOnSeekBarChangeListener(new
onSeekBarChange(txtPosDesMot1, onSeekBarChange.Motor1));
sbPosDesMot2.setOnSeekBarChangeListener(new
onSeekBarChange(txtPosDesMot2, onSeekBarChange.Motor2));
}
/**
* Cria o menu de opcoes.
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menuprincipal, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.dispositivoBT:
SelecionarDispositivoBluetooth();
break;
case R.id.configuracoes:
Configuracoes();
break;
case R.id.sair:
if (PodeSair()) {
finish();
System.exit(0);
}
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
/**
* Recebe respostas das atividades iniciadas, como solicitacao de
procura de dispositivos Bluetooth
* e abrir tela de propriedades.
*/
81
@Override
protected void onActivityResult(int requestCode,
Intent data) {
// Recebe resposta as solicitacoes
switch (requestCode) {
int
resultCode,
// Recebe o dispositivo Bluetooth escolhido na atividade
case ProcuraDispositivo:
if (resultCode == RESULT_OK)
dispositivoBluetooth
=
new
DispositivoBluetooth(data.getStringExtra(BluetoothActivity.name),
data.getStringExtra(BluetoothActivity.address));
break;
case AbrePreferencias:
CarregarValoresPreferencias();
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
@Override
protected void onResume() {
AtualizarInterface();
super.onResume();
}
@Override
protected void onDestroy() {
unregisterReceiver(broadcastReceiver);
super.onDestroy();
}
/** Nome para salvar estado persistente da variavel "strEstado" **/
private static final String strEstado = "estado";
/**
Nome
para
salvar
estado
persistente
da
variavel
"strNomeDispositivoBluetooth" **/
private static final String strNomeDispositivoBluetooth = "nome";
/**
Nome
para
salvar
estado
persistente
da
variavel
"strEnderecoDispositivoBluetooth" **/
private
static
final
String
strEnderecoDispositivoBluetooth
=
"endereco";
/**
* Permite ao aplicativo manter seu estado apos a tela ser
redesenhada,
* seja na rotacao da tela, ou se o aplicativo for fechado pelo
sistema.
*
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putInt(strEstado, estado);
if (dispositivoBluetooth != null) {
outState.putString(strNomeDispositivoBluetooth,
DispositivoBluetooth.getNome());
outState.putString(strEnderecoDispositivoBluetooth,
DispositivoBluetooth.getEndereco());
}
super.onSaveInstanceState(outState);
82
}
/**
* Permite ao aplicativo manter seu estado apos a tela ser
redesenhada,
* seja na rotacao da tela, ou se o aplicativo for fechado pelo
sistema.
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
String
nome
=
savedInstanceState.getString(strNomeDispositivoBluetooth);
String
endereco
=
savedInstanceState.getString(strEnderecoDispositivoBluetooth);
if (nome != null && endereco != null)
dispositivoBluetooth
=
new
endereco);
DispositivoBluetooth(nome,
estado = savedInstanceState.getInt(strEstado);
super.onRestoreInstanceState(savedInstanceState);
}
/**
* Nao permite o usuario fechar o aplicativo sem estar no estado
desconectado.
*/
@Override
public void onBackPressed() {
if (PodeSair()) {
super.onBackPressed();
System.exit(0);
}
}
/**
*
Apresenta na tela os valores dos angulos dos motores, conforme
modificado nas barras de progresso.
*/
private class onSeekBarChange implements OnSeekBarChangeListener {
private TextView textView;
private boolean Motor;
public static final boolean Motor1 = false, Motor2 = true;
public onSeekBarChange(TextView textView, boolean Motor) {
this.textView = textView;
this.Motor = Motor;
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void
onProgressChanged(SeekBar
seekBar,
int
progress,
83
boolean fromUser) {
if (fromUser) {
if (Motor == Motor1)
textView.setText(progress
ValoresPreferencias.limiteInferiorMotor1 + "º");
else if (Motor == Motor2)
textView.setText(progress
ValoresPreferencias.limiteInferiorMotor2 + "º");
}
}
}
+
+
private static final int ProcuraDispositivo = 1;
private static final int AbrePreferencias = 2;
/** Permite ao usuario selecionar um dispositivo Bluetooth. **/
private void SelecionarDispositivoBluetooth() {
// Inicializa uma atividade para escolher um dispositivo
Bluetooth
if (estado == estadoDesconectado)
startActivityForResult(new
Intent(Principal.this,
BluetoothActivity.class), ProcuraDispositivo);
}
/** Abre a tela de configuracoes. **/
private void Configuracoes() {
if (estado == estadoDesconectado)
startActivityForResult(new
Preferencias.class), AbrePreferencias);
Intent(Principal.this,
}
/**
*
Carrega
da
memoria
persistente
os
valores
salvos
das
configuracoes.
*/
private void CarregarValoresPreferencias() {
SharedPreferences
sharedPreferences
=
PreferenceManager.getDefaultSharedPreferences(context);
ValoresPreferencias.limiteInferiorMotor1
=
Integer.parseInt(sharedPreferences.getString(getString(R.string.limite_infe
rior_motor1), getString(R.string.limite_inferior_motor1_defaultValue)));
ValoresPreferencias.limiteSuperiorMotor1
=
Integer.parseInt(sharedPreferences.getString(getString(R.string.limite_supe
rior_motor1), getString(R.string.limite_superior_motor1_defaultValue)));
ValoresPreferencias.limiteInferiorMotor2
=
Integer.parseInt(sharedPreferences.getString(getString(R.string.limite_infe
rior_motor2), getString(R.string.limite_inferior_motor2_defaultValue)));
ValoresPreferencias.limiteSuperiorMotor2
=
Integer.parseInt(sharedPreferences.getString(getString(R.string.limite_supe
rior_motor2), getString(R.string.limite_superior_motor2_defaultValue)));
ValoresPreferencias.precisao
=
Integer.parseInt(sharedPreferences.getString(getString(R.string.precisao_ke
y), getString(R.string.precisao_defaultValue)));
if
(ValoresPreferencias.limiteInferiorMotor1
ValoresPreferencias.limiteSuperiorMotor1
ValoresPreferencias.limiteInferiorMotor1
<
margemSegurancaMotor1
ValoresPreferencias.limiteSuperiorMotor1
>
anguloMaxMotor1
margemSegurancaMotor1 ) {
ValoresPreferencias.limiteInferiorMotor1
>=
||
||
=
84
Integer.parseInt(getString(R.string.limite_inferior_motor1_defaultValue));
ValoresPreferencias.limiteSuperiorMotor1
=
Integer.parseInt(getString(R.string.limite_superior_motor1_defaultValue));
String[] mensagens = {"Limites do Motor
inferior maior que superior", "Redefinindo valores padrao."};
Mensagens.Notificacao(context, mensagens);
}
1",
"Valor
if
(ValoresPreferencias.limiteInferiorMotor2
>=
ValoresPreferencias.limiteSuperiorMotor2
||
ValoresPreferencias.limiteInferiorMotor2
<
margemSegurancaMotor2
||
ValoresPreferencias.limiteSuperiorMotor2
>
anguloMaxMotor2
margemSegurancaMotor2) {
ValoresPreferencias.limiteInferiorMotor2
=
Integer.parseInt(getString(R.string.limite_inferior_motor2_defaultValue));
ValoresPreferencias.limiteSuperiorMotor2
=
Integer.parseInt(getString(R.string.limite_superior_motor2_defaultValue));
String[] mensagens = {"Limites do Motor
inferior maior que superior", "Redefinindo valores padrao."};
Mensagens.Notificacao(context, mensagens);
}
2",
"Valor
sbPosDesMot1.setMax(ValoresPreferencias.limiteSuperiorMotor1
ValoresPreferencias.limiteInferiorMotor1);
sbPosDesMot2.setMax(ValoresPreferencias.limiteSuperiorMotor2
ValoresPreferencias.limiteInferiorMotor2);
-
pbPosMot1.setMax(anguloMaxMotor1);
pbPosMot2.setMax(anguloMaxMotor2);
sbPosDesMot1.setProgress(sbPosDesMot1.getMax() / 2);
sbPosDesMot2.setProgress(sbPosDesMot2.getMax() / 2);
}
/**
* Registra um {@link BroadcastReceiver} para receber comandos das
threads.
*/
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(bcAtualizarInterface)) {
AtualizarInterface();
} else if (intent.getAction().equals(bcIniciarServico)) {
Intent
intentBluetoothService
=
new
Intent(BluetoothService.ConexaoBluetoothGuincho);
intentBluetoothService.setClass(Principal.this,
BluetoothService.class);
Principal.this.startService(intentBluetoothService);
} else if (intent.getAction().equals(bcPararServico)) {
Intent
intentBluetoothService
=
new
Intent(BluetoothService.ConexaoBluetoothGuincho);
intentBluetoothService.setClass(Principal.this,
BluetoothService.class);
Principal.this.stopService(intentBluetoothService);
}
else
if
85
(intent.getAction().equals(bcAtualizaValoresMotor)) {
AtualizaValoresMotor();
} else if (intent.getAction().equals(bcAtualizaSensor1))
{
int valor = intent.getIntExtra(bcAtualizaSensor1, 1);
System.out.println("Valor 1: " + valor);
if (valor != -1) {
valor
=
(int)
(valor
*
anguloMaxMotor1) / 255));
pbPosMot1.setProgress(valor);
txtPosMot1.setText(valor + "º");
}
(((float)
} else if (intent.getAction().equals(bcAtualizaSensor2))
{
int valor = intent.getIntExtra(bcAtualizaSensor2, 1);
System.out.println("Valor 2: " + valor);
if (valor != -1) {
valor
=
(int)
(valor
*
anguloMaxMotor2) / 255));
pbPosMot2.setProgress(valor);
txtPosMot2.setText(valor + "º");
}
(((float)
}
}
};
/**
* Registra um filtro para um {@link BroadcastReceiver}, para filtrar
as solicitacoes desejadas.
*/
private void RegistrarReciever() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(bcAtualizarInterface);
intentFilter.addAction(bcIniciarServico);
intentFilter.addAction(bcPararServico);
intentFilter.addAction(bcAtualizaValoresMotor);
intentFilter.addAction(bcAtualizaSensor1);
intentFilter.addAction(bcAtualizaSensor2);
registerReceiver(broadcastReceiver, intentFilter);
}
private static Context context;
private
static
final
String
bcAtualizarInterface
"ufg.eeec.principal.AtualizarInterface";
private
static
final
String
bcIniciarServico
"ufg.eeec.principal.IniciarServico";
private
static
final
String
bcPararServico
"ufg.eeec.principal.PararServico";
private
static
final
String
bcAtualizaValoresMotor
"ufg.eeec.principal.AtualizaValoresMotor";
private
static
final
String
bcAtualizaSensor1
=
=
=
=
=
86
"ufg.eeec.principal.AtualizaSensor1";
private
static
final
"ufg.eeec.principal.AtualizaSensor2";
String
bcAtualizaSensor2
=
/** Solicita uma conexao Bluetooth com o dispositivo selecionado. **/
private static void Conectar() {
if (estado == estadoDesconectado && dispositivoBluetooth !=
null) {
estado = estadoConectando;
context.sendBroadcast(new Intent(bcAtualizarInterface));
// CONECTA A INTERFACE BLUETOOTH
(new TarefaConectar()).execute((Void) null);
}
}
/** Expressa o desejo do usuario em desconectar a conexao Bluetooth.
**/
private static void Desconectar() {
if (estado == estadoConectado) {
estado = estadoDesconectando;
context.sendBroadcast(new Intent(bcAtualizarInterface));
SolicitarDesconexao();
}
}
/**
* Verifica se o aplicativo esta em condicoes de ser fechado, ou
seja, se as conexoes foram fechadas.
**/
private static boolean PodeSair() {
// Verifica se foi desconectado
if (estado == estadoDesconectado) {
return true;
} else {
String[] mensagens = {"Dispositivo conectado.", "Por
favor, desconecte antes de sair."};
Mensagens.Notificacao(context, mensagens);
return false;
}
}
/** Cria os estados do ambiente grafico. **/
private static final int estadoConectado = 0, estadoDesconectado = 1,
estadoConectando = 2, estadoDesconectando = 3;
private static int estado = estadoDesconectado;
/** Objeto que armazena os dados de um dispositivo Bluetooth **/
private static class DispositivoBluetooth {
private static String nome;
private static String endereco;
public DispositivoBluetooth(String nome, String endereco) {
DispositivoBluetooth.nome = nome;
DispositivoBluetooth.endereco = endereco;
}
public static String getNome() {
87
return nome;
}
public static String getEndereco() {
return endereco;
}
}
/** Armazena um {@link DispositivoBluetooth} com o dispositivo
selecionado. **/
private static DispositivoBluetooth dispositivoBluetooth;
/** Armazena uma solicitacao de desconexao. **/
private static boolean solicitadoDesconexao = false;
/** Registrar que foi solicitado uma desconexao. **/
private synchronized static void SolicitarDesconexao() {
solicitadoDesconexao = true;
}
/** Registrar que a solicitacao de desconexao foi atendida. **/
private synchronized static void SolicitacaoAtendida() {
solicitadoDesconexao = false;
}
/** Retorna um valor represenando se existe uma solicitacao
desconexao. **/
private synchronized static boolean SolicitadoDesconexao() {
return solicitadoDesconexao;
}
de
/**
*
Tarefa executada em segundo plano, responsavel por inicar a
comunicacao Bluetooth atraves
* da classe {@link BluetoothConnection}.
*/
private static class TarefaConectar extends AsyncTask<Void, Void,
Boolean> {
@Override
protected void onPostExecute(Boolean resultado) {
if (resultado.booleanValue()) {
estado = estadoConectado;
context.sendBroadcast(new Intent(bcIniciarServico));
(new TarefaComunicar()).execute((Void) null);
} else {
String[]
mensagens
{BluetoothConnection.getMensagemErro()};
Mensagens.Notificacao(context, mensagens);
estado = estadoDesconectado;
}
=
context.sendBroadcast(new Intent(bcAtualizarInterface));
super.onPostExecute(resultado);
}
@Override
protected Boolean doInBackground(Void... params) {
return
88
Boolean.valueOf(BluetoothConnection.Conectar(DispositivoBluetooth.getEndere
co()));
}
}
/**
* Tarefa executada em segundo plano, responsavel por realizar as
chamadas as funcoes
* de comunicacao Bluetooth definidas em {@link BluetoothConnection}
seguindo o protocolo pre-especificado.
*/
private static class TarefaComunicar extends AsyncTask<Void, Integer,
Boolean> {
private static final int ValoresMotor = 0, Sensor1 = 1, Sensor2
= 2;
/**
* Executada assim que a tarefa e concluida.
* Executa os procedimentos de desconexao e reestabelecimento
das condicoes iniciais.
*/
@Override
protected void onPostExecute(Boolean resultado) {
BluetoothConnection.Desconectar();
SolicitacaoAtendida();
estado = estadoDesconectado;
context.sendBroadcast(new Intent(bcPararServico));
context.sendBroadcast(new Intent(bcAtualizarInterface));
super.onPostExecute(resultado);
}
/**
* Executada para publicar os eventos da tarefa na interface
grafica do aplicativo.
*/
@Override
protected void onProgressUpdate(Integer... values) {
Intent intent;
switch (values[0].intValue()) {
case ValoresMotor:
context.sendBroadcast(new
Intent(bcAtualizaValoresMotor));
break;
case Sensor1:
intent = new Intent(bcAtualizaSensor1);
intent.putExtra(bcAtualizaSensor1, values[1]);
context.sendBroadcast(intent);
break;
case Sensor2:
intent = new Intent(bcAtualizaSensor2);
intent.putExtra(bcAtualizaSensor2, values[1]);
context.sendBroadcast(intent);
break;
}
89
super.onProgressUpdate(values);
}
/**
* Tread responsavel por executar a tarefa. Define o protocolo
a nivel de Software
* a ser utilizado na comunicacao.
*/
@Override
protected Boolean doInBackground(Void... params) {
try {
while (!SolicitadoDesconexao()) {
publishProgress(ValoresMotor);
BluetoothConnection.Escrever(PegaValoresMotor());
publishProgress(Sensor1,
BluetoothConnection.Ler());
publishProgress(Sensor2,
BluetoothConnection.Ler());
}
return Boolean.TRUE;
} catch (IOException e) {
return Boolean.FALSE;
}
}
}
/**
*
* Define o servico que mantem ativa a conexao Bluetooth
* para o caso da interface grafica ser encerrada, nao permitindo
* que o sistema mate a aplicacao.
*
*/
public static class BluetoothService extends Service {
public static final int id = 5114463;
public
static
final
String
ConexaoBluetoothGuincho
"ufg.eeec.guincho.bluetooth";
=
@Override
public void onDestroy() {
stopForeground(true);
super.onDestroy();
}
@Override
public void onCreate() {
super.onCreate();
Notification
notification=
Notification(R.drawable.ic_launcher,
getText(R.string.conexao_inicializada), System.currentTimeMillis());
new
Intent intents = new Intent(this, Principal.class);
PendingIntent contentIntent = PendingIntent.getActivity(this,
0, intents, 0);
90
notification.setLatestEventInfo(this,
getText(R.string.conexao_inicializada),
getText(R.string.dispositivo_bluetooth_conectado), contentIntent);
startForeground(id, notification);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
return START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
};
/**
* Faz as alteracoes visuais
nos controles, habilitando
desabilitando,
*
de acordo com a condicao do aplicativo: conectado
desconectado.
*/
private void AtualizarInterface() {
String[] mensagens;
ou
ou
cmdLigaDeslMot1.setEnabled(estado == estadoConectado);
cmdLigaDeslMot2.setEnabled(estado == estadoConectado);
cmdLigaDeslIma.setEnabled(estado == estadoConectado);
cmdBluetooth.setEnabled(estado == estadoDesconectado);
cmdConnect.setEnabled(dispositivoBluetooth != null && estado ==
estadoDesconectado);
cmdDisconnect.setEnabled(estado == estadoConectado);
if (dispositivoBluetooth != null) {
mensagens = new String[3];
if (estado == estadoConectado) {
mensagens[0] = "Conectado:";
} else if (estado == estadoConectando) {
mensagens[0] = "Conectando:";
} else if (estado == estadoDesconectando) {
mensagens[0] = "Desconectando:";
} else if (estado == estadoDesconectado) {
mensagens[0] = "Selecionado:";
}
mensagens[1] = DispositivoBluetooth.getNome();
mensagens[2] = " (" + DispositivoBluetooth.getEndereco()
+ ")";
} else {
mensagens = new String[1];
mensagens[0] = getString(R.string.SemDispositivo);
}
Mensagens.Notificacao(getApplicationContext(), mensagens);
}
91
/**
* Busca as informacoes nos controles visuais, como botoes ou barras
de progresso,
* e armazena estas informacoes em objetos {@link Motor}.
*/
private synchronized void AtualizaValoresMotor() {
if (BluetoothConnection.Motor1 != null) {
BluetoothConnection.Motor1.setLigado(cmdLigaDeslMot1.isChecked()
Math.abs(sbPosDesMot1.getProgress()
ValoresPreferencias.limiteInferiorMotor1
pbPosMot1.getProgress())
ValoresPreferencias.precisao);
BluetoothConnection.Motor1.setHorario(sbPosDesMot1.getProgress()
ValoresPreferencias.limiteInferiorMotor1 > pbPosMot1.getProgress());
}
&&
+
>
+
if (BluetoothConnection.Motor2 != null) {
BluetoothConnection.Motor2.setLigado(cmdLigaDeslMot2.isChecked()
Math.abs(sbPosDesMot2.getProgress()
ValoresPreferencias.limiteInferiorMotor2
pbPosMot2.getProgress())
ValoresPreferencias.precisao);
BluetoothConnection.Motor2.setHorario(sbPosDesMot2.getProgress()
ValoresPreferencias.limiteInferiorMotor2 > pbPosMot2.getProgress());
}
&&
+
>
+
BluetoothConnection.Ima = cmdLigaDeslIma.isChecked();
}
/**
* Pega os valores dos objetos {@link Motor} e serializa em um numero
inteiro de 0 a 255.
* O numero e formado somando-se os valores conforme abaixo:
* <br>
* <br>
Motor1
Ligado
= 1
* <br>
Motor1
Sentido
= 2
* <br>
Motor2
Ligado
= 4
* <br>
Motor2
Sentido
= 8
* <br>
Ima
Ligado
= 16
*
* @return Um inteiro de 0 a 255.
*/
private synchronized static int PegaValoresMotor() {
int retorno = 0;
if (BluetoothConnection.Motor1.isLigado())
retorno
+=
if (BluetoothConnection.Motor1.isHorario())
retorno
+=
if (BluetoothConnection.Motor2.isLigado())
retorno
+=
if (BluetoothConnection.Motor2.isHorario())
retorno
+=
if (BluetoothConnection.Ima)
retorno
+=
0x01;
0x02;
0x04;
0x08;
0x10;
return retorno;
}
92
/**
* Armazena os valores das ultimas preferencias salvas.
*/
private static class ValoresPreferencias {
private static int limiteInferiorMotor1;
private static int limiteSuperiorMotor1;
private static int limiteInferiorMotor2;
private static int limiteSuperiorMotor2;
private static int precisao;
}
}
package ufg.eeec.guincho;
import
import
import
import
java.io.IOException;
java.io.InputStream;
java.io.OutputStream;
java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
/**
*
Cria todas as condicoes para comunicacao Bluetooth.
*
*/
public class BluetoothConnection {
/**
*
* Define os parametros da conexao Bluetooth
*
*
*/
private static String mensagemErro;
private static BluetoothSocket bluetoothSocket;
private static OutputStream outputStream;
private static InputStream inputStream;
public static Motor Motor1, Motor2;
public static boolean Ima;
public static boolean Conectar(String enderecoDispositivo) {
BluetoothAdapter
bluetoothAdapter
BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter != null) {
BluetoothDevice
bluetoothDevice
bluetoothAdapter.getRemoteDevice(enderecoDispositivo);
=
=
try {
mensagemErro
=
"Erro
ao
criar
conexao
com
dispositivo";
bluetoothSocket
=
bluetoothDevice.createRfcommSocketToServiceRecord(UUID.fromString("00001101
-0000-1000-8000-00805F9B34FB"));
93
mensagemErro = "Erro ao conectar ao dispositivo";
bluetoothSocket.connect();
mensagemErro = "Erro ao solicitar Canal de Saida";
outputStream = bluetoothSocket.getOutputStream();
mensagemErro
=
"Erro
ao
solicitar
Canal
de
Entrada";
inputStream = bluetoothSocket.getInputStream();
Motor1 = new Motor();
Motor2 = new Motor();
return true;
} catch (IOException e) {
Desconectar();
return false;
}
} else {
mensagemErro = "Nao foi encontrado adaptador Bluetooth.";
return false;
}
}
public static boolean Desconectar() {
try {
if (outputStream != null)
outputStream.close();
} catch (IOException e) {}
try {
if (inputStream != null)
inputStream.close();
} catch (IOException e) {}
try {
if (bluetoothSocket != null)
bluetoothSocket.close();
} catch (IOException e) {}
outputStream = null;
inputStream = null;
bluetoothSocket = null;
Motor1 = null;
Motor2 = null;
Ima = false;
return true;
}
public static int Ler() throws IOException {
int valor = inputStream.read();
System.out.println("In: " + valor);
return valor;
}
public static void Escrever(int valor) throws IOException {
outputStream.write(valor);
System.out.println("Out: " + valor);
94
}
public static String getMensagemErro() {
return mensagemErro;
}
/**
*
* Define os valores ativados para os Motores e para o Ima
*
*/
public static class Motor {
private boolean ligado = false;
private boolean horario = true;
public synchronized boolean isLigado() {
return ligado;
}
public synchronized void setLigado(boolean ligado) {
this.ligado = ligado;
}
public synchronized boolean isHorario() {
return horario;
}
public synchronized void setHorario(boolean horario) {
this.horario = horario;
}
}
}
package ufg.eeec.guincho;
import
import
import
import
import
java.util.ArrayList;
java.util.HashMap;
java.util.Iterator;
java.util.Map;
java.util.Set;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
android.app.Activity;
android.app.AlertDialog;
android.app.Dialog;
android.bluetooth.BluetoothAdapter;
android.bluetooth.BluetoothDevice;
android.content.BroadcastReceiver;
android.content.Context;
android.content.DialogInterface;
android.content.Intent;
android.content.IntentFilter;
android.os.Bundle;
android.provider.Settings;
android.view.View;
android.widget.AdapterView;
android.widget.Button;
android.widget.ListView;
android.widget.SimpleAdapter;
95
public class BluetoothActivity extends Activity {
private BluetoothAdapter bluetooth;
@Override
protected void onDestroy() {
try {
unregisterReceiver(broadcastReceiver);
} catch (Exception e) {}
super.onDestroy();
}
private
int
DialogTitle,
DialogText;
private
String
DialogTitleString;
private DialogInterface.OnClickListener DialogOkAction;
private DialogInterface.OnClickListener DialogCancelAction;
final private int DialogOk = 0, DialogOkCancel = 1, DialogWishConnect
= 2;
final private int turnOnBluetooth = 100;
final private int showBluetoothConfig = 200;
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DialogOk:
return
AlertDialog.Builder(BluetoothActivity.this)
.setTitle(DialogTitle)
.setPositiveButton(android.R.string.ok,
DialogOkAction)
.setMessage(DialogText)
.create();
case DialogOkCancel:
return
AlertDialog.Builder(BluetoothActivity.this)
.setTitle(DialogTitle)
.setPositiveButton(android.R.string.ok,
DialogOkAction)
.setNegativeButton(android.R.string.cancel,
DialogCancelAction)
.setMessage(DialogText)
.create();
case DialogWishConnect:
return
AlertDialog.Builder(BluetoothActivity.this)
.setTitle(DialogTitleString)
.setPositiveButton(android.R.string.ok,
DialogOkAction)
.setNegativeButton(android.R.string.cancel,
DialogCancelAction)
.setMessage(DialogText)
.create();
default:
return null;
}
}
@Override
protected
Intent data) {
void
onActivityResult(int
requestCode,
int
new
new
new
resultCode,
96
switch (requestCode) {
case turnOnBluetooth:
if (resultCode == RESULT_CANCELED)
TurnOnBluetooth();
break;
case showBluetoothConfig:
LoadBTTypes();
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
private
final
BroadcastReceiver() {
BroadcastReceiver
broadcastReceiver
=
@Override
public void onReceive(Context context, Intent intent) {
if
(intent.getAction().compareTo(BluetoothAdapter.ACTION_STATE_CHANGED)
{
if
(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-1)
BluetoothAdapter.STATE_OFF)
TurnOnBluetooth();
else
(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-1)
BluetoothAdapter.STATE_ON)
LoadBTTypes();
}
}
};
new
==
0)
==
if
==
private void TurnOnBluetooth() {
if (!bluetooth.isEnabled()) {
DialogTitle = R.string.BluetoothOffTitle;
DialogText = R.string.BluetoothOffText;
DialogOkAction = new DialogInterface.OnClickListener() {
@Override
public void
onClick(DialogInterface
dialog,
int
which) {
startActivityForResult(new
Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE), turnOnBluetooth);
}
};
DialogCancelAction = new DialogInterface.OnClickListener()
{
@Override
public void
onClick(DialogInterface
dialog,
int
which) {
if (!bluetooth.isEnabled())
BluetoothActivity.this.finish();
}
};
showDialog(DialogOkCancel);
} else LoadBTTypes();
}
97
public static final String name = "Name", address = "Address";
private void LoadBTTypes() {
final
ListView
findViewById(R.id.lstBTTypes);
lstBTTypes
=
(ListView)
String[] from = {name, address};
int[] to = {android.R.id.text1, android.R.id.text2};
Set<BluetoothDevice> devices = bluetooth.getBondedDevices();
if (devices != null)
lstBTTypes.setAdapter(new
SimpleAdapter(this,
DevicesToNameAddress(devices),
android.R.layout.simple_list_item_2,
from,
to));
}
private
ArrayList<Map<String,
DevicesToNameAddress(Set<BluetoothDevice> devices) {
ArrayList<Map<String,
String>>
nameAddress
ArrayList<Map<String,String>>();
String>>
=
new
Iterator<BluetoothDevice> iterator = devices.iterator();
while (iterator.hasNext())
nameAddress.add(DeviceToMap(iterator.next()));
return nameAddress;
}
private Map<String, String> DeviceToMap(BluetoothDevice device) {
Map<String, String> map = new HashMap<String, String>();
map.put(name, device.getName());
map.put(address, device.getAddress());
return map;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bluetooth);
bluetooth = BluetoothAdapter.getDefaultAdapter();
if (bluetooth != null) {
registerReceiver(broadcastReceiver,
IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
TurnOnBluetooth();
new
((Button)
findViewById(R.id.btnBTConfig)).setOnClickListener(new
Button.OnClickListener() {
@Override
public void onClick(View v) {
startActivityForResult(new
Intent(Settings.ACTION_BLUETOOTH_SETTINGS), showBluetoothConfig);
}
});
98
final
ListView
findViewById(R.id.lstBTTypes);
lstBTTypes
=
(ListView)
lstBTTypes.setOnItemClickListener(new
ListView.OnItemClickListener() {
@Override
public void
arg1, int item, long arg3) {
final
lstBTTypes.getItemAtPosition(item);
onItemClick(AdapterView<?>
Map<?,
?>
map
=
arg0,
View
(Map<?,
?>)
DialogTitleString = ((String) map.get(name)) +
"\n(" + ((String) map.get(address)) + ")";
DialogText = R.string.WishConnect;
DialogOkAction
=
new
DialogInterface.OnClickListener() {
@Override
public
void
onClick(DialogInterface
dialog, int which) {
Intent data = new Intent();
data.putExtra(name,
(String)
map.get(name));
data.putExtra(address,
(String)
map.get(address));
BluetoothActivity.this.setResult(BluetoothActivity.RESULT_OK, data);
BluetoothActivity.this.finish();
}
};
DialogCancelAction
DialogInterface.OnClickListener() {
@Override
public
void
=
new
onClick(DialogInterface
dialog, int which) {}
};
showDialog(DialogWishConnect);
}
});
} else {
DialogTitle = R.string.BluetoothAdapterNotFoundTitle;
DialogText = R.string.BluetoothAdapterNotFoundText;
DialogOkAction = new DialogInterface.OnClickListener() {
@Override
public void
onClick(DialogInterface
dialog,
int
which) {
BluetoothActivity.this.finish();
}
};
showDialog(DialogOk);
}
}
}
99
package ufg.eeec.guincho;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class Preferencias extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
setResult(BluetoothActivity.RESULT_OK);
}
}
package ufg.eeec.guincho;
import
import
import
import
import
import
android.annotation.SuppressLint;
android.content.Context;
android.view.Gravity;
android.widget.LinearLayout;
android.widget.TextView;
android.widget.Toast;
public class Mensagens {
@SuppressLint("ShowToast")
public static void Notificacao(Context context, String[] mensagens) {
if (mensagens != null) {
if (mensagens.length > 0) {
Toast toast = Toast.makeText(context, mensagens[0],
Toast.LENGTH_SHORT);
LinearLayout
linearLayout
=
(LinearLayout)
toast.getView();
for (int i = 1; i < mensagens.length; i++) {
TextView
textView
=
(TextView)
Toast.makeText(context,
mensagens[i],
Toast.LENGTH_SHORT).getView().findViewById(android.R.id.message);
((LinearLayout)
textView.getParent()).removeView(textView);
linearLayout.addView(textView);
}
linearLayout.setGravity(Gravity.CENTER_HORIZONTAL);
toast.show();
}
}
}
}
100
Download