pontifícia universidade católica do paraná escola politécnica curso

Propaganda
PONTIFÍCIA UNIVERSIDADE CATÓLICA DO PARANÁ
ESCOLA POLITÉCNICA
CURSO DE ENGENHARIA DE COMPUTAÇÃO
CHRISTIAN ARROSI
CHRISTIAN KITZMANN GOMES
TITAN HIGHWAYS
CURITIBA
2012
CHRISTIAN ARROSI
CHRISTIAN KITZMANN GOMES
TITAN HIGHWAYS
Relatório apresentado ao curso de
Engenharia de Computação, da Pontifícia
Universidade Católica do Paraná, como
requisito parcial de avaliação, da disciplina
de Resolução de Problemas da Engenharia.
Prof. Afonso Ferreira Miguel
CURITIBA
2012
SUMÁRIO
RESUMO ........................................................................................................................................ 5
GLOSSÁRIO DE SIGLAS ................................................................................................................... 6
GLOSSÁRIO DE PALAVRAS ............................................................................................................. 7
INDICE DE IMAGENS ...................................................................................................................... 8
METODOLOGIA............................................................................................................................ 11
OBJETIVOS ................................................................................................................................... 12
GERAL ...................................................................................................................................... 12
ESPECÍFICOS ............................................................................................................................ 12
MATERIAIS UTILIZADOS............................................................................................................... 12
EQUIPAMENTOS UTILIZADOS...................................................................................................... 13
SOFTWARES UTILIZADOS ............................................................................................................ 13
PROBLEMA APRESENTADOS ....................................................................................................... 13
INTERFACE ................................................................................................................................... 14
PROCESSADOR DE PACOTES ....................................................................................................... 15
BANCO DE DADOS ....................................................................................................................... 16
CÓDIGO INICIAL ....................................................................................................................... 17
CÓDIGO DE CONEXÃO DO BANCO DE DADOS .................................................................... 17
CÓDIGO DA CLASSE SENSORES ........................................................................................... 19
CÓDIGO DA CLASSE PRINCIPAL ........................................................................................... 20
MAQUETE .................................................................................................................................... 21
INTEGRAÇÃO ............................................................................................................................... 21
PLACA DE CIRCUITOS................................................................................................................... 21
CÓDIGO FINAL DO PROJETO ....................................................................................................... 22
INTEGRAÇÃO DOS CÓDIGOS ................................................................................................... 22
jFInterface ........................................................................................................................... 22
MainClass ............................................................................................................................ 25
BytesArray ........................................................................................................................... 25
ProcessadorPacotes ............................................................................................................ 26
Sensor .................................................................................................................................. 26
Connection .......................................................................................................................... 27
OpcodeHandlerlor. .............................................................................................................. 28
MANUAL DO USUÁRIO ................................................................................................................ 30
HISTÓRICO DE DESENVOLVIMENTO............................................................................................ 31
RESUMO
O desenvolvimento do mesmo visa melhorar a segurança dos usuários de
autoestradas, controlando a iluminação e integrado ao mesmo, um sistema integrado de
segurança inteligente. O projeto visa integrar dois módulos distintos criando algo
inovador, trazendo assim mais tecnologia para a vida diária das pessoas.
Separando as autoestradas em várias partes é possível monitorar a quantidade de
veículos transitando em cada trecho da estrada, integrado com um sistema de
iluminação que atuará nas faixas e nas placas de transito presentes na estrada.
Adicionalmente os olhos-de-gato serão substituídos por pequenas lanternas. O sistema
de iluminação será ativado durante a noite e quando existirem veículos transitando no
trecho da estrada em questão.
Um sistema de segurança utilizará as informações como quantidade de veículos
em um trecho da estrada para determinar possíveis acidentes, ao suspeitar de um
acidente a informação será enviada a uma central, possibilitando que ações sejam
tomadas imediatamente.
Palavras-chave: Desenvolvimento, Iluminação, Segurança.
GLOSSÁRIO DE SIGLAS
HTTP
Hypertext Transfer Protocol
MDF
Medium Density Filterboard
NC
NO
PCI
TCP
Normally Closed
Normally Open
Transmission Control Protocol
Protocolo de Transferência de Hipertexto
Placa de fibra de madeira de média
densidade
Normalmente fechado
Normalmente aberto
Placa de Circuito Impresso
Protocolo de controle de transmissão
GLOSSÁRIO DE PALAVRAS
Arduíno
Byte
Header
MySQL
Set
Software
Table
Micro controlador programável
Octeto binário na computação
Cabeçalho de um pacote
Software utilizado para banco de dados
Alterar um conteúdo para o especificado
Sequência de instruções para o computador
Tabela
INDICE DE IMAGENS
Figura 1 - PCI do projeto
Figura 2 - Demonstração dos trechos controlados e seus respectivos sensores.
Figura 3 - Demonstração da conexão dos cabos Ethernet
Figura 4 - Demonstração dos cabos da maquete, estes devem ser ligados ao Arduíno
Figura 5 - Demonstração da ligação de todos os cabos do Arduíno, locais e suas respectivas ligações.
METODOLOGIA
Para o desenvolvimento do projeto foi aplicada a metodologia de separar um
grande problema em várias partes, para a execução desse projeto foi utilizado o seguinte
modelo de separação:
 Software: Módulo onde a comunicação e gerenciamento de informações fora
