Entrar    Registrar

Como medir tensao e corrente ac com pic

Software e Hardware para uC PIC

Moderadores: aluis-rcastro, guest2003, 51, Renie

  • Autor
    Mensagem

Re: Como medir tensao e corrente ac com pic

Mensagempor aluis-rcastro » 23 Mai 2015 18:56

Novamente, voce nao informou em que linha está ocorrendo o erro.

De qualquer modo, a causa do problema ainda não foi totalmente eliminada e continuamos sem saber se esse é realmente o motivo do Warning, pois na 1a linha da função void lineariza_e_mostra(void) logo após a atribuição leitura_tensao=read_adc(); voce realiza uma nova conversão sem delay intercalando as duas. A propósito, não procurei por outras ocorrencias de leitura do AD sem intervalo pra conversão...

Outra coisa: Notei também que voce não está iniciando a conversão com as constantes ADC_READ_ONLY e ADC_START_ONLY como parametro para a função read_adc(). Recomendo que voce dê uma olhada em exemplos da Web, não lembro exatamente como usar, mas é fato que tem de dar um tempo entre uma e outra para concluir a conversão analogico pra digital.
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
aluis-rcastro
Dword
 
Mensagens: 5338
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Como medir tensao e corrente ac com pic

Mensagempor ze » 25 Mai 2015 12:07

