Você está na página 1de 47

Universidade Federal de Pernambuco

Departamento de Eletrônica e Sistemas

Reservatório Microcontrolado
Implementação com PIC16F877

Henrique Müller Vasconcelos


Tallita Campêlo Sobral
Rafaelli Neves de Alencar Vidal

Orientador:
Prof. Mauro Rodrigues dos Santos

Relatório final, referente às atividades realizadas na disci-


plina EL361 - Trabalho de Graduação 1, apresentado ao
Curso de Graduação em Engenharia Elétrica modalidade
Eletrônica da Universidade Federal de Pernambuco.

DES - UFPE
Março de 2007
Conteúdo

1 Introdução 5
1.1 Motivação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2 Projeto da Interface Gráfica 6


2.1 Software de Interface Gráfica e Linguagem de Programação . . . . . . 6
2.2 Blocos da interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

3 Projeto do Microcontrolador 8
3.1 O Microcontrolador PIC16F877 . . . . . . . . . . . . . . . . . . . . . 8
3.2 Blocos do Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.2.1 O sensor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.2.2 Digitalização do nı́vel . . . . . . . . . . . . . . . . . . . . . . . 10
3.2.3 Comparação dos nı́veis . . . . . . . . . . . . . . . . . . . . . . 10
3.2.4 Bloco de decisão . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.2.5 Troca de dados serialmente com o PC . . . . . . . . . . . . . . 11
3.3 Registros especiais do PIC . . . . . . . . . . . . . . . . . . . . . . . . 12
3.3.1 Entradas e saı́das . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.3.2 Conversão AD . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.3.3 Comunicação serial . . . . . . . . . . . . . . . . . . . . . . . . 13
3.4 Lista de material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

4 Sistema de Potência 16
4.1 Acionamento da Bomba . . . . . . . . . . . . . . . . . . . . . . . . . 16

5 Montagem Fı́sica do Projeto 18


5.1 Montagem do cabo de Comunicação Serial . . . . . . . . . . . . . . . 18
5.2 Layout dos PCBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
5.2.1 Controlador . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
5.2.2 Potência . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
5.3 Confecção da Placa de Circuito Impresso . . . . . . . . . . . . . . . . 21
5.4 Montagem do Sensor de Nı́vel e Sistema Fı́sico . . . . . . . . . . . . . 26
5.5 Testes Experimentais . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

6 Conclusão 29

2
A Tabelas para configuração dos registros especiais do PIC16F877 30

B Código Fonte 33
B.1 Programação do PIC16F877 em ASSEMBLY . . . . . . . . . . . . . . 33
B.2 Programação da interface com o Borland C++ . . . . . . . . . . . . . 39
B.2.1 controle.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
B.2.2 controle.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

3
Lista de Figuras

3.1 Esquema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.2 Botões LIGA e MANUAL . . . . . . . . . . . . . . . . . . . . . . . . 15
3.3 Botão RESET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.4 Tensões de referência . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

4.1 Esquemático do sistema de potência . . . . . . . . . . . . . . . . . . . 16

5.1 Layout do circuito impresso do controlador . . . . . . . . . . . . . . . 19


5.2 Layout do circuito impresso do acionamento da bomba . . . . . . . . 20
5.3 Circuito do controlador de nı́vel de água montado no protoboard. . . 22
5.4 Desenho do circuito desenhado em computador impresso em papel
gloss. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
5.5 Papel com o desenho do circuito impresso e placa de fenolite. . . . . . 23
5.6 Prensa térmica utilizada para transferir o desenho impresso no papel
para a placa de fenolite. . . . . . . . . . . . . . . . . . . . . . . . . . 23
5.7 Conjunto de placa e papel na água para esfriar. . . . . . . . . . . . . 24
5.8 Placa de fenolite após a transferência do desenho. . . . . . . . . . . . 24
5.9 Mergulhando a placa na solução de percloreto de ferro. . . . . . . . . 25
5.10 Placa de fenolite sendo corroı́da por percloreto de ferro. . . . . . . . . 25
5.11 Placa depois da lavagem. . . . . . . . . . . . . . . . . . . . . . . . . . 26
5.12 Sistema fı́sico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
5.13 Aquário . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
5.14 Bloco Controlador . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
5.15 Microcontrolador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

A.1 Registro ADCON0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30


A.2 Registro ADCON1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
A.3 Registro TXSTA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
A.4 Registro RCSTA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
A.5 Registro SPBRG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

4
Capı́tulo 1

Introdução

O uso de uma tecnologia reprogramável, como nos microcontroladores, permite


modificações e melhorias no projeto sem modificar o sistema. Dessa forma, a fase de
projeto é reduzida e barateada e a confiabilidade aumenta, pois estamos usando uma
menor quantidade de CIs. O conceito de microcontrolador se espalhou rapidamente
e hoje em dia existe uma grande diversidade de produtos para solucionar os mais
diferentes problemas de controle.
De uma forma geral neste projeto, o PIC controlará o fluxo de entrada do re-
servatório de acordo com os dados recebidos pelo sistema hidráulico, sendo este
composto por um sensor de nı́vel e pelo próprio reservatório.

1.1 Motivação
A motivação deste trabalho está em implementar a tecnologia dos microcontro-
ladores em um problema prático utilizando recursos do PIC, de forma a comple-
mentar os conhecimentos adquiridos ao longo do curso de graduação em Engenharia
Eletrônica. O projeto será concluı́do com a montagem fı́sica do sistema, chegando
ao produto final.

1.2 Objetivos
Este trabalho de graduação visa projetar e montar um controlador de nı́vel de
água de um reservatório utilizando o PIC16F877 que terá uma comunicação bilateral
com um computador através da porta serial. Desta forma, pelo computador, o
usuário estará apto a fornecer ao controlador configurações relativas ao nı́vel de
água e coletar dados obtidos pelo mesmo.

5
Capı́tulo 2

Projeto da Interface Gráfica

Por meio da interface provida pelo computador, o usuário deve ser capaz de
se comunicar de forma simples com o dispositivo de hardware. Os tipos de dados
enviados (PC → PIC) envolve informar o nı́vel em percentual da altura do reser-
vatório e requisição de nı́vel. Entre os dados recebidos (PIC → PC), conterá apenas
informações do nı́vel do reservatório.
Como informação gráfica dos dados, a interface contará com uma animação do
reservatório variando o nı́vel a partir dos dados recebidos pelo PIC. É importante
ressaltar que é apenas o PIC realiza o acionamento ou não da bomba.

2.1 Software de Interface Gráfica e Linguagem de


Programação
Utilizando o software Borland C++ Builder, podemos criar a interface com o
auxı́lio de diversas ferramentas num ambiente gráfico. É o mesmo ambiente do
Delphi e muito parecido com o Visual BASIC, inclusive na forma de construção
gráfica do aplicativo.
O Borland C++ Builder é um ambiente de desenvolvimento de aplicações, orien-
tado a objeto, que permite desenvolver sistemas para alguns sistemas operacionais,
por enquanto somente da famı́lia Windows da Microsoft. Para se criar aplicativos
começa-se com a montagem de componentes em janelas, como se fosse um programa
gráfico, o usuário também pode utilizar componentes desenvolvidos por terceiros ou
criar seus próprios componentes.

