Ir ao conteúdo
  • Comunicados

    • Gabriel Torres

      Seja um moderador do Clube do Hardware!   12-02-2016

      Prezados membros do Clube do Hardware, Está aberto o processo de seleção de novos moderadores para diversos setores ou áreas do Clube do Hardware. Os requisitos são:   Pelo menos 500 posts e um ano de cadastro; Boa frequência de participação; Ser respeitoso, cordial e educado com os demais membros; Ter bom nível de português; Ter razoável conhecimento da área em que pretende atuar; Saber trabalhar em equipe (com os moderadores, coordenadores e administradores).   Os interessados deverão enviar uma mensagem privada para o usuário @Equipe Clube do Hardware com o título "Candidato a moderador". A mensagem deverá conter respostas às perguntas abaixo:   Qual o seu nome completo? Qual sua data de nascimento? Qual sua formação/profissão? Já atuou como moderador em algo outro fórum, se sim, qual? De forma sucinta, explique o porquê de querer ser moderador do fórum e conte-nos um pouco sobre você.   OBS: Não se trata de função remunerada. Todos que fazem parte do staff são voluntários.
    • DiF

      Poste seus códigos corretamente!   21-05-2016

      Prezados membros do Fórum do Clube do Hardware, O Fórum oferece um recurso chamado CODE, onde o ícone no painel do editor é  <>     O uso deste recurso é  imprescindível para uma melhor leitura, manter a organização, diferenciar de texto comum e principalmente evitar que os compiladores e IDEs acusem erro ao colar um código copiado daqui. Portanto convido-lhes para ler as instruções de como usar este recurso CODE neste tópico:  
pisettalindomar

Conversor ADC pic 16f876 só lê canal 0

Recommended Posts

Olá boa tarde a todos, estou com um projeto de um voltímetro aqui que esta meio enrolado. :confused:

Ele funciona assim: é um voltímetro de 7 segmentos x 3 dígitos e mede de 0  a 500 volts no canal 0.

Ele funciona tudo OK, porém, eu quero ler um outro pino do adc que não seja o canal 0, qualquer outro pino do adc e não consigo de nenhuma maneira!!

Meu conhecimento em programação é bem curto, não consigo resolver ele.

Este projeto tem partes que eu peguei da web de um voltímetro que usava o 16f873 ai eu mudei para o 876 fiz mais umas gambiaras para que em determinada tensão ligue e desligue alguns leds e tudo funcionou, mas trocar de canal do adc nem matando ele :mad: .

Segue cod em ccs.

 

A quem quiser me ajudar qualquer ideia, sugestão é bem vinda.

   #include <16F876.h>   #device ADC=10    #fuses NOWDT, XT PUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD   #use delay(clock=4000000)   #use fast_io(A)   #use fast_io(   #use fast_io(C)   #DEFINE   Q1   PIN_B0                   // display 3   #DEFINE   Q2   PIN_B1                   // display 2   #DEFINE   Q3   PIN_B2                   // display 1   #BYTE    display=7   long  valor;   float volts;   int   a;  //------------------------------------------------------------------------------   struct digito_separados    {         //variavel em bcd  unidade dezena centena   int  unidade, dezena, centena;   }    digito;//------------------------------------------------------------------------------   struct dados    {                 // variavel de dados entrada e saida   int  dados1, dados2, resultado;   }   numeros;//------------------------------------------------------------------------------   void separar_digitos(){      // separa resultado en unidade, dezena, centena     int   temp;     digito.unidade=0;     digito.dezena=0;     temp=numeros.resultado;     while(temp>=10){       temp-=10;       digito.dezena++;     }     digito.unidade=temp;   }//------------------------------------------------------------------------------   void mostrar()   {               int const bcd_7seg[10]= {0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7B};      int contador;           //0    1     2    3    4    5    6    7    8    9      output_low(Q1);      output_low(Q2);      output_low(Q3);       for(contador=0;contador<11;contador++)         {         display=bcd_7seg[digito.unidade];           //mostra unidade         output_high(Q1);         delay_ms(5);         output_low(Q1);         delay_cycles(4);         display=bcd_7seg[digito.dezena];            //mostra dezena         output_high(Q2);         delay_ms(5);         output_low(Q2);         delay_cycles(4);         display=bcd_7seg[digito.centena];           //mostra centena         output_high(Q3);         delay_ms(5);         output_low(Q3);         delay_cycles(4);         }    }//------------------------------------------------------------------------------void main()   {   set_tris_a(0x00000001);     //canal 0 entrada restante saida   output_a(0b00000000);        // limpa    set_tris_b(0x00000000);     //tudo saida   output_b(0b00000000);        //limpa   set_tris_c(0x00000000);     //tudo saida               output_C(0b00000000);        //limpa     setup_adc_ports(ALL_ANALOG);   setup_adc(ADC_CLOCK_DIV_2);   set_adc_channel(0);   d:    valor = Read_ADC();  //  adcon1=0x0e;   delay_us(20);   volts=0.00488758*(float)valor;   a=(int)volts;   //------------------------------------------------------------------------------            if (valor>=430)// maior que   {   output_b(0b10000000);   }   //---------------------------------------------------------------------------   if (valor>=450)// maior que   {     output_b(0b01000000);   }   //---------------------------------------------------------------------------   if (valor>=470)// maior que   {   output_b(0b00100000);   }   //---------------------------------------------------------------------------   if (valor>=491)// maior que   {   output_b(0b00010000);   }   //---------------------------------------------------------------------------   if (valor>=511)// maior que   {   output_b(0b00001000);   }   //---------------------------------------------------------------------------   if (valor<=420)// menor que   {   output_b(0b00000000);   }   //---------------------------------------------------------------------------   if (valor>=515)// maior que   {   output_b(0b00000000);   }   //------------------------------------------------------------------------------   digito.centena=a;   volts=volts-(float)a;   numeros.resultado=(int)(100.0*volts);   separar_digitos();   mostrar();   goto  d;}