desenvolvido;
 Elétrica: Projeto dos circuitos e seus testes;
 Maquete: Simulação de uma autoestrada de duas faixas com uma curva;
 Integração: Instalação dos LEDs, sensores, fiação e PCI na maquete.
Após a separação cada etapa foi desenvolvida separadamente.
Para o desenvolvimento do software foi feita novamente uma separação, a parte
de comunicação, banco de dados, comunicação com o arduíno
Desenvolvemos o projeto separando por setores, iniciando-se na parte de
software, onde desenvolvemos toda a lógica e executamos os testes dos sistemas. Após
concluir está etapa passamos a desenvolver a parte de hardware, onde criamos um placa
de circuito impresso exclusivamente para o melhor funcionamento do sistema. Após
executadas estas tarefas passamos a montar a maquete e a integrar todo o setor de
software com o setor de hardware.
O projeto foi desenvolvido na forma de uma maquete para o melhor
entendimento do funcionamento. Cada parte foi projetada, desenvolvida e testada
separadamente. Terminando a integração das partes do projeto, realizamos os testes
finais do funcionamento do projeto.
OBJETIVOS
GERAL
Com base nos programas de aprendizagem das disciplinas do curso de
engenharia da computação, construir um sistema inteligente de iluminação e
emergências para rodovias.
ESPECÍFICOS
 Confeccionar um sistema de iluminação inovador para estradas.
 Integrar o sistema de iluminação com um sistema de emergência.
 Criar algo inovador.
 CD do projeto com imagens, vídeos e documentação sobre o projeto.
MATERIAIS UTILIZADOS
 Placa fenolite
 Compensado MDF
;

resistor de

resistores de

resistores de

receptores infravermelho-
;

emissores infravermelho –
;


;
LED’s auto brilho –
;
de fiação;
 Cola Quente;
 Arduino Duemilanove c/ ATmega328;
 Ethernet Shield Arduino - Enc28j60;

Tintas Spray – Preto, Branco, Verde;
 Estanho com fluxo de solda;
 4 Reles NC – 5V;
 4 Transistores NPN;
EQUIPAMENTOS UTILIZADOS
 Furadeira;
 Broca de
;
 Ferro de Solda;
 Pistola de cola quente;
 Multímetro;
 Computador;
SOFTWARES UTILIZADOS











SolidWorks 2012 – Student Edition;
Eagle 6.1;
NetBeans IDE 7.1.1;
Eclipse HELIOS;
Microsoft Office 2010 - Project;
Microsoft Office 2010 - Word;
Microsoft Office 2010 - Excel;
Microsoft Office 2010 - Visio ;
MySQL Server 5.5;
MySQL GUI Tools;
Arduino 1.0;
PROBLEMA APRESENTADOS
PROBLEMAS ENCONTRADOS
Interferência dos sensores infravermelho
com os demais sensores.
Ruído na entrada do arduino.
Falta de Alimentação para o
funcionamento dos sensores estabelecidos
na maquete.
Problema no código do banco de dados.
Problemas no código do processador de
pacotes.
SOLUÇÕES
Foi utilizado um pequeno tubo de madeira
para direcionar o feixe do sensor.
Foi necessário a utilização de resistores
Pull-Down.
Utilizou-se uma nova fonte de
alimentação, utilizando um cabo USB
ligado ao computador.
Reestruturação do código.
Reestruturação do código.
INTERFACE
A interface assim como todo código do projeto foi criada na linguagem Java,
esta possui quatro campos distintos, nos quais exibiram as informações dos sensores e
de seus trechos. Os campos recebem o nome de acordo com suas funções especificas
sendo de:
 Console: Este recebe a função de imprimir as informações de conexão,
possíveis erros de sistemas e avisos do programa;
 Estatísticas: Este campo recebe a função de mostrar as informações de
um determinado trecho, imprimindo o valor da quantidade de carros no
trecho.
 Sensores: Este campo demostra a instalação e desinstalação dos sensores
