TCC Rov
TCC Rov
TCC Rov
ASSOCIADAS DE ENSINO
Campus SÃO JOÃO DA BOA VISTA
Curso de Engenharia da Computação
2
COMUNICAÇÃO E CONTROLE DO ROV SUBAQUÁTICO
3
DEDICATÓRIA
4
AGRADECIMENTOS
5
RESUMO
6
ABSTRACT
7
LISTA DE FIGURAS
Figura 17: Figura do microcontrolador apto para receber mensagens de uma porta serial................ 35
8
Figura 26: Método getConexaoCom()................................................................................................... 46
Figura 37: Porta serial virtual encontrada pela interface visual do computador externo.................... 64
9
LISTA DE TABELAS
10
LISTA DE ABREVIATURAS E SIGLAS
11
SUMÁRIO
1. INTRODUÇÃO .............................................................................................................................. 13
1.1.JUSTIFICATIVA.............................................................................................................................. 15
1.2. OBJETIVOS .................................................................................................................................. 16
1.2.1. Objetivo Geral....................................................................................................................... 16
1.2.2. Objetivo Especifico .................................................................................................................. 16
3. MÉTODOS E TÉCNICAS.............................................................................................................. 22
3.1. COMUNICAÇÃO ........................................................................................................................... 22
3.1.1. Comunicação Serial............................................................................................................. 22
3.1.2. Padrão RS-232..................................................................................................................... 24
3.1.3. Temporização ....................................................................................................................... 25
3.1.4. Modo de Transmissão Serial.............................................................................................. 25
3.1.5. Tipo de Transmissão Serial ................................................................................................ 26
3.2. CIRCUITO CONTROLADOR........................................................................................................ 29
3.2.1. Regulador de Tensão .......................................................................................................... 31
3.2.2. Driver MAX232 e Microncontrolador PIC 16F877A ........................................................ 32
3.2.3. Circuito Integrado L298 ....................................................................................................... 35
3.2.4. Ponte H.................................................................................................................................. 37
3.2.5. PWM ...................................................................................................................................... 40
3.3. PROGRAMA DO COMPUTADOR EXTERNO ............................................................................. 42
3.3.1. API Comm ............................................................................................................................. 44
3.3.2. API JMF ................................................................................................................................. 47
3.3.3. Interface de Configuração dos Parâmetros de Controle................................................ 49
3.3.4. Classe ArqDat....................................................................................................................... 53
3.3.5. Interface Visual Principal..................................................................................................... 54
3.4. PROGRAMA DO MICROCONTROLADOR ................................................................................. 56
3.4.1. Controle Direcional .............................................................................................................. 59
3.4.2. Controle de Velocidade ....................................................................................................... 61
4. TESTES......................................................................................................................................... 63
5. CONCLUSÂO................................................................................................................................ 66
5.1. TRABALHOS FUTUROS.............................................................................................................. 67
BIBLIOGRAFIA..................................................................................................................................... 68
APÊNDICE A - CIRCUITO CONTROLADOR ...................................................................................... 73
APÊNDICE B - DIAGRAMA DE CLASSE ........................................................................................... 74
APÊNDICE C - PROGRAMA DO COMPUTADOR EXTERNO ........................................................... 75
APÊNDICE D - PROGRAMA DO MICROCONTROLADOR................................................................ 99
APÊNDICE E - SIMULAÇÃO ............................................................................................................. 101
12
INTRODUÇÃO
Fonte: Do Autor
13
Figura 2: Estrutura e Pinagem do conector DB9 de transmissão
Existem três tipos de RS-232 (A, B e C), cada um define tensões diferentes
para bits em 1 e bits em 0. O tipo mais utilizado é o RS-232C, que define a voltagem
do bit ligado entre -3V e -12V e a tensão do bit desligado entre +3V e +12V(Figura
4). A especificação define que esse sinal só é viável para distancias de até 8 metros,
para distâncias superiores é necessário outros protocolos. (PUCRS, 2005)
14
Figura 4: Sinal elétrico do padrão RS-232
A placa PCI para o controle dos motores poderá ser projetada após a
definição da comunicação entre o PC (Computador Pessoal) e o ROV. Como o
objetivo da comunicação implica simplesmente em transmitir dados para o
dispositivo, o modo de comunicação Simplex transmitindo o sinal serial assíncrono
atende perfeitamente as necessidades de comunicação deste projeto.
1.1. Justificativa
1.2. Objetivos
16
2. REVISÂO BIBLIOGRAFICA
17
operadores, os movimentos de navegação são causados pela atuação de
propulsores hidráulicos ou elétricos. (VALERIO, 2010)
Os ROVs podem ser divididos em duas classes: observação e de intervenção.
Os de observação são, geralmente, menores que um metro cúbico e não dispõem
de braços, basicamente são compostos por câmeras de vídeo que se movimentam.
Os veículos de intervenção costumam ser maiores, em torno de dois metros de
altura por três de comprimento e chegam a pesar mais de três toneladas. Estes
ROVs possuem braços manipuláveis para que se possam agarrar objetos, operarem
válvulas e quase todas as operações que um mergulhador faria em águas mais
rasas, tendo capacidade para carregar uma grande quantidade de ferramentas para
intervenções nos poços e equipamentos submarinos. (TECNOPEG, 2010)
O controle e a comunicação entre o operador e o veiculo são ferramentas
extremamente importantes para o sucesso das missões onde os ROVs são usados
como ferramentas principais. Atualmente pode-se observar uma grande quantidade
de universidades que desenvolvem tecnologias para criar e/ou aperfeiçoar as
ferramentas já existentes para estes veículos.
O British Columbia Institute of Technology tem seu sistema de controle
eletrônico distribuído entre três módulos separados: Módulo de interface de usuário,
Módulo de controle de ferramenta e Módulo de controle do propulsor.(B.C.I.T., 2005)
Cada módulo contém um microcontrolador Atmel AVR ATmega644 em uma
placa de circuito impresso personalizada. O GNU Compiler Collection suporta a
arquitetura AVR para que programação possa ser feita em alto nível de linguagens.
A capacidade de programar o ROV em uma linguagem de alto nível permite
alterações mais rápidas e facilitam o processo de encontrar e reduzir erros na
programação.
O módulo de interface do usuário está localizado nos controles na superfície.
Ele recebe os comandos do dispositivo de entrada, um joystick, transforma em
instruções para o ROV e envia as instruções através do protocolo EIA485. Seu
funcionamento é descrito na Figura 5.
18
Energia Inicializa Coletar Entrada Calcular a Enviar instruções s
r distribuição pelo EIA485
do impulso
Não
19
O módulo de controle do propulsor está localizado na parte traseira do ROV.
Ele recebe instruções do módulo de controle de ferramenta via SPI e produz sinais
PWM para os controladores motores de acordo com as instruções. Sua operação é
descrita na Figura 8:
Sim
Mensagem Ler a Regular PWM
de Inicio? Mensagem - propulsor
Não
20
cria um campo eletromagnético que oferece uma razoável proteção contra
interferências externas.
Os cabos podem ser blindados ou não, cuja única diferença entre eles é que
os cabos blindados além de contarem com a proteção do entrelaçamento dos fios
possuem uma blindagem externa, sendo mais adequados a ambientes com fortes
fontes de interferências, como grandes motores elétricos e estações de rádio que
estejam muito próximas. Outras fontes menores de interferências são as lâmpadas
fluorescentes, cabos elétricos quando colocados lado a lado com os cabos de rede e
mesmo telefones celulares muito próximos dos cabos.
Este tipo de cabo permite uma distância máxima entre os pontos de até 100
metros, os cabos do tipo par transado são mais baratos que os outros tipos de cabo
e sua velocidade máxima é de 100 mbps. O que atende as necessidades de
transmissão de dados de um ROV acadêmico. (ALEX, 2001)
A seguir, nos próximos capítulos utilizaremos conceitos abordados para
projetar o sistema de controle e comunicação entre o ROV e o operador.
21
3. MÉTODOS E TÉCNICAS
3.1. Comunicação
Fonte: Do autor
23
Figura 10: Sinal elétrico do caracter ‘P’ (10110 binários)
O padrão RS-232 foi criado no inicio da década de 1960, a partir das idéias de
telefonia vistas anteriormente. Ela especifica as tensões, temporizações e funções
dos sinais, um protocolo para troca de informações, e as conexões mecânicas. Com
o passar dos anos foram aparecendo varias versões da RS-232, como por exemplo,
os tipos RS-232A, RS-232B, RS-232C, RS-232D e tipo RS-232E, onde esta é a
mais recente sendo lançada em 1991 (CANZIAN, 2005).
Cada uma define tensões diferentes para bits em 0 e 1, que variam de -3V e -
25V para o bit em nível baixo (Space), e +3V a +25V para o nível alto (Mark)
24
(PUCRS, 2005). Algumas interfaces seriais nos computadores atuais fornecem -12V
e +12V, mas suportam mínimas de -25V e +25V (ROGERCOM, 2006).
3.1.3. Temporização
25
Figura 111: Canais independentes de comunicação do modo Full-Duplex
26
avisando que a transmissão começou e que serão necessários pulsos de
temporização (clock) (CANZIAN, 2005).
Na Figura 12 a seguir, podemos observar que o emissor e o receptor
possuem relógios temporizadores independentes.
O bit que fica entre o ultimo bit de dados e o Stop Bit é o bit de paridade. Este
bit é utilizado apenas no tipo de comunicação assíncrona para servir como uma
solução primaria a nível físico para detectar a ocorrência de erros na transmissão de
dados. Para definir se houve algum erro na transmissão o contador dos bits do
receptor verifica se a quantidade recebida é par ou ímpar. Por exemplo, se
definirmos nas configurações do receptor e emissor o bit de paridade sendo como
par, a soma de todos os bits mais o bit de paridade deve ser par para ser
considerada uma transmissão correta, caso os dados recebidos sejam ímpar, isso
significa que a informação sofreu alguma modificação ao decorrer da transmissão
(ROGERCOM, 2006) (CANZIAN, 2005) (PUCRS, 2006).
Na Figura 13 á seguir, será apresentado um exemplo de uma mensagem de
dados enviado pelo tipo de comunicação assíncrono.
27
Figura 13: Exemplo de mensagem enviada pelo tipo de comunicação assíncrono
28
Se cada marca ou espaço pode ser reconhecido pelo receptor em um tempo
T de 52us, e definimos que a mensagem de controle enviada para o protótipo não
possuirá o bit de paridade, contendo assim uma quantidade total de 10 bits, o tempo
estimado para uma mensagem ser recebida completamente será:
MOTORES DO PROTÓTIPO
Motor Tensão (V) Amperagem (A)
Motor 1 12 2,5
Motor 2 12 2,5
Motor 3 12 2,5
29
• Opção para controle de velocidade dos motores;
• Utilizar um microcontrolador para realizar o comando das opções de
controle;
Com as informações expostas acima, pode ser notado que serão utilizados
três motores, onde todos eles serão propulsores do protótipo. No total serão seis
comandos direcionais para seu controle, ou seja, para a execução de todos os
sentidos propostos, os motores deverão operar nos dois sentidos distintos utilizando
a inversão de giro. Partindo da idéia que o circuito controlador ficará constantemente
recebendo alimentação, a inversão de giro será realizada por uma ponte H na sua
saída para os motores, podendo habilitar e desabilitar o sentido desejado.
Outra observação pré-definida é o controle de velocidade dos motores. A
técnica utilizada para este controle chama-se Modulação por Largura de Pulso ou
simplesmente PWM (Pulse Wildth Modulation), que será descrita posteriormente
assim como o sistema da ponte H (VINICIUS, 1999).
Uma vez definido as técnicas de controle dos motores, estabelecemos o
microcontrolador que tenha tais funcionalidades, que neste caso será utilizado o PIC
16F877A, que possui 40 pinos no total, sendo eles 33 pinos somente como I/O, que
servirão como chaveadores dos componentes, e também 2 pinos similares a uma
saída analógica, podendo ser usados como moduladores de velocidade PWM
(MICROCHIP, 2000).
No item 3.1.2 foi citado o padrão serial de comunicação RS-232, esta é uma
das mais utilizadas para troca de informações com microncontroladores, pois o fato
de ser veloz e possuir apenas dois fios de dados, um apenas para o envio e outro
para o recebimento, facilita a projeção de um circuito controlador e posteriormente a
construção do cordão umbilical utilizado (TORRES, 2000). Por este motivo, a
comunicação serial já possui um componente específico para a eletrônica, sendo ele
o driver MAX232, que é o responsável pelo interfaceamento com o microcontrolador.
O PC enviará através de um fio de dados do cordão umbilical o comando
serial no padrão RS-232, o driver MAX232 converterá em um sinal compatível com o
microcontrolador, onde o restante do circuito por já estar recebendo alimentação
constante, apenas será chaveado a partir da execução do comando recebido caso
seja este um comando direcional, ou modulando o sinal analógico quando recebido
um comando de velocidade.
30
Pela sua fácil utilização e atendimento dos requisitos de comunicação e
controle deste projeto, todo o desenvolvimento do circuito controlador foi realizado
na versão 7.6 da ferramenta de simulação eletrônica Proteus Designer Suíte, da
indústria de softwares Labcenter Eletronics. O circuito completo se encontra
anexado no Apêndice A e a partir dele será detalhado a sua estrutura e
funcionamento nos subitens a seguir.
31
Convencionalmente um regulador de tensão possui apenas três pinos, o
receptor (Pino 1), emissor (Pino 3) e o GND (Ground, pino 2) como terra. Para o
desequilíbrio interno da carga elétrica foi utilizado dois capacitores em paralelo para
cada uma das alimentações existentes no circuito, para a tensão de 5V do
microcontrole um capacitor de 470uF e outro de 100nF (Robótica Simples, 2005).
32
Figura 15: Funcionamento do Driver MAX232
Analisando o conteúdo da Figura 15, pode ser observado que o driver possui
uma especificação pré-definida, que são seus geradores com um valor de 1uF cada
um deles (SOARES, 2008).
O microcontrolador PIC 16F877A é o componente principal de todo circuito
controlador deste projeto, pois é a partir dele que o restante deste circuito é
desenvolvido. A especificação deste microcontrolador estabelece seus pinos RA,
RB, RC, RD e RE, sendo os pinos I/O, totalizando 33 pinos, conforme apresentado
na Figura 16. Neste projeto todos os pinos I/O utilizados para controlar o protótipo,
serão configurados para operar apenas como saída (Output).
Um pino I/O funciona analogicamente, ou seja, trabalha em falso e verdadeiro
(0 e 1), onde o seu estado lógico 0 representa uma tensão de saída de 0V, e seu
estado lógico 1, uma tensão de 5V. Estas informações podem ser simplificadas
dizendo que, quando o pino se encontra no estado 0 ele esta desligado, e quando
estiver no estado 1 ele esta ligado (MICROCHIP, 2000).
33
Figura 16 Pinagem do microcontrolador PIC 16F877A
34
Figura 17: Figura do microcontrolador apto para receber mensagens de uma porta serial
Fonte: Do autor (ROGERCOM, Curso USB/Serial)
35
cargas indutivas como reles, solenóides, motores DC e motores de passo (ST
Microelectronics, 1995) (SOUZA, 1998).
Este CI possui uma pinagem relativamente simples para sua utilização, sendo
dividos em duas classes (A e B), onde ambas possuem 2 pinos de entrada (input)
para receber os comando TTL do microcontrolador e 2 pinos de saída (output) para
direcionar a alimentação aos pólos dos motores. Isso significa que é possível
controlar até dois motores por um único chip. Mas pelo fato de não suportar uma
corrente adequada para controlar mais de um motor de propulsão do protótipo, será
utilizado neste projeto um CI para cada um deles, representando um total de 3 CI’s.
A sua estrutura possui um pino (Pino 6, VS ou Supply Voltage) que recebe
uma alimentação constante da fonte, neste caso 12V, e será exatamente esta há ser
enviada para os motores. Podemos considerar que o funcionamento deste CI segue
a teoria de um transistor, onde este pino teoricamente seria o seu coletor, os pinos
input a base e seu respectivo output o emissor. Outro pino a ser considerado é o
VSS (Logic Supply Voltage), que é representado pelo pino de número 9, onde ele
recebe o nível lógico de controle do CI, 5V provenientes do regulador tensão
(PAULA, 2000).
Cada classe de pinos possui um denominado Enable, que são os
responsáveis em habilitar ou desabilitar o uso desta classe. Este pino ficará
conectado diretamente no microcontrolador, recebendo o seu sinal lógico, portanto,
quando receber o sinal em nível alto, os pinos I/O da classe estão habilitados, e
quando este sinal estiver em nível baixo, à classe permanece desabilitada para uso
independentemente do nível que esta sendo recebido pelos seus respectivos pinos
input. Aproveitando-se deste fato utilizamos à modulação PWM exatamente no pino
Enable, modulando sua habilitação/desabilitação para controlar a velocidade de giro
dos motores (SOUZA, 1998) (PAULA, 2000) (RABELO, 2000).
36
Figura 18: Funcionamento do CI L298
Fonte: Do autor (ROBÔS AUTONOMOS)
3.2.4. Ponte H
Controle Analógico
Terminal 1 Terminal 2 Execução
0 0 Parado
1 0 Direção 1
0 1 Direção 2
1 1 Proibido
38
Figura 19: Execução do segundo e terceiro comando de controle da Tabela 2
3.2.5. PWM
40
Figura 22: Exemplo de um ciclo ativo em um determinado período de tempo
Fonte: MALAQUIAS
Um sinal PWM pode ser considerado um sinal analógico, pois num instante
de tempo é “1” e em outro é “0”, onde 1 é o tempo durante o qual a carga é
alimentada, e 0 é o tempo durante o qual a carga não é alimentada (GUERREIRO,
2004).
Para demonstrar a utilização da modulação no controle de velocidade dos
motores deste projeto, exemplificaremos da seguinte forma. Os motores necessitam
para operar em pleno movimento de uma alimentação total de 12V, e a largura de
um pulso ocorre exatamente em 1s. Se configurarmos o ciclo do pulso que habilita
os motores em 80% em nível alto, a tensão média aplicada ao motor será 9,6V.
Caso configurado com um ciclo 30% ativo, a tensão média aplicada ao motor será
3,6V. Este exemplo está apresentado na Figura 23.
42
desenvolvimento do sistema, pois simula perfeitamente sua estrutura e
funcionamento, uma vez definido a utilização de uma linguagem orientada a objeto
para o controlador da superfície (MEDEIROS, 2007).
Pode ser observado no diagrama de classe anexado no Apêndice B, que o
sistema possui duas classes especificas desenvolvidas e utilizadas para o controle,
WebCam e Comm, onde elas respectivamente configuram e comandam o sistema
de reprodução de imagens e a conexão com a porta serial utilizada para enviar os
comandos para o microcontrolador. Para a utilização da classe WebCam é
necessário utilizar uma API (Application Programming Interface) da linguagem Java
especifica para o desenvolvimento de controle multimídia, que é a JMF (Java Media
Framework). Igualmente utilizamos a API Comm para possibilitar o manuseio das
funcionalidades das portas I/O.
Uma API é um conjunto de rotinas e padrões estabelecidos para a utilização
de suas funcionalidades por softwares desenvolvidos para apenas manusear seus
serviços, ou seja, uma API é acessível apenas por programação para utilizar
características especificas menos evidentes a um sistema comum (MEDEIROS,
2007). Como, por exemplo, as API’s utilizadas neste projeto, pois cada uma é criada
especificamente para um determinado tipo de desenvolvimento, comunicação I/O e
imagens.
Outra opção disponível desenvolvida é a interface visual de configuração
onde podemos definir os parâmetros dos comandos de controle do ROV, e as teclas
de atalho para utilizar o teclado como controlador, todas essas opções sendo salvas
em arquivos, não necessitando sua configuração novamente sempre que aberto o
programa.
Nos próximos subitens deste capitulo será descrita a estrutura e as principais
funções do sistema de controle desenvolvido para o computador da superfície, onde
o mesmo estará completo anexado no Apêndice C, onde poderá ser observado
constantemente ao decorrer das explicações das classes desenvolvidas.
43
3.3.1. API Comm
A API Comm pode ser utilizada para o envio e recepção de dados entre dois
periféricos, pois em seu controle entre as portas podemos configurar interrupções,
sincronizar clock, reconhecer stop bits, paridade e ainda lidar com o código ASCII
(American Standard Code for Information Interchange) gerado pelo teclado. Com o
padrão atual de microprocessadores e microcontroladores, pode ser utilizado
recursos como esta API para fazer este trabalho de comunicação (ORENSTEIN,
2007).
Para integrar a API Comm á maquina virtual Java do computador e
disponibilizar sua utilização, é necessário realizar primeiramente três passos após a
descompactação do arquivo disponibilizado no link
http://java.sun.com/products/javacomm/index.jsp da Sun Microsystems
(GOMES, 2005). Estes passos são:
44
e as teclas de atalho do teclado. Todos estes parâmetros são carregados para as
variáveis da classe e enviadas para o menu visual principal na inicialização do
programa, que é a classe MenuInterface. Este método pode ser observado na Figura
24.
45
realizada sem ter encontrado nenhuma exceção. O método getConexaoCom() será
apresentado na Figura 26.
46
sistema do microcontrolador está descrito no subitem 3.4, onde será exposto sua
estrutura e funcionamento.
Na seqüência do código aparecem os comandos catch que representam os
erros que podem ocorrer ao decorrer da execução das linhas de configuração da
comunicação (FURGERI, 2005). A seguir na Figura 27 poderá ser observado o
método encarregado de enviar os comandos seriais para o microcontrolador, este é
o setExecutaComando().
A API JMF pode ser utilizada para fins que envolva vários tipos de formatos de
media de um computador, como capturar fotos e vídeos com uma webcam,
reproduzir musicas ou até mesmo gravar sons por um microfone. Para sua
integração com a maquina virtual Java instalada no computador, esta API
igualmente a API Comm também necessita de alguns passos para ser integrada e
disponibilizada para sua utilização. Basta descompactar o arquivo disponibilizado no
link http://www.oracle.com/technetwork/java/javase/download-142937.html (JMF, 2006). Os
passos são:
47
• Instalar o software JMF 2.1.1e;
• Copiar o arquivo “jmf.jar” na pasta /BIN/LIB/EXT do diretório JRE e JDK;
48
As palavras entre aspas ("vfw:Logitech USB Video Camera:0") da linha de
código CaptureDeviceInfo deviceInfo =
CaptureDeviceManager.getDevice("vfw:Logitech USB Video Camera:0"); da
Figura 22, é onde especificamos exatamente qual a WebCam que será carregada,
neste caso, uma câmera padrão conectada por meio de uma porta USB (VINICIUS,
1999). Este é um método booleano, ou seja, se ao decorrer da execução das linhas
de código para capturar o driver da webcam instalada no computador, e atribuí-la ao
gerador de imagens (Component) apresentarem algum erro, o método ira retorna o
valor falso para aquele que a executou, e apenas ira retornar verdadeiro se não
ocorrer nenhum erro na sua execução.
O método que retorna o Component que irá gerar as imagens no menu
principal do programa é o getComponent(), ele possui a função simples de apenas
retornar o gerador de imagens para ser apresentada na interface visual, caso a
conexão com o driver da câmera esteja estabelecido (FURGERI, 2005). O
responsável em finalizar a captura das imagens, desconectar-se do driver carregado
e limpar suas variáveis é o método setClosePlayer() (Javafree.org, 2006).
49
Figura 29: Interface de configuração dos parâmetros de controle
51
Figura 30: Método setParametrosBean()
52
valores inteiros de controle, o processo de gravação nos arquivo pelo método
setDat() será descrito no subitem 3.3.4.
Por ultimo, o método actionPerformed irá salvar nos parâmetros do JavaBean
ControleBean as informações configuradas ou atualizadas para serem utilizadas
como controle do ROV. E este JavaBean contendo as informações de controle será
atribuído novamente a classe MenuInterface pelo método setParametrosBean().
Todo o método actionPerformed responsável em executar o processo de gravação
das informações será apresentada na Figura 31.
53
informações, configurações que serão utilizados no decorrer de sua execução (
TERRA, 2008).
Para habilitarmos a manipulação de arquivos basta importarmos no cabeçalho
o pacote I/O, este pacote habilita a classe a utilizar todas as funcionalidades de
entrada e saída de dados, para arquivos com qualquer tipo de formato.
O primeiro dos três métodos que a classe possui é o setDat(), e é por meio
deste que será salvo os comandos de envio, e os códigos das teclas de atalho em
dois arquivos distintos na pasta de configurações do diretório do programa, com os
nomes Comandos e ComandosTeclado respectivamente, ambos com o formato dat.
O método recebe como argumentos duas array do tipo inteira contendo as
informações que serão salvas nos arquivos.
O método que retorna uma array com os comandos de envio do arquivo
Controle.dat, é o getDatComandos(), ele simplesmente abre este arquivo que está
na pasta de configurações e realiza a varredura dos dados capturando cada um
deles para os campos desta array numérica inteira. Caso anteriormente não tenha
sido realizado nenhum processo de gravação e o arquivo não exista, a array será
retornada com os valores zerados. Todo o processo do método
getDatComandosTeclado() de abrir e retornar os valores é exatamente igual ao
método getDatComandos(), com a única diferença que irá utilizar o arquivo
ComandosTeclado.dat que contem os códigos das teclas de atalho.
Fonte: Do autor
55
configurações de controle descrita no subitem 3.3.3, os botões de envio dos
comandos direcionais, o controlador de velocidade (Slider) e a caixa de combinação
(ComboBox) com as portas I/O já disponíveis para escolha. Todas elas com imagens
para ilustrar a interface. Para utilizar alguma das portas I/O para enviar os comandos
de controle, primeiramente devemos criar uma conexão com a porta, através do
botão “Conexão” disponível ao lado direito da caixa de combinação das portas I/O,
este botão irá executar o método getConexao() da classe Comm explicada no
subitem 3.3.1, podendo ser observada na Figura 19, enviando como argumento a
porta serial escolhida para utilização.
Somente após a conexão com a porta serial ser realizada perfeitamente será
liberado a utilização dos botões de controle. Cada um desses botões quando
pressionado irá executar o método getExecutaComando() da classe Comm,
enviando como argumento o seu devido comando.
Igualmente a conexão com a porta serial, também é preciso criar outra
conexão com a webcam acoplada ao protótipo, para isto o botão “WebCam” logo
abaixo do componente destino a gerar suas imagens, executara o método
getComponentWebCam() da classe WebCam descrita anteriormente. E caso não
haja nenhum erro nesta execução, as imagens serão direcionadas para o
componente de visualização da interface visual. Para finalizar as conexões com a
porta serial e a webcam, basta clicar novamente nos seus respectivos botões.
56
Figura 33: Linhas de configurações do sistema do microcontrolador
58
Figura 34: Loop Eterno
Pode ser observado na Figura 28, que o programa estará executando um loop
eterno, ou seja, ele estará interminavelmente verificando se houve um comando
serial recebido pelo microcontrolador através do fio de dados do cordão umbilical.
Esta verificação é realizada pelo comando “if(kbhit())”, onde caso esta condição seja
considerada verdadeira, dara prosseguimento na execução dos códigos internos.
Comparando a Figura acima com a Figura 31 do subitem 3.3.3, pode ser observado
que as condições (case) dos comandos recebidos devem estar perfeitamente
relacionadas ao conteúdo dos parâmetros de envio, e somente com este
59
sincronismo que a execução do controle será realizada com sucesso (PEREIRA,
2001).
O código que executa o comando recebido caso seja este direcional, é o
“output_d(0bXXXXXXXX)”, sendo cada uma das variáveis “X” o valor 0 ou 1, que
indica respectivamente que o pino entrará em estado low or high (Baixo ou alto).
Cada uma das variáveis “X” representa os pinos I/O da classe RD, e define o estado
dos pinos RD7 ao RD0 ordenadamente, conforme apresentado na Figura 35
(PEREIRA, 2001).
Fonte: Do autor
60
3.4.2. Controle de Velocidade
61
mensagem de aumento, até atingir 100% de ciclo ativo, onde executara a velocidade
máxima.
O programa completo desenvolvido para o microcontrolador está anexado no
Apêndice D.
62
4. TESTES
63
Figura 36: Configuração da comunicação serial do componente COMPIM
Figura 37: Porta serial virtual encontrada pela interface visual do computador externo
Fonte: Do autor
64
Para uma simulação visualmente mais próxima do real, foram substituídos
nas pontes H dos CI’s L298 com os diodos os pinos conectores que teoricamente
iriam ser plugados aos pólos dos motores, por um motor virtual DC simples
disponibilizado pelo Proteus nas opções de componentes simuladores
eletromecânicos. Este motor é acionado de acordo com a execução do circuito a
partir do recebimento do comando serial direcional do computador externo (BREIJO,
1995). Para a observação do PWM gerado para o controle de velocidade dos
motores também foi adicionado ao circuito um osciloscópio virtual que demonstra
perfeitamente as ondas do sinal analógico do pino CCP1/RC2 conectado as portas
enables dos CI’s L298 (KITOEAG, 2000). Por fim, para que o microcontrolador do
Proteus receba e execute os comandos recebidos basta adicionarmos em sua opção
“Program File” o caminho onde o programa desenvolvido para ser gravado na
memória do microcontrolador se encontra no computador.
Após a simples modificação do circuito e a conexão do cabo serial virtual
estar configurada em ambos os programas, podemos executar o Proteus
selecionando a opção “Play” de seu menu (BREIJO, 1995). A partir desta opção é
possível observar a troca de informações entre ambos os programas, a execução
dos mesmos pelo microcontrolador movimentando os motores virtuais em ambos os
sentidos, e também o sinal PWM demonstrado no osciloscópio. Algumas imagens
desta simulação e também da captação de vídeo do programa por meio de uma
webcam comum conectada ao computador, poderão ser observadas no Apêndice E
onde serão adicionadas imagens dos testes realizados.
65
5. CONCLUSÂO
66
recebido. Por este motivo o controle de velocidade foi retirado do sistema
controlador do computador externo e o microcontrolador acabou reprogramado para
enviar um ciclo ativo de 100% para os motores, operando sempre em carga máxima.
O processo de simulações proporcionou que todo sistema controlador
desenvolvido fosse testado e colocado à prova sua execução completa. Este
processo de testes atingiu as expectativas demonstrando que o sistema de controle
funcionou corretamente, o que possibilitou posteriormente à placa de circuito
impresso ser confeccionada para ser utilizada na prática com o protótipo.
Devido a problemas técnicos na fabricação da placa e a ultrapassagem do
cronograma previsto, uma devida revisão ou reconstrução acabou sendo
impossibilitada, onde por este motivo a PCI não pode ser observada em
funcionamento controlando os motores no meio físico.
O resultado final do sistema de controle projetado não atingiu os objetivos
iniciais, que tinha como termino a utilização do circuito na prática para controlar o
ROV, embora foi concluído a partir dos testes virtuais que o sistema esta
funcionando corretamente.
67
BIBLIOGRAFIA
CANZIAN, Edmur. Comunicação Serial - RS232; Cotia: CNZ Engenharia e
Informática Ltda, 2001.
TORRES, Gabriel. Por Que Serial?; acesso em 16 de maio de 2010. Disponível em:
http://www.clubedohardware.com.br/artigos/726.
68
VALERIO, Marcos. ROV na Indústria do Petróleo, acesso em 02 de julho de 2010.
Disponível em: http://www.webartigos.com/articles/25133/1/ROV-na-Industria-do-
Petroleo/pagina1.html
TORRES, Gabriel. Por que Serial?, acesso em 15 de julho de 2010. Disponível em:
http://www.clubedohardware.com.br/artigos/726
69
MIRANDA, José Carlos. O REGULADOR DE VOLTAGEM, acesso em 15 de julho
de 2010. Disponível em: http://www.scribd.com/doc/14826195/o-Regulador-de-
Voltagem
70
http://www.pnca.com.br/index.php?option=com_content&view=article&id=67:pwm&c
atid=42:saiba-mais&Itemid=150
71
JEREK. Como Conectar O Proteus A Uma Porta De Comunicação, acesso em 20
de agosto de 2010. Disponível em:
http://www.asm51.eng.br/phpBB/viewtopic.php?t=69
72
APÊNDICE A - Circuito Controlador
73
APÊNDICE B - Diagrama de Classe
74
APÊNDICE C - Programa do Computador externo
Casse MainInetrface
package init;
class MainInterface
{
public static void main(String args[])
{
LoadingInterface loading = new LoadingInterface();
}
}
Classe LoadingInterface
package init;
import javax.swing.*;
class LoadingInterface
{
LoadingInterface()
{
ArqDat arqDat = new ArqDat();
Classe ArqDat
package init;
import java.io.*;
import javax.swing.*;
class ArqDat
{
protected void setDat(int Comandos[], int ComandosTeclado[])
{
75
try
{
FileOutputStream arq = new FileOutputStream("Configuracoes/Comandos.dat");
BufferedOutputStream buf = new BufferedOutputStream(arq);
DataOutputStream dado = new DataOutputStream(buf);
while(true)
{
Comandos[cont] = dado.readInt();
cont++;
}
}
catch(java.io.EOFException err)
{
}
catch(java.io.IOException erro)
{
JOptionPane.showMessageDialog(null,"Erro ao salvar o arquivo \"Comandos.dat\"",
":: Error ::",JOptionPane.ERROR_MESSAGE);
76
}
return Comandos;
}
Classe Comm
package init;
import java.io.*;
import java.util.*;
import javax.comm.*;
import javax.swing.*;
class Comm
{
private static CommPortIdentifier portId = null;
private static SerialPort portSerial = null;
private static ParallelPort portParalela = null;
private static OutputStream outputStream = null;
77
Vector PortasIO = new Vector();
while(portList.hasMoreElements())
{
portId = (CommPortIdentifier)portList.nextElement();
PortasIO.addElement(portId.getName());
}
return PortasIO;
}
78
JOptionPane.showMessageDialog(null,"Erro na comunicação 'OutputStream'!","::
Error ::",
JOptionPane.ERROR_MESSAGE);
}
return false;
}
79
{
}
catch(InterruptedException erro)
{
}
}
Classe ParametrosBean
package init;
import java.util.Vector;
public ParametrosBean()
{
}
80
this.ComandosTeclado = ComandosTeclado;
}
Classe WebCam
package init;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.*;
class WebCam
{
private static Component comp = null;
private static Player player = null;
81
{
try
{
CaptureDeviceInfo deviceInfo =
CaptureDeviceManager.getDevice("vfw:Logitech USB Video Camera:0");
MediaLocator mediaLocator = deviceInfo.getLocator();
player = Manager.createRealizedPlayer(mediaLocator);
player.start();
if((comp = player.getVisualComponent()) != null)
{
return true;
}
}
catch(Exception erro)
{
JOptionPane.showMessageDialog(null,erro.getMessage(),":: Error ::",
JOptionPane.ERROR_MESSAGE);
}
return false;
}
Classe ControleInterface
package init;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
82
class ControleInterface extends JFrame implements ActionListener, KeyListener
{
//Components Swing
private TextField textFieldComandos[] = new TextField[9];
private TextField textFieldTeclado[] = new TextField[9];
private JButton buttonSalvar, buttonSair;
//Variaveis
private int Comandos[];
private int ComandosTeclado[];
//ParametroBeans
private ParametrosBean parametrosBean;
ControleInterface()
{
setTitle(":: ROV Submarino Interface :: Configurações de Controle");
setSize(450,300);
setResizable(false);
setLocation(420,300);
setIconImage(new ImageIcon("Imagens/Icone.png").getImage());
//JLabel
JLabel labelLogo = new JLabel(new ImageIcon("Imagens/Configuracoes.jpg"));
JLabel labelComandosInfo = new JLabel("Valor: Coluna onde deve ser definida a mensagem
que será enviada");
labelComandosInfo.setFont(new Font("Times New Roman", Font.PLAIN, 12));
JLabel labelTecladoInfo = new JLabel("Teclado: Teclas de atalho para executar os comandos");
labelTecladoInfo.setFont(new Font("Times New Roman", Font.PLAIN, 12));
//JTextField
for(int i = 0; i < 9; i++)
83
{
textFieldComandos[i] = new TextField(8);
textFieldTeclado[i] = new TextField(8);
textFieldTeclado[i].addKeyListener(this);
}
//JButton
buttonSalvar = new JButton("Salvar");
buttonSalvar.setToolTipText("Salvar Alterações");
buttonSalvar.setMnemonic(KeyEvent.VK_S);
buttonSalvar.addActionListener(this);
buttonSalvar.setContentAreaFilled(false);
buttonSalvar.setBorderPainted(true);
buttonSalvar.setFocusPainted(false);
84
getContentPane().setLayout(new BorderLayout());
getContentPane().setBackground(Color.white);
getContentPane().add("West", panelWest);
getContentPane().add("Center", panelCenter);
getContentPane().add("South", panelSouth);
}
setSaveDat();
parametrosBean.setComandos(Comandos);
parametrosBean.setComandosTeclado(ComandosTeclado);
MenuInterface menuInterface = new MenuInterface();
menuInterface.setParametrosBean(parametrosBean);
}
return;
}
if(e.getSource() == buttonSair)
{
dispose();
return;
}
}
85
if(e.getSource() == textFieldTeclado[0])
textFieldTeclado[0].setText("" + e.getKeyCode());
if(e.getSource() == textFieldTeclado[1])
textFieldTeclado[1].setText("" + e.getKeyCode());
if(e.getSource() == textFieldTeclado[2])
textFieldTeclado[2].setText("" + e.getKeyCode());
if(e.getSource() == textFieldTeclado[3])
textFieldTeclado[3].setText("" + e.getKeyCode());
if(e.getSource() == textFieldTeclado[4])
textFieldTeclado[4].setText("" + e.getKeyCode());
if(e.getSource() == textFieldTeclado[5])
textFieldTeclado[5].setText("" + e.getKeyCode());
if(e.getSource() == textFieldTeclado[6])
textFieldTeclado[6].setText("" + e.getKeyCode());
if(e.getSource() == textFieldTeclado[7])
textFieldTeclado[7].setText("" + e.getKeyCode());
if(e.getSource() == textFieldTeclado[8])
textFieldTeclado[8].setText("" + e.getKeyCode());
e.setKeyCode(e.VK_ESCAPE);
return;
}
public void keyReleased(KeyEvent e)
{
return;
}
public void keyTyped(KeyEvent e)
{
return;
}
textFieldTeclado[i].getText().equals(textFieldTeclado[j].getText()))
{
throw new Exception();
}
}
catch(Exception erro)
{
86
JOptionPane.showMessageDialog(null,"Erro ao validar as
configurações do controle:\n1. Verifique se há codigos em branco\n2. Verifique se há codigos repetidos","::
Error ::",JOptionPane.ERROR_MESSAGE);
return false;
}
}
return true;
}
Classe MenuInterface
package init;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
87
private JMenu menuArquivo;
private JMenuItem menuItemConfiguracoes, menuItemSair;
private JPanel panelNorth, panelCenter, panelSouth, panelWebCam, panelDefaultWebCam,
panelComponentWebCam, panelControle;
private CardLayout panelCard;
private JLabel labelLogo, labelWebCam, labelStatusWebCam, labelSouth, labelPortas;
private JButton buttonConexao, buttonDriverCamera, buttonConfiguracoes, buttonControle[] = new
JButton[7];
private JToggleButton buttonTeclado;
private JComboBox comboPortas;
private JSlider slider;
//Variáveis
private int Comandos[];
private int ComandosTeclado[];
private int ComandoExecutado = 0, Velocidade = 0;
MenuInterface()
{
setTitle(":: ROV Submarino Interface ::");
setSize(950,630);
setResizable(false);
setLocationRelativeTo(null);
setIconImage(new ImageIcon("Imagens/Icone.png").getImage());
//Barra de Menus
menuArquivo = new JMenu("Arquivo");
menuItemConfiguracoes = new JMenuItem("Configurações", new
ImageIcon("Imagens/Config2.jpg"));
menuItemConfiguracoes.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,ActionEvent.ALT_MA
SK));
menuItemConfiguracoes.setMnemonic(KeyEvent.VK_C);
menuItemConfiguracoes.setBackground(Color.white);
menuItemConfiguracoes.addActionListener(this);
menuItemSair.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,ActionEvent.ALT_MASK));
menuItemSair.setMnemonic(KeyEvent.VK_S);
menuItemSair.setBackground(Color.white);
menuItemSair.addActionListener(this);
menuArquivo.add(menuItemConfiguracoes);
menuArquivo.addSeparator();
88
menuArquivo.add(menuItemSair);
//PanelNorth
labelLogo = new JLabel(new ImageIcon("Imagens/Logo.jpg"));
//PanelWebCam
labelWebCam = new JLabel(new ImageIcon("Imagens/WebCam.jpg"));
//PanelControle
ImageIcon imageControle[] = getImageIconControle();
buttonControle[0].setToolTipText("Parar");
89
buttonControle[1].setToolTipText("Esquerda");
buttonControle[2].setToolTipText("Ré");
buttonControle[3].setToolTipText("Direita");
buttonControle[4].setToolTipText("Frente");
buttonControle[5].setToolTipText("Emergir");
buttonControle[6].setToolTipText("Submergir");
buttonControle[0].setBounds(30,25,50,35);
buttonControle[1].setBounds(105,205,80,40);
buttonControle[2].setBounds(190,205,80,40);
buttonControle[3].setBounds(275,205,80,40);
buttonControle[4].setBounds(190,155,80,45);
buttonControle[5].setBounds(30,95,45,70);
buttonControle[6].setBounds(30,175,45,70);
buttonTeclado.setBounds(330,30,90,30);
slider.setBounds(50,250,355,25);
90
//PanelCenter
labelStatusWebCam = new JLabel("Câmera Desconectada...");
labelStatusWebCam.setForeground(Color.red);
panelWebCam.setBounds(0,0,450,450);
buttonDriverCamera.setBounds(0,455,100,20);
labelStatusWebCam.setBounds(110,455,250,20);
labelPortas.setBounds(470,20,100,20);
comboPortas.setBounds(540,20,220,20);
buttonConexao.setBounds(790,20,120,20);
buttonConfiguracoes.setBounds(470,70,50,40);
panelControle.setBounds(470,170,450,280);
91
panelCenter.add(labelPortas);
panelCenter.add(comboPortas);
panelCenter.add(buttonConexao);
panelCenter.add(buttonConfiguracoes);
panelCenter.add(panelControle);
//PanelSouth
labelSouth = new JLabel("UNIFAE :: São João da Boa Vista 2010 :: 1ª Turma de Engenharia da
Computação :: Trabalho de Conclusão de Curso :: Equipe de Controle :: Gustavo e Mateus");
//getContentPane()
setJMenuBar(menuBar);
getContentPane().setLayout(new BorderLayout());
getContentPane().add("North", panelNorth);
getContentPane().add("Center", panelCenter);
getContentPane().add("South", panelSouth);
setButtons(false);
}
//ActionListener
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == menuItemConfiguracoes || e.getSource() == buttonConfiguracoes)
{
if(controleInterface.isVisible() == true)
controleInterface.dispose();
92
Comm.setClose();
System.exit(0);
}
if(e.getSource() == buttonDriverCamera)
{
if(labelStatusWebCam.getText().equals("Câmera Desconectada..."))
setDriverWebCam();
else
setClosePlayer();
return;
}
if(e.getSource() == buttonConexao)
{
if(buttonConexao.getText().equals("Conectar"))
{
boolean conexao = Comm.getConexao("" + comboPortas.getSelectedItem());
if(conexao == true)
{
comboPortas.setEnabled(false);
buttonConexao.setText("Desconectar");
buttonConexao.setBackground(new Color(136,180,136));
setButtons(true);
}
}
else
if(buttonConexao.getText().equals("Desconectar"))
{
Comm.setClose();
comboPortas.setEnabled(true);
buttonConexao.setText("Conectar");
buttonConexao.setBackground(Color.white);
setButtons(false);
}
return;
}
if(e.getSource() == buttonControle[0])
{
setExecutaComando(Comandos[0]);
}
if(e.getSource() == buttonControle[1])
{
setExecutaComando(Comandos[1]);
return;
}
if(e.getSource() == buttonControle[2])
{
setExecutaComando(Comandos[2]);
return;
}
93
if(e.getSource() == buttonControle[3])
{
setExecutaComando(Comandos[3]);
return;
}
if(e.getSource() == buttonControle[4])
{
setExecutaComando(Comandos[4]);
return;
}
if(e.getSource() == buttonControle[5])
{
setExecutaComando(Comandos[5]);
return;
}
if(e.getSource() == buttonControle[6])
{
setExecutaComando(Comandos[6]);
return;
}
}
//MouseListener
public void mousePressed(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
if(e.getSource() == buttonDriverCamera)
buttonDriverCamera.setCursor(new Cursor(Cursor.HAND_CURSOR));
if(e.getSource() == buttonConexao)
buttonConexao.setCursor(new Cursor(Cursor.HAND_CURSOR));
}
public void mouseExited(MouseEvent e)
{
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
}
//KeyListener
public void keyPressed(KeyEvent e)
{
if(e.getSource() == buttonTeclado)
{
if(buttonTeclado.isSelected() == true)
94
{
if(e.getKeyCode() == ComandosTeclado[0])
setExecutaComando(Comandos[0]);
if(e.getKeyCode() == ComandosTeclado[1])
setExecutaComando(Comandos[1]);
if(e.getKeyCode() == ComandosTeclado[2])
setExecutaComando(Comandos[2]);
if(e.getKeyCode() == ComandosTeclado[3])
setExecutaComando(Comandos[3]);
if(e.getKeyCode() == ComandosTeclado[4])
setExecutaComando(Comandos[4]);
if(e.getKeyCode() == ComandosTeclado[5])
setExecutaComando(Comandos[5]);
if(e.getKeyCode() == ComandosTeclado[6])
setExecutaComando(Comandos[6]);
if(e.getKeyCode() == ComandosTeclado[7])
{
Velocidade = 1;
slider.setValue(slider.getValue() + 1);
}
if(e.getKeyCode() == ComandosTeclado[8])
{
Velocidade = 0;
slider.setValue(slider.getValue() - 1);
}
}
}
return;
}
public void keyReleased(KeyEvent e)
{
return;
}
public void keyTyped(KeyEvent e)
{
return;
}
//FocusListener
public void focusGained(FocusEvent e)
{
return;
}
public void focusLost(FocusEvent e)
{
buttonTeclado.setSelected(false);
}
//ChangeListener
95
public void stateChanged(ChangeEvent e)
{
if(Velocidade == 1)
setExecutaComando(Comandos[7]);
else
setExecutaComando(Comandos[8]);
}
//Metodos
private ImageIcon[] getImageIconControle()
{
ImageControleInterface image = new ImageControleInterface();
ImageIcon imageControle[] = image.getImageIconControle();
return imageControle;
}
96
else
{
for(int i = 0; i < PortasIO.size(); i++)
comboPortas.addItem(PortasIO.get(i));
}
return;
}
Classe ImageControleInterface
package init;
import javax.swing.*;
class ImageControleInterface
97
{
protected ImageIcon[] getImageIconControle()
{
ImageIcon imageControle[] = new ImageIcon[7];
String Imagem = "";
for(int i = 0; i < 7; i++)
{
Imagem = "Imagens/Controle/Controle" + i + ".jpg";
imageControle[i] = new ImageIcon(Imagem);
}
return imageControle;
}
}
98
APÊNDICE D - Programa do microcontrolador
#include <16f877A.h>
#use delay(clock=4000000)
#fuses HS,PUT,NOWDT,NOBROWNOUT,NOLVP,NOPROTECT
#use rs232(BAUD=19200,parity=N,BITS=8,rcv=PIN_C7)
//Prototipo
void velocidade(int i);
//Variaveis
long int duty = 0;
void main(void)
{
setup_timer_2 (T2_DIV_BY_4, 255, 1);
setup_ccp1 (ccp_pwm);
set_pwm1_duty (1023);
set_tris_d(0b00000000);
output_d(0b00000010);
while(true)
{
if(kbhit())
{
switch(getc())
{
case '0': //Parar
output_d(0b00000010);
break;
case '1': //Esquerda
output_d(0b00001010);
break;
case '2': //Ré
output_d(0b01000110);
break;
case '3': //Direita
output_d(0b10000010);
break;
case '4': //Frente
output_d(0b10001010);
break;
case '5': //Pera cima
output_d(0b00100010);
break;
case '6': //Para baixo
output_d(0b00010010);
break;
99
case '7': //Aumenta Velocidade
//velocidade(1);
break;
case '8': //Diminui Velocidade
//velocidade(0);
break;
}
}
}
setup_ccp1(CCP_OFF);
}
set_pwm1_duty (duty);
}
100
APÊNDICE E - Simulação
101
102
103
104