Android Oscilloscope: Osciloscópio com

Propaganda
Universidade Federal do Rio de Janeiro
Escola Politécnica
Departamento de Eletrônica e de Computação
Android Oscilloscope: Osciloscópio com Tecnologia Android
Autor:
_________________________________________________
Luiz Alberto Santos da Silva
Orientador:
_________________________________________________
Prof. Sergio Barbosa Villas-Boas, Ph. D.
Examinador:
_________________________________________________
Prof. Aloysio de Castro Pinto Pedroza, Dr.
Examinador:
_________________________________________________
Prof. Jorge Lopes de Souza Leão, Dr.
DEL
Janeiro de 2014
UNIVERSIDADE FEDERAL DO RIO DE JANEIRO
Escola Politécnica – Departamento de Eletrônica e de Computação
Centro de Tecnologia, bloco H, sala H-217, Cidade Universitária
Rio de Janeiro – RJ
CEP 21949-900
Este exemplar é de propriedade da Universidade Federal do Rio de Janeiro, que
poderá incluí-lo em base de dados, armazenar em computador, microfilmar ou adotar
qualquer forma de arquivamento.
É permitida a menção, reprodução parcial ou integral e a transmissão entre
bibliotecas deste trabalho, sem modificação de seu texto, em qualquer meio que esteja
ou venha a ser fixado, para pesquisa acadêmica, comentários e citações, desde3 que sem
finalidade comercial e que seja feita a referência bibliográfica completa.
Os conceitos expressos neste trabalho são de responsabilidade do(s) autor(es) e
do(s) orientador(es).
ii
iii
AGRADECIMENTO
Dedico este trabalho, primeiramente, a Deus, à minha família, ao meu Orientador
Prof. Sergio Barbosa Villas-Boas e a todos que contribuíram de forma significativa à
minha formação e estada nesta Universidade. Este projeto é uma pequena forma de
retribuir o investimento e confiança em mim depositados.
iv
RESUMO
O presente trabalho visa implementar um osciloscópio em um sistema
operacional Android, que se comunique com um hardware utilizando a tecnologia
Bluetooth. Dessa forma, será possível trazer um pouco do instrumento de bancada mais
utilizado em laboratórios de eletrônica para diversos lugares, através de um dispositivo
móvel.
Palavras-Chave: osciloscópio, Android, Arduino, Bluetooth.
v
ABSTRACT
The objective of this project is to implement an oscilloscope on Android
operating system that communicates with a hardware using Bluetooth technology. That
way, it’ll be possible bring a little more of that bench instrument, heavily used in
electronic laboratories, to different places, through a mobile device.
Key-words: oscilloscope, Android, Arduino, Bluetooth.
vi
SIGLAS
SDK – Software Development Kit
iOS – iPhone Operational System
OS – Operational System
IDE – Integrated Development Environment
ADT – Android Development Tools
A/D – Analógico / Digital
ISR – Interrupt Service Routine
UART - Universal asynchronous receiver/transmitter
API – Application Programming Interface
ADSC – A/D Start Conversion
vii
Sumário
1 Introdução
1.1 – Tema
1.2 – Delimitação
1.3 – Justificativa
1.4 – Objetivos
1.5 – Metodologia
1.6 – Descrição
1
1
1
1
2
2
2
2 Android
2.1 – Sistema Operacional Android
2.2 – Recursos do Android
2.3 – Versões do Android
2.4 – Ferramentas para Desenvolvimento
2.5 – Estrutura de um Aplicativo Android
2.5.1 – Estrutura do Projeto no IDE Eclipse
2.5.2 – Activities e Intents
2.5.2.1 – Activity
2.5.2.2 – Intent
2.6 – API Bluetooth para Android
2.6.1 – Tornando o dispositivo descobrível e procurando por outros
dispositivos
2.6.2 – Comunicação Bluetooth
2.7 – API aChartEngine 1.0.0
4
4
4
5
5
6
6
7
8
12
14
3 Hardware
3.1 – Arduino
3.1.1 – Conversor A/D do Arduino
3.1.1.1 – Arquitetura
3.1.1.2 – Clock e Prescaler
3.1.2 – Software Arduino IDE
3.2 – Módulo Bluetooth
21
21
22
23
24
27
30
4 Android Oscilloscope
4.1 – Análise do Código para o Arduino
4.1.1 – Definições do Código para o Arduino
4.1.2 – Tecnologias Arduino e Módulo Bluetooth
4.2 – Análise do Aplicativo Android
4.2.1 – Activity Inicial
4.2.2 – Bluetooth Android
4.2.3 – Activity do Osciloscópio
4.2.3.1 – Processo de Exibição do Gráfico
4.2.3.2 – Cálculo de Vmáx, Vpp e Frequência
4.2.3.3 – Trigger do Osciloscópio
32
32
32
34
35
35
37
38
41
43
46
5 Conclusões
Bibliografia
49
50
viii
16
17
18
Lista de Figuras
Figura 2.1 – Exemplo AndroidManifest.xml
Figura 2.2 – Exemplo Activity
Figura 2.3 – Ciclo de Vida da Activity
Figura 2.4 – Ciclo de Vida da Activity com Instances
Figura 2.5 – Exemplo de Instances
Figura 2.6 – Intent no AndroidManifest
Figura 2.7 – Métodos para chamar outra Activity
Figura 2.8 – Resultado da Activity
Figura 2.9 – Armazenar valor para a próxima Activity
Figura 2.10 – Exemplo de onActivityResult
Figura 2.11 – Permissão Bluetooth no AndroidManifest
Figura 2.12 – Verifica se Bluetooth está Ativo
Figura 2.13 – Solicitar Ativação Bluetooth
Figura 2.14 – Conexão com Dispositivo Bluetooth
Figura 2.15 – Site da API AChartEngine
Figura 3.1 – Site da Arduino
Figura 3.2 – Diagrama de Blocos do Conversor A/D
Figura 3.3 – Configuração padrão do Prescaler do Microcontrolador
Figura 3.4 – Código Setup do Teste de Prescaler
Figura 3.5 – Código Loop do Teste de Prescaler
Figura 3.6 – Resultado com Prescaler igual a 64
Figura 3.7 – Resultado com Prescaler igual a 4
Figura 3.8 – Código Exemplo de Estrutura de Programa para Arduino
Figura 3.9 – Módulo Bluetooth
Figura 4.1 – Exemplo de Profundidade de Memória
Figura 4.2 – Tela Inicial do Aplicativo
Figura 4.3 – Tela About do Aplicativo
Figura 4.4 – Solicitando Permissão para ativar Bluetooth
Figura 4.5 – Menu do Aplicativo
Figura 4.6 – DeviceListActivity
Figura 4.7 – Conectando ao dispositivo Bluetooth
Figura 4.8 – Exemplo 1 – Cálculo Vmax e Vpp
Figura 4.9 – Exemplo 2 – Cálculo Vmax e Vpp
Figura 4.10 – Exemplo – Cálculo de Frequência
Figura 4.11 – Exemplo – Trigger do Osciloscópio
Figura 4.12 – Exemplo dos Botões da Activity Principal
ix
7
8
10
11
12
12
13
13
13
14
14
15
15
18
20
22
23
24
25
25
26
27
29
31
33
36
37
39
40
41
42
44
45
46
47
48
Capítulo 1
Introdução
1.1 – Tema
O tema do trabalho consiste no estudo e implementação de um aplicativo com
funções de um osciloscópio, armazenado em um dispositivo móvel com sistema
operacional Android. Este dispositivo recebe o sinal amostrado por um Arduino, via
comunicação Bluetooth. Desta forma, o dispositivo com Android vai possibilitar ao
usuário a visualização do sinal na tela do mobile.
1.2 – Delimitação
O desenvolvimento restringe-se ao ambiente Android, plataforma que, junto com
o iOS (Apple), domina o mercado de smartphones. A escolha da plataforma se deve a
facilidade para desenvolver no ambiente Android, podendo-se utilizar computadores
com Windows, Mac OS ou Linux. Além de ser uma plataforma aberta, qualquer um
pode baixar o código-fonte do Android e o Android SDK para desenvolvimento, sem
custos.
1.3 – Justificativa
A escolha da plataforma de desenvolvimento se justifica, conforme citado
anteriormente, ao baixo custo de desenvolvimento e por possuir, atualmente, um grande
número de consumidores.
Quanto ao osciloscópio, este é um instrumento que nos permite observar e
efetuar medidas de um sinal de tensão elétrica. A intenção do projeto, pelo fato de ser
portátil, é alcançar outros usuários.
1
1.4 – Objetivos
O objetivo geral é criar uma aplicação para Android que simule as
funcionalidades de um osciloscópio real, logicamente com algumas limitações que o
hardware impõe. O sinal a ser observado na tela do mobile é o sinal lido e amostrado
pelo Arduino e transmitido via Bluetooth. O objetivo não é desenvolver um aplicativo
que possua exatamente as mesmas especificações ou algo próximo de um osciloscópio
real, pois para isso seria necessário o uso de um hardware mais específico e
consequentemente mais custoso.
1.5 – Metodologia
Este projeto foi desenvolvido, em sua maioria, utilizando linguagem de
programação Java e uma biblioteca open source (achartengine) para construir os
gráficos e exibi-los na tela. A IDE escolhida para o desenvolvimento do Software
Android foi o Eclipse, também open source e possui compatibilidade com as
ferramentas Android: componentes Android SDK e ADT Plugin para Eclipse. O
computador utilizado foi um com sistema operacional Windows 7.
Para o hardware, responsável por tratar o sinal e depois transmiti-lo para o
dispositivo móvel, foram utilizados: um microcontrolador Arduino, modelo UNO R3,
com um conversor A/D com entrada analógica de no máximo 5 Volts de tensão e capaz
de amostrar sinais analógicos com resolução de 10 bits e um módulo de comunicação
serial Bluetooth, modelo HC-05. No software para Arduino foi utilizada a linguagem de
programação C e uma IDE disponibilizada pela própria fabricante do Arduino que nos
permite desenvolver e fazer o upload do aplicativo para a memória do
microcontrolador.
1.6 – Descrição
No capítulo 2 falaremos sobre o Android: como está o cenário atual para os
desenvolvedores e para os usuários, assim como sua arquitetura de sistema operacional,
bibliotecas e recursos disponíveis e a estrutura de um aplicativo Android em linguagem
2
de programação Java. Esse capítulo foi reservado para explicitar o conhecimento
teórico de programação Android absorvido na graduação que foi de grande valia para o
desenvolvimento do projeto.
O capítulo 3 abordará o hardware do projeto: características do Arduino e do
módulo de comunicação Bluetooth.
Os detalhes de implementação do projeto e a análise dos resultados serão
apresentados no capítulo 4.
Por fim, o capítulo 5 com as conclusões acerca do projeto: objetivos realizados e
possíveis melhorias a serem feitas.
3
Capítulo 2
Android
2.1 – Sistema Operacional Android
O Android é um sistema operacional para mobile que é baseado em uma versão
modificada do Linux. Este foi adquirido, junto com a equipe de desenvolvimento, pela
Google, como parte da estratégia para entrar no mercado de dispositivos móveis.
Quando o iPhone foi lançado, muitos fabricantes tiveram que encontrar novas
formas de revitalizar seus produtos. Para estes fabricantes de hardware, o Android foi
visto como uma solução, eles continuam a fabricar seu hardware e usam o Android
como o sistema operacional que o potencializa. Existir um sistema operacional para
mobile, open source, como o Android, possibilita-os customizar o sistema para
diferenciar seu produto.
Para os desenvolvedores, a principal vantagem de programar para Android é que
ele oferece uma abordagem única nas aplicações. Desenvolvedores precisam
desenvolver somente para Android, e, com isso, suas aplicações devem ser capazes de
rodar em diferentes dispositivos.
2.2 – Recursos do Android
Um dos benefícios de desenvolver para o Android é o fato da plataforma ser
open source. O sistema operacional é aberto e livre, permitindo que o desenvolvedor
veja o código-fonte e veja como seus recursos são implementados. O desenvolvedor
pode também contribuir reportando erros ou participando de grupos de discussão.
Existem inúmeros aplicativos Android da Google e outros disponíveis na internet.
Por ser um sistema livre, não existem hardwares ou softwares fixos, no entanto,
existem recursos que o Android oferece:
 Suporta GSM/EDGE, CDMA, Bluetooth, Wi-Fi e 3G;
 Sensores de acelerômetro e proximidade, câmera e GPS;