achei mais uma ocorrência
void lineariza_e_mostra(void)
{
leitura_tensao=read_adc();

if((leitura_tensao>=562)){ //maior que 220v
leitura_conv=(read_adc() * fm);goto fim;}
delay_ms(1);

e deve ter +
Pra evitar estes delays sem sentido entre uma leitura e outra, coloque-o dentro da própria função read_adc() como indiquei em posts anteriores. Caso não consiga se desvincular dos mastigados do ccs, tente algo assim
Código: Selecionar todos
void _read_adc()
{
read_adc();
delay(xxx);
}

Notou o sutil underline?
abç
Avatar do usuário
ze
Dword
 
Mensagens: 1645
Registrado em: 05 Jun 2007 14:32

Re: Como medir tensao e corrente ac com pic

Mensagempor carlucio » 01 Jun 2015 16:14

A cada dia que passo, vejo como é dificil conseguir implementar uma solução pra esse problema meu.

Ja tentei sim testar o situações sugeridas por alguns do senhores, mas o meu problema continua.


Hoje o meu problema e que quando estou usando os 2 canais analogicos, nenhum dos dois esta funcionando. Se deixo so o canal 0 ai funciona o voltimetro.

Testei uma outra formula de corrente mas nada de dar certo, o valor nem aparece no display.
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como medir tensao e corrente ac com pic

Mensagempor KrafT » 01 Jun 2015 20:02

Querido, veja o lado bom: você pode vender os direitos para o Silvio Santos.

Falando sério: Acho que a solução já está nesse tópico, você que não deu atenção :roll:

Ou não...

Seguinte: Não sei se já falei isso mas fiz um treco parecido com o seu, com PIC e ficou uma bo&¨$% Troquei para um Kinetis com ADC de 12bits e ficou jóia.
"..."Come to the edge," he said. And so they came. And he pushed them. And they flew."― Guillaume Apollinaire
Avatar do usuário
KrafT
Dword
 
Mensagens: 2153
Registrado em: 11 Out 2006 14:15
Localização: Blumenau -SC

Re: Como medir tensao e corrente ac com pic

Mensagempor carlucio » 01 Jun 2015 23:59

Kraft,


Não é que eu não dei atenção a estas informações repassadas pelo pessoal (Zé, Andre, ....). O problema é que no topico referido a parte da tensao esta funcionando bem (mesmo eu sendo advertido aqui por pessoas no topico quanto ao uso de float). Agora a parte da corrente essa sim esta sendo uma pedra no sapato. (Quando uso dois canais ad nenhum esta funcionando, mesmo orientado para fazer da maneira que o pessoal do forum pediu)

Veja que o assunto é tao dificil de ser encontrado ( acs 712 com pic em linguagem c ccs) que se for procurar na internet vai ver que é muito complicado de encontrar, não impossivel. Depois disso a outra parte de dificuldade é adaptar ao meu caso, que é agora onde eu estou travado. Ja tentei algumas formulas para o pic e tentei mais ainda adaptar do arduino para o pic.

Desisitir não vou, tentando e pelejando se vence a batalha.
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como medir tensao e corrente ac com pic

Mensagempor ze » 02 Jun 2015 08:33

e eu troquei por um attiny que tem referência interna e o mais legal: um amplificador operacional 20 ou 200x que usei pra medir a corrente. Mas isso acho que não te ajuda. Afinal pic é a sua solução&|problema. Tente dar um tempo (bem) maior entre uma mudança de um canal pra outro tipo 1 segundo (apelação). Tente atualizar seu compilador. Este tróço (ou trôço) pode estar bugado.
Tente migrar pra outro p.ex. mikroc. A sintaxe é quase a lesma lerda e é 1/2 de graça. SDCC é uma opção 100% free mas acoplá-lo ao mplab é 1/2 xatinho (mas possível)

Realmente desistir é para os fracos. Porque vc acha que ainda estou a dar chutes neste seu tópico?
A propósito, porquê será que todo idiota termina uma frase com ponto de interrogação?
Avatar do usuário
ze
Dword
 
Mensagens: 1645
Registrado em: 05 Jun 2007 14:32

Re: Como medir tensao e corrente ac com pic

Mensagempor carlucio » 10 Jun 2015 22:32

Apos n tentativas, acho que agora estou quase chegando la, so que eu to com um problema tão basico que não to conseguindo enxergar onde esta o problema.

Com o codigo mais enxuto, para prever os testes estou esbarrando numa situação tão basica que ja tentei tanto que não vi o erro.
O problema é que no codigo abaixo, o mesmo não envia mensagem nenhuma no display. Com a mesma montagem do display utilizando outro codigo o display funciona normal.

As chamadas do display, acho eu que estão corretas.

Onde esta o erro? O codigo abaixo:

Código: Selecionar todos
//-----------------------fuses do pic-----------------------//

   #include <16F876A.h>
   #device adc=10
   #include "lcd.c"
   #use delay(clock=4000000)
   #fuses xt,nolvp,nowdt,
   #include <math.h>

   
   //--------------variaveis globais---------------------------//
   
   unsigned int16 leitura_tensao;//global
   unsigned int16 leitura_conv;

  /* #define  sensor_corrente pin_a1
   float sensorValue_aux =0;
   float sensorValue =0;
   float currentValue =0.00;
   float voltsporunidade = 0.0048828125;*/

   //----------------VARIAVEIS CORRENTE--------------//
   int i,j,VQ, total_lidos;     
   int16 val, valor_anal;
   float vlr_Analog0;
   int sensib_ADC = 73;
   int32 dif_ADC = 512;
   
   //-------------constantes de conversão----------------------//

   float fm = 0.393;
   float fm1 =0.393;
   float fm2 =0.382;
   float fm3 =0.380;
   float fm4 =0.373;
   float fm5 =0.370;
   float fm6 =0.366;
   float fm7 =0.365;
   float fm8 =0.364;
   float fm9 =0.362;
   float fm10=0.365;
   float fm11=0.365;
   float fm12=0.368;
   float fm13=0.368;

   //--------------------funções------------------//
   
   void lineariza_e_mostra(void)         // leitura e apresentação de tensao
   {
   leitura_tensao=read_adc();

   if((leitura_tensao>=562)){  //maior que 220v
   leitura_conv=(read_adc()  * fm);goto fim;}
  // delay_ms(1);

   if ((leitura_tensao<=561) && (leitura_tensao>=544)){ // 220 a 210v
   leitura_conv=(read_adc()* fm1);goto fim;}
  // delay_ms(1);

   if ((leitura_tensao<=543)&& (leitura_tensao>=526)){ //210 a 200v
   leitura_conv = (read_adc()*  fm2);goto fim;}
   //delay_ms(1);

   if ((leitura_tensao<=525) && (leitura_tensao>=509)){ // 200 a 190v
   leitura_conv=(read_adc()*  fm3);goto fim;}
   //delay_ms(1);

   if ((leitura_tensao<=508) && (leitura_tensao>=487)){ // 190 a 180v
   leitura_conv= (read_adc()* fm4);goto fim;}
  // delay_ms(1);

   if ((leitura_tensao<=486)&& (leitura_tensao>=464)) { //180 a 170v
   leitura_conv = (read_adc()* fm5);goto fim;}
  // delay_ms(1);

   if ((leitura_tensao<=463)&& (leitura_tensao>=438)) { // 170 a 160v
   leitura_conv = (read_adc()*  fm6);goto fim;}
   //delay_ms(1);

   if ((leitura_tensao<=437)&& (leitura_tensao>=411)) { // 160 a 150v
   leitura_conv = (read_adc()*  fm7);goto fim;}
   //delay_ms(1);

   if ((leitura_tensao<=410)&& (leitura_tensao>=385)) { // 150 a 140v
   leitura_conv = (read_adc()*  fm8);goto fim;}
   //delay_ms(1);

   if ((leitura_tensao<=386)&& (leitura_tensao>=359)) { //140 a 130v
   leitura_conv = (read_adc()*  fm9);goto fim;}
   //delay_ms(1);

   if ((leitura_tensao<=358)&& (leitura_tensao>= 329)) { //130 a 120v
   leitura_conv = (read_adc()*  fm10);goto fim;}
  // delay_ms(1);

   if ((leitura_tensao<=328)&& (leitura_tensao>= 301)) { //120 a 110v
   leitura_conv = (read_adc()*  fm11);goto fim;}
   //delay_ms(1);

   if ((leitura_tensao<=300)&& (leitura_tensao>=272)) { // 110  a 100v
   leitura_conv = (read_adc()*  fm12);goto fim;}
  // delay_ms(1);

   if (leitura_tensao<=271) {  // menor que 100v
   leitura_conv = (read_adc()*  fm13);goto fim;}
   //delay_ms(1);

   //etc ...
   fim:
   
   //----------------apresentação do display----------------//
   
   delay_ms(500); //
   lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
   printf(lcd_dado,"%3lu",leitura_conv);  //Mostra a tensão medida
   }

   void corrente (void){
     
      delay_ms(100);
      set_adc_channel(1); // Canal  do ADC

      for(i=1;i<=5;i++){

         val = read_adc();

         if(val>dif_ADC){
         valor_anal += (val - dif_ADC);
         }else{
         valor_anal += (dif_ADC - val);
         }

         total_lidos++;

         delay_ms(1);
      }   

      valor_anal = valor_anal/total_lidos;     

      vlr_Analog0 = 0;
      vlr_Analog0 = (valor_anal*sensib_ADC);

      lcd_locate(1,8);
      printf(lcd_dado "%2.2f", vlr_Analog0);
      delay_ms(150);
   }

   //-------------------programa principal-----------------//
   
    void main(void)
    {     
           
      inicializa_lcd();

           
      setup_adc(ADC_CLOCK_DIV_8);
      setup_adc_ports(an0_an1_an3);            //###############Configura A/D //Primeiro configura o ADC_PORT, depois ADC_CLOCK
      //setup_adc(ADC_CLOCK_INTERNAL);
     // setup_adc(ADC_CLOCK_DIV_8); 

      delay_ms(10);
    /* 
      //Pega a média da tensão para o calculo
      set_adc_channel(1); // Canal  do ADC                                                   
      for(j=0;j<1000;j++){
         val = read_adc();
         VQ += val;
         delay_ms(1);
      }

      //Atualiza Vq de acordo com a tensão
      VQ = VQ/1000;
      dif_ADC = VQ;
           
      while(1)
      { 
      */
   
         //inicializa hw
lcd_locate(1,0);
printf(lcd_dado,"V=");

         lcd_locate(1,6);
         printf(lcd_dado,"A=");
     // }
    // for(;;)    {
         //Leitura ADC 0
        set_adc_channel(0);         
         delay_ms(30);

         leitura_tensao=read_adc();
         leitura_conv=leitura_tensao;
         lineariza_e_mostra();
         delay_ms(250);
       

         //Leitura ADC 1
      //   corrente();
         delay_ms(250);
      }
     // }
   
 //   }
    //-----------------fim---------------//



No aguardo...
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como medir tensao e corrente ac com pic

Mensagempor EDSONCAN » 11 Jun 2015 08:06

Olha isso:
int i,j,VQ, total_lidos; ......

for(j=0;j<1000;j++){

Como você quer que uma int de 8 bits chegue em 1000 o máximo e 256?

Use const para o que constante e pare de usar memoria RAM a toa.

const float....

Constant Data:

The CONST qualifier will place the variables into program memory. If the keyword CONST is used before the identifier, the identifier is treated as a constant. Constants should be initialized and may not be changed at run-time. This is an easy way to create lookup tables
EDSONCAN
Word
 
Mensagens: 875
Registrado em: 11 Out 2006 14:11

Re: Como medir tensao e corrente ac com pic

Mensagempor ze » 11 Jun 2015 10:32

na minha época int era 16 bits mesmo. Pena que não acompanhei a "evolução".
Mas de toda a forma este loop for pode dar problema se o resultado do ad for maior que 65 (e olha que o ad pode ir até 1023!) pelo motivo que o amigo edson intuiu: mil iterações vão provocar 66000 no valor de VQ o que não cabe dentro de um int. E outra, vc deve zerar VQ antes de começar a somar. E outra mais: média de mil é exagero. Se eu fosse vc usava no máximo 32. (de fato exatos 32)
O amigo edson está 99.99% correto em sugerir usar const. Pra 100% (no seu caso) sugiro #define mesmo
//float fm = 0.393;
#define fm 0.393
Acho que já disse isso
Agora dá licença que vou reacender o fogo da caverna pro almoço
Avatar do usuário
ze
Dword
 
Mensagens: 1645
Registrado em: 05 Jun 2007 14:32

Re: Como medir tensao e corrente ac com pic

Mensagempor xultz » 11 Jun 2015 11:23

José, por definição o int tem o tamanho da largura do processador. Assim, um processador de 16 bits tem int de 16 bits, um processador de 32 bits tem int de 32 bits, e teoricamente um processador de 8 bits como o PIC tem int de 8 bits. Só que até onde sei, só o CCS respeita essa definição pros PICs, os outros usam 16 bits porque é o que todo mundo tá acostumado.
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 2960
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Re: Como medir tensao e corrente ac com pic

Mensagempor ze » 11 Jun 2015 12:19

ok xu. falei sobre o velho c e não mc e obviamente desconheço nuances do ccs... enfim
falando nisso me lembro que um unsigned char no keil ou iar num lpcxxxx era 32bits. Neste caso sim, tens razão. Compilador-mc dependente.
Avatar do usuário
ze
Dword
 
Mensagens: 1645
Registrado em: 05 Jun 2007 14:32

Re: Como medir tensao e corrente ac com pic

Mensagempor EDSONCAN » 11 Jun 2015 13:23

Keil
Type Size in bits Natural alignment in bytes
char 1 byte
int 4 byte

CCS
Int = int8 1 byte

É só olhar o help do compilador.....
EDSONCAN
Word
 
Mensagens: 875
Registrado em: 11 Out 2006 14:11

Re: Como medir tensao e corrente ac com pic

Mensagempor carlucio » 13 Jun 2015 21:44

Galera,

Concordo com o que voces falaram tanto na questão do int, quanto o do define do ze.

Esta parte do int esta se referindo a tensão que neste momento ainda não estou usando (esta comentado no codigo acima). Ja ze o define vou implementa-lo sim, no caso quando conseguir esta segunda parte no que se refere a corrente com o acs712. Assim que conseguir a parte da corrente vou fazer um refinamento do codigo com toda a informação passada pelo pessoal do forum. ( primeiro quero fazer a parte basica funcionar e depois aprimorar o que tiver de aprimorar)

Os problemas enfrentados por mim neste momento sao dois:

1º - E que nesse codigo que foi dada uma primeira enxugada, o mesmo não apresenta os dados no display e não é o hw montado no proteus que neste caso estou testando que esta com problema, pois o codigo anterior a esse foi testado n vezes e funciona perfeitamente. Agora, eu não sei que na mudança que foi feita nada aparece, sendo que os printf's estão iguais aos do codigo anterior.

2º - Era quando uso dois canais analogicos não funciona nenhum o outro (tensão ou corrente), quando comentava o de corrente o de tensao funcionava normal.


Pra não falar que o codigo de corrente não funciona, e o mesmo desse video abaixo, exceto a parte do printf usado para o hyperterminal:





Se ainda puder contar com a ajuda de vocês ....
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como medir tensao e corrente ac com pic

Mensagempor carlucio » 15 Jun 2015 01:05

Para melhor exemplificar o meu problema vejam o video em anexo:



Não consigo agora fazer nenhum tipo de leitura em nenhum dos canais, o problema do display apresentação foi ate resolvido.
A configuração dos canais analogicos estao erradas (locais de declaração)?

Código: Selecionar todos
 //-----------------------fuses do pic-----------------------//

   #include <16F876A.h>
   #device adc=10
   #include "lcd.c"
   #use delay(clock=4000000)
   #fuses xt,nolvp,nowdt,
   #include <math.h>

   
   //--------------variaveis globais---------------------------//
   
   unsigned int16 leitura_tensao;//global
   unsigned int16 leitura_conv;

  /* #define  sensor_corrente pin_a1
   float sensorValue_aux =0;
   float sensorValue =0;
   float currentValue =0.00;
   float voltsporunidade = 0.0048828125;*/

   //----------------VARIAVEIS CORRENTE--------------//
   int i=0,j=0,VQ=0, total_lidos=0;     
   int16 val=0, valor_anal=0;
   float vlr_Analog0;
   int sensib_ADC = 73;
   int32 dif_ADC = 512;
   
   //-------------constantes de conversão----------------------//

   float fm = 0.393;
   float fm1 =0.393;
   float fm2 =0.382;
   float fm3 =0.380;
   float fm4 =0.373;
   float fm5 =0.370;
   float fm6 =0.366;
   float fm7 =0.365;
   float fm8 =0.364;
   float fm9 =0.362;
   float fm10=0.365;
   float fm11=0.365;
   float fm12=0.368;
   float fm13=0.368;

   //--------------------funções------------------//
   
   void lineariza_e_mostra(void)         // leitura e apresentação de tensao
   {
   leitura_tensao=read_adc();

   if((leitura_tensao>=562)){  //maior que 220v
   leitura_conv=(read_adc()  * fm);goto fim;}
  // delay_ms(1);

   if ((leitura_tensao<=561) && (leitura_tensao>=544)){ // 220 a 210v
   leitura_conv=(read_adc()* fm1);goto fim;}
  // delay_ms(1);

   if ((leitura_tensao<=543)&& (leitura_tensao>=526)){ //210 a 200v
   leitura_conv = (read_adc()*  fm2);goto fim;}
   //delay_ms(1);

   if ((leitura_tensao<=525) && (leitura_tensao>=509)){ // 200 a 190v
   leitura_conv=(read_adc()*  fm3);goto fim;}
   //delay_ms(1);

   if ((leitura_tensao<=508) && (leitura_tensao>=487)){ // 190 a 180v
   leitura_conv= (read_adc()* fm4);goto fim;}
  // delay_ms(1);

   if ((leitura_tensao<=486)&& (leitura_tensao>=464)) { //180 a 170v
   leitura_conv = (read_adc()* fm5);goto fim;}
  // delay_ms(1);

   if ((leitura_tensao<=463)&& (leitura_tensao>=438)) { // 170 a 160v
   leitura_conv = (read_adc()*  fm6);goto fim;}
   //delay_ms(1);

   if ((leitura_tensao<=437)&& (leitura_tensao>=411)) { // 160 a 150v
   leitura_conv = (read_adc()*  fm7);goto fim;}
   //delay_ms(1);

   if ((leitura_tensao<=410)&& (leitura_tensao>=385)) { // 150 a 140v
   leitura_conv = (read_adc()*  fm8);goto fim;}
   //delay_ms(1);

   if ((leitura_tensao<=386)&& (leitura_tensao>=359)) { //140 a 130v
   leitura_conv = (read_adc()*  fm9);goto fim;}
   //delay_ms(1);

   if ((leitura_tensao<=358)&& (leitura_tensao>= 329)) { //130 a 120v
   leitura_conv = (read_adc()*  fm10);goto fim;}
  // delay_ms(1);

   if ((leitura_tensao<=328)&& (leitura_tensao>= 301)) { //120 a 110v
   leitura_conv = (read_adc()*  fm11);goto fim;}
   //delay_ms(1);

   if ((leitura_tensao<=300)&& (leitura_tensao>=272)) { // 110  a 100v
   leitura_conv = (read_adc()*  fm12);goto fim;}
  // delay_ms(1);

   if (leitura_tensao<=271) {  // menor que 100v
   leitura_conv = (read_adc()*  fm13);goto fim;}
   //delay_ms(1);

   //etc ...
   fim:
   
   //----------------apresentação do display----------------//
   
   delay_ms(500); //
   lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
   printf(lcd_dado,"%3lu",leitura_conv);  //Mostra a tensão medida
   }

   void corrente (void){
     
      delay_ms(100);
      set_adc_channel(1); // Canal  do ADC

      for(i=1;i<=5;i++){

         val = read_adc();

         if(val>dif_ADC){
         valor_anal += (val - dif_ADC);
         }else{
         valor_anal += (dif_ADC - val);
         }

         total_lidos++;

         delay_ms(1);
      }   

      valor_anal = valor_anal/total_lidos;     

      vlr_Analog0 = 0;
      vlr_Analog0 = (valor_anal*sensib_ADC);

      lcd_locate(1,8);
      printf(lcd_dado "%2.2f", vlr_Analog0);
      delay_ms(150);
   }

   //-------------------programa principal-----------------//
   
    void main(void)
    {     
           
      inicializa_lcd();

           
      setup_adc(ADC_CLOCK_DIV_8);
      setup_adc_ports(an0_an1_an3);            //###############Configura A/D //Primeiro configura o ADC_PORT, depois ADC_CLOCK
      //setup_adc(ADC_CLOCK_INTERNAL);
     // setup_adc(ADC_CLOCK_DIV_8); 

      delay_ms(10);
    /* 
      //Pega a média da tensão para o calculo
      set_adc_channel(1); // Canal  do ADC                                                   
      for(j=0;j<1000;j++){
         val = read_adc();
         VQ += val;
         delay_ms(1);
      }

      //Atualiza Vq de acordo com a tensão
      VQ = VQ/1000;
      dif_ADC = VQ;
           
      while(1)
      { 
      */
   
         //inicializa hw
lcd_locate(1,0);
printf(lcd_dado,"V=");

         lcd_locate(1,6);
         printf(lcd_dado,"A=");
     // }
    // for(;;)    {
         //Leitura ADC 0
        set_adc_channel(0);         
         delay_ms(30);

         leitura_tensao=read_adc();  // comentado tensao
         leitura_conv=leitura_tensao;
         lineariza_e_mostra();
         delay_ms(250);
       

         //Leitura ADC 1
       //  corrente();
         delay_ms(250);
      }
     // }
   
 //   }
    //-----------------fim---------------/
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como medir tensao e corrente ac com pic

Mensagempor eletroinf » 15 Jun 2015 08:11

O 712 é tranquilo de usar, saída = VCC/2 quando não há corrente passando pelo sensor. Se a corrente aumenta num sentido, a saída aumenta, do contrário diminui, em razão proporcional mV/Ampere conforme datasheet. Esta razão depende do fundo de escala do componente (tem versões de 20 A, 30 A, 10 A...).
"De cada um segundo sua capacidade a cada um segundo sua necessidade."
Avatar do usuário
eletroinf
Word
 
Mensagens: 842
Registrado em: 12 Out 2006 14:59
Localização: Santa Maria - RS

AnteriorPróximo

Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 2 visitantes