2.2 Blocos da interface


A interface gráfica do projeto é composta por quatro botões, dois campos para
números e um display na forma de ”progress bar”, que mostra o nı́vel do reservatório.
O Botão 1 (Abrir Porta) abre a porta serial que foi selecionada. Inicialmente
verifica-se qual porta foi selecionada, após esta verificação chama-se uma função que

6
tem como argumento de entrada a porta que será aberta e como argumento de saı́da
uma variável booleana, que indica se a porta esta aberta (“true”) ou não (“false”).
Se a variável de saı́da da função for “false” é por que ocorreu algum erro, desta forma
o erro é detalhado, podendo aparecer duas mensagens de erro diferentes: a porta
selecionada não existe ou a porta selecionada está em uso. Se não ocorreu erro, ou
seja, a saı́da da função é “true”, a função ConfiguraUART é chamada. Esta função
configura a porta serial que será utilizada. Uma mensagem é enviada para o usuário
de que a porta selecionada já está aberta. O botão 1 é desabilitado, impedindo que
usuário tente abrir a porta novamente uma vez que ela já esteja aberta.
O Botão 2 (Fechar Porta) é responsável por fechar a porta selecionada. Primei-
ramente, verifica-se a porta selecionada, se estiver aberta, ela é fechada através da
função CloseHandle. O Botão 1 é reabilitado, botão responsável por abrir porta
serial, o botão 2 é desabilitado, e a mensagem que a porta selecionada está fechada
é enviada ao usuário.
O Botão 3 (Enviar) é responsável por enviar dados para a porta serial. O objetivo
é enviar ao PIC a altura da água no reservatório que se deseja ter. Para que isto seja
entendido pelo PIC, devemos enviar a ele a relação do sensor (potenciômetro) e não
da porcentagem de água no reservatório. Como o usuário entra com a porcentagem
desejada, uma função de conversao transforma a porcentagem (de 0 a 100) em um
byte referente ao resultado da conversão A/D do PIC. O PIC precisa saber que o
dado que será recebido por ele é altura desejada, então, é enviado ao PIC o comando
de envio de altura (caracter “i”). Um tempo de delay é dado para que o PIC possa
receber todos os dados corretamente. O próximo dado é o valor de saı́da da função
conversão (“rc1”). O mesmo tempo de delay é dado. No caso de não entar enviando
um valor novo para o nı́vel, o PC envia o comando de requisição de nı́vel (caracter
”a”), e espera a resposta do PIC. Esta resposta é convertida pela função inversa
da anterior, que nos fornece um valor de 0 a 100, que é utilizada para atualizar o
”progress bar”. Depois disso, o Timer 1 é habilitado para que o PC fique executando
esse loop.
O Botão 4 (Parar) é responsável por desabilitar a transmissão automática de
dados PIC-PC.
Os detalhes da função de conversão podem ser estudados na seção de com-
paração dos nı́veis do capı́tulo 3. O código fonte da programação da interface gráfica
encontra-se disponı́vel em anexo no apêndice B.

7
Capı́tulo 3

Projeto do Microcontrolador

3.1 O Microcontrolador PIC16F877


A idéia básica do microcontrolador é construir um processador com uma grande
quantidade de recursos voltados para o controle. Com isso, o sistema fica muito mais
simples e emprega poucos componentes. Dessa forma, a fase de projeto é reduzida e
barateada e a confiabilidade aumenta, pois estamos usando uma menor quantidade
de CIs. Como não será feito processamento sofisticado, sua CPU não precisa de
ter uma grande capacidade de processamento, mas deve oferecer um conjunto de
instruções simples, que gere programas pequenos e de rápida execução.
O PIC 16F877 é um microcontrolador da famı́lia de 8 bits e núcleo de 14 bits
fabricado pela Microchip Technology. Possui memória flash de programa com 8192
palavras de 14 bits, memória RAM com 368 bytes e memória eeprom com 256 bytes.
Sua frequência de operação (clock) vai até 20MHz, resultando em uma velocidade
de processamento de 5 MIPS. Seu conjunto de instruções RISC se compõe de 35
instruções. Pode funcionar com alimentação de 2V a 5,5V. Sua pinagem DIP tem 40
pinos. PICs com memória FLASH são altamente flexı́veis na fase de desenvolvimento
pois permitem uma rápida alteração do código de programa.
Faremos uso para o projeto das funções:

• Conversor analógico digital


• Periférico de comunicação serial
• Portas de entrada e saı́da de dados

A configuração destas funções é feita através de registros especiais do PIC16F877


e será detalhada mais adiante.

3.2 Blocos do Hardware


Para atender as necessidades básicas de um controlador de nı́vel de reservatório,
estabelecemos que este bloco deveria realizar as seguintes tarefas:

8
• Ler informação de nı́vel enviado pelo sensor

• Realizar a conversão A/D e armazenar o nı́vel lido

• Comparar o nı́vel lido com o ”setado”pelo usuário

• Decidir habilitar ou não a bomba d’água

• Realizar trocas de dados serialmente com o PC

3.2.1 O sensor
A escolha do sensor de nı́vel é um dos pontos mais crı́ticos de um controlador de
nı́vel de um reservatório, pois sua informação estabelece como e quando o controle
da bomba atuará e o quanto de exatidão teremos da leitura real. Em virtude da
montagem fı́sica simplificada do nosso projeto, optamos pelo esquema abaixo.

Figura 3.1: Esquema

O uso de uma resistência variável com o giro de um potenciômetro gera um


sinal de tensão variável de acordo com o ângulo compreendido entre a haste de
comprimento fixo e o eixo vertical como mostrado na figura.
Desta forma, o arranjo fı́sico deve posibilitar que a haste do sensor percorra
toda extensão de nı́veis do reservatório, proporcionando os ângulos φmax e φmin ,
relacionados respectivamente por, nı́vel máximo e mı́nimo a serem setados pelo
usuário.

9
3.2.2 Digitalização do nı́vel
Como o sinal do sensor é representado por um simples divisor de tensão, o nı́vel
que faz o máximo ângulo φmax deve ser convertido para o valor 255 (11111111) na
conversão A/D, assim como o nı́vel mı́nimo para o valor 0 (00000000). Porém o giro
do potenciômetro não percorre toda a sua extensão um vez que φmax − φmin nunca
excederá 90o (na verdade, nem chegará a 90o ).
O PIC16F877 permite que você estabeleça as tensões de referência máxima e
mı́nima externamente, criando o intervalo de tensão que será digitalizado. Isso
significa que pode ser feito um ajuste durante a instalação do equipamento ao re-
servatório medindo as tensões de saı́da do sensor e fixando a máxima amplitude de
nı́veis para o dado reservatório.

3.2.3 Comparação dos nı́veis


O arranjo proposto para o sensor de nı́vel ainda é caracterizado pela relação
não-linear entre o nı́vel de tensão convertido pelo microcontrolador e a altura real
do reservatório.

lmax = 1 − cosφmax
lmin = 1 − cosφmin
hmax = lmax − lmin = cosφmin − cosφmax

O resultado da conversão A/D (RC) é um número inteiro entre 0 e 255, portanto,


o ângulo φmax − φmin é dividido em 255 partes iguais (potenciômetro linear). Desta
forma, seja:

