Ir ao conteúdo
  • Cadastre-se

Leitura analogica com PIC e colocar o valor da leitura no display


Ir à solução Resolvido por rodrigocirilo,

Posts recomendados

 

"\fAD:%04ld"

 

aprendi aqui que o "\f" limpa o display, 

também que o 04 é digamos a quantidade de digitos mas o que é o ld?

 

Uma boa opção é entender o que faz a função printf, bem como os tipos de formatação. Como já citado acima o "ld" é um código de como sua variável será formatada.

Só lembrando que o padrão C o tipo long é de 32bits inteiiro e não 16bits como o CCS usa.

 

 

 

 

Outra coisa, como posso tentar estabilizar um pouco mais a conversão de forma a deixar """mais preciso""".

Cuidado para não confundir os conceitos, precisão está associada a exatidão da sua medida ou da porcentagem de correspondência entre o valor que você mede e o valor real de uma determinada grandeza (idealmente ela é 100% apenas durante algum tempo, pois condições de temperatura, por exemplo, variam e muito).

Para elevar a precisão de uma medida, vários fatores devem ser considerados, a resolução, menor valor que seu conversor A/D consegue capturar, filtragem anti-aliasing já citada, correto condicionamento do sinal, eliminação de ruído em modo comum enfim existe varias formas de melhorar a exatidão do resultado.

Minha sugestão INICIALl para melhoria nesse ponto, seria o uso de um conversor A/D de maior resolução (algo ente 16 e 24bits).

Agora so que queres fazer é estabilizar o valor da medida, a história é outra, na verdade o que você deve fazer antes de tudo é determinar qual a informação final que será apresentada ao usuário no LCD (essa realmente nao pode ficar variando, o que justificaria o uso de um filtro de média móvel citado no meu post anterior, volte la e o releia porque).

Quando tiver isso na mão ai pensamos em como estabilizar a medida.

:)

Abs.

Felipe.

Link para o comentário
Compartilhar em outros sites

  • 6 meses depois...

URGENTE Problemas com AD pic

Senhores a algum tempo deixei esse codigo funcionando perfeitamente, hoje quando terminei um outro codigo gigante fui testar esse novamente para então junta-los.

No entanto esse codigo parece nao funcionar mais, quando o fiz era pro 16f877 hj é pro 18f4550 mas nao funciona em nenhum dos dois.

O display fica travado em dois valores e nao sai disso .... como se nao tivesse executando o programa

 

 
 
#include <18f4550.h>
#device adc = 10      //Habilitar ADC de 10 bits
#use delay(clock = 20000000)
 
#fuses HS           //Clock > 4Mhz
#fuses NOWDT        //No Watch Dog Timer
#fuses PUT          //Power Up Timer
#fuses NOBROWNOUT   //No brownout reset
#fuses NOLVP        //No low voltage progming, B3(PIC16)or B5(PIC18)used for I/O
#fuses NOPROTECT    //Code not protected from reading
#fuses NOCPD        //No EE protection
#FUSES NODEBUG      // No Debug mode for ICD
#FUSES NOWRT        // Program memory not write protected
 
#include "C:\Users\ivan\Desktop\Codigos\Bibliotecas\4550\Flex_lcd_20x4_4550.c"
#include "C:\Users\ivan\Desktop\Codigos\Bibliotecas\4550\DS1307 - 4550.c"
#include <internal_eeprom.c>
#include <stdlib.h>
 
/************************** Variaveis do Track ********************************/
float An;           // Variável da Conversão do Angulo
float T;            // Variável da Conversão de Temperatura
float C;            // Variável da Conversão da Corrente de Saída
float Ten;          // Variável da Conversão da Corrente de Saída
 
int16 ldr1, ldr2, ldr3, ldr4;   // Variáveis da Conversão do LDR
 
int1 fim_dir;
int1 fim_esq;
 
