Ir ao conteúdo
  • Cadastre-se

Entrada analogica no pic


AllanRoncali

Posts recomendados

boa tarde meus caros!! estou com problema para fazer um programa que teste um pino com uma entrada de um sensor de temperatura LM35. bom tenho duvidas quanto a configurar o pino como entrada analógica e utilizar o conversor adc do próprio microcontrolador que no caso sera o PIC16F877A e pegar os valores lidos pelo determinado pino e armazena-los em uma variável de tipo "float"!

trata-se de um projeto de uma chocadeira. o objetivo geral e fazer o PIC acionar um cooler quando a chocadeira atingir a temperatura máxima que vai manter as aves aquecidas na temperatura correta. comecei a digitar o programa mas não funcionou!

o programa foi o seguinte:

#include <16F877A.h>

#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES PUT //Power Up Timer
#FUSES NOBROWNOUT //No brownout reset

#use delay(clock=16000000)


// entradas================
#define calor pin_e0
#define mais pin_e1
#define menos pin_e2


// saidas==================
#define cooler pin_a0



// subrotinas===============

void cooler_on (void)
{
output_a(0b000001);
delay_ms (500);
}
void cooler_off (void)
{output_a(0b000000);
delay_ms (500);
}

// variaveis================

float temperatura = 0;

short b = 0;

char a = 0;




void main()
{

while(TRUE)
{
if(!input(mais))
a++;

if(!input(menos))
a--;

if (input(calor))
{
temperatura > a;
b++;
{
if (b == 1);
cooler_on();

if (b == 0);
cooler_off();
}

}

}

}

o projeto possui também 4 displays de 7 seg que irao mostrar a temperatura captada pelo sensor. os botões "mais" e "menos" serão os botões que irao configurar a temperatura máxima que quando ultrapassada liga o cooler!! sei que falta muita coisa no programa principalmente com relação ao display e os botões, mas se alguem puder me ajudar pelo menos com a entrada analogica e o teste do sensor eu ficaria grato!!!

Link para o comentário
Compartilhar em outros sites

Olá

bom vamos por partes, pelo que vejo no seu código falta configurações, não conheço muito do CCS mas sei que nele pode-se configurar desta maneira

#device adc=10

mas me parece errado ai, não vejo especificado o canal ADC que vai usar, mas como disse, não sei mexer no CCS por isso não afirmo com 100% de certeza, por isso te aconselho a usar o método de configuração normal

http://img38.imageshack.us/img38/487/y335.jpg

a tabela, retirada do datasheet, mostra valores que se da para o registrador ADCON1 e que o faz habilitar ou desabilitar os canais de leitura, esse método é mais chato, por isso se quiser continuar usando o método oferecido pelo CCS aguarde os mais manjadores desse compilador

outra coisa que creio estar errado é esta linha

temperatura > a;

nela você manda a variável "temperatura" ficar maior que a variável "A" , e esse comando não existe.

não sei qual foi sua intenção ai, mas se quisesse comparar deveria ser assim

if(temperatura>=a)

outra coisa que eu notei é que, você simplesmente cria uma variável chamada "temperatura", mas em momento nenhum faz a leitura do sensor para verificar a temperatura, a variável "temperatura" não recebera o valor do sensor só por ter este nome, na verdade você que tem que ler o valor da temperatura, e colocar ele nesta variável, mais ou menos desta forma

temperatura=adc_read(0);

digo mais ou menos porque no compilador que eu uso é assim, mas no seu deve ter uma pequena diferença

outra coisa, é que o sensor não te da um numero de temperatura bunitinho e prontinho pra usar, você tem que ler o canal analógico pegar o valor que ele te da, fazer uma conversão, para ai sim o seu pic entender aquele numero

bom, é só isso de minha parte por enquanto

flowww

Link para o comentário
Compartilhar em outros sites

ah sim!! obrigado pelos toques ai, porém depois que eu postei essas duvidas ai eu nao consegui segurar a curiosidade e continuei pesquisando. cheguei a escrever esse programa aqui:

#include <16F877A.h>
#device *=16
#device adc=10

#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES PUT //Power Up Timer
#FUSES NOBROWNOUT //No brownout reset

#use delay(clock=16000000)

// entradas================
#define calor pin_a0
#define mais pin_e1
#define menos pin_e2

// saidas==================
#define cooler pin_a5



//===============================
void cooler_on (void)
{
output_high(pin_a5);
delay_ms (500);
}
//===============================
void cooler_off (void)
{
output_low(pin_a5);
delay_ms (500);
}
//===============================

long int tensão,temperatura;
float temporario;
short b = 0;
float a = 38;