4
 Suporta telas multi-touch (capaz de reconhecer mais de dois pontos de contato
com a tela);
 Suporta aplicações multitarefa;
 Inclui suporte a diversos formatos de mídia: H.264, H.263, MP4, MP3, JPEG,
PNG, GIF;
 Usa SQLite para armazenagem de dados.
2.3 – Versões do Android
Cada versão do Android é nomeada com o nome de um doce, e segue ordem
alfabética:
 Android 1.6 (Donut);
 Android 2.0/2.1 (Eclair);
 Android 2.2 (Froyo);
 Android 2.3 (Gingerbread);
 Android 3.0/3.1/3.2 (Honeycomb);
 Android 4.0 (Ice Cream Sandwich);
 Android 4.1/4.2/4.3 (Jelly Bean).
O aplicativo Android desenvolvido para este projeto pode ser executado em
celulares com a versão 2.3 ou maior.
2.4 – Ferramentas para Desenvolvimento
O ambiente de desenvolvimento mais recomendado para programar aplicativos
Android é o Eclipse. É uma IDE que suporta diversas linguagens, incluindo Java,
linguagem utilizada na maioria dos aplicativos Android. É uma IDE que segue o modelo
de open souce no desenvolvimento de Software. A IDE escolhida para este projeto foi o
Eclipse, por se tratar de um ambiente que possui maior compatibilidade com o Android.
O Eclipse, juntamente com o plugin ADT, é o único oficialmente suportado e
recomendado pela Google.
O ADT (Android Development Tools) permite criar, executar e depurar
aplicativos Android, e é possível também exportar o aplicativo para arquivo .apk para
futura distribuição, no Android Market, por exemplo. Este plugin também inclui uma
5
interface gráfica de desenvolvimento (GUI), sendo possível arrastar e largar
componentes em qualquer lugar da tela, sem uso de código para tal.
Uma outra ferramenta é o Android Emulator, inclusa no Android SDK, que
permite executar aplicativos Android em um ambiente simulado. Este emulador
apresenta a tela de um mobile com Android. Antes de executar o aplicativo, é necessário
criar um AVD (Android Virtual Device) que define as características do dispositivo,
como o hardware, o tamanho da tela, armazenagem dos dados e outros. Para testar o
aplicativo em diferentes dispositivos Android é preciso criar diferentes AVD’s, cada um
emulando um dispositivo específico. O Android Emulator não se faz tão necessário se o
desenvolvedor já possuir um dispositivo móvel. Neste projeto não foi preciso usar esta
ferramenta, se fez uso de um dispositivo Android da fabricante Samsung.
É possível encontrar um passo a passo de como instalar e configurar o ambiente
no site: http://developer.Android.com.
2.5 – Estrutura de um Aplicativo Android
O próximo passo é entender como é a estrutura de um aplicativo Android:
estrutura do projeto no IDE Eclipse, o arquivo AndroidManifest.xml, Activities e Intents,
componentes de uma tela Android, trabalhar com orientação da tela.
2.5.1 – Estrutura do Projeto no IDE Eclipse
São várias as pastas e arquivos que compõe um projeto Android no Eclipse,
seguem as principais pastas abaixo:
 src – a pasta que contém todos os arquivos-fonte .java do projeto;
 gen – o arquivo R.java fica localizado nesta pasta. Um arquivo gerado pelo
compilador que referencia todos os recursos do projeto. Este arquivo não deve
ser alterado pelo desenvolvedor;
 Android 2.3.3 – contém o arquivo android.jar, possui todas as classes
necessárias para uma aplicação Android;
 assets – contém arquivos HTML, arquivos texto, banco de dados, etc;
 bin – onde fica armazenado o arquivo .apk gerado;
 res – possui algumas subpastas como: layout, menus e values;
6
 AndroidManifest.xml – o arquivo manifest da aplicação, discutido mais a frente.