n = φmax − φmin
φmax − φmin
δ=
255
Logo:
   
h = 1 − cos φmin + RC · δ − 1 − cosφmin
e

h cosφmin − cos(φmin + RC · δ)
h% = · 100 = · 100
hmax φmin − φmax

Assim, o resulatdo da conversão é entendido como nı́vel percentual do reser-


vatório pela função acima. Porém, este cálculo é deixado para fer feito na interface
gráfica com o usuário, onde se utiliza uma linguagem de programação de alto nı́vel

10
(C ++ ) em contraponto à linguagem por nós adotada para o PIC16F877 (ASSEM-
BLY). Finalmente, quando o usuário insere o nı́vel percentual do reservatório, é
aplicada a seguinte fórmula:

1 h  h%  i
RC = · arccos cosφmin − (cosφmin − cosφmax ) − φmin
δ 100

que é a função inversa da anterior, e o valor obtido é enviado serialmente em binário


padrão para o microcontrolador que pode comparar o nı́vel setado pelo usuário di-
retamente com o nı́vel digitalizado da entrada analógica referente ao sensor. O
resultado desta comparação indica o acionamento ou não da bomba de entrada do
reservatório. Deste modo, os ângulos φmax e φmin devem ser medidos experimental-
mente e informados na interface para a realização dos cálculos.

3.2.4 Bloco de decisão


Para este tipo de controle, onde apenas estamos habilitando e desabilitando uma
bomba de aquário simples, basta fazer a comparação direta do nı́vel setado pelo
usuário e o nı́vel atual medido pelo sensor. Mas basear-se apenas nisso pode ser
perigoso na medida em que os nı́veis vão se igualando. Pequenas variações em torno
da medida pode ligar e desligar repetidas vezes a bomba causando um transitório
que em ulguns casos podem danificar o equipamento. Este problema é ainda mais
frequente em sistemas dinâmicos como o que pretendemos criar.
A saı́da para esta situação pode ser implementada facilmente criando-se um nı́vel
ligeiramente inferior ao realmente setado pelo usuário, de modo que a bomba só é
re-ligada quando o nı́vel está abaixo do nı́vel inferior e desligada somente quando o
nı́vel ultrapassa o limite superior, que é de fato o setado pelo usuário. A separação
dos nı́veis deve ser suficiente para evitar que as vibrações e oscilações no nı́vel d’água
não liguem e religuem a bomba sucessivamente.
Um algorı́tmo para implementar esta decisão pode ser visto abaixo.

COMPARA COM NÍVEL INFERIOR


SE MENOR: LIGA A BOMBA

TESTA SE BOMBA ESTÁ LIGADA


SE SIM: COMPARA COM NÍVEL SUPERIOR
SE MAIOR OU IGUAL: DESLIGA A BOMBA

3.2.5 Troca de dados serialmente com o PC


A troca de informação entre a interface gráfica e os dispositivos de hardware
obedece a um protocolo pré-definido. A comunicação é sempre requisitada pela
interface que aguarda até que o microcontrolador envie a resposta. O protocolo
escolhido para o projeto foi a USART em modo assı́ncrono. Neste modo, o trans-
missor e o receptor utilizam o mesmo formato de dados e concordam com uma taxa

11
de transmissão (Baud Rate) em comum. Durante a comunicação, tem-se um start
bit, oito bits de dados e por fim um stop bit.
Para ocorrer a troca de informação, a interface envia dois bytes consecutivos
mas separados por um intervalo de tempo curto. Exitem dois tipos de comando
que a interface estabelece. Mandando o caracter ASCII ’i’ (01101001), o microcon-
trolador indentifica que o segundo byte é referente nı́vel setado pelo usuário (setup
level) e mandando o caracter ASCII ’a’ (01100001), o microcontrolador identifica a
requisição de dados (asking level) e retorna serialmente o nı́vel atual do reservatório.

3.3 Registros especiais do PIC


3.3.1 Entradas e saı́das
A configuração dos registros especias PORT foi feita da forma mostrada abaixo.
Os ∗ indicam que não importa o valor do referido bit porque o mesmo não está sendo
usado ou porque não existe função para ele.

PORTA
∗ ∗ 1 ∗ 1 1 1 1

RA0 (pino 2) Entrada analógica canal 1


RA1 (pino 3) Entrada analógica canal 2
RA2 (pino 4) VREF − para conversão AD
RA3 (pino 5) VREF + para conversão AD
RA5 (pino 7) Ligar

PORTB
0 ∗ 0 ∗ ∗ ∗ ∗ ∗

RB5 (pino 40) Led Power On


RB7 (pino 38) Led PIC Comunicando

PORTC
1 0 0 ∗ 0 ∗ ∗ 1

RC0 (pino 15) Modo Manual


RC3 (pino 18) VCC auxiliar
RC5 (pino 24) Enable Bomba
RC6 (pino 25) TX Output
RC7 (pino 26) RX Input

PORTD
∗ ∗ ∗ ∗ ∗ ∗ 0 ∗

12
RD1 (pino 20) Indicador Modo Manual Ativo

3.3.2 Conversão AD
A configuração da conversão AD no PIC se faz pelos dois registros abaixo.

ADCON0
1 0 0 0 0 0 ∗ 1

Configuramos o relógio do conversor com frequencia F = FOSC


32
, usaremos o canal
0 (RA0/AN0) inicialmente e o canal 1 (RA1/AN1) mudando o bit 3 para 1 durante
o programa. Para iniciar uma conversão A/D, setamos o bit 2 de ADCON0. O
mesmo bit volta pra zero quando a conversão é finalizada. O bit 0 liga o módulo de
conversão A/D.

ADCON1
0 ∗ ∗ ∗ 1 1 0 1

O resultado da conversão encontra-se em ADRESH e outros dois bits menos


significantes em ADRESL. Durante o programa somente consideramos o registro
ADRESH. Os pinos de RA2 e RA3 estão habilitados para receber VREF − e VREF + ,
respectivamente. E RA0 e RA1 são as duas entradas analógicas que podem ser
usadas pelo módulo conversor.

3.3.3 Comunicação serial


A transmitissão dados serialmente pelo PIC se faz configurando os três registros
abaixo.
TXSTA
∗ 0 1 0 ∗ 1 0 0

Configuramos transmissão de 8 bits de dados usando USART em modo assı́ncrono,


high speed Baud Rate. O bit 1 indica se o registro de deslocamento da transmissão
está vazio (1) ou se ainda está cheio (0). Ou seja, basta testar este bit para saber
se podemos carregar o buffer.

RCSTA
1 0 ∗ 1 0 0 0 0

O bit 7 habilita a porta serial do PIC. Configuramos a recepção de 8 bits de


dados, recepção contı́nua, modo de endereçamento desabilitado.

SPBRG
0 0 0 1 1 0 0 1

13
Cálculo do Baud Rate:
FOSC
BaudRate =
16(X + 1)
Escolhemos:
Baud Rate = 9600 bps
FOSC = 4M Hz
Logo:
4 · 106
X= −1
16 · 9600
X = 25
Portanto, carregando SPBRG com 25 teremos ransmissão numa taxa de 9600
bps.
As tabelas de configuração dos registros especiais do PIC para este projeto
encontra-se no apêndice A.