void main()
{
setup_adc_ports(AN0); //


while(true) {
SET_ADC_CHANNEL(0);
delay_ms(10);
tensão = READ_ADC(7);
temporario = tensão * 0.0048828125;
temperatura = temporario / 0.01;
delay_ms(1000);
}
if ( temperatura >= a, b++ )
{
if ( b == 0 );
cooler_on();

if ( b == 1 );
cooler_off();

}
}

sobre a parte da sua resposta onde fala disso ( #device adc=10 ) o proprio CCS gera essa diretiva quando você inicializa ele ai ele pede pra você escolher o oscilador, se vai vai acionar o low up time... ai quando você quer um pino determinado ( nesse caso o pino A0 ) como analogico você pode configurar la acredito que seja pra facilitar nao necessitando de você digitar as diretivas enfim nao fui eu que pus isso la nao foi proprio compilador.

ja sobre a conversao do valor do LM35 eu ja sabia que tinha que ser feito so que nao sabia como fazer! ainda to na duvida mas eu tentei copiar de um outro programa so pra ver se era isso mesmo que eu tinha que estudar.

mas o que ocorre é o seguinte: depois da compilaçao o CCS me mostra uma mensagem de aviso mas informa que correu tudo bem o programa, so que ainda nao deu certo!!

olha so na imagem

ccs.jpg

esse troço é muito louco, mas e legal demais se nao fosse eu desistiria!!! kkkkk

de todo modo obrigado pela força!!!

Link para o comentário
Compartilhar em outros sites

Prazer revê-lo aqui de novo, amigo! Eu fiz uma pequena modificação no seu código e agora ta funcionando, porém não sei se da maneira que você quer. USEI O PIC WIZARD. Dá uma olhada...


// entradas================
#define calor pin_a0
#define mais pin_e1
#define menos pin_e2

// saidas==================
#define cooler pin_a5



//===============================
void cooler_on (void)
{
output_high(pin_a5);
delay_ms (500);
}
//===============================
void cooler_off (void)
{
output_low(pin_a5);
delay_ms (500);
}
//===============================

long int tensão,temperatura;
float temporario;
short b = 0;
float a = 38;

void main()
{

setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);

// TODO: USER CODE!!
while(true){
SET_ADC_CHANNEL(0);
delay_ms(10);
tensão = READ_ADC(7);
temporario = tensão * 0.0048828125;
temperatura = temporario / 0.01;


if ( temperatura >= a )


{
cooler_on();}

else{
cooler_off();}
}
}

Link para o comentário
Compartilhar em outros sites

void main()
{
setup_adc_ports(AN0); //


while(true) {
SET_ADC_CHANNEL(0);
delay_ms(10);
tensão = READ_ADC(7);
temporario = tensão * 0.0048828125;
temperatura = temporario / 0.01;
delay_ms(1000);
}
if ( temperatura >= a, b++ )
{
if ( b == 0 );
cooler_on();

if ( b == 1 );
cooler_off();

}
}

havia um pequeno erro no seu código,que foi corrigido no programa feito pela amiga ai. você fechava a "}" do while(true) sem colocar dentro deste laço essa verificação aqui


if ( temperatura >= a, b++ )
{
if ( b == 0 );
cooler_on();

if ( b == 1 );
cooler_off();

}

ou seja, ele ia ficar sempre repetindo essa parte aqui


while(true) {
SET_ADC_CHANNEL(0);
delay_ms(10);
tensão = READ_ADC(7);
temporario = tensão * 0.0048828125;
temperatura = temporario / 0.01;
delay_ms(1000);
}

e nunca ia executar o resto do programa, ou seja nunca ia ligar o cooler. Deve-se sempre prestar muita atenção nesses detalhes, são fáceis de erra e difíceis de enxerga-los. quantas vezes quis chorar por não achar o erro da programação, e quando ia ver eram esses tipos de detalhes hahaha

flowwww

Link para o comentário
Compartilhar em outros sites

que coisa doida!!! raquel como você chegou a isso aqui??

 "  setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE); "

fala mister nintendo!! ola raquel!!! eu entendi bem o que você disse sobre a }!!! passei por coisa parecida quando programava em assembler kkkkk pior e falha nao esta no programa!!! mas valeu a força!!

raquel!! eu compilei o programa mesmo sem entender o trecho do programa em que aparece

" setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);"

eu vi também que a variavel 'b' nunca é utilizada no programa e o compilador informa isso!!

mas eu li o programa e qto a isso eu entendi que nem precisa dessa variavel!!

mas eu gostaria de entender esses setups ai se possivel!!! se nao fosse vocês eu ia ta careca!! kkkkkkkkkk

Link para o comentário
Compartilhar em outros sites