O arquivo AndroidManifest.xml contém informações sobre a aplicação:
Figura 2.1 – Exemplo AndroidManifest.xml.
Fonte: Oscilloscope Android.
 Define o nome do pacote da aplicação;
 Define permissões de uso como, por exemplo, a do Bluetooth;
 Na aba application alguns atributos definem o nome da aplicação, string
app_name, e a figura do ícone da aplicação e, dentro, as declarações das
activity’s;
 A aba action dentro de intent-filter indica a activity ChartDemo como a principal
da aplicação. A aba category define que esta mesma activity é a que será
executada quando o usuário clicar no ícone da aplicação;
 Mais abaixo o atributo android:minSdkVersion da aba uses-sdk especifica a
menor versão do sistema operacional, na qual a aplicação funcionará.
2.5.2 – Activities e Intents
Uma activity é uma janela que contém a interface com o usuário da aplicação. É
um componente que possui vários estágios dentro de uma aplicação, conhecido como o
ciclo de vida da activity. Conhecer este ciclo é importantíssimo para ter certeza que a
aplicação funciona corretamente.
7
Outro componente abstrato importante em um aplicativo Android é o intent. É
basicamente o que une diferentes activities de diferentes aplicações, podendo ser usada
para “chamar” aplicações nativas do Android como o navegador, telefone, mapas, email, e outras.
2.5.2.1 – Activity
Para criar uma Activity basta criar uma classe Java que estende uma classe base
Activity.
Figura 2.2 – Exemplo Activity.
Fonte: Oscilloscope Android.
Todos esses métodos podem ser sobrescritos, já que com o extends pode-se
estender as funcionalidades da classe Activity e herdar todos os métodos. O método
super inicializa a classe pai antes de inicializar a classe herdeira.
A Activity é definida de acordo com o arquivo XML que fica no diretório
res/layout do projeto. O método setContentView vai indicar o XML específico da
activity.
Toda activity do projeto deve ser declarada no AndroidManifest.xml.
A classe base segue uma série de eventos que definem o ciclo de vida de uma
Activity. Os eventos são:
8
 onCreate() – evento chamado quando a Activity é criada pela primeira vez.
Sempre seguido de onStart();
 onStart() – evento chamado quando ela se torna visível para o usuário. Seguido
por onResume() se a activity estiver entrando em primeiro plano ou por onStop()
se estiver saindo do primeiro plano;
 onResume() – chamado quando a Activity começa a interagir com usuário.
Sempre seguido por um onPause();
 onPause() – acontece quando a activity atual é pausada e a anterior começa a
interagir com o usuário. Seguido por onResume(), se a activity estiver voltando
para o primeiro plano ou onStop(), se estiver ficando invisível para o usuário;
 onStop() – quando a activity não é mais visível para o usuário. Seguido por
onRestart(), se a activity estiver voltando a interagir com o usuário ou
onDestroy(), se estiver sendo encerrada;
 onDestroy() – chamada antes da activity ser destruída pelo sistema
(manualmente ou para o sistema conservar memória). Pode acontecer se a
activity está sendo finalizada pela (chamada do método finish()) ou porque o
sistema está tentando liberar recursos;
 onRestart() – chamada quando a activity for parada e depois reiniciada. Sempre
seguida do onStart().
O ciclo de vida inteiro de uma activity acontece entre o onCreate() e o
onDestroy(). No onCreate() são feitas todas as configurações globais, como criar as
views, instanciar objetos que serão usados na aplicação e chamar o método
setContentView(), por exemplo, e no onDestroy() são liberados os recursos utilizados.
O ciclo de vida visível acontece entre o onStart() e o onStop(). Neste intervalo, o
usuário pode ver a activity, mesmo que esta esteja em segundo plano e não esteja
interagindo com o usuário.
O ciclo de vida em primeiro plano acontece entre o onResume() e o onPause().
Entre estes dois métodos, a activity está em primeiro plano e interagindo com o usuário.
No onResume() podemos iniciar qualquer serviço ou código que precisa ser executado
enquanto a activity está em primeiro plano. Enquanto no onPause() podemos parar os
serviços ou códigos que não precisam ser executados quando a activity está em segundo
plano.
9
Segue abaixo um esquemático do ciclo de vida da Activity:
Figura 2.3 – Ciclo de Vida da Activity.
Fonte: http://developer.Android.com/reference/Android/app/Activity.html.
Outros dois métodos importantes dentro do ciclo de vida de uma activity são:
onSaveInstanceState() e o onRestoreInstanceState(). Quando uma activity é pausada ou
parada, o objeto da classe Activity se mantém na memória, isto é, o estado atual do
objeto permanece intacto. Todas as alterações que o usuário faz são salvas e quando a
activity retorna para o primeiro plano, essas mudanças permanecem. Mas quando o
10
sistema destrói e o usuário inicia a activity novamente, o objeto é recriado. Para
preservar o estado da activity pode-se sobrescrever o método onSaveInstanceState(). O
sistema passa para esse método um Bundle (contém pares de nomes e valores), onde
podemos guardar as informações. Assim, quando o sistema destrói e recria a activity,
este Bundle é passado o onCreate() e o onRestoreInstanceState().
Figura 2.4 – Ciclo de Vida da Activity com Instances.
Fonte: http://developer.Android.com/reference/Android/app/Activity.html.
Este dois métodos são muito úteis quando uma mudança no dispositivo ocorre
durante a execução do aplicativo, por exemplo, na orientação do mobile. Quando
acontece, a activity é destruída e criada novamente. Pode-se tratar esta mudança de
orientação usando esses dois métodos, pois, antes de a activity ser destruída, o
onSaveInstanceState()
é
chamado
e,
quando
for
reconstruída,
o
onRestoreInstanceState() é chamado. Abaixo temos um exemplo, onde as variáveis x e i
foram salvas para, posteriormente, serem recuperadas.
11
Figura 2.5 – Exemplo de Instances.
Fonte: Oscilloscope Android.
Também
podemos
adicionar
uma
tag,
para
cada
activity,
no
AndroidManifest.xml e definir uma orientação fixa (screenOrientation) ou avisar ao
Android para não chamar o onCreate() a cada mudança de orientação (configChanges).
2.5.2.2 – Intent
Quando a aplicação tem mais de uma activity, inevitavelmente será necessário
navegar de uma para outra. No Android, essa navegação entre activities é conhecida
como intent.
Como visto anteriormente, toda nova activity do projeto deve possuir um
arquivo xml para definir o layout e uma classe que herda de Activity. No
AndroidManifest.xml deve-se declarar a nova activity também e, nesse arquivo, pode-se
inserir a tag intent-filter para definir o nome e a categoria do intent filter. Outras
activities que quiserem chamar esta nova devem fazê-lo pelo nome do intent filter.
Figura 2.6 – Intent no AndroidManifest.
Fonte: Oscilloscope Android.
Utiliza-se o método startActivity() para iniciar outra activity, criando uma
instância da classe Intent e passando para o construtor dessa classe o nome do intent
12
filter. Desta forma, a activity pode ser chamada por qualquer outra aplicação do
dispositivo móvel. Mas se a activity a ser invocada é da mesma aplicação, o método
startActivity() pode ser usado da segunda maneira abaixo.
Figura 2.7 – Métodos para chamar outra Activity.
Fonte: Oscilloscope Android.
O método startActivity() invoca uma outra activity mas não possibilita o retorno
de informação para a activity atual. Para isso, pode-se utilizar o método
startActivityForResult(). Além de passar um objeto da classe Intent, é necessário passar
um inteiro porque quando uma activity retorna um valor precisamos de uma forma de
identificar qual foi a activity.
Figura 2.8 – Resultado da Activity.
Fonte: Oscilloscope Android.
Na activity chamada, para retornar um valor, pode-se usar o método setData()
ou putExtra() da classe Intent. Neste segundo, passamos o par de atributos nome e
valor, conforme visto na figura abaixo.
Figura 2.9 – Armazenar valor para a próxima Activity.
Fonte: Oscilloscope Android.
Além destes métodos, podemos criar um objeto da classe Bundle e utilizar o
método putExtras().
Para recuperar os dados na activity original, utilizamos o método
onActivityResult(). Este método recebe dois inteiros e um objeto da classe Intent. O
13
requestCode é o código original fornecido para o método startActivityForResult(), para
identificar de qual activity veio o resultado. O resultCode é o código enviado pela
activity chamada no método setResult(). O objeto da classe Intent é o que fornecerá os
dados enviados pela activity chamada.
Com o método, da classe Intent, getStringExtra() podemos recuperar os dados
enviados pela activity chamada.
Figura 2.10 – Exemplo de onActivityResult.
Fonte: Oscilloscope Android.
2.6 – API Bluetooth para Android
Utilizando a API do Bluetooth, pode-se procurar por e conectar-se a outros
dispositivos Bluetooth. Iniciando o link de comunicação, usando os Sockets Bluetooth, é
possível transmitir e receber dados entre dispositivos.
O dispositivo Bluetooth local é controlado através da classe BluetoothAdapter,
que representa o dispositivo Android em que a aplicação está executando. Para acessar o
adaptador Bluetooth padrão pode-se utilizar o método getDefaultAdapter().
Antes de iniciar a busca por dispositivos Bluetooth, deve-se incluir as
permissões do Bluetooth no AndroidManifest.xml. Para modificar as propriedades do
dispositivo local, a permissão de BLUETOOTH_ADMIN deve ser concedida. Abaixo
temos um exemplo das linhas a serem adicionadas no arquivo AndroidManifest.xml.
Figura 2.11 – Permissão Bluetooth no AndroidManifest.
Fonte: Oscilloscope Android.
14
O adaptador Bluetooth oferece métodos para leitura e configuração das
propriedades do hardware Bluetooth. Esse adaptador pode ler ou configurar se estiver
habilitado. Caso não esteja, o método getDefaultAdapter() retorna null. Este teste é feito
no onCreate() da activity principal do projeto, conforme código abaixo.
Figura 2.12 – Verifica se Bluetooth está Ativo.
Fonte: Oscilloscope Android.
Para conservar a vida da bateria, a maioria dos usuários mantém o Bluetooth
desabilitado até eles planejarem utilizá-lo. Para habilitar o adaptador Bluetooth, pode-se
usar a constante BluetoothAdapter.ACTION_REQUEST_ENABLE com o método
startActivityForResult(). Aparecerá uma tela pedindo que o usuário habilite o Bluetooth.
Código utilizado para tal pode ser visto abaixo:
Figura 2.13 – Solicitar Ativação Bluetooth.
Fonte: Oscilloscope Android.
Com a permissão do BLUETOOTH_ADMIN inclusa no manifest é possível
habilitar e desabilitar o Bluetooth do dispositivo usando os métodos enable e disable.
Segue abaixo uma descrição das classes dessa API utilizadas para configurar o
Bluetooth, procurar por dispositivos, conectar-se aos dispositivos pareados e transferir
dados entre os dispositivos.
 BluetoothAdapter: representa o adaptador Bluetooth. Com essa classe, é possível
