Академический Документы
Профессиональный Документы
Культура Документы
Goinia
2013
Trabalho
de
Concluso
de
Curso
Engenharia
de
Computao
da
Goinia
2013
Trabalho
de
Concluso
de
Curso
Engenharia
de
Computao
da
Aprovado em __/__/____
BANCA EXAMINADORA
1 RESUMO
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
Agradeo, acima de tudo, a Deus, que me deu a vida e a fora. Aos meus
filhos, por serem minha inspirao, e a minha esposa, por todo apoio. Mas em
especial agradeo aos meus pais, por tudo, e dedico a eles essa conquista.
SUMRIO
1
RESUMO .............................................................................................................. 4
ABSTRACT........................................................................................................... 5
AGRADECIMENTOS ............................................................................................ 6
CAPTULO 1 - INTRODUO............................................................................ 16
7.1
7.2
9.2
9.3
9.4
9.5
9.6
9.6.1
9.6.2
9.7
9.8
10
10.1
11
11.1
AT89C52 ................................................................................................... 36
11.1.1
11.2
11.2.1
Definio ............................................................................................ 39
11.2.2
11.2.3
Ponte H .............................................................................................. 41
11.3
11.4
11.4.1
Caractersticas: .................................................................................. 45
11.4.2
Funcionamento: .................................................................................. 46
11.4.3
11.5
ULN2803 ................................................................................................... 48
11.6
Potencimetro ........................................................................................... 49
11.7
L298N ....................................................................................................... 50
12
12.1
Proteus...................................................................................................... 53
12.2
PEQui........................................................................................................ 54
12.2.1
Funcionamento: .................................................................................. 54
12.3
ChipMax2 .................................................................................................. 55
12.4
MaxLoader ................................................................................................ 56
12.5
13
13.1
13.2
13.3
13.4
14
15
BIBLIOGRAFIA................................................................................................ 69
16
APNDICE
CDIGO
EM
ASSEMBLY
DO
PROGRAMA
DO
MICROCONTROLADOR........................................................................................... 74
17
4 ndice de Figuras
5 ndice de Tabelas
6 Smbolos e Siglas
7 CAPTULO 1 - INTRODUO
Os
microcontroladores
esto
presentes no
cotidiano
da
populao,
conquistando cada vez mais espao em diversas aplicaes e ganhando cada vez
mais espao no mercado.
Nos sistemas eletrnicos, eles so responsveis pela diminuio das
dimenses dos equipamentos, gerenciam e controlam as tarefas internas, facilitam a
manuteno, tornam alguns sistemas mais baratos e robustos, alm de otimizar e
automatizar tarefas, facilitando a vida moderna.
Em questo de investimentos o microcontrolador fornece um excelente custobenefcio, sendo um componente verstil que se adqua a vrios tipos de aplicaes
diferentes, geralmente voltados para propsitos especficos.
Por possuir a maioria dos componentes necessrios para o desenvolvimento
de um sistema em um nico chip, torna muito mais vivel sua utilizao em vrios
projetos, deixando o sistema mais simples, barato e reduzido. Cada vez mais os
sistemas microcontrolados ganham mais destaque e importncia, sendo de suma
importncia em sistemas de automao 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 comunicao mvel baseado na tecnologia Bluetooth,
para que dispositivos mveis que possuam comunicao 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.
16
7.1
18
7.2
19
8 Captulo 2 - Microcontroladores
20
8.1
Aplicaes de Microcontroladores
21
9.1
Introduo Histrica
A famlia MSC-51 teve sua origem a partir da MCS-48 (lanada pela INTEL
em 1976), que foi a primeira famlia de controladores lanada pela INTEL. Por no
ser to limitada quanto seu antecessor e nem to cara como a MCS-96,
praticamente a famlia 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 tambm o ncleo
para toda a MCS-51.
Seus principais modelos so:
Tabela 1 - Principais modelos da famlia MCS-51 com especificao de ROM, RAM e T/C.
Modelo
ROM
RAM
Temporizadores/
Contadores
8031
2 T/C
8051
2 T/C
8751
2 T/C
8032
3 T/C
8052
3 T/C
8752
3 T/C
9.2
condicionais
so
processados,
por
suas
instrues
serem
especializadas.
Possui
aperfeioamentos
constantes,
como
aumento
da
9.3
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 endereveis.
Memria de dados externa e memria de programa externa com
capacidade de at 64KB cada.
23
9.4
9.5
25
Nome do Pino
Numerao
Descrio / Funcionamento
Porta P0 (P0.0
a P0.7)
39 a 32
Porta P1 (P1.0
a P1.7)
1a8
Porta P2 (P2.0
a P2.7)
21 a 28
Porta P3 (P3.0
a P3.7)
10 a 17
Fonte de
alimentao Vcc
40
Terra - Vss
20
Reset
Adress Latch
Enable
30
Program Store
Enable
29
XTAL1 e
XTAL2
18 e 19.
External
Access Enable
31
27
9.6
ORGANIZAO DA MEMRIA
O 8051 fornece uma memria de dados interna com um mnimo de 128 bytes,
com isso para muitas aplicaes que no necessitam de grande quantidade de
memria, no h a necessidade de fazer uso da RAM externa.
28
9.7
Registrador de Funo
Especial
Funo bsica
utilizado
para
PCON (87H)
TL0 (8AH), TH0 (8CH), So 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)
IE (A8H) e IP (B8H)
PSW (D0H)
ACC (E0H)
B ( F0H)
30
9.8
CONJUNTO DE INSTRUES
31
10 CAPTULO 3 BLUETOOTH
interferncia.
32
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.
Figura 10 - Duas piconets formando uma scatternet, com um dispositivo escravo em comum.
33
O raio de operao da piconet vai depender dos dispositivos que esto sendo
utilizados. Tais dispositivos so classificados em trs categorias, de acordo com a
tabela 4.
Tabela 4 - Classificao dos dispositivos Bluetooth.
Classe
Alcance
Potncia
Classe 1
Entre 1 mW e 100 mW
Classe 2
Classe 3
Curtssimo (1 m)
At 1 mW
10.1
35
11 DISPOSITIVOS UTILIZADOS
11.1
AT89C52
O AT89C52 foi projetado com lgica esttica para operar com freqncias
prximas de zero, e possui dois modos de economia de energia selecionveis por
software. O modo de espera interrompe a CPU enquanto permite que a RAM,
temporizadores/contadores, a porta serial, e o sistema de interrupo permaneam
funcionando. O modo de desligamento salva o contedo da RAM, mas congela o
oscilador, desabilitando todas as outras funes do chip, at o prximo sinal de reset
do hardware.
Caractersticas:
Compatvel com produtos de MCS-51
8KB de memria Flash reprogramvel
Operao inteiramente de esttica: 0 hertz a 24 megahertz
Fechamento em trs nveis da memria do programa
RAM interno de 8 bits de 256 x
36
Isso significa que os 128 bytes superiores possuem o mesmo endereo que
os Registradores de Funes Especiais, mas esto fisicamente seprados no espao
de memria.
Podemos
observar
que
as
operaes de
pilha
so
exemplos
de
38
11.2
MOTOR DE PASSO
11.2.1 Definio
Os Motores de Passo so dispositivos eletro-mecnicos sncronos, que
possuem a funo de converter pulsos digital de algum sinal (geralmente sinais
eltricos) em movimentos mecnicos rotativos bem preciso, gerando variaes
angulares discretas. Os motores de passo podem ser aplicados em sistemas de
malha aberta, ou seja, sem qualquer controle de realimentao, e possuem trs
tipos bsicos: de relutncia varivel, m permanente e hbridos.
Relutncia Varivel
Consiste de um rotor de ferro, com mltiplos dentes e um estator com uma
quantidade especifica de enrolamentos. Se energizarmos os enrolamentos do
estator com corrente DC os plos cam magnetizados. A rotao ocorre quando os
dentes do estator so atrados para os plos do estator energizado, para que o
sistema tenha o circuito com menor relutncia.
m Permanente
Possuem baixo custo e baixa resoluo e baixo torque. O rotor construdo
com ms permanentes e no possui dentes. Os plos magnetizados do rotor
provm uma maior intensidade de uxo magntico exibindo ento uma melhor
caracterstica de torque.
Hbrido
Mais caro do que os demais, porm possui melhor desempenho com respeito
resoluo de passo, torque e velocidade. O rotor multi-dentado e contem um m
permanente ao redor do seu eixo. Para aplicaes que exigem um controle bem
rgido e um ajuste fino de posicionamento, em mquinas de pequena e mdia
dimenso, os motores de passo hbrido so os mais utilizados devido sua tima
relao custo/benefcio.
40
11.2.3 Ponte H
42
11.3
43
11.4
uma
escada
diferencial
potenciomtrica.
No
necessrio
nenhum
A sua sada poder assumir valores entre 0 a 255 decimal (ou de 00000000
at 11111111 binrio), sendo equivalente a 5V podendo ser convertidos em valores
44
11.4.1 Caractersticas:
Pinos
VIN(+) e VIN(-)
DB0 a DB7
Funo/Descrio
Entradas analgicas diferenciais
Sadas digitais
45
/CS (entrada)
/RD (entrada)
/WR (entrada)
CLOCK IN
(entrada)
/INTR (sada)
Terminal de malha RC
Sinal indicando fim de converso quando comutado para nvel "0"
AGND
Terra analgico
DGND
Terra digital
VREF/2
CLOCK R
(entrada)
V+ ou VREF
11.4.2 Funcionamento:
46
ULN2803
Figura 18 - CI ULN2803.
suportar pelo menos 50V no estado desligado. As sadas podem ser configuradas
em paralelo para suportarem uma corrente maior.
Potencimetro
49
11.7
L298N
Caractersticas:
52
12.1
Proteus
ambiente
ISIS
podemos
criar
esquemas
eltricos
utilizando
cruzamento
proximidade
das
trilhas,
prevenindo
interferncias
53
12.2
PEQui
e outro com
ChipMax2
55
12.4
MaxLoader
56
aplicaes
grficas
multiplataforma
sem
sacrificar
compatibilidade.
Orientao ao desenvolvimento baseado em plugins, que possuem
inmeras funcionalidades diferentes, como: suporte a servidores de
aplicao, visualizadores de banco de dados, geradores de diagramas
UML, etc.
Porttil, ou seja, as aplicaes desenvolvidas so compatveis com
vrios ambientes.
Permite a refatorao do cdigo, permitindo melhorar o design sem
alterar a funcionalidade.
57
13 RESULTADOS OBTIDOS
58
prticos,
13.3
As placas individuais podem ser vistas nas figuras 28, 29 e 30. J a figura 31
mostra o circuito eletrnico completo necessrio para o funcionando do projeto.
61
62
63
64
Foi criada uma tela de configuraes (figura 34), para possibilitar ao usurio
mudar, em tempo de execuo, os valores de algumas constantes do sistema.
Atravs desta tela possvel limitar o curso do guincho e definir a preciso de
parada.
- A barra de posio atual do motor pode ser vista como a poro de giro do
cursor do potencimetro.
- A barra de posio desejada do motor onde o usurio ir controlar o
movimento do motor, fazendo com que a barra de posio atual se locomova at a
posio desejada.
- A interface contm botes para ligar e desligar os motores, o m, e tambm
para conectar e desconectar os dispositivos Bluetooth.
66
Por fim, o trabalho gera grandes expectativas para o futuro, tendo em vista
apresentar uma tecnologia que, apesar de no ser muito nova, ainda mostra um
enorme potencial para o mercado. Os dispositivos Bluetooth, considerando a
integrao com dispositivos mveis, so uma tendncia de mercado para os novos
dispositivos, e ainda no possuem um concorrente com abrangncia comparvel.
Isso significa que aplicaes escritas para estes dispositivos podem atingir a um
nmero muito grande de usurios, com a provvel tendncia de que este quadro no
se altere nos prximos anos.
68
15 BIBLIOGRAFIA
[2] TAUB, H.; Circuitos Digitais e Microprocessadores. So Paulo: Mc- Graw Hill,
1984.
69
70
71
[35] Cavalheiro, L. Como fazer sua PCI (Placa de Circuito Impresso). Disponvel em:
<http://lucascavalheiro.wordpress.com/2008/10/22/como-fazer-pci/> Acessado em
26 fev. 2013.
72
73
16 APNDICE
CDIGO
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;
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;
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
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;
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
*
*
*
*
(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,
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 + "");
}
}
}
+
+
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
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
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
"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
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
==
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
lstBTTypes
(ListView)
String>>
=
new
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<?,
?>)
onClick(DialogInterface
(String)
map.get(address));
BluetoothActivity.this.setResult(BluetoothActivity.RESULT_OK, data);
BluetoothActivity.this.finish();
}
};
DialogCancelAction
DialogInterface.OnClickListener() {
@Override
public
void
new
onClick(DialogInterface
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;
100