Obtenho estas configurações usando o pic wizard do ccs(pcw). Em Project -> PIC Wizard, na janela salvar como, dê um nome ao projeto e salve. Abre-se a janela PIC WIZARD, escolha o device e digite a frequência. Ao lado click em Analog para escolher a porta analógia a ser usada (A0), nas setas ao lado escolha (units:0-1023) resolução de 1024 bits e internal: 2-6us. Dê ok e aparecerá todas aquelas configurações escolhidas. Tem muita coisa lá pra ser feita, mas infelizmente não sei explicar muita coisa. Procura no Youtube por Programação em C para Pic de MrAppleBr, tem me ajudado bastante. Bons estudos!

Link para o comentário
Compartilhar em outros sites

isso ai eu entendi!! e básico pra compilar o programa! inclusive eu escrevi o programa (embora nao tenha dado certo) seguindo essas instruçoes! talves eu tenho formulado a duvida de maneira errada! engraçado também é que seguindo isso ai o compilador nao gerou esse trecho!! enfim eu vou dar uma olhada no youtube! valeu!

Link para o comentário
Compartilhar em outros sites

Bom.

O LM35 gera uma tensão de 10mV para cada grau.

Não deu para ler tudo que já foi escrito, mas é necessário um "Circuito condicionador de sinal" entre o LM35 e a entrada analógica.

Explico:

Se você pretende ler até 100ºC, então a maior tensão fornecida pelo LM35 será de :

Vmáx = 100ºC * 10mV/ºC = 1000mV = 1,000V.

A tensão de referência do seu PIC, para o CAD, se usar a da própria fonte Vdd, será igual a 5V. Então seu CAD só vai ler 1/5 dos possíveis valores, ou seja. Se ele for configurado para 10 bits (1024 valores) ele somente variará entre os valores 0 e 1024/5, ou cerca dos primeiros 200 valores.

Você precisa colocar um ganho de tensão de uns 5 entre o LM35 e a entrada analógica do PIC. Aí seu CAD fornecerá quase todos os 1024 valores possíveis.

Como estará medindo a temperatura, que deve variar lentamente, o seu circuito deverá possuir um filtro passa-baixas frequências. Caso contrário, o CAD poderá ler valores do ruído elétrico incorporado.

Outro detalhe é a tensão de referência retirada do Vdd. Ela pode situar-se entre 4,75V e 5,25V (alimentação TTL).

Com isso sua leitura não terá acurácia.

Imagine que o seu CAD com 10 bits possui 1024 possíveis valores. Cada valor é cerca de 0,1% do valor total (1/1000). Se o valor da sua tensão Vdd pode cair entre 4,75V e 5,25V, ou seja, 0,5V em 5V (0,5/5 = 0,1 ou 10%). De nada adianta um CAD com 10 bits de resolução, se sua tensão de referência pode apresentar um erro de + ou - 5%.

É por isso que a tensão de referência é gerada por um circuito com maior precisão. Pesquise TL431.

Em tempo:

Você pode até dispensar o circuito com ganho 5 e deixar o LM35 fornecer, no máximo, 1,00V. Com os 200 possíveis valores, sua resolução seria de 0,5ºC (100ºC/200). Mas a referência (certamente) poderia tornar a medida errada em até 5%, para mais ou para menos.

MOR_AL

Link para o comentário
Compartilhar em outros sites

Aproveitando a ideia de usar um TL431 :

Faça um divisor de tensão na saída do TL431 , de maneira que essa tensão seja um pouco só maior do que a saída do LM35 na temperatura máxima do seu ambiente, e ligue na entrada de referência de tensão externa no PIC, assim terá uma excelente precisão na leitura do LM35.

Coloque um belo capacitor eletrolítico ligado na saída do LM35, eu usei um de 22uF e melhorou muito a estabilidade da leitura.

Se essa temperatura máxima de uso for pequena, é melhor montar um circuitinho que converta essa pequena variação em uma nova escala indo de 0 a 5 volts.

Paulo

Link para o comentário
Compartilhar em outros sites

  • 4 semanas depois...

pessoal obrigado pela força ai! eu encontrei um projeto de um voltimetro que me ajudou a entender muito melhor o termometro! os principios sao os mesmos e observando os dois circuitos embora utilizem microcontroladores diferentes sao ate muito parecidos! o que eu percebi é que o termometro tem um dispositivo que converte o calor em eletricidade e o resto do circuito "sente" aquela eletricidade e a mede enviando a informaçao pro display! e logico que as variaveis do programa vão ser diferentes e eu posso ate estar enganado mas o algoritimo desse codigo ai em cima pode ser usado pra ambos os projetos!

enfim! eu agradeço muito a ajuda e Deus abençoe a todos!!!

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!