3.4 Lista de material


Lista de material e componentes
Descrição Especificação Quant
Microcontrolador PIC16F877 1
Driver/Receiver MAX232 1
Regulador de tensão 7805 1
Cristal 4MHz 1
Diodo Zener 2.7V 1
Diodo Zener 4.7V 1
Resistor 1kΩ 4
Resistor 1.2kΩ 2
Resistor 1.8kΩ 2
Resistor 6.8kΩ 4
Capacitor eletrolı́tico 10µF/16V 4
Capacitor eletrolı́tico 1µF/16V 3
Capacitor eletrolı́tico 4.7µF/16V 1
Capacitor poliéster 0.1µF 1
Capacitor poliéster 47nF 1
Botão de pressão Single Pole 3
Trimpot 10kΩ 1
Led Qualquer cor 4
Soquete 3 Conexões para fios 2
Caixa 19 x 11 x 5 cm 1

Abaixo são mostrados os esquemáticos para ligações de botões e as tensões de


referência.

14
Figura 3.2: Botões LIGA e MANUAL

Figura 3.3: Botão RESET

Figura 3.4: Tensões de referência

15
Capı́tulo 4

Sistema de Potência

Neste sistema, temos o poder de controlar o fluxo de entrada do reservatório


acionando uma bomba. Num primeiro momento, seria interessante o controle da
potência da bomba e, por consequência, o fluxo. Porém, isto envolveria um estudo
detalhado da bomba em questão, caracterizando seu comportamento sob diferentes
amplitudes e frequencias da alimentação. Somente após este estudo, poderı́amos
indicar que tipo de conversor de potência deverı́amos implementar.
Em nosso trabalho, apenas nos concentramos em ligar e desligar a bomba. Um
sinal de controle (enable) é gerado pelo microcontrolador que deve ser ligado ao
sistema de potência.

4.1 Acionamento da Bomba

Figura 4.1: Esquemático do sistema de potência

16
Utilizando um relé controlado pelo PIC, faremos o acionamento da bomba. O
circuito também é responsável pela alimentação da placa do microcontrolador com
9V, obviamente, este nı́vel é baixado para 5V para alimentar os circuitos digitais.
A lista dos componentes usados nesta parte são listados abaixo:

Lista de componentes
Descrição Especificação Quant
Capacitor eletrolı́tico 1000µF 1
Capacitor poliéster 33nF 1
Resistor 4K7 1
Diodo 1N4001 5
Transistor BC547 1
Regulador de tensão 7809 1
SPDT Relé 5A/250Vac 1

17
Capı́tulo 5

Montagem Fı́sica do Projeto

A montagem fı́sica do projeto para um controlador de nı́vel de água foi, primeira-


mente, montada sobre um protoboard onde seria fácil modificar algum componente
à medida que os testes fossem feitos e que se tornasse necessário esta mudança.
Quando o circuito montado sobre o protoboard estava mostrando os resultados es-
perados, só então o circuito foi montado sobre uma placa de circuito impresso.
Ambos os circuitos, no protoboad e na placa de circuito impresso, foram tes-
tados juntamente com o programa feito no computador para se comunicar com o
usuário. Desta forma, um cabo para viabilizar a comunicação serial entre o PIC e o
computador foi montado.
Um sistema mecânico também foi montado com o objetivo de relacionar o nı́vel de
água num reservatório com um sinal de entrada no PIC, este sinal é posteriormente
enviado ao computador para ser processado. Todos os circuitos que foram citados
anteriormente são descritos com detalhes nesta seção.

5.1 Montagem do cabo de Comunicação Serial


A comunicação entre o dispositivo de hardware e o PC utiliza um protocolo de
comunicação no qual faz-se necessário duas vias de dados (Rx e Tx) e outra de
tensão referencial (terra). O cabo acessa a porta serial DB-9 do PC fazendo uso de
apenas 3 pinos. O pino 2 do DB-9 do PC é o TX do computador, enquanto que o
pino 3 é o RX. É pelo TX que ele envia dados e pelo RX ele os recebe. O pino 5 é
o pino de referência. Os nı́veis de tensão usados pela porta serial são padronizados
em 12v em relação ao pino de referência. Como o microcontrolador opera com sinais
de até 5v, esses nı́veis de tensão precisam ser convertidos no caminho entre o PIC
e o PC. O uso do chip MAX232 faz-se necessário por ser um driver/receiver que
converte nı́veis TTL/CMOS em nı́veis IA/EIA-232-F e vice-versa. O MAX232 está
incluso na placa do circuito com o PIC, restando apenas a confecção do cabo com a
conecção dos pinos apropriados.
Usamos dois conectores DB-9, um macho e outro fêmea, um cabo de 1,5 metro de
comprimento com pelo menos três fios. Soldamos um fio ligando os pinos 2 de cada
DB-9, outro fio para os pinos 3 e, por fim, os pinos 5 com o terceiro fio. Para testar

18
se o cabo está corretamente soldado, fizemos uso de um pequeno software chamado
rcomserial, cedido no site rogercom.com. Conectando o cabo numa porta serial do
PC e jumpeando os pinos 2 e 3, podemos enviar dados e conferir o recebimento
dos mesmos pela interface do rcomserial. Uma vez estabelecida a transmissão e a
recepção dos dados, o cabo está pronto para ser usado na comunicação serial entre
o PC e o PIC.

5.2 Layout dos PCBs


O primeiro passo para a concepção fı́sica do nosso dispositivo de hardware é
desenhar as trilhas para a placa de circuito impresso. É de fundamental importância
a utilização de softwares para design de PCBs. Existem bibliotecas com os mais
variados componentes usados em eletrônica com suas pinagens e tamanhos padrão
para facilitar o desenho. Também é fundamental criar um arquivo que pode ser
usado inumeras vezes para reproduzir a fabricação da placa.
Para o design dos layouts escolhemos o Protel DXP.

5.2.1 Controlador

Figura 5.1: Layout do circuito impresso do controlador

Para contrução do layout da placa do controlador, usamos as medidas da tabela


abaixo.

19
Medidas para o CI
Hole size 0.9mm
X - size 2mm
Y - size 2mm
Shape Round
Medidas para os demais componentes
Hole size 0.8mm
Diameter 2mm
Lines width 1mm
Medidas para os soquetes
Hole size 0.8mm
Diameter 2.4mm
Medidas para o conector de fonte
Hole size 0.8mm
X - size 3mm
Y - size 2mm
Shape Rectangle

5.2.2 Potência

Figura 5.2: Layout do circuito impresso do acionamento da bomba

20
Medidas para os componentes
Hole size 0.8mm
X - size 2.4mm
Y - size 2.4mm
Shape Round
Medidas para as trilhas
Lines width 1mm
Medidas para solda dos fios
Hole size 0.8mm
X - size 4mm
Y - size 5mm
Shape Rectangle

5.3 Confecção da Placa de Circuito Impresso


A placa de circuito impresso foi feita em várias etapas. Desde seu desenho, feito
em software, até a soldagem de seus componentes na placa. Todas estas etapas
são detalhadamente explicadas na ordem cronológica em que foram feitas, e fotos
explicativas foram tiradas de todas essas etapas para que pudesse ser mais facilmente
visualizado como é o processo de confecção de um circuito em placa impressa.