na rodovia, mostrando também a localização do sensor no trecho em que
foi instalado.
 Emergências: Este por sua vez mostra os avisos de possíveis acidentes,
utilizando as estatísticas do local, emitindo assim para o operador o
alerta.
PROCESSADOR DE PACOTES
O processador de pacotes é um módulo do projeto que foi criado para realizar
determinar operações dependendo do conteúdo de um pacote recebido. Antes de o
software iniciar o seu papel é inicialmente estabelecida uma conexão com o software
responsável por adquirir as informações do servidor HTTP do Arduíno, uma vez
conectado ele irá receber os pacotes TCP enviados a fim de interpretá-los.
Para a interpretação dos pacotes o primeiro passo é verificador se o tamanho em
bytes do pacote é consistente com os parâmetros esperados. Após isso é necessário ler o
seu header que consiste em um único byte e verificar se o seu valor é consistente com
os códigos operacionais do programa.
O código operacional levará a uma das operações a seguir:





Gravação de um novo sensor no banco de dados;
Apagar um sensor do banco de dados;
Incrementar o contador de um sensor em particular;
Decrementar o contador de um sensor em particular;
Set o valor de um sensor em particular.
Uma vez interpretado o header do pacote a operação solicitada será executada se
possível, verificando ao longo de sua execução se ocorreu algum erro, os possíveis erros
tratados são:






Número de bytes do pacote inconsistente com o esperado;
Gravação de um sensor que já existe;
Remoção de um sensor que não existe;
Incrementar ou decrementar sensor que não existe;
Decrementar sensores com nenhum veículo circulando;
Set valor de um sensor que não existe.
BANCO DE DADOS
O banco de dados foi projetado para receber e armazenar as informações
adquiridas a partir das estatísticas de tráfeg , a escolha de utilizar o MySQL foi devido a
sua facilidade na manipulação dos dados. Inicialmente seu código foi projetado de
forma separada, mas tarde sendo incorporado ao código final do projeto.
O código foi criado na linguagem Java, possuindo um driver para executar a
conexão com o MySQL, para iniciar a conexão é necessário ser definido o local, login e
senha no código fonte.
O banco possui uma table com cinco colunas, cada coluna deve armazenar um
determinado valor correspondente ao seu campo. Os campos foram estabelecidos de
acordo com seus nomes mantendo assim a organização dos dados armazenados, os
valores serão guardados e separados nestes campos sendo eles de:
 Identificador: Este armazena o valor de identificação dos sensores, onde cada
sensor terá um numero exclusivo, facilitando assim a identificação de possíveis
erros;
 TotalCarrosOntem: Este armazena o valor das estatísticas de veículos que
circularam num determinado trecho no dia anterior, este valor para
demonstração será atualizado manualmente;
 TotalCarrosHoje: Este armazena o valor das estatísticas de veículos que
circularam num determinado trecho no dia atual;
 MaiorQuantidadeDeCarros: Este armazena o valor das estatísticas de veículos
que circularam no trecho no determinado período, sendo atualizado
constantemente;
 LimiteTipico: Este armazena o valor das estatísticas da média de veículos no