int16 A0()                             // Leitura da Inclinação
  {
     int16 angulo = 0;
     int j;
     
     set_adc_channel(0);             // Prepara o canal leitura da Inclinação
     delay_us(10);
     
     for (j=0; j<16; j++)            // Faz a leitura 15x
       {
       angulo = angulo + read_adc();
       }
       
     angulo = (angulo/16);
     return(angulo);
  }
 
int16 A1()                             // Leitura da Temperatura
  {
     int16 temperatura = 0;
     int j;
     
     set_adc_channel(1);             // Prepara o canal leitura da Temperatura
     delay_us(10);
     
     for (j=0; j<16; j++)            // Faz a leitura 15x
       {
       temperatura = temperatura + read_adc();
       }
       
     temperatura = (temperatura/16);
     return(temperatura);
  }
      
int16 A2()                             // Leitura LDR1
  {
     int16 ldr1 = 0;
     int j;
     
     set_adc_channel(2);             // Prepara o canal leitura do ldr1
     delay_us(10);
     
     for (j=0; j<16; j++)            // Faz a leitura 15x
       {
       ldr1 = ldr1 + read_adc();
       }
       
     ldr1 = (ldr1/16);
     return(ldr1);
      
  }
  
int16 A3()                             // Leitura LDR2
  {
     int16 ldr2 = 0;
     int j;
     
     set_adc_channel(3);             // Prepara o canal leitura do ldr2
     delay_us(10);
     
     for (j=0; j<16; j++)            // Faz a leitura 15x
       {
       ldr2 = ldr2 + read_adc();
       }
       
     ldr2 = (ldr2/16);
     return(ldr2);
      
  }
  
int16 A4()                             // Leitura LDR3
  {
     int16 ldr3 = 0;
     int j;
     
     set_adc_channel(4);             // Prepara o canal leitura do ldr1
     delay_us(10);
     
     for (j=0; j<16; j++)            // Faz a leitura 15x
       {
       ldr3 = ldr3 + read_adc();
       }
       
     ldr3 = (ldr3/16);
     return(ldr3);
  }
 
int16 A5()                             // Leitura LDR4
  {
     int16 ldr4 = 0;
     int j;
     
     set_adc_channel(5);             // Prepara o canal leitura do ldr1
     delay_us(10);
     
     for (j=0; j<16; j++)            // Faz a leitura 15x
       {
       ldr4 = ldr4 + read_adc();
       }
       
     ldr4 = (ldr4/16);
     return(ldr4);
      
  }
 
int16 A6()                             // Leitura LDR5
  {
     int16 ldr5 = 0;
     int j;
     
     set_adc_channel(6);             // Prepara o canal leitura do ldr1
     delay_us(10);
     
     for (j=0; j<16; j++)            // Faz a leitura 15x
       {
       ldr5 = ldr5 + read_adc();
       }
       
     ldr5 = (ldr5/16);
     return(ldr5);
      
  }
  
int16 A7()                             // Leitura Corrente do PFV
  {
     int16 corrente = 0;
     int j;
     
     set_adc_channel(7);             // Prepara o canal Corrente do PFV
     delay_us(10);
     
     for (j=0; j<16; j++)            // Faz a leitura 15x
       {
       corrente = corrente + read_adc();
       }
       
     corrente = (corrente/16);
     return(corrente);
  }
 
int16 A8()                             // Leitura Tensão do PFV
  {
     int16 tensão = 0;
     int j;
     
     set_adc_channel(8);             // Prepara o canal leitura tensão PFV
     delay_us(10);
     
     for (j=0; j<16; j++)            // Faz a leitura 15x
       {
       tensão = tensão + read_adc();
       }
       
     tensão = (tensão/16);
     return(tensão);
  }
 
void main()
   {
  
    ds1307_init();
    lcd_init();
        
    data_hora = read_eeprom(0x07);   // Variavel para informar se o RTC ja foi ajustado pela primeira vez
    delay_ms(10);
    lcd_putc("\f");                  //Limpa display
    db_1 = db_2 = db_3 = 0;
    
      
    
    while(true)
         {
           
         //Medida do Angulo de Inclinação   (AN0)
         An = ((0.28325 * A0())-185.573);
         lcd_gotoxy(1,3);                // Coloca Angulo no Display
         printf(lcd_putc,"%.2f%c",An,0xDF);
           
         //Medida da Temperatura      (AN1)
         T = (0.08145 * A1());           // Converte em graus Celsius
         lcd_gotoxy(1,4);                // Coloca Temperatura no Display
         printf(lcd_putc,"%.1f%cC",T,0xDF);
           }
   }
   
   

 [/code][/spoiler]

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