procurar por outros dispositivos e se conectar a eles;
 BluetoothDevice: representa o outro dispositivo Bluetooth. Pode-se solicitar ao
dispositivo remoto uma conexão ou informações do dispositivo;
 BluetoothSocket: representa a interface para um soquete Bluetooth;
15
 BluetoothServerSocket: representa um servidor aberto para atender requisições
de outros dispositivos. Funciona com um host.
2.6.1 – Tornando o dispositivo descobrível e procurando por outros
dispositivos
Para o dispositivo remoto encontrar o dispositivo local (Adaptador Bluetooth) é
necessário que este esteja configurado como descobrível. Existe uma maneira de saber
se o dispositivo local está descobrível ou não através do método getScanMode da classe
BluetoothAdapter. Esse método retorna uma das seguintes constantes:
 SCAN_MODE_CONNECTABLE_DISCOVERABLE – significa que o adaptador
local Bluetooth pode ser descoberto por qualquer outro dispositivo;
 SCAN_MODE_CONNECTABLE – significa que este não está descobrível para
novos dispositivos remotos, ou seja, só pode conectar-se a dispositivos que já o
descobriram anteriormente;
 SCAN_MODE_NONE – nenhum dispositivo remoto pode encontrar o adaptador
Bluetooth local.
Por questões de privacidade, esta ação fica, por padrão, desabilitada. É possível
ligá-la através de uma permissão explícita do usuário, iniciando uma nova Activity
usando ACTION_REQUEST_DISCOVERABLE. Também por padrão, o dispositivo
local fica descobrível por dois minutos, porém é possível alterar a duração adicionando
EXTRA_DISCOVERABLE_DURATION na execução do Intent.
Para saber se o usuário permitiu ou não que o dispositivo fique apto a ser
descoberto por outros dispositivos Bluetooth pode-se sobrescrever o onActivityResult() e
verificar o parâmetro resultCode. Caso ele seja positivo, indica o tempo, em segundos,
que o adaptador Bluetooth local ficará numa situação possível de ser descoberto. Caso
seja negativo, indica que o usuário rejeitou o pedido.
Alguns métodos úteis da classe BluetoothAdapter para encontrar outros
dispositivos seguem abaixo:
 isDiscovering() – retorna um boolean que indica se o dispositivo está ou não
fazendo uma busca por outros dispositivos remotos;
16
 startDiscovery() – inicia uma busca por dispositivos que se encontram dentro do
alcance do adaptador Bluetooth local;
 cancelDiscovery() – cancela a procura por outros dispositivo.
2.6.2 – Comunicação Bluetooth
As API’s do Bluetooth para Android se baseiam no protocolo de comunicação
RFCOMM, que são um mecanismo para abrir soquetes de comunicação entre dois
dispositivos Bluetooth pareados.
Antes que a aplicação possa estabelecer a comunicação entre os dispositivos,
estes devem estar pareados, ou seja, ligados. Se o usuário tentar se conectar antes de
parear, os dispositivos vão primeiro parear para em seguida se conectarem.
Para estabelecer uma comunicação Bluetooth RFCOMM bidirecional podemos
usar as classes: BluetoothServerSocket e BluetoothSocket. A primeira designa um
dispositivo que age como um servidor, que atende e pode aceitar pedidos de conexão. Já
a segunda, funciona como um cliente. Uma vez que estabelecemos uma conexão entre
os dispositivos, os Bluetooth Sockets são usados para transferir dados.
Um Bluetooth Server Socket é usado para esperar e atender pedidos de conexão
de outros dispositivos Bluetooth. Para dois dispositivos Bluetooth se conectarem, um
deles deve agir como servidor e o outro como cliente. Depois de conectados, a
comunicação entre os dois é tratada por um Bluetooth Socket.
O método listenUsingRfcommWithServiceRecord é usado para deixar o
dispositivo “esperando” por pedidos de conexão. Os parâmetros são o nome que
identifica o servidor e um identificador universalmente único (UUID). Para que o
cliente possa se conectar ele deverá “saber” esse UUID. O método retorna um objeto
BluetoothServerSocket.
Quando o método accept() é chamado, o Server Socket irá bloquear até que um
cliente tente se conectar com o UUID definido pelo servidor. Se a tentativa de conexão
for realizada com um dispositivo remoto não pareado, aparecerá uma tela com um
pedido de pareamento.
Se a conexão for concluída com sucesso, o método accept() retornará um
BluetoothSocket e este pode ser usado para transferência de dados entre os dispositivos.
Abaixo segue código utilizado no projeto:
17
Figura 2.14 – Conexão com Dispositivo Bluetooth.
Fonte: Oscilloscope Android.
Depois de conectados, teremos um Bluetooth Socket para o dispositivo cliente e
o servidor. Esse conceito de cliente e servidor só serve para exemplificar como funciona
a comunicação entre os dispositivos até a conexão ser estabelecida. A partir deste
momento não existe distinção entre os dispositivos, pode-se enviar e receber dados
através do Bluetooth Socket.
A transferência de dados entre os dispositivos é tratado pelas classe Java
OutputStream e InputStream, que pode-se obter do Bluetooth Socket através dos
métodos getOutputStream e getInputStream.
2.7 – API aChartEngine 1.0.0
Esta é uma API Android open source utilizada para criação de gráficos. São
diversos tipos de gráficos disponíveis e muitas funcionalidades. Pode ser baixada no
Google Code através do link: https://code.google.com/p/achartengine/. Pode ser baixada
também no site dos desenvolvedores www.achartengine.org. Alguns dos recursos
incluem:
 Classe Pan – permite que o usuário “arraste” o gráfico e possibilita uma visão