1. O protoboard é uma ferramenta muito útil quando queremos montar um cir-


cuito de teste. O circuito pode ser facilmente modificado até que possamos
obter o resultado esperado. Por este motivo, o circuito do controlador de nı́vel
de água foi inicialmente montado num protoboard, pois as alterações que ocor-
reram durante o desenvolvimento do projeto podiam ser facilmente obtidas,
seja por pequenas modificações que foram feitas nos recursos do controlador,
ou pela mudança de parâmetros que pediam modificações de componentes.

2. O circuito a ser montado foi desenhado em um software direcionado para


impressão de circuito em placa, no nosso caso, o software utilizado foi o Protel.
A placa utilizada para a montagem do circuito é uma placa de fenolite.

3. O desenho feito no Protel foi impresso em papel gloss em impressora a laser


para que a tinta da impressora fosse, posteriormente, transferida para a placa.
O papel gloss foi utilizado porque a tinta é mais facilmente transferida para
a placa depois do aquecimento em comparação com a folha de transparência
para retroprojetores que também é comumente utilizada para este tipo de
procedimento.

4. O papel gloss impresso é então colocado sobre a placa o desenho virado para a
parte condutora. A placa deve ser previamente ariada com palha de aço para
remover oxidações e gorduras que possam dificultar a passagem da tinta para
a mesma ou prejudicar a corrosão. Vedamos as extremidades do papel e da

21
Figura 5.3: Circuito do controlador de nı́vel de água montado no protoboard.

Figura 5.4: Desenho do circuito desenhado em computador impresso em papel gloss.

22
placa com fita adesiva para que, numa etapa posterior, não entre água entre
a placa e o papel, borrando, assim, o desenho.

Figura 5.5: Papel com o desenho do circuito impresso e placa de fenolite.

5. O conjunto da placa e do papel é então colocado num equipamento que funci-


ona como uma prensa, mas as chapas, superior e inferior, aquecem, e a medidas
que esquentam e desenho que estava no papel gloss vai sendo transferido para
a placa por contato. A placa e o papel ficam em contato dentro deste equipa-
mento por cerca de 1 minuto e 50 segundos.

Figura 5.6: Prensa térmica utilizada para transferir o desenho impresso no papel
para a placa de fenolite.

6. Após o tempo descrito anteriormente, a placa e o papel são colocados em um

23
recipiente com água para que a placa possa esfriar. Eles ficam na água por
cerca de 4 minutos.

Figura 5.7: Conjunto de placa e papel na água para esfriar.

7. Após o tempo determinado na água, as fitas adesivas e o papel são retirados,


ficamos somente com a placa de fenolite com o desenho impresso nela.

Figura 5.8: Placa de fenolite após a transferência do desenho.

8. Após a placa de fenolite está com o desenho do circuito, podemos, então,


corroer o metal sobre a placa, pois o desenho transferido irá proteger as áreas
que não queremos que sejam corroı́das. A placa é mergulhada em percloreto
de ferro para que o metal seja corroı́do.

24
Figura 5.9: Mergulhando a placa na solução de percloreto de ferro.

Figura 5.10: Placa de fenolite sendo corroı́da por percloreto de ferro.

9. Depois que o metal é completamente corroı́do pelo percloreto de ferro, o que


resta é a placa com o desenho do circuito em metal. A placa é lavada em água
para retirar o restante do percloreto de ferro.

10. A placa é, então, perfurada para a introdução dos componentes e soquetes.
Foi feito o uso de um perfurador de pressão manual próprio para placas de
circuito impresso. Para os orifı́cios que precisaram ser alargados, usamos uma
furadeira de mão também para uso em eletrônica.

11. Agora, usamos palha de aço para retirar a tinta que protegeu o desenho durante
a corrosão. Os componentes são colocados em suas devidas posições e, em
seguida, soldados na placa.

12. Passamos também verniz para circuito impresso a fim de proteger as trilhas
em metal da oxidação e de curtos entre as trilhas que ficam expostas.

25
Figura 5.11: Placa depois da lavagem.

5.4 Montagem do Sensor de Nı́vel e Sistema Fı́sico


Para a confecção do sensor de nı́vel foi preciso encontrar um potenciômetro com
pouca resistência ao giro (torque) de forma que ele acompanhasse o sobe e desce
do nı́vel d’água. A haste deve ser de um material anti-oxidante e leve como o
alumı́nio. O uso de um knob de parafuso foi utilizado para conectar uma parte à
outra, encaixando-se por um furo feito cuidadosamente com o diâmetro da haste.
Na outra extremidade, um material deve ser usado para desempenhar o papel de
uma bóia.
O sistema fı́sico deve possuir um recipiente como um aquário com o sensor me-
canicamente acoplado e com um registro de saı́da d’água no fundo que despeja em
um segundo recipiente. Uma bomba é usada para retornar a água para o primeiro
aquário.

5.5 Testes Experimentais


Para a montagem funcionar devidamente, alguns parâmetros tiveram que ser
ajustados na prática. Primeiramente, verificamos que não dava para colocar sim-
plesmente qualquer valor para as referencias do sensor. Isto implicou que o menor
caracter lido no reservatório (dada uma posição do sensor acoplado) não foi o Nulo
(00000000), logo não tinhamos 255 divisões que separavam o φmax e φmin . Porém,
pequenas alterações na fórmula de conversão na parte da programação da interface
resolveram o problema.

26
Figura 5.12: Sistema fı́sico

Figura 5.13: Aquário

27
Figura 5.14: Bloco Controlador

Figura 5.15: Microcontrolador

28
Capı́tulo 6

Conclusão

A realização fı́sica do projeto nos mostrou nos testes que a leitura do sensor foi
bem sucedida para a aplicação proposta apesar de sua simplicidade. A interface
gráfica torna o ambiente mais amigável para usuários leigos e permite monitorar re-
servatórios fechados ou à distância. O microcontrolador desempenhou com maestria
seu papel no sistema de controle e os seus diferentes recursos nos permite ir muito
além do que foi explorado neste projeto.
Alguns pontos podem ser relevantes para melhorias futuras ou motivação para
outros estudantes. Um tipo de controle que analise o comportamento e variação do
nı́vel d’água para fornecer diferentes potências à bomba. Um sensor de proteção para
informar se o reservatório da bomba está seco. E uma interface capaz de apresentar
um histórico gráfico do reservatório com os nı́veis que foram lidos em cada instante
passado.
Este trabalho de graduação se fez importante para complementar nossos conhe-
cimentos de microcontroladores em sistemas de controle usando o recurso de comu-
nicação serial com outros dispositivos, construção de interfaces gráficas, manuseio
de softwares para design de layouts e manufatura de placas de circuito impresso.

29
Apêndice A

Tabelas para configuração dos


registros especiais do PIC16F877

Figura A.1: Registro ADCON0

30
Figura A.2: Registro ADCON1

Figura A.3: Registro TXSTA

31
Figura A.4: Registro RCSTA

Figura A.5: Registro SPBRG

32
Apêndice B

Código Fonte

B.1 Programação do PIC16F877 em ASSEMBLY

