Escolar Documentos
Profissional Documentos
Cultura Documentos
Reservatório Microcontrolado
Implementação com PIC16F877
Orientador:
Prof. Mauro Rodrigues dos Santos
DES - UFPE
Março de 2007
Conteúdo
1 Introdução 5
1.1 Motivação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
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
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
Capı́tulo 1
Introdução
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
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.
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
8
• Ler informação de nı́vel enviado pelo sensor
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.
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.
lmax = 1 − cosφmax
lmin = 1 − cosφmin
hmax = lmax − lmin = cosφmin − cosφmax
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
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
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.
PORTA
∗ ∗ 1 ∗ 1 1 1 1
PORTB
0 ∗ 0 ∗ ∗ ∗ ∗ ∗
PORTC
1 0 0 ∗ 0 ∗ ∗ 1
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
ADCON1
0 ∗ ∗ ∗ 1 1 0 1
RCSTA
1 0 ∗ 1 0 0 0 0
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.
14
Figura 3.2: Botões LIGA e MANUAL
15
Capı́tulo 4
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
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.1 Controlador
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
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
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.
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.6: Prensa térmica utilizada para transferir o desenho impresso no papel
para a placa de fenolite.
23
recipiente com água para que a placa possa esfriar. Eles ficam na água por
cerca de 4 minutos.
24
Figura 5.9: Mergulhando a placa na solução de 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.
26
Figura 5.12: Sistema fı́sico
27
Figura 5.14: Bloco Controlador
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
30
Figura A.2: Registro ADCON1
31
Figura A.4: Registro RCSTA
32
Apêndice B
Código Fonte
;---------------------------------------------------------------------
;-----------------------TRABALHO DE GRADUACAO-------------------------
;--------------------HENRIQUE MULLER VASCONCELOS----------------------
;---------------------RAFAELLI NEVES DE ALENCAR-----------------------
;----------------------TALLITA CAMPELO SOBRAL-------------------------
;---------------------------------------------------------------------
#INCLUDE<P16F877.INC>
CBLOCK 0X20
ENDC
;---------------------------------------------------------------------
;-----------------------------ENTRADAS--------------------------------
;---------------------------------------------------------------------
33
#DEFINE LIGAR PORTA,5 ; BOTAO LIGA
;---------------------------------------------------------------------
;------------------------------SAIDAS---------------------------------
;---------------------------------------------------------------------
;---------------------------------------------------------------------
;------------------------------0UTROS---------------------------------
;---------------------------------------------------------------------
;---------------------------------------------------------------------
;---------------------------------------------------------------------
;---------------------------------------------------------------------
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
BANK0
MOVLW 0x20
MOVWF FSR
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
BLOCO_DECISAO
MOVF DIFERENCA,W
SUBWF SETUP_SUP, W ; SETUP_SUP - DIFERENCA
MOVWF SETUP_INF ; GUARDA RESULTADO EM SETUP_INF
36
GOTO DESLIGAR_BOMBA ; SETUP_SUP = CONV_CH1. MANDA DESLIGAR
GOTO LIGAR_BOMBA ; SETUP_SUP > CONV_CH1. MANDA LIGAR
LIGAR_BOMBA
DESLIGAR_BOMBA
;---------------------------------------------------------------------
;-----------------------------ROTINAS---------------------------------
;---------------------------------------------------------------------
FIM_CONVERSAO_AD
DADO_RECEBIDO
TRANSMISSAO
37
MODIFY_LEVEL
DESCARTA
MODO_MANUAL
;---------------------------------------------------------------------
;---------------------------------------------------------------------
;---------------------------------------------------------------------
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"
//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
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Configuracao da Porta Serial
//-----------------------------------------------------------------------------
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 ...
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Botao 1: Abre a porta selecionada
//-----------------------------------------------------------------------------
StrCom=ComboBox1->Text ;
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;
//-----------------------------------------------------------------------------
// 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
//-----------------------------------------------------------------------------
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;
//-----------------------------------------------------------------------------
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
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
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;
}
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>
//---------------------------------------------------------------------------
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;
//---------------------------------------------------------------------------
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.
47