perdão tembém por não analisar seu código como você merece. Permita-me só chutes:

altere o nível de otimização do seu compilador (se tiver como)

tenta a versão anterior do seu compilador.

eu gosto de deixar brownout ligado

Tenta simular pra ver se ok. Se sim...

tenta ver problemas no hw.

Aguarde... em instantes um de nossos atendentes vai te atender

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

ok. vi seu email. você já deve ter tentado as opções anteriores né????

Vá por partes. Trava antes ou dentro do loop? Na simulação ou na real?

comente a linhas que chamam as funções Ax()

//T = (0.08145 * A1());           // Converte em graus Celsius

e coloque

T=1.234;// p.ex. 

depois tente

T=1234;

pra ver se operações com ponto flutuante tão zoando o barraco

não entendi direito a função do lcd_putc. Lembrando que o printf com mc´s come muito recurso. + ainda com floats

printf(lcd_putc,"%.2f%c",An,0xDF);

tente printf direto

printf(An);

+  tarde penso +

Link para o comentário
Compartilhar em outros sites

Ax() é uma função cria para fazer a leitura do canal Ad. Em testes aqui agora pouco percebi que chamo a rotina e o programa fica preso dentro dele, preciso fazer o codigo executar uma vez e sair dessa rotina.

 

lcd_putc é uma função da biblioteca do display para colocar os caracteres na tela do lcd, qto ao printf aparentemente ele nao esta consumindo memoria.

 

Com esses testes percebi tambem que o programa trava quando eu chamo ele pra ler o RTC, ou seja quando faço isso:

 

ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
 
 

...qto a isso eu não sei o que fazer...

 

 

while(true)
         {
         set_adc_channel(1);             // Prepara o canal leitura da Temperatura
         delay_us(10);
         temperatura = read_adc();
                    
                
         
         T = (0.08145 * temperatura);           // Converte em graus Celsius
         lcd_gotoxy(1,3);                // Coloca Temperatura no Display
         printf(lcd_putc,"%.1f%cC",T,0xDF);
         output_high(pin_A4);
         
         
         
         delay_ms(100);
         botao_enter = input(pin_b5);
         if(!botao_enter && !db_3)
           {
           menu = 1;
            if(filtro != 0)
              {
               filtro--;
              }
              else
                 {
                  db_3 = 1;
                  valor = 1;
                  menu = 1;
                 }
           }
            else
               {
                filtro = t_filtro;
                db_3 = 0;
               }
          
         if(menu == 1)
           {
            Menu_principal();
           }
           else menu = 0;
            
          if(sensor == 1)
           {
            Menu_sensor();
           }
            
          if(acionamento == 1)
           {
            Menu_acionamento();
           }
            
          if(data == 1)
           {
            Menu_data();
           }
           
          
         ds1307_get_date(day,month,yr,dow);
         ds1307_get_time(hrs,min,sec);
         output_low(pin_a4);
         lcd_gotoxy(1, 1);
         printf(lcd_putc,"%s %02d:\%02d:\%02d",dia_da_semana[dow-1],hrs,min,sec);
         lcd_gotoxy(1, 2);
         printf(lcd_putc,"%02d/\%02d/\%02d",day,month,yr);
         
        
           }

Link para o comentário
Compartilhar em outros sites

Encontrei o erro, estou usando o 18F4550 onde as portas SCL e SDA tambem são entradas analogicas. Como eu estava "setando" todas as portas como analogicas dava um conflito tremendo que inpedia que fizesse tanto a conversão AD quanto se comunicar com o RTC.

 

Grato pela ajuda pessoal.

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber 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...