maior deste. Também possui uma classe panListener própria;
18
 Classe Zoom – obviamente, permite que o usuário efetue um zoom no gráfico.
Também é possível criar um zoomListener para tratar um evento de zoom;
 Os gráficos são criados como uma view;
 Suporta vários tipos de gráficos;
 Suporta mais de uma série de dados em um mesmo gráfico.
Para o projeto, foi utilizado o gráfico de linha com algumas modificações no
renderizador (classe XYSeriesRenderer), que dizem respeito a parte estética do gráfico.
A XYSeries é a classe que armazena os valores dos pontos do gráfico. É possível
também remover um dado ponto e obter o valor máximo e o mínimo com seus métodos.
A classe XYSeriesRenderer trata da estética da curva, no caso do gráfico de
linha, como o estilo dos pontos do gráfico e a largura da linha. A
XYMultipleSeriesRenderer é similar a classe anterior mas possui mais ferramentas e
maiores possibilidades de alterar a estética do gráfico. Com esta última é possível
alterar a cor da curva e do fundo, alterar a escala dos eixos, habilitar ou desabilitar o
zoom e o “arrastar” do gráfico (pan), colocar rótulo para cada curva do gráfico, etc.
É uma API de fácil utilização. O site dos desenvolvedores disponibiliza diversos
exemplos para download, para auxiliar na compreensão e implementação de suas
funcionalidades. Também estão disponíveis todos os javadocs.
19
Figura 2.15 – Site da API AChartEngine.
Fonte: http://www.achartengine.org/.
20
Capítulo 3
Hardware
3.1 – Arduino
É uma plataforma eletrônica open source, com um microcontrolador, que possui
um ambiente de desenvolvimento específico para programar os componentes que o
fazem parte. Ela pode ser comprada já pré-programada ou, por ser open source, pode ser
construída pelo próprio usuário, ou seja, eles podem adaptá-la as suas necessidades e
depois atualizar e distribuir suas próprias versões. Os esquemas, as características de
cada versão, os datasheets dos seus componentes, além dos arquivos EAGLE para a
montagem da própria placa podem ser encontrados no site do Arduino:
www.arduino.cc.
O software pode ser programado utilizando as linguagens C ou C++. No site do
Arduino estão disponíveis para download a IDE, que permite o desenvolvimento e o
carregamento do Software para o microcontrolador, e diversos exemplos para auxiliar
todos os tipos de usuário do Arduino, que vão desde aqueles que levam como um
passatempo até aqueles que possuem certa especialização em eletrônica.
21
Figura 3.1 – Site da Arduino.
Fonte: http://arduino.cc/.
No projeto do osciloscópio foi utilizada a versão Arduino Uno R3, por se tratar
de uma versão que possui os componentes necessários e por ser menos custosa. Nesse
tópico iremos tratar da arquitetura deste Arduino, evidenciando o conversor A/D, como
funciona a programação utilizando a IDE e o código do projeto.
3.1.1 – Conversor A/D do Arduino
O Arduino Uno R3 é baseado em um microcontrolador (ATmega238) que possui
alguns componentes necessários para que este dispositivo possa se comunicar com o
computador. Seguem abaixo algumas características dessa versão:
 Tensão de entrada: 7-12V;
 14 pinos de entrada e saída digitais (6 saídas PWM – 8 bits);
 6 entradas analógicas;
 32 kbytes de memória Flash;
 Clock de 16 MHz;
 Suporta comunicação TWI;
 Conversor A/D de 10 bits de resolução.
22
Destes, o mais relevante para ser citado é o conversor A/D (ou ADC), pois foi
trabalhado muito em cima dele, neste projeto.
3.1.1.1 – Arquitetura
O ADC é usado para converter um sinal analógico (varia continuamente) em
valores digitais. O valor analógico representa alguma medida real, neste caso uma
medida de tensão elétrica. Como já é conhecido, os valores digitais não são contínuos,
eles são amostrados um certo número de vezes a cada período de tempo.
O conversor A/D do Arduino realiza a conversão através do método de
aproximações sucessivas. Abaixo temos um diagrama simples que ilustra o ADC.
Figura 3.2 – Diagrama de Blocos do Conversor A/D.
Fonte: Modelo do datasheets do microcontrolador - http://www.atmel.com/Images/doc8161.pdf.
O ADC possui oito entradas analógicas e que são controladas pelo
multiplexador, isto é, a operação de conversão é realizada para uma entrada de cada vez.
Após a conversão valor digital é armazenado em dois registradores (ADCH e ADCL),
já que o ATmega328 é um microcontrolador de 8 bits e o conversor A/D possui 10 bits
de resolução.
A tensão de entrada (Vin), do sinal analógico, deve estar entre 0 volts e a tensão
de referência do ADC (Vref). Normalmente, o Vref é igual a tensão de alimentação do
Arduino. O valor convertido é o inteiro mais próximo do resultado da operação:


Vin 10
2 1 .
Vref
23
Existem dois modos de operação do conversor: conversão simples e o modo
livre. No modo de conversão simples é necessário iniciar cada conversão, isto é, quando
uma conversão é finalizada, os resultados são guardados nos registradores ADCH e
ADCL. Nenhuma outra conversão é iniciada. Só será possível iniciar uma outra
conversão quando o bit ADSC for para 1. Para indicar um evento de término de
conversão, pode ser utilizada uma rotina de interrupção (ISR).
No modo livre, a primeira conversão é iniciada e as outras subseqüentes são
iniciadas automaticamente. Só será necessário indicar qual canal será convertido,
através do registrador ADMUX.
3.1.1.2 – Clock e Prescaler
O ADC deve ter um clock recomendado entre 50 kHz e 200 kHz, quando
desejamos uma resolução de 10 bits. Isso nos leva a crer que existe um prescaler
(divisor) para configurar o mesmo, já que o clock do microcontrolador é de 16 MHz.
Para configurar o divisor, devemos trabalhar com os bits ADPS (2..0). Esses bits
estão armazenados no registrador ADCSRA e podem ser atribuídos os valores 2, 4, 8,
16, 32, 64 e 128. Esse registrador é configurado por padrão no arquivo wiring.c da
biblioteca do Arduino.
Figura 3.3 – Configuração padrão do Prescaler do Microcontrolador.
Fonte: código de API disponibilizada pelo fabricante
Portanto, o clock do conversor A/D pode ser:
 16 MHz / 2 = 8 MHz
24
 16 MHz / 4 = 4 MHz
 16 MHz / 8 = 2 MHz
 16 MHz / 16 = 1 MHz
 16 MHz / 32 = 500 kHz
 16 MHz / 64 = 250 kHz
 16 MHz / 128 = 125 kHz
Para calcular ou chegar próximo de um valor para o tempo de amostragem,
devemos levar em consideração quantos clock’s do ADC são necessários para uma
conversão. De acordo com o datasheets do microcontrolador, na primeira conversão são
necessários 25 clock’s de ADC e nas subseqüentes somente 13 clock’s. Logo, se
configurarmos o prescaler para 64, teremos por volta de 19.230 amostras por segundo.
Utilizando o código abaixo, somos capazes de medir o tempo de amostragem
para cada conversão. Neste código, que será explicado mais a frente, configuramos o
prescaler para 64. Mais abaixo, foram feitas cem medidas e, a cada conversão, tomamos
o tempo antes e depois. O resultado está ilustrado na figura abaixo.
Figura 3.4 – Código Setup do Teste de Prescaler.
Fonte: Oscilloscope Android
Figura 3.5 – Código Loop do Teste de Prescaler.
Fonte: Oscilloscope Android
25
Pelo resultado abaixo, podemos calcular uma freqüência de amostragem de
16,667 kHz, ou seja, temos 16.667 amostras por segundo com o prescaler de 64, valor
próximo do calculado anteriormente.
Figura 3.6 – Resultado com Prescaler igual a 64.
Fonte: Oscilloscope Android
Por experiência neste projeto, pudemos comprovar que, conforme diminuímos o
prescaler (tornando o ADC mais rápido), os valores de freqüência de amostragem
medidos e calculados foram se afastando cada vez mais. Quando o divisor de freqüência
foi configurado para 4, tivemos o resultado abaixo. Com um tempo de amostragem
médio de 10 us. Essa é a configuração inicial utilizada no projeto, pois neste foram
utilizados três tipos de prescaler, dependendo de qual escala de tempo o usuário
escolher para fazer a análise do sinal.
26
Figura 3.7 – Resultado com Prescaler igual a 4.
Fonte: Oscilloscope Android
No datasheets do microocontrolador consta que quanto maior o clock do
conversor A/D, menos se pode garantir uma resolução de 10 bits. Por facilitar a
comunicação do Arduino com o dispositivo Android e baseado nesta recomendação a
resolução utilizada para o conversor, no projeto do osciloscópio, foi de 8 bits.
3.1.2 – Software Arduino IDE
Depois de entender como funciona, em parte, o hardware do Arduino, se faz
necessário implementar esse entendimento via software. Através do código em C ou
C++ podemos fazer todo o tratamento dos dados convertidos pelo ADC e transmiti-los
via Bluetooth para o dispositivo Android.
Neste tópico iremos abordar a estrutura de um programa para o
microcontrolador do Arduino.
Antes de adentrarmos a estrutura de um programa do Arduino, precisamos nos
atentar a configuração do ambiente, para nos prevenir de futuros contratempos na etapa
de programação e carregamento do software para o microcontrolador.
27
A plataforma (IDE) de desenvolvimento do software para o microcontrolador
Arduino recomendada é a disponibilizada pela própria faricante: Arduino IDE. Apesar
de possuir poucas funcionalidades, ela se mostra uma IDE simples e de fácil utilização.
Para inicialmente instalar o ambiente de desenvolvimento devemos seguir
alguns passos de configuração da plataforma, são eles:
 A