;---------------------------------------------------------------------
;-----------------------TRABALHO DE GRADUACAO-------------------------
;--------------------HENRIQUE MULLER VASCONCELOS----------------------
;---------------------RAFAELLI NEVES DE ALENCAR-----------------------
;----------------------TALLITA CAMPELO SOBRAL-------------------------
;---------------------------------------------------------------------

#INCLUDE<P16F877.INC>

CBLOCK 0X20

SETUP_SUP ; GUARDA VALOR RECEBIDO EM RCREG


SETUP_INF ; GUARDA LIMITE INFERIOR
CONV_CH1 ; GUARDA VALOR DA ULTIMA CONVERSAO NO CH1
CONV_CH2 ; GUARDA VALOR DA ULTIMA CONVERSAO NO CH2
INF_LEVEL ; INFORMACAO DE NIVEL
ASK_LEVEL ; REQUISICAO DE NIVEL
ADDRESS ; GUARDA BYTE DE ENDERECAMENTO
DIFERENCA ; GUARDA A DIFERENCA ENTRE OS NIVEIS SETUP SUP E INF

ENDC

;---------------------------------------------------------------------
;-----------------------------ENTRADAS--------------------------------
;---------------------------------------------------------------------

#DEFINE AD_P1 PORTA,0 ; SENSOR DE NIVEL


#DEFINE AD_P2 PORTA,1 ; POT. SETUP MANUAL
#DEFINE VREF1 PORTA,2 ; VREF- PARA CONVERSAO A/D
#DEFINE VREF2 PORTA,3 ; VREF+ PARA CONVERSAO A/D

33
#DEFINE LIGAR PORTA,5 ; BOTAO LIGA

#DEFINE MANUAL PORTC,0 ; BOTAO SETUP MANUAL


#DEFINE RXUSART PORTC,7 ; COMUNICACAO SERIAL IN

;---------------------------------------------------------------------
;------------------------------SAIDAS---------------------------------
;---------------------------------------------------------------------

#DEFINE POWER PORTB,5 ; INDICADOR ON/OFF


#DEFINE COMMUN PORTB,7 ; TRANSMITINDO DADO

#DEFINE VCC_AUX PORTC,3 ; VCC AUXILIAR


#DEFINE ENABLE PORTC,5 ; ENABLE CONTROL
#DEFINE TXUSART PORTC,6 ; COMUNICACAO SERIAL OUT

#DEFINE SET_MANUAL PORTD,1 ; LOOP DE SETUP MANUAL

;---------------------------------------------------------------------
;------------------------------0UTROS---------------------------------
;---------------------------------------------------------------------

#DEFINE BANK0 BCF STATUS,RP0 ; MUDA PARA O BANK 0


#DEFINE BANK1 BSF STATUS,RP0 ; MUDA PARA O BANK 1

#DEFINE CH_1 BCF ADCON0,3 ; MUDA PARA CANAL 1 AD (AN0)


#DEFINE CH_2 BSF ADCON0,3 ; MUDA PARA CANAL 2 AD (AN1)

;---------------------------------------------------------------------
;---------------------------------------------------------------------
;---------------------------------------------------------------------

ORG 0X0000
GOTO INICIAR

INICIAR ; INICIALIZACAO

CLRF PORTA
CLRF PORTB
CLRF PORTC
CLRF PORTD
CLRF PORTE

CLRF ADDRESS
CLRF SETUP_SUP
CLRF SETUP_INF

34
CLRF CONV_CH1
CLRF CONV_CH2

BANK1

MOVLW B’11111111’ ; INPUT PINS


MOVWF TRISA ;
MOVLW B’00000000’ ; OUTPUT PINS
MOVWF TRISB ;
MOVLW B’10000001’ ; INPUT PINS
MOVWF TRISC ;
MOVLW B’00000000’ ; OUTPUT PINS
MOVWF TRISD ;
MOVLW B’00000000’ ; OUTPUT PINS
MOVWF TRISE ;
MOVLW B’11010111’ ; CONFIGURA OPTION_REG
MOVWF OPTION_REG ;
MOVLW B’00000000’ ; INTERRUPCOES DESABILITADAS
MOVWF INTCON ;
MOVLW B’00001101’ ; CONFIGURA CONVERSAO A/D
MOVWF ADCON1 ;
MOVLW B’00100100’ ; CONFIGURA TRANSMISSAO
MOVWF TXSTA ;
MOVLW .25 ; CONFIGURA BAUD RATE
MOVWF SPBRG ;

BANK0

MOVLW B’10010000’ ; CONFIGURA RECEPCAO


MOVWF RCSTA ;
MOVLW B’10000001’ ; CONFIGURA CONVERSAO A/D
MOVWF ADCON0 ;

MOVLW 0x20
MOVWF FSR

MOVLW B’01101001’ ; CARACTERE "i"


MOVWF INF_LEVEL ; CONFIGURA ENDERECO DE INFORMACAO DE NIVEL
MOVLW B’01100001’ ; CARACTERE "a"
MOVWF ASK_LEVEL ; CONFIGURA ENDERECO DE REQUISICAO DE NIVEL
MOVLW B’00000100’
MOVWF DIFERENCA

BSF VCC_AUX ; PIC PROGRAMADO E CONFIGURADO, PINO USADO COMO 5V

35
;---------------------------------------------------------------------
;-----------------------------PROGRAMA--------------------------------
;---------------------------------------------------------------------

PRINCIPAL

BCF POWER
BCF ENABLE
BCF SET_MANUAL
BTFSS LIGAR ; TESTA BOTAO LIGAR APERTADO
GOTO $-1 ; ESPERA ATE QUE INICIO DO PULSO
BTFSC LIGAR
GOTO $-1 ; ESPERA ATE FIM DO PULSO
BSF POWER ; LIGA LED DE POWER ON
BSF ADCON0,GO ; INICIA CONVERSAO AD

LOOP

BTFSC MANUAL ; TESTA BOTAO MANUAL APERTADO


CALL MODO_MANUAL ; SIM, CHAMAR A ROTINA MODO_MANUAL

BTFSS ADCON0,GO ; TESTA FIM DA CONVERSAO AD


CALL FIM_CONVERSAO_AD ; SIM, CHAMAR A ROTINA FIM_CONVERSAO_AD

BTFSC PIR1,RCIF ; TESTA FLAG DE RECEPCAO DE DADOS NA SERIAL


CALL DADO_RECEBIDO ; SIM, CHAMAR ROTINA DADO_RECEBIDO
BCF COMMUN ; DESLIGA LED DE COMUNICACAO

BLOCO_DECISAO

MOVF DIFERENCA,W
SUBWF SETUP_SUP, W ; SETUP_SUP - DIFERENCA
MOVWF SETUP_INF ; GUARDA RESULTADO EM SETUP_INF

MOVF CONV_CH1,W ; TESTA ALTURA COM SETUP_INF


SUBWF SETUP_INF,W ; SETUP_INF - CONV_CH1
BTFSC STATUS,C ; TESTA O CARRY
BSF ENABLE ; SETUP_INF >= CONV_CH1, LIGA A BOMBA

BTFSS ENABLE ; TESTA BOMBA LIGADA