post-596061-0-51746900-1420142446_thumb.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá, 

 Numa olhada rápida no seu código, vi que você seta o canal 0 somente "sec_adc_channel(0);", tenta setar o canal 1 antes de usar a função read_adc();

int16 adc2;set_adc_channel(1);//delay_us(10); //Pode ser necessário um delayadc2 = read_adc();....

Att,

Editado por Fervolt
  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • Autor do tópico
  • Olá Fervolt muito grato pela ajuda, olha até funcionou, consegui trocar de canal an0, an1, an2, etc porém,,,,  :D  olha só que praga :mad: por exemplo eu seto o canal 0

    vou la no proteus e funciona.

    No potenciometro para ajustar a tensão acerto ele para ler 220V, ta OK funciona, ai ,,,, eu vou la no ccs e seto o canal 1 compila e tal. no proteus sem mexer no potenciometro apenas troco o pino an0 por an1 .

    teclo F12, funcionou, porém ele indica apenas 100V  :mad:  :muro:  

    Vou continuar mexendo, uma hora vai aparecer o grilo que tem aqui.  

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Você descomentou a linha do delay? caso não, tente!

    Seu esquema está meio estranho, não entendi o porque daqueles 2 pots daquele jeito. Coloque a referencia nos pots adequadamente, pino superior -> Power(vcc), pino do meio -> canal AD e pino inferior -> GND(0v).

    Para usar os vários canais, não precisa ficar mudando o código e compilando, crie variáveis para receber o valor de cada canal, como por exemplo:

    int16 adc0, adc1, adc2;//em algum ponto dentro de main()set_adc_channel(0);delay_us(15);adc0 = read_adc();set_adc_channel(1);delay_us(15);adc1 = read_adc();set_adc_channel(2);delay_us(15);adc2 = read_adc();//...//segue o código

    Att,

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • post-596061-0-65644400-1420241545_thumb.

    beleza :aplausos:  agora esta tomando jeito a brincadeira aqui, perfeito Fervolt com sua ideia deu certo agora consigo trocar de canal sem ter que compilar cada vez,, é que a cabeça aqui não ajuda . :D ...

    também mudei aquela gambiara de potenciometro  e coloque uma chavinha seletora para trocar de canal.

    Bom sobrou só um detalhe agora, que é o seguinte, o canal 0 da resultado diferente dos outros  :confused:  só o canal 0, os outros dão o mesmo resultado quando muda de posição a chave seletora.

    É estranho porque deveria todos os canais dar o mesmo resultado, eu acho kkkkkkkkkkkkkkkkk.

    segue cod 

       #include <16F876.h>   #device ADC=10    #fuses NOWDT, XT PUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD   #use delay(clock=4000000)   #use fast_io(A)   #use fast_io(   #use fast_io(C)   #DEFINE   Q1   PIN_B0                   // display 3   #DEFINE   Q2   PIN_B1                   // display 2   #DEFINE   Q3   PIN_B2                   // display 1   #BYTE    display=7  // long  valor;   float volts;   int16 adc0,adc1,adc2 ;   int   a;  //------------------------------------------------------------------------------   struct digito_separados    {         //variavel em bcd  unidade dezena centena   int  unidade, dezena, centena;   }    digito;//------------------------------------------------------------------------------   struct dados    {                 // variavel de dados entrada e saida   int  dados1, dados2, resultado;   }   numeros;//------------------------------------------------------------------------------   void separar_digitos(){      // separa resultado en unidade, dezena, centena     int   temp;     digito.unidade=0;     digito.dezena=0;     temp=numeros.resultado;     while(temp>=10){       temp-=10;       digito.dezena++;     }     digito.unidade=temp;   }//------------------------------------------------------------------------------   void mostrar()   {               int const bcd_7seg[10]= {0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7B};      int contador;           //0    1     2    3    4    5    6    7    8    9      output_low(Q1);      output_low(Q2);      output_low(Q3);       for(contador=0;contador<11;contador++)         {         display=bcd_7seg[digito.unidade];           //mostra unidade         output_high(Q1);         delay_ms(5);         output_low(Q1);         delay_cycles(4);         display=bcd_7seg[digito.dezena];            //mostra dezena         output_high(Q2);         delay_ms(5);         output_low(Q2);         delay_cycles(4);         display=bcd_7seg[digito.centena];           //mostra centena         output_high(Q3);         delay_ms(5);         output_low(Q3);         delay_cycles(4);         }    }//------------------------------------------------------------------------------void main()   {   set_tris_a(0x00000111);     //canal 0 entrada restante saida   output_a(0b00000000);        // limpa    set_tris_b(0x00000000);     //tudo saida   output_b(0b00000000);        //limpa   set_tris_c(0x00000000);     //tudo saida               output_C(0b00000000);        //limpa      setup_adc_ports(ALL_ANALOG);   setup_adc(ADC_CLOCK_DIV_2);   d:   set_adc_channel(0);delay_us(15);adc0 = read_adc();set_adc_channel(1);delay_us(15);adc1 = read_adc();set_adc_channel(2);delay_us(15);adc2 = read_adc();                          volts=0.0488758*(float)adc0,adc1,adc2;   a=(int)volts;   //------------------------------------------------------------------------------    /*        if (valor>=430)// maior que   {   output_b(0b10000000);   }   //---------------------------------------------------------------------------   if (valor>=450)// maior que   {     output_b(0b01000000);   }   //---------------------------------------------------------------------------   if (valor>=470)// maior que   {   output_b(0b00100000);   }   //---------------------------------------------------------------------------   if (valor>=491)// maior que   {   output_b(0b00010000);   }   //---------------------------------------------------------------------------   if (valor>=511)// maior que   {   output_b(0b00001000);   }   //---------------------------------------------------------------------------   if (valor<=420)// menor que   {   output_b(0b00000000);   }   //---------------------------------------------------------------------------   if (valor>=515)// maior que   {   output_b(0b00000000);   }   //------------------------------------------------------------------------------*/   digito.centena=a;   volts=volts-(float)a;   numeros.resultado=(int)(100.0*volts);   separar_digitos();   mostrar();      goto  d;}

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

     

    attachicon.giftesteok.jpg

           volts=0.0488758*(float)adc0,adc1,adc2;   a=(int)volts;   }

     

    Não entendo nada de C, mas essa multiplicação deve ser o seu problema....

    Como o programa sabe qual desses 3 valores tem de ser multiplicado ????

    Creio que o compilador faz apenas o primeiro, que é o do adc0.

    Os outros canais, embora iguais, devem estar errados.

     

    Paulo

    Editado por aphawk
    • Curtir 1

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Crie uma conta ou entre para comentar

    Você precisar ser um membro para fazer um comentário






    Sobre o Clube do Hardware

    No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações 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

    ×