própria
instalação
da
IDE
(executável
no
endereço
www.arduino.cc/en/Main/Software);
 Necessário também instalar os drivers referentes à versão do hardware (placa)
utilizada;
 Já na própria IDE, identificar e configurar a porta serial onde a placa está
conectada.
Essas etapas de configuração são simples e podem ser encontradas no manual
disponibilizado pelo fabricante. Após conclusão, podemos nos dirigir diretamente ao
código em si.
Como já dito anteriormente, podemos programar o software do Arduino
utilizando as linguagens de programação C e C++. A placa utilizada neste projeto
(Arduino Uno R3) nos permite programar com as duas linguagens. Já que o código do
projeto não possui uma complexidade alta, a ponto de fazermos uso de orientação a
objetos, foi escolhido como linguagem padrão o C.
A figura abaixo ilustra a interface gráfica da IDE e como é a estrutura de um
programa do Arduino.
28
Figura 3.8 – Código Exemplo de Estrutura de Programa para Arduino.
Fonte: Oscilloscope Android
Existem dois blocos principais no programa, o setup e o loop. O setup é o bloco
que é executado somente uma vez e no início da execução. Na maior parte dos códigos
e exemplos presentes no IDE, no setup se coloca todas as configurações iniciais do
programa. No exemplo acima, foi inicializada e configurada a velocidade da
comunicação serial.
Já no bloco de loop, o usuário aplica a parte do software que precisa ser
executada continuamente. Obviamente, como indica o próprio nome, o loop é executado
seguidamente até cessa a alimentação do hardware. Neste bloco, normalmente é onde
fica a parte principal do código, seria como o main da programação voltada para
29
computadores. No exemplo acima, é feita uma conversão analógico-digital do pino A0,
através da função analogRead(). Logo após é calculado o valor da tensão, a partir do
valor digital medido, e depois este é transmitido pela porta serial.
O Arduino possui uma biblioteca própria com diversas funções, abaixo seguem
as mais conhecidas:
 pinMode() – configurar um pino específico da placa. Como entrada (INPUT) ou
saída (OUTPUT) no caso de pinos digitais, por exemplo;
 digitalWrite() – com esta função é possível ligar ou desligar um pino digital,
estado alto (HIGH) ou estado baixo (LOW). O pino deve ser previamente
configurado como saída;
 digitalRead() – retorna o estado de um pino digital de entrada;
 analogReference() – atribui o valor da tensão de referência de uma entrada
analógica. O padrão é 5 volts;
 analogRead() – retorna o valor digital convertido de um dado pino analógico;
 tone() – gera uma função quadrada de freqüência e duração desejadas. Foi
utilizada para efeito de testes;
 micros() – retorna o tempo, em microssegundos, que decorreu desde que o