trecho, sendo emitido o estado de alerta quando ultrapassado.
CÓDIGO INICIAL
CÓDIGO DE CONEXÃO DO BANCO DE DADOS
Este é uma das partes mais importantes para o banco de dados, já que este
conecta o sistema com o MySQL, através do driver próprio para isso. Está parte do
código fica responsável por pegar o usuário e a senha e testa-la para verificar se este tem
autoridade para acessar o banco. Lembrando que este código é apenas demonstrativo, já
que este é o código antigo do banco de dados. Este código também possui as funções de
gravação dos sensores.
public class ConectaBanco {
private String url;
private String login;
private String senha;
public ConectaBanco(String url, String login, String senha) {
setUrl(url);
setLogin(login);
setSenha(senha);
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getSenha() {
return senha;
}
public void setSenha(String senha) {
this.senha = senha;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public void insere(String s, String msg) {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
//System.out.println("\n Salvando URL: ...\n");
try {
Connection conn = DriverManager.getConnection(getUrl(),getLogin(),
getSenha());
try {
String sql = s;
Statement stm = conn.createStatement();
try {
stm.executeUpdate(sql);
System.out.println(msg);
} catch (Exception ex) {
System.out.println("\nErro no resultset!\n" + ex);
}
} catch (Exception ex) {
System.out.println("\nErro no statement!");
}
} catch (Exception ex) {
System.out.println("\nErro no connection!");
}
} catch (Exception ex) {
System.out.println("\nDriver nao pode ser carregado!");
}
}
public ArrayList busca(String s) {
ArrayList Sensores = new ArrayList();
Sensores a = new Sensores();
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
//System.out.println("\n Salvando URL: ...\n");
try {
Connection conn = DriverManager.getConnection(getUrl(),getLogin(),
getSenha());
try {
String sql = s;
Statement stm = conn.createStatement();
try {
ResultSet rs = stm.executeQuery(sql);
while (rs.next()) {
a.setCod(rs.getInt(1));
a.setIdentificador(rs.getString(2));
a.setTotalCarrosOntem(rs.getString(3));
a.setTotalCarrosHoje(rs.getString(4));
a.setMaiorQuantidadeDeCarros(rs.getString(5));
a.setLimiteTipico(rs.getString(6));
Sensores.add(a);
}
System.out.println("Sensor Encontrado com Sucesso!!!\n");
System.out.println("Identificador: "+a.getIdentificador()
+"\nTotalCarrosOntem: " + a.getTotalCarrosOntem()+ "\nTotalCarrosHoje: "+
a.getTotalCarrosHoje()+ "\nMaiorQuantidadeDeCarros: "+a.getMaiorQuantidadeDeCarros() +
"\nLimiteTipico: "+a.getLimiteTipico() +"\n");
//System.out.println(rs.getInt(1));
} catch (Exception ex) {
System.out.println(ex);
}
} catch (Exception ex) {
System.out.println("\nErro no statement!");
}
} catch (Exception ex) {
System.out.println("\nErro no connection! " + ex);
}
} catch (Exception ex) {
System.out.println("\nDriver nao pode ser carregado!");
}
return Sensores;
}
}
CÓDIGO DA CLASSE SENSORES
public class Sensores {
private int cod;
private String Identificador;
private String TotalCarrosOntem;
private String TotalCarrosHoje;
private String MaiorQuantidadeDeCarros;
private String LimiteTipico;
public int getCod() {
return cod;
}
public void setCod(int cod) {
this.cod = cod;
}
public String getIdentificador(){
return Identificador;
}
public void setIdentificador(String Identificador) {
this.Identificador = Identificador;
}
public String getTotalCarrosOntem() {
return TotalCarrosOntem;
}
public void setTotalCarrosOntem(String TotalCarrosOntem) {
this.TotalCarrosOntem = TotalCarrosOntem;
}
public String getTotalCarrosHoje() {
return TotalCarrosHoje;
}
public void setTotalCarrosHoje(String TotalCarrosHoje) {
this.TotalCarrosHoje = TotalCarrosHoje;
}
public String getMaiorQuantidadeDeCarros() {
return MaiorQuantidadeDeCarros;
}
public void setMaiorQuantidadeDeCarros(String MaiorQuantidadeDeCarros) {
this.MaiorQuantidadeDeCarros = MaiorQuantidadeDeCarros;
}
public String getLimiteTipico() {
return LimiteTipico;
}
public void setLimiteTipico(String LimiteTipico) {
this.LimiteTipico = LimiteTipico;
}
}
CÓDIGO DA CLASSE PRINCIPAL
public class MainClass {
private static String
private static String
private static String
private static String
MaiorQuantidadeDeCarros;
LimiteTipico;
TotalCarrosHoje;
TotalCarrosOntem;
public static void main(String[] args) {
Scanner ler = new Scanner(System.in);
ConectaBanco cb = new ConectaBanco("jdbc:mysql://URL", "LOGIN", "SENHA");
int x=-1;
while (x != 0) {
System.out.println("Escolha uma opcao");
System.out.println("1 - Cadastrar novo Sensor");
System.out.println("2 - Buscar Sensor cadastrado");
System.out.println("3 - Sair");
x = Integer.parseInt(ler.nextLine());
switch (x) {
case 1: {
Sensores sensor = new Sensores();
System.out.println("Digite o Identificador do sensor:");
sensor.setIdentificador(ler.nextLine());
System.out.println("Digite a estatistica de carros ontem:");
sensor.setTotalCarrosOntem(ler.nextLine());
System.out.println("Digite a estatistica de carros hoje:");
sensor.setTotalCarrosHoje(ler.nextLine());
System.out.println("Qual foi a maior quantidade de carros:");
sensor.setMaiorQuantidadeDeCarros(ler.nextLine());
System.out.println("Qual o limite tipico de veiculos
transitando no local:");
sensor.setLimiteTipico(ler.nextLine());
cb.insere("INSERT INTO estatisticas.cadastro VALUES (NULL ,
'" + sensor.getIdentificador() + "', '" + sensor.getTotalCarrosOntem() + "', '" +
sensor.getTotalCarrosHoje() + "', '" + sensor.getMaiorQuantidadeDeCarros() + "', '"
+sensor.getLimiteTipico() + "' );", "Sensor gravado corretamente...");
break;
}
case 2: {
ArrayList a = new ArrayList();
System.out.println("Digite o Sensor para procura:");
String Identificador = ler.nextLine();
a = cb.busca("SELECT * FROM estatisticas.cadastro WHERE
Identificador LIKE '" + Identificador+ "%';");
if (a.size()>0){
}
else{
System.out.println("nao achamos o sensor. ");
}
break;
}
case 3: {
x=0;
}
}
}
}
}
MAQUETE
A maquete foi criada a partir de MDF, possuindo as dimensões de
Foram utilizadas tintas spray para a pintura, sendo:
.
 Preto: Para o asfalto da rodovia;
 Branco: Para as faixas laterais de centrais da rodovia;
 Verde: Para pintura lateral ao acostamento, representando assim a vegetação.
Os furos são passantes e possuem dimensões de
para a maquete.
, que é o tamanho dos LEDs,
INTEGRAÇÃO
Para concluir o projeto foi necessário juntar os módulos que foram desenvolvidos
separadamente.
também utilizamos sensores infravermelho de
, sendo um emissor e um
receptor, possuindo uma distancia de
entre eles. Foi utilizado cola quente para
fixação na maquete das peças utilizadas, também foi colocado.
PLACA DE CIRCUITOS
Para controlar a alimentação dos LEDs em cada um dos trechos da rodovia,
estão sendo utilizados relés, para isso foi necessário criar uma placa de circuito
impresso (Figura 1).
A PCI consiste nos seguintes materiais:


transistores NPN;
relés NF;
CÓDIGO FINAL DO PROJETO
INTEGRAÇÃO DOS CÓDIGOS
Aqui se concentra o código final do projeto, tendo toda sua integração concluída.
jFInterface
Este é o código para criação da interface, esta está dividida em quatro setores,
onde estes devem corresponder a uma parte do programa, senso um para o console,
estatísticas, emergências e sensores.
public class jFInterface extends javax.swing.JFrame {
public jFInterface() {
initComponents();
}
@SuppressWarnings("unchecked")
private void initComponents() {
jPanel1 =
textArea4
jPanel2 =
textArea2
jPanel3 =
textArea3
jPanel4 =
textArea1
new javax.swing.JPanel();
= new java.awt.TextArea();
new javax.swing.JPanel();
= new java.awt.TextArea();
new javax.swing.JPanel();
= new java.awt.TextArea();
new javax.swing.JPanel();
= new java.awt.TextArea();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Console",
javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Arial", 0, 18)));
textArea4.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
textArea4.setEditable(false);
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(textArea4, javax.swing.GroupLayout.DEFAULT_SIZE, 361,
Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(textArea4, javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(null,
"Estatisticas", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Arial", 0, 18)));
textArea2.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
textArea2.setEditable(false);
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(textArea2, javax.swing.GroupLayout.DEFAULT_SIZE, 495,
Short.MAX_VALUE)
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(textArea2, javax.swing.GroupLayout.DEFAULT_SIZE, 242,
Short.MAX_VALUE)
);
jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Sensores",
javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Arial", 0, 18)));
// NOI18N
textArea3.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
textArea3.setEditable(false);
javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
jPanel3.setLayout(jPanel3Layout);
jPanel3Layout.setHorizontalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(textArea3, javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
jPanel3Layout.setVerticalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(textArea3, javax.swing.GroupLayout.DEFAULT_SIZE, 221,
Short.MAX_VALUE)
);
jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder(null,
"Emergencias", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Arial", 0, 18)));
// NOI18N
textArea1.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
textArea1.setEditable(false);
javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
jPanel4.setLayout(jPanel4Layout);
jPanel4Layout.setHorizontalGroup(
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(textArea1, javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
jPanel4Layout.setVerticalGroup(
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(textArea1, javax.swing.GroupLayout.DEFAULT_SIZE, 239,
Short.MAX_VALUE)
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
pack();
}
public void setTextEmergencias (String s, boolean append) {
if (append)
this.textArea1.appendText(s);
else
this.textArea1.setText(s);
}
public void setTextEstatisticas (String s, boolean append) {
if (append)
this.textArea2.appendText(s);
else
this.textArea2.setText(s);
}
public void setTextSensores (String s, boolean append) {
if (append)
this.textArea3.appendText(s);
else
this.textArea3.setText(s);
}
public void setTextConsole(String s, boolean append) {
if (append)
this.textArea4.appendText(s);
else
this.textArea4.setText(s);
}
private
private
private
private
private
private
private
private
}
javax.swing.JPanel jPanel1;
javax.swing.JPanel jPanel2;
javax.swing.JPanel jPanel3;
javax.swing.JPanel jPanel4;
java.awt.TextArea textArea1;
java.awt.TextArea textArea2;
java.awt.TextArea textArea3;
java.awt.TextArea textArea4;
MainClass
A função deste código é executar todas as threads do programa, executando a
interface, o processador de pacotes e o banco de dados.
import MainCls.jFInterface;
import ProcessadorDePacotes.ProcessadorPacotes;
public class MainClass {
public static jFInterface inter = new jFInterface();
public static void main(String args[]) {
ProcessadorPacotes p = new ProcessadorPacotes();
Thread thread = new Thread (p);
thread.start();
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
inter.setVisible(true);
}
});
}
BytesArray
Classe usada para efetuar operações com arrays de bytes.
package Bytes;
public class BytesArray {
Convertendo um inteiro para um array de bytes.
public static byte[] intToByteArray(int value) {
return new byte[] {
(byte)(value >>> 24),
(byte)(value >>> 16),
(byte)(value >>> 8),
(byte)value};
}
Aqui faremos o inverso, convertendo um array de bytes para um inteiro.
public static int byteArrayToInt(byte[] b) {
return byteArrayToInt(b, 0);
}
Convertendo um array de bytes para um inteiro utilizando a posição offset.
public static int byteArrayToInt(byte[] b, int offset) {
int value = 0;
for (int i = 0; i < 4; i++) {
int shift = (4 - 1 - i) * 8;
value += (b[i + offset] & 0x000000FF) << shift;
}
return value;
}
}
ProcessadorPacotes
O processador de pacotes é um módulo do projeto que foi criado para realizar
determinar operações dependendo do conteúdo de um pacote recebido. Antes de o
software iniciar o seu papel é inicialmente estabelecida uma conexão com o software
responsável por adquirir as informações do servidor HTTP do Arduíno, uma vez
conectado ele irá receber os pacotes TCP enviados a fim de interpretá-los.
import
import
import
import
import
import
import
MainCls.MainClass;
TCP.Connection;
java.io.IOException;
java.net.ServerSocket;
java.net.Socket;
java.util.logging.Level;
java.util.logging.Logger;
public class ProcessadorPacotes implements Runnable {
private static final int port = 7000;
@Override
public void run (){
ServerSocket server = null;
try {
server = new ServerSocket(port);
} catch (IOException ex) {
Logger.getLogger(ProcessadorPacotes.class.getName()).log(Level.SEVERE, null,
ex);
}
MainClass.inter.setTextConsole("Servidor online!\n", false);
MainClass.inter.setTextConsole("Aguardando coneccoes na porta " + port+"\n",
true);
System.out.println("[Info.] Servidor online!");
System.out.println("[Info.] Aguardando conecções na porta " + port);
while (true) {
Socket client = null;
try {
client = server.accept();
} catch (IOException ex) {
Logger.getLogger(ProcessadorPacotes.class.getName()).log(Level.SEVERE,
null, ex);
}
Connection connection = new Connection (client);
Thread thread = new Thread (connection);
thread.start();
}
}
}
Sensor
Este é responsável pelo contador, executando também as operações do banco de
dados. O contador deve acrescentar ou decrementar o numero de veículos no trecho do
sensor, passando essas informações para as estatísticas.
package Sensor;
public class Sensor {
private static Sensor sensores[] = new Sensor[1];
private static int contador = 0;
private int id;
private int veiculos;
Este é o construtor da classe, onde se cria uma nova instancia da classe, ou seja, um
novo sensor, em seguida envia seu identificador a um vetor.
private Sensor (int id) {
this.id = id;
this.veiculos = 0;
}
Método usado para criar um novo sensor dinamicamente, onde o array ajuda seu
tamanho de acordo com a necessidade.
public static Sensor novoSensor (int id) {
if (idExiste(id))
return null;
Sensor s = new Sensor (id);
sensores[contador++] = s;
Sensor copy[] = new Sensor[contador + 1];
System.arraycopy(sensores, 0, copy, 0, sensores.length);
sensores = copy;
return s;
}
Aqui incrementamos o contador de veículos que estão deste sensor até o próximo.
public void incrementarContador (int id) {
this.veiculos++;
}
Aqui decrementamos o contador de veículos que estão deste sensor até o próximo.
public void decrementarContador (int id) {
this.veiculos--;
if (this.veiculos < 0)
veiculos = 0;
}
Aqui verificamos se o sensor com o identificador especificado existe.
public static boolean idExiste (int id) {
for (int k = 0; k < (sensores.length - 1); k++) {
if (sensores[k].id == id)
return true;
}
return false;
}
Método que busca o sensor pelo identificador e retorna o mesmo, caso este seja
encontrado.
public static Sensor getSensor (int id) {
for (int k = 0; k < (sensores.length - 1); k++) {
if (sensores[k].id == id)
return sensores[k];
}
return null;
}
}
Connection
Esta classe será utilizada para conversar com os clientes conectados, utilizandose threads.
import
import
import
import
import
import
MainCls.MainClass;
java.io.IOException;
java.io.InputStream;
java.net.Socket;
java.util.logging.Level;
java.util.logging.Logger;
public class Connection implements Runnable {
private Socket client;
private static int contador = 0;
private int identificador;
Construtor da classe, esse inicializa os campos do Socket do cliente conectado e
incrementa o contador.
public Connection (Socket client) {
this.client = client;
this.identificador = contador++;
}
@Override
public void run () {
MainClass.inter.setTextConsole("[Debug] -- Conexão aberta com " +
this.getClient().getInetAddress()+ ":" +this.getClient().getPort()+"\n", true);
System.out.println("[Debug] -- Conexão aberta com " +
this.getClient().getInetAddress()+ ":" +
this.getClient().getPort());
int size;
byte[] buffer = new byte[255];
try {
InputStream in = this.getClient().getInputStream();
while (true) {
size = in.read(buffer);
if (size == -1)
continue;
MainClass.inter.setTextConsole("[Debug] Recebi um pacote de " + size + "
bytes de " + this.getClient().getInetAddress()+"\n", true);
System.out.println("[Debug] Recebi um pacote de " + size + " bytes de "
+ this.getClient().getInetAddress());
MainClass.inter.setTextConsole("[Debug] Conteudo : \n", true);
System.out.print("[Debug] Conteudo : ");
for (int k = 0;; k++) {
if ((k + 1) == size) {
System.out.println(buffer[k]);
break;
}
System.out.print(buffer[k] + "-");
}
byte[] data = new byte[size+1];
System.arraycopy(buffer, 0, data, 0, size);
if (!OpcodeHandler.handlePacket(data))
MainClass.inter.setTextConsole("[Debug] Ocorreu um erro processando
um pacote enviado por " + this.getClient().getInetAddress()+"\n", true);
System.out.println("[Debug] Ocorreu um erro processando um pacote
enviado por " + this.getClient().getInetAddress());
}
} catch (IOException ex) {
Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
}
}
public Socket getClient() {
return client;
}
public int getIdentificador() {
return identificador;
}
}
OpcodeHandlerlor.
Classe usada para fazer a chamada de cada opcode de acordo com o seu v
import Bytes.BytesArray;
import MainCls.MainClass;
import Sensor.Sensor;
public class OpcodeHandler {
Método usado para decidir se o tamanho de bytes é consistente com o esperado, caso o
tamanho do resultado da operação for inconsistente será retornado falso, caso contrário
retornaremos verdadeiro.
private static boolean verifySize (int i) {
if (i == 6)
return true;
return false;
}
Este método será usado para adicionar um novo sensor, e escolher um identificador para
o mesmo.
private static Sensor addSensor (int id) {
Sensor s = Sensor.novoSensor(id);
if (s != null) {
MainClass.inter.setTextSensores("[Debug] -- Sensor com o identificador " +
id + " adicionado!\n", true);
System.out.println ("[Debug] -- Sensor com o identificador " + id + "
adicionado!");
return s;
}
MainClass.inter.setTextSensores("[Debug] -- Sensor com o identificador " + id +
" não pode ser adicionado!\n", true);
System.out.println ("[Debug] -- Sensor com o identificador " + id + " não pode
ser adicionado!");
return null;
}
Método usado para se remover um novo sensor que tenha seu identificador
escolhido
private static boolean removeSensor (int id) {
MainClass.inter.setTextSensores("Operação não tratada: remover sensor\n", true);
System.out.println("Operação não tratada: remover sensor");
return true;
}
Método usado para incrementar o contador do sensor que tenha seu identificador
escolhido.
private static boolean incrementCounter (int id) {
Sensor s = Sensor.getSensor(id);
if (s == null) {
MainClass.inter.setTextSensores("[Debug] -- Sensor de identificador " + id +
" não existe!\n", true);
System.out.println ("[Debug] -- Sensor de identificador " + id + " não
existe!");
return false;
}
s.incrementarContador(id);
MainClass.inter.setTextSensores("[Debug] -- Sensor " + id + " incrementado!\n",
true);
System.out.println ("[Debug] -- Sensor " + id + " incrementado!");
return true;
}
Método usado para decrementar o contador de um sensor que tenha seu identificador
escolhido.
private static boolean decrementCounter (int id) {
Sensor s = Sensor.getSensor(id);
if (s == null) {
MainClass.inter.setTextSensores("[Debug] -- Sensor de identificador " + id +
" não existe!\n", true);
System.out.println ("[Debug] -- Sensor de identificador " + id + " não
existe!");
return false;
}
s.decrementarContador(id);
MainClass.inter.setTextSensores("[Debug] -- Sensor " + id + " decrementado!\n",
true);
System.out.println ("[Debug] -- Sensor " + id + " decrementado!");
return true;
}
Método usado para interpretar os bytes recebidos pela conexão aberta.
public static boolean handlePacket (byte[] packet) {
int i = packet.length;
// Verificando o tamanho do pacote recebido para evitar inconsistências, se o
array de bytes tiver um tamanho menor que um devemos retornar falso
if (!verifySize(i))
return false;
// Recebe o primeiro byte do pacote, ou seja o seu código operacional
byte header = packet[0];
// Os 4 bytes a partir do segundo byte são convertidos em um inteiro que é o
identificador do sensor
int id = BytesArray.byteArrayToInt(packet, 1);
// Executando operações distintas para cada opcode
switch (header) {
case 0xA: // Adicionar sensor novo
if (addSensor(id) == null)
return false;
return true;
case 0xB: // Deletar sensor existente
return removeSensor(id);
case 0xC: // Incrementar contador
return incrementCounter(id);
case 0xD: // Decrementar contador
return decrementCounter(id);
default:
return false;
}
}
}
MANUAL DO USUÁRIO
A maquete é dividida em quatro sensores, onde cada um destes controla um
determinado trecho, conforme mostrado na figura 2. Para a montagem de todo
equipamento é necessário que primeiramente conecte os cabos ethernet no modem,
demonstrado na Figura 3, após concluir esta etapa é necessário conectar um dos cabos
no computador a ser utilizado e outro no Arduíno, isso é extremamente importante para
o recebimento e envio de informações.
Agora é necessário ligar todos os cabos da maquete (Figura 4) no Arduíno para o
acionamento da PCI (embutida no interior da maquete), os fios devem ser conectados
seguindo a ordenação do software do Arduíno, estes devem ser conectados conforme
demonstrado na Figura 5.
Após executar essas atividade, ligamos o cabo de energia da maquete em uma
tomada 110V e o cabo USB, também embutido na maquete no próprio computador, este
será responsável pela energia dos sensores. Após tudo estiver ligado de forma adequada,
executa-se o software, onde abrirá uma interface de controle.
Se tudo estiver funcional, o projeto funcionará perfeitamente.
HISTÓRICO DE DESENVOLVIMENTO
11/03/2012
12/03/2012
15/03/2012
20/03/2012
23/03/2012
30/03/2012
04/04/2012
11/04/2012
18/04/2012
25/04/2012
02/05/2012
06/05/2012
09/05/2012
18/05/2012
23/05/2012
28/05/2012
06/06/2012
12/06/2012
Criação do Blog – Este deve conter todas as informações do
andamento do projeto.
Neste dia ocorreu a apresentação da defesa do projeto, no qual
este foi aprovado, e assim iniciamos as atividades oficiais.
Fomos apresentados ao Arduíno, como programa-lo e suas
funcionalidades de um componente importante para o
desenvolvimento.
Chegou o shield Ethernet, no qual foi embutido ao Arduíno
para ser utilizado na comunicação TCP/IP entre a central e os
sensores.
O Arduíno chegou após nossa encomenda, logo após
iniciamos uma fase de testes, para aprender mais sobre suas
funções e suas possibilidades de funcionamento.
Esta semana iniciou-se o desenvolvimento dos fluxogramas
para o software de comunicação através da programação do
Arduíno e o shield Ethernet, também começamos a
desenvolver o desenho da maquete no SolidWorks.
Concluímos o projeto da maquete no SolidWorks, também
concluímos o projeto do software da central e do Arduíno.
Concluímos a interface gráfica da central.
Foi concluído o processador de pacotes que irá interpretar os
bytes recebidos do Arduíno e irá fazer as devidas entradas no
banco de dados, este também governará o que será mostrado
na interface gráfica da central.
Aguardamos a chegada de alguns componentes.
Iniciamos a procura de possíveis bugs no software.
Iniciamos a montagem da maquete e iniciamos testes com os
sensores infra-vermelho.
Foi concluída a maquete
Concluímos a PCI e instalamos os componentes na maquete
Iniciamos o relatório e terminamos de implementar os
sensores na maquete.
Após todas as implementações concluímos todas as atividades
relacionadas a criação, manutenção ou procura de possíveis
erros.
Pré-apresentação do projeto e demonstração da prévia da
documentação.
Apresentação oficial aos professores e termino da
documentação.
Download