GOTO LOOP ; BOMBA DESLIDADA, VOLTA PRO LOOP
MOVF CONV_CH1,W ; BOMBA LIGADA, TESTA ALTURA COM SETUP_SUP
SUBWF SETUP_SUP,W ; SETUP_SUP - CONV_CH1
BTFSS STATUS,C ; TESTA O CARRY
GOTO DESLIGAR_BOMBA ; SETUP_SUP < CONV_CH1. MANDA DESLIGAR
BTFSC STATUS,Z ; SETUP_SUP >= CONV_CH1, TESTA IGUALDADE

36
GOTO DESLIGAR_BOMBA ; SETUP_SUP = CONV_CH1. MANDA DESLIGAR
GOTO LIGAR_BOMBA ; SETUP_SUP > CONV_CH1. MANDA LIGAR

LIGAR_BOMBA

BSF ENABLE ; HABILITA A BOMBA


GOTO LOOP ; RETORNA PARA INICIO DO LOOP

DESLIGAR_BOMBA

BCF ENABLE ; DESABILITA A BOMBA


GOTO LOOP ; RETORNA PARA INICIO DO LOOP

;---------------------------------------------------------------------
;-----------------------------ROTINAS---------------------------------
;---------------------------------------------------------------------

FIM_CONVERSAO_AD

MOVF ADRESH,W ; RESULTADO DA CONVERSAO DO CANAL 1


MOVWF CONV_CH1 ; GRAVA EM CONV_CH1
BSF ADCON0,GO ; INICIA OUTRA CONVERSAO
RETURN ; CONTINUA PROGRAMA

DADO_RECEBIDO

BSF COMMUN ; SETA LED DE COMUNICACAO


MOVF RCREG,W ; CARREGA RECEPCAO EM WORK
MOVWF ADDRESS ; SALVA O ENDERECO RECEBIDO
SUBWF INF_LEVEL,W ;
BTFSC STATUS,Z ; COMPARA O ENDERECO COM INF_LEVEL
GOTO MODIFY_LEVEL ; OK. CHAMA ROTINA DE MODIFICACAO DE NIVEL
MOVF ADDRESS,W ; CARREGA RECEPCAO EM WORK
SUBWF ASK_LEVEL,W ;
BTFSC STATUS,Z ; COMPARA O ENDERECO COM ASK_LEVEL
GOTO TRANSMISSAO ; OK. CHAMA ROTINA DE TRANSMISSAO
GOTO DESCARTA ; NAO IDENTIFICADO. CHAMA ROTINA DE DESCARTE

TRANSMISSAO

MOVF CONV_CH1,W ; CARREGA CONV_CH1 EM WORK


BANK1 ; MUDA PARA BANK 1
BTFSS TXSTA,TRMT ; VERIFICA SEM BUFFER ESTA VAZIO
GOTO $-1 ; ESPERA ESVAZIAR BUFFER
BANK0 ; VOLTA PARA BANK 0
MOVWF TXREG ; CARREGA BUFFER E INICIA TRANSMISSAO
GOTO DESCARTA ; CHAMA ROTINA DE DESCARTE

37
MODIFY_LEVEL

BTFSS PIR1,RCIF ; ESPERA DADO DE NIVEL


GOTO MODIFY_LEVEL ; CONTINUA NA ROTINA ATE QUE CHEGUE O DADO
MOVF RCREG,W ; MOVE O DADO RECEBIDO EM WORK
MOVWF SETUP_SUP ; CARREGA NIVEL EM SETUP_SUP
RETURN ; CONTINUA PROGRAMA

DESCARTA

BTFSS PIR1,RCIF ; ESPERA PROXIMO BYTE


GOTO DESCARTA ; CHAMA ROTINA DE DESCARTE
MOVF RCREG,W ; LE O REGISTRO RCREG
MOVLW .0 ; DESCARTA
RETURN ; CONTINUA PROGRAMA

MODO_MANUAL

BTFSC MANUAL ; TESTA FIM DO PULSO


GOTO $-1 ; AGUARDA FIM DO PULSO
BSF SET_MANUAL ; LIGA LED INDICADOR DO MODO MANUAL
CH_2 ; MUDA PARA O CANAL 2 DE CONVERSAO A/D (RA1)
BSF ADCON0,GO ; PEDE CONVERSAO
BTFSC ADCON0,GO ; TESTA FIM DA CONVERSAO AD
GOTO $-1 ; AGUARDA RESULTADO
MOVF ADRESH,W ; CARREGA RESULTADO EM WORK
MOVWF CONV_CH2 ; SALVA RESULTADO EM CONV_CH2
MOVWF SETUP_SUP ; CARREGA NIVEL EM SETUP_SUP
BTFSS MANUAL ; TESTE DE FIM DA OPERACAO
GOTO MODO_MANUAL ; NEGATIVO, CONTINUA NO LOOP DE AJUSTE
CH_1 ; POSITIVO. MUDA PARA O CANAL 1 DE CONVERSAO A/D (RA0)
BSF ADCON0,GO ; INICIA CONVERSAO A/D
BTFSC MANUAL ; TESTA FIM DO PULSO
GOTO $-1 ; AGUARDA FIM DO PULSO
BCF SET_MANUAL ; DESLIGA LED INDICADOR DO MODO MANUAL
RETURN ; CONTINUA PROGRAMA

;---------------------------------------------------------------------
;---------------------------------------------------------------------
;---------------------------------------------------------------------

END ; FIM DO PROGRAMA

38
B.2 Programação da interface com o Borland C++
B.2.1 controle.cpp

//----------------------------------------------------------------------------
// Inclusao de Bibliotecas, difinicoes de Variaveis Globais e !!!!!!
//----------------------------------------------------------------------------

#include <vcl.h>
#include<math.h>
#include <stdio.h>
#pragma hdrstop
#include "controle.h"

#pragma package(smart_init)
#pragma resource "*.dfm"

#define LEN_BUFFER 100

//Variaveis Globais

TForm1 *Form1;

//Variaveis da API

HANDLE hCom;
DCB dcb;
COMMTIMEOUTS CommTimeouts;
DWORD COMStatus;
DWORD BytesEscritos=0;
DWORD BytesLidos=0;
Word TimeOver;
int TamaString, g=0;
char BufferEnvia[LEN_BUFFER];
char BufferLer[LEN_BUFFER];
bool CONECTADO=false; // bool pq n"o

39
void Status(String Comando);
String StrCom;
float conversao(int);
float conversao1(int);
//bool vModoAuto;
//bool vModoManual;

//-----------------------------------------------------------------------------
// Form1
//-----------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)


: TForm(Owner)
{
}

//-----------------------------------------------------------------------------
//Configuracao da Porta Serial
//-----------------------------------------------------------------------------

bool ConfiguraUART(DWORD baud, BYTE size, BYTE parity, BYTE stop)