programa iniciou a execução.
Ainda existe a biblioteca de comunicação serial, muito utilizada nesse projeto.
Essa API possui diversas funções, entre elas as de iniciar ou finalizar uma comunicação
e de enviar e receber dados pelas vias TX e RX.
3.2 – Módulo Bluetooth
O dispositivo usado no projeto para fazer a comunicação Bluetooth dos dados
convertidos no Arduino para o dispositivo Android foi o modelo HC-05. Este é um
módulo Bluetooth padrão no mercado, ou seja, é pouco custoso e é muito utilizado em
aplicações simples. Para o propósito do projeto do osciloscópio Android, este
dispositivo possui as características necessárias e se adéqua bem ao placa do Arduino.
Este módulo quatro pinos: dois de alimentação e dois de transmissão e recepção
dos dados. O VCC e GND foram ligados diretamente nos pinos de 5 volts e de comum
30
do Arduino e os pinos que possibilitam a comunicação foram ligados nos pinos da porta
serial do Arduino.
Segue abaixo uma imagem do dispositivo:
Figura 3.9 – Módulo Bluetooth.
Fonte:Imagem retirada do datasheets do módulo - http://www.exp-tech.de/service/datasheet/HCSerial-Bluetooth-Products.pdf
31
Capítulo 4
Android Oscilloscope
4.1 – Análise do Código para o Arduino
Depois de entender como funciona a programação no Arduino, foi feita uma
análise do que era preciso ser feito no software do projeto e foram definidos a estrutura
e os requisitos para o programa no Arduino.
Neste tópico serão abordadas as principais definições no software do Arduino,
as tecnologias utilizadas e a comunicação serial via Bluetooth.
4.1.1 – Definições do Código para o Arduino
A quantidade de informação enviada pelo Arduino para o Android é uma das
definições mais importante do sistema, pois esta afeta diversos aspectos importantes
neste projeto.
Em um osciloscópio, dentre várias outras características, devemos nos atentar a
uma em especial: taxa de atualização de tela ou também conhecida como “tempo
morto”. Este é o tempo necessário para que o osciloscópio possa converter, disparar,
processar os dados e então exibi-los na tela. Quanto maior essa taxa de atualização,
maior a probabilidade de capturar um evento não freqüente.
Neste projeto, a taxa de atualização ficou consideravelmente alta, mesmo o
hardware utilizado não sendo de alta performance. Obviamente, nada comparado aos
osciloscópios padrões de bancada disponíveis no mercado. Estes podem alcançar taxas
de atualização da ordem de femtossegundos.
Para a quantidade de informação enviada (quantidade de amostras) ficou
definido o envio de 500 amostras com valores convertidos pelo ADC para o dispositivo
Android. Parece uma quantidade exagerada de amostras, mas foi o necessário para
varrer o gráfico em uma tela inteira do programa Android e garantir que teremos
amostras suficientes sem que prejudique o sistema de trigger do Osciloscópio. Isto é,
32
devemos ter uma quantidade de amostras que permita ao software do Android, após
identificar o ponto de início do gráfico (trigger point), preencher a tela inteira.
A essa quantidade de amostras capturadas pelo osciloscópio é dado o nome de
profundidade de memória, que seria igual à taxa de amostragem multiplicado pela
configuração do tempo por divisão (escala no tempo) multiplicado ainda pela
quantidade de divisões.
No exemplo abaixo do aplicativo Oscilloscope, podemos ver que temos cinco
divisões no tempo e que a escala no tempo é de 1,0 milissegundos por divisão. Sabendo
que a taxa de amostragem para esta situação é de 100 kHz, podemos chegar à conclusão
que a profundidade de memória mínima é de 500 pontos (amostras).
Figura 4.1 – Exemplo de Profundidade de Memória.
Fonte: Oscilloscope Android
33
No programa do Arduino foi necessária a criação de um vetor de bytes, esse
array recebe como primeiro valor um byte de start (valor digital 254), logo após
quinhentas amostras e depois um byte de stop, identificando assim quando se inicia e
termina o array de dados.
Outro ponto a ser destacado é a velocidade de conversão (clock do ADC) já
discutida anteriormente nesse texto. O programa do Arduino possibilita ao programa do
Android a escolha entre três taxas de amostragem diferentes, ou seja, dependendo da
mensagem enviada pelo Android solicitando novos dados, eles podem ser convertidos
com velocidades distintas.
O prescaler pode ser igual a 4, 8 ou 16. Essas opções de taxa de amostragem
seriam um início de melhoria do aplicativo Android para que este possa ter uma ou mais
taxas de amostragem configuráveis. Essa possibilidade será discutida mais adiante.
Conforme dito anteriormente, o conversor A/D do Arduino Uno R3 possui uma
resolução de 10 bits, porém essa configuração é não é editável. Em uma versão mais
recente desse microcontrolador foi adicionada esta funcionalidade em que o usuário
pode, através de uma função da API do Arduino, informar qual a resolução. É a versão
do Arduino Due. Essa placa possui um ADC de até 12 bits, porém o usuário, via
software, pode, por exemplo, configurar para 8 bits e assim os 12 bits previamente
convertido são mapeados para formarem um byte. Caso o usuário coloque 16 bits, por
exemplo, os outros 4 bits que complementar os 12 bits convertidos são preenchidos com
zero. No projeto, para realizar esse mapeamento manualmente foi construída uma
função para transformar os valores de 0 a 1023 em valores de 0 a 253 (254 e 255 foram
reservados para start e stop byte).
As funções utilizadas para a porta serial do Arduino (UART ou USART)
também devem ser ressaltadas. A porta foi configurada para transmitir 9600 bits por
segundo e as funções de read – recebe a mensagem enviada pelo Android – e write –
envia a mensagem/dados para o dispositivo móvel.
4.1.2 – Tecnologias Arduino e Módulo Bluetooth
A tecnologia utilizada tanto para o Arduino (Arduino Uno R3) como para o
módulo Bluetooth foram inteiramente suficientes para o bom funcionamento do
osciloscópio. Apesar de sempre existirem versões e produtos no mercado que
34
possibilitam uma maior performance, conforme dito anteriormente no caso do Arduino
Due, o hardware deste projeto, incluindo o celular Android, foi o adequado e suportou
bem a todos os testes realizados. Em nenhum momento houve falhas neste hardware.
Uma versão futura do projeto poderia incluir comunicação com mais de um
dispositivo, ou seja, seria necessário um hardware com mais portas seriais. A conclusão
óbvia que podemos tirar é que um hardware que possui melhor performance ou mais
recursos, isto é, maior velocidade e precisão na conversão analógico-digital, mais portas
seriais, maior velocidade de processamento, teria facilitado e permitido mais
funcionalidades para o projeto.
4.2 – Análise do Aplicativo Android
Neste tópico será feita a análise do programa Oscilloscope desenvolvido na
plataforma Android. Os aspectos do código que serão abordados: as activities do
software e todos os componentes pertencentes a elas (time e voltage scales, trigger,
cálculo das propriedades do sinal e o gráfico do sinal), dando ênfase à tela onde o
osciloscópio é executado, e a comunicação Bluetooth.
4.2.1 – Activity Inicial
Logo quando o aplicativo é executado o usuário se depara com a activity inicial
(figura abaixo), esta é uma tela que possui dois botões, onde cada um deles direciona
para uma activity diferente.
35
Figura 4.2 – Tela Inicial do Aplicativo.
Fonte: Oscilloscope Android
Foi utilizada uma técnica para inserir os botões, através de imagens. Um
onClickListener no próprio LinearLayout, isto é, um layout foi criado, mas, ao invés de
adicionar componentes a ele, este foi utilizado como um botão. Assim, caso o usuário
clique na região de uma das figuras, este será direcionado para a tela de “About”, com
as informações do projeto, ou para a tela do osciloscópio, onde poderá “inicializar” a
aplicação propriamente dita.
Segue abaixo uma figura da tela “About” do aplicativo, esta activity possui
alguns textViews com as informações básicas do projeto.
36
Figura 4.3 – Tela About do Aplicativo.
Fonte: Oscilloscope Android
4.2.2 – Bluetooth Android
Um dos exemplos disponíveis para os desenvolvedores em plataforma Android é
o Bluetooth Chat, este que é um aplicativo que permite conversa (chat) entre dois
dispositivos Android onde as mensagens são enviadas e recebidas pelo Bluetooth.
Este aplicativo serviu como base na elaboração da comunicação Bluetooth do
aplicativo Oscilloscope Android.
A classe BluetoothChatService foi inteiramente aproveitada para o projeto. É a
classe que possui os métodos para tratar a conexão Bluetooth, como iniciar e finalizar a
comunicação, mudanças do estado da conexão. O construtor dessa classe recebe como
parâmetro um Handler, para quando, por exemplo, houver perda de conexão o método
sendMessage é acionado e o usuário recebe um Toast com a informação.
37
4.2.3 – Activity do Osciloscópio
A tela principal do aplicativo, onde o propósito do projeto se encontra, é a
OscilloscopeActivity. Nela existem diversos componentes e funcionalidades que serão
explicitados adiante.
O primeiro ponto que precisa ser destacado na análise dessa tela é a
funcionalidade de WakeLock. É dada a esta activity a permissão para alterar o
gerenciamento de energia do celular Android, por isso, enquanto o usuário estiver nesta
tela, o sistema não poderá entrar em modo de espera (apagar a tela). Essa funcionalidade
se faz possível utilizando a classe PowerManager.WakeLock e de fato facilita a medição
do sinal exibido no osciloscópio.
Como já é conhecido, o aplicativo só funciona quando o Bluetooth do celular
estiver ativo, por isso a primeira verificação que esta activity faz ao ser iniciada é para
saber se o dispositivo Android está com o recurso do Bluetooth habilitado. Caso não
esteja, uma activity central será inicializada solicitando a ativação do Bluetooth. Essa
solicitação é automática e nativa de dispositivos Android, sempre que o software
requisitar pelo adaptador Bluetooth e este não estiver habilitado. Caso o usuário clique
em “Não”, a aplicação será encerrada.
38
Figura 4.4 – Solicitando Permissão para ativar Bluetooth.
Fonte: Oscilloscope Android
Depois de permitir a ativação do Bluetooth, o usuário precisa conectar o celular
ao módulo Bluetooth e iniciar o processo de aquisição de dados. Para isto, é necessário
clicar no botão “menu” do celular Android
(imagem abaixo) e então “Conect a
Device”. A aplicação vai exibir a DeviceListActivity que permite fazer um escâner por
dispositivos Bluetooth disponíveis e selecionar a qual irá conectar-se. O módulo
Bluetooth está representado como “linvor” na figura abaixo.
39
Figura 4.5 – Menu do Aplicativo.
Fonte: Oscilloscope Android
40
Figura 4.6 – DeviceListActivity.
Fonte: Oscilloscope Android
Após conectar-se a um dispositivo, o usuário deve clicar no “menu” novamente
e iniciar o processo de conversão e exibição do sinal medido clicando em “Start”.
4.2.3.1 – Processo de Exibição do Gráfico
Após entender o comportamento do aplicativo quanto à ativação do Bluetooth e
o gerenciamento de energia, podemos seguir com a análise do processo de aquisição,
tratamento e exibição do gráfico.
No capítulo anterior foi definido que o período em que o osciloscópio faz a
conversão, tratamento e processamento dos dados, antes de exibi-los na tela, se chama
“tempo morto”. Nesta aplicação, este período começa quando o usuário clicar no botão
“Start”.
41
O fluxo dos dados começa quando o botão “Start” é acionado, neste momento o
celular envia para o módulo Bluetooth uma requisição de dados, esta mensagem é
interpretada pelo microcontrolador e inicia-se processo de tratamento dos dados
convertidos, conforme explicitado anteriormente.
Para fazer o controle de transmissão e recepção dos dados, na aplicação
Android, foi utilizado um método da classe Handler chamado handleMessage. Logo,
quando uma mensagem contendo os dados do sinal analógico convertido chega ao
celular, este método de controle é acionado. Este método recebe como parâmetro um
objeto da classe Message.
São quatro tipos de mensagem:
 DEVICE_NAME – quando ocorre esta mensagem, o usuário recebe um Toast
indicando que a conexão foi realizada com sucesso e exibe na tela o nome do
dispositivo ao qual se conectou;
Figura 4.7 – Conectando ao dispositivo Bluetooth.
Fonte: Oscilloscope Android
42
 STATE_CHANGE – essa mensagem traz como argumento um dos quatro
possíveis estados do dispositivo Bluetooth: CONECTED, CONECTING,
LISTEN e NONE;
 WRITE – quando uma mensagem foi enviada. Esse é o momento de reiniciar as
variáveis de controle do código;
 READ – este é acionado quando uma mensagem foi recebida. Neste bloco do
programa é feito o tratamento dos dados em sua forma “pura”, isto é, uma
mensagem com vários bytes é recebida e se faz necessário dividir em blocos de
um byte e identificar o início da cadeia de dados (start byte) e o término (stop
byte). Somente após a chegada do stop byte é que o programa chama a rotina
para desenhar o gráfico.
Dentro da rotina de desenhar o gráfico (plotData) são chamadas outras três
rotinas que serão tratadas mais adiante: Trigger do osciloscópio e o cálculo de algumas
propriedades do sinal.
A rotina de desenhar o gráfico simplesmente exibe todos os dados, começando
pelo valor definido pelo Trigger, para preencher a tela inteira da View que ilustra a
curva. Após carregar todos os dados no objeto da classe XYSeries (achartengine), existe
uma linha do código para atualizar a tela, utilizando o método repaint.
4.2.3.2 – Cálculo de Vmáx, Vpp e Frequência
Essa rotina de cálculo é acionada dentro da rotina responsável por desenhar o
gráfico. As informações de tensão máxima, valor pico-a-pico e de freqüência são
atualizados a com base na mesma taxa de atualização da tela, isto é, a cada novo array
de dados, essas informações são recalculadas.
Os cálculos de Vmáx e Vpp são feitos utilizando os métodos da API
achartengine: getMaxY e getMinY, métodos da classe XYSeries. Abaixo podemos ver
um exemplo de uma onda quadrada gerada por um timer 555, alimentado com 5 volts.
43
Figura 4.8 – Exemplo 1 – Cálculo Vmax e Vpp.
Fonte: Oscilloscope Android
No exemplo acima, podemos conferir que o Vmax e o Vpp estão de acordo com
o esperado, sabendo que o Timer 555 em sua configuração astável possui tensão
máxima na saída igual a tensão de alimentação.
Na figura abaixo temos um outro exemplo com uma onda triangular:
44
Figura 4.9 – Exemplo 2 – Cálculo Vmax e Vpp.
Fonte: Oscilloscope Android
Para o cálculo da freqüência, a fórmula utilizada já é conhecida. A freqüência de
uma onda periódica é igual ao inverso da duração de um período dessa curva. Portanto,
tendo como valor inicial o ponto de Trigger, o vetor de dados foi “varrido” até achar o
próximo ponto com o mesmo valor inicial “subindo”, ou seja, o valor encontrado
precisa ter um valor anterior menor do que o próprio para identificar que a onda neste
instante está com derivada positiva.
Segue exemplo abaixo de uma onda triangular com freqüência de
aproximadamente 500 Hz.
45
Figura 4.10 – Exemplo – Cálculo de Frequência.
Fonte: Oscilloscope Android
4.2.3.3 – Trigger do Osciloscópio
O sistema de funcionamento do Trigger de um osciloscópio foi de essencial
entendimento para dar prosseguimento no projeto. A importância desta funcionalidade é
máxima por diversos aspectos, podemos destacar o principal. O sistema de Trigger
permite que o usuário do osciloscópio possa ver uma onda periódica como se ela
estivesse “parada” na tela, possibilitando as medições e o entendimento de como uma
dada tensão varia no tempo.
Esse processo é essencial no momento de desenhar o gráfico, pois, antes de fazêlo, é necessário identificar o ponto de Trigger no vetor de dados recebido. É importante
ressaltar que não basta identificar somente o valor, é necessário identificar também se
este está em uma região de derivada positiva ou negativa.
46
Neste projeto, foi tomado como padrão a região do Trigger onde a derivada é
positiva e o valor inicial é calculado e é igual à média do valor máximo com o valor
mínimo do vetor de dados. Esse valor inicial só é alterado quando o usuário alterar o
nível de Trigger.
Para identificar se o Trigger está ativo e com bom funcionamento é necessário
verificar, em várias atualizações de tela, se a onda periódica está “fixa”, mas para
ilustrar seguem abaixo algumas imagens do osciloscópio, onde o valor do ponto de
Trigger foi alterado pelo usuário.
Figura 4.11 – Exemplo – Trigger do Osciloscópio.
Fonte: Oscilloscope Android
4.2.3.4 – Botões da Activity do Osciloscópio
Além da view que compõe o gráfico, existem quatro componentes na
OscilloscopeActivity: os dois seekBar para alterar as escalas de tempo e tensão, os dois
botões para alterar o valor do Trigger e outros dois botões para alterar a posição curva
no eixo das ordenadas.
Tanto o Trigger Level como o Position são botões simples que alteram os
valores discretamente. As barras para mudança de escala possuem cinco posições cada.
Para a escala de tensão os valores por divisão são: 0,1 V, 0.2 V, 0.5V, 1,0 V e 2,0 V.
47
Para a escala de tempo os valores definidos por divisão são: 0,1 ms, 0,2 ms, 0,5 ms, 1.0
ms e 2.0 ms.
Seguem abaixo alguns exemplos de alteração das escalas:
Figura 4.12 – Exemplo dos Botões da Activity Principal.
Fonte: Oscilloscope Android
48
Capítulo 5
Conclusões
Esse projeto teve início durante o período letivo em que cursava a disciplina de
Software para Smartphone. O trabalho evoluiu de apenas um simulador no trabalho final
da disciplina eletiva a um aplicativo que realmente pode ser utilizado para análises de
sinais de tensão. Obviamente, este trabalho ainda não tem a pretensão de substituir um
osciloscópio de bancada, que vem sendo utilizado há muitos anos em diversos
laboratórios de várias universidades e escolas, mas pode entregar ao usuário (leigo em
eletrônica ou não) um Software para dispositivo móvel que possibilita análise de sinais
de tensão em qualquer lugar.
Houveram dificuldades por se tratar de um projeto que lida com dois blocos
separados de hardware e software, foi necessário um ajuste (sincronismo) entre as duas
camadas. Outra dificuldade seria em relação aos testes, foram necessárias diversas
visitas ao laboratório para fazer uso do gerador de funções e do osciloscópio de bancada
(questões de comparação). Entre outras, todas foram superadas.
Realmente o trabalho atingiu os objetivos traçados na proposta inicial, porém
existem muitas possibilidades e melhorias para este. Seguem abaixo alguns possíveis
trabalhos futuros:
 Voltage Level Shifting – é uma técnica para ajustar de tensão de um circuito. O
conversor A/D utilizado nesse permite apenas entradas de 0 a 5 volts e maioria
dos conversores no mercado funcionam da mesma forma, porém é possível
ajustar o nível de tensão na entrada do conversor para que o usuário possa medir,
por exemplo, um sinal de -10 a 10 volts, este sinal ser tratado pelo circuito de
voltage level shifting e entrar no conversor como um sinal de 0a 5 volts;
 Osciloscópio com mais de um canal – esse segundo canal poderia ser
implementado de diversas formas, talvez a mais correta seja a utilização de um
Arduino com mais de uma porta serial. Dessa forma, o hardware poderia enviar
dois sinais em paralelo.
49
Bibliografia
[1] AGILENT TECHNOLOGIES., Arquiteturas de memória de osciloscópio – Por que
toda memória de aquisição não é criada igualmente. 2012
[2] DON WILCHER. Learn Electronics with Arduino. 2010.
[3] _________ Datasheets ATmega 328. 2009.
[4] RETO MEIER. Profissional Android 4 application development, 2012.
[5] http://www.exp-tech.de/service/datasheet/HC-Serial-Bluetooth-Products.pdf
[6] http://developer.Android.com/reference/Android/app/Activity.html
[7] http://www.achartengine.org/
[8] http://arduino.cc/
[9] http://www.atmel.com/Images/doc8161.pdf
50
Download