{
if(!GetCommState(hCom, &dcb))
{
return false;
}

dcb.BaudRate = baud;
dcb.ByteSize = size;
dcb.Parity = parity;
dcb.StopBits = stop;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;

if ( SetCommState(hCom, &dcb) == 0 )
{
return false;
}
return true;

//-----------------------------------------------------------------------------
//Abre a Porta Serial COMx
//-----------------------------------------------------------------------------

40
bool AbrirPortaSerial(char *NomePorta)
{
hCom = CreateFile(
NomePorta,
GENERIC_READ | GENERIC_WRITE,
0, // dispositivos comm abertos com acesso exclusivo
NULL, // sem atributos de seguranÁa
OPEN_EXISTING, //deve usar OPEN_EXISTING
0, //Entrada e saÌda sem ovelap.
NULL //hTemplate deve ser NULL para comm
);

if(hCom == INVALID_HANDLE_VALUE)
{
return false;
}

return true;
}

//-----------------------------------------------------------------------------
// Organizacao ...
//-----------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)


{
//inicializando todos os botıes como desativados
GroupBox3->Enabled=false;
Timer1->Enabled=false;
}

//-----------------------------------------------------------------------------
// Botao 1: Abre a porta selecionada
//-----------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)


{
DWORD ComErro;
bool ret;

StrCom=ComboBox1->Text ;

ret = AbrirPortaSerial(StrCom.c_str()); //Abre a Porta Serial Especificada.

if(ret == false) //se houve erro.


{
switch(GetLastError()) //Detalha o erro.

41
{
case ERROR_FILE_NOT_FOUND:
ShowMessage("A Porta "+StrCom+" selecionada nao existe!");
break;
case ERROR_ACCESS_DENIED:
ShowMessage("A Porta "+StrCom+" selecionada esta em uso!");
break;

default: break;
}
}
else
{
ConfiguraUART(CBR_9600,8,NOPARITY,ONESTOPBIT); //Configura UART.
CONECTADO=true;

Label4->Caption="Porta "+StrCom+" Aberta";


GroupBox3->Enabled=true;
Button1->Enabled = false;
Button2->Enabled = true;
Button3->Enabled = true;
Button4->Enabled = true;
}
}

//-----------------------------------------------------------------------------
// Botao 2: Fecha a porta selecionada
//-----------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if(hCom != INVALID_HANDLE_VALUE) // Se a porta est· aberta.
CloseHandle(hCom); //Fecha a porta.
Button1->Enabled = true;
Button2->Enabled = false;
Button3->Enabled = false;
Button4->Enabled = false;
Label4->Caption="Porta "+StrCom+" Fechada";

GroupBox3->Enabled=false;

//-----------------------------------------------------------------------------
// Botao 3: Envia dado para a porta serial
//-----------------------------------------------------------------------------

void __fastcall TForm1::Button3Click(TObject *Sender)

42
{
float rc,rc1;
int h,alt;
alt=atoi(Form1->Edit1->Text.c_str());
h=alt;
rc=conversao(h);
rc1=floor(rc);
BufferEnvia[0]=’i’; // comando de envio de altura
BufferEnvia[1]=’\0’;
WriteFile(hCom, BufferEnvia,1,&BytesEscritos,NULL);
Sleep(10);
BufferEnvia[0]=rc1; // valor da altura
BufferEnvia[1]=’\0’;
WriteFile(hCom, BufferEnvia,1,&BytesEscritos,NULL);
Sleep(10);
Button3->Enabled = true;
Button4->Enabled = true;
Timer1->Enabled=true;

//-----------------------------------------------------------------------------

void __fastcall TForm1::Timer1Timer(TObject *Sender)


{
int alt,altr,alts,h;
BufferEnvia[0]=’a’; // comando de envio de altura
BufferEnvia[1]=’\0’;
WriteFile(hCom, BufferEnvia,1,&BytesEscritos,NULL);
Sleep(10);
BufferEnvia[0]=’a’; // comando de envio de altura
BufferEnvia[1]=’\0’;
WriteFile(hCom, BufferEnvia,1,&BytesEscritos,NULL);
Sleep(100);
ReadFile(hCom,BufferLer,2,&BytesLidos,NULL);

altr=BufferLer[0];
if(altr>=0)
alts=altr;
else
alts=256+altr;
ProgressBar1->Min=0;
ProgressBar1->Max=100;
h=conversao1(alts);
ProgressBar1->Position= h;
Edit2->Text=h;
}

43
//---------------------------------------------------------------------------

void __fastcall TForm1::Button4Click(TObject *Sender)


{
Timer1->Enabled=false;
Button4->Enabled=false;
Button3->Enabled=true;
}

//---------------------------------------------------------------------------

float conversao1(int rc2)


{
int alt,altr,alts;
char Crac;
float a,b,c,d,rc,rc1,x;
float h;
float tmax=72.5, tmin=32.5;
float pi=3.1415;
float tmax1, tmin1,n, delta;

alt=atoi(Form1->Edit1->Text.c_str());

h=alt;
tmax1=(tmax/180)*pi;
tmin1=(tmin/180)*pi;

a=cos(tmax1);
b=cos(tmin1);
c=tmin1;
d=b-a;

n=tmax1-tmin1;
delta=n/(255-44);

h=100*(b-cos(c+(rc2-44)*delta))/d ;

if (h>=0)
return h;
else
return 0;
}

float conversao(int h2)


{
int alt,altr,alts;

44
char Crac;
float a,b,c,d,rc,rc1,x;
float h;
float tmax=72.5, tmin=32.5;
float pi=3.1415;
float tmax1, tmin1,n, delta;

alt=atoi(Form1->Edit1->Text.c_str());

h=alt;
tmax1=(tmax/180)*pi;
tmin1=(tmin/180)*pi;

a=cos(tmax1);
b=cos(tmin1);
c=tmin1;
d=b-a;
n=tmax1-tmin1;
delta=n/(255-44);

rc=44+(acos(b-h*d/100)-c)/delta;

return rc;
}

B.2.2 controle.h

//---------------------------------------------------------------------------

#ifndef controleH
#define controleH

//---------------------------------------------------------------------------

#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------

class TForm1 : public TForm


{
__published: // IDE-managed Components

45
TGroupBox *GroupBox1;
TGroupBox *GroupBox3;
TButton *Button1;
TButton *Button2;
TLabel *Label1;
TEdit *Edit1;
TLabel *Label2;
TEdit *Edit2;
TLabel *Label3;
TLabel *Label4;
TLabel *Label7;
TTimer *Timer1;
TButton *Button3;
TButton *Button4;
TProgressBar *ProgressBar1;
TLabel *Label8;
TLabel *Label9;
TComboBox *ComboBox1;

void __fastcall Button1Click(TObject *Sender);


void __fastcall Button2Click(TObject *Sender);
void __fastcall Button3Click(TObject *Sender);

void __fastcall FormCreate(TObject *Sender);


void __fastcall Timer1Timer(TObject *Sender);
void __fastcall Button4Click(TObject *Sender);
//void __fastcall RadioButton5Click(TObject *Sender);
//void __fastcall RadioButton6Click(TObject *Sender);

private: // User declarations


public: // User declarations
__fastcall TForm1(TComponent* Owner);
};

//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------

#endif

46
Bibliografia

[1] David José de Souza, Nicolás César Lavinia, Conectando o PIC: Recursos
avançados, Editora Érica, primeira edição, 2003.

[2] Mohan, Undeland, Robbins, Power ElectronicsConverters: Applications and


Design, second edition, 1995

[3] H. M. Deitel, P. J. Deitel, C++: Como Programar, Editora Bookman, terceira


edição, 2001

47

Você também pode gostar