Como medir tensao e corrente ac com pic

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Re: Como medir tensao e corrente ac com pic

Mensagempor carlucio » 26 Mar 2015 23:10

Nem usando o formato a seguir, deu certo. Por 2 como o ze disse.

Agora os dados no display nem aparecem. E não e problema de hardware porque testei outro codigo. Simplesmente não aparece nada. Eu ja fiz uma tabela de linearização com 12 valores, mas o meu problema é pegar a conversão do ad, comparar dentros dos if's e depois fazer aparecer o valor no display.

So não sei onde esta o problema.

Trecho do codigo abaixo:

Código: Selecionar todos

int leitura_tensao_conv;
int leitura_tensao;
 
 
 
 void main(void)
 {     
           
      inicializa_lcd();                       //Chama função de inicialização lcd     
     
           
      setup_adc(ADC_CLOCK_DIV_8);             // Configura clock da conversão
      setup_adc_ports(RA0_ANALOG);            // Configura A/D
      set_adc_channel(0);                     // Lê a entrada 0

      while(1)
      { 
         leitura_tensao=read_adc();

if((leitura_tensao >=562)&& (leitura_tensao<=561)) // tensao maior ou igual 220v e menor ou igual a 210v
         leitura_tensao_conv = ((leitura_tensao * 99)>>8);
       
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3u",leitura_tensao_conv);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao >=560)&& (leitura_tensao<=544)){ // tensao maior ou igual 210v e menor ou igual a 200v
         leitura_tensao_conv = ((leitura_tensao * 97)>>8);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3u",leitura_tensao_conv);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao >=543)&& (leitura_tensao<=526)){ // tensao maior ou igual 200v e menor ou igual a 190v
         leitura_tensao_conv = ((leitura_tensao * 95)>>8);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3u",leitura_tensao_conv);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao >=525)&& (leitura_tensao<=509)){ // tensao maior ou igual 190v e menor ou igual a 180v
         leitura_tensao_conv = ((leitura_tensao * 95)>>8);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3u",leitura_tensao_conv);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao >=508)&& (leitura_tensao<=487)){ // tensao maior ou igual 180v e menor ou igual a 170v
         leitura_tensao_conv = ((leitura_tensao * 94)>>8);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3u",leitura_tensao_conv);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao >=486)&& (leitura_tensao<=464)){ // tensao maior ou igual 170v e menor ou igual a 160v
         leitura_tensao_conv = ((leitura_tensao * 93)>>8);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3u",leitura_tensao_conv);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao >=463)&& (leitura_tensao<=438)){ // tensao maior ou igual 160v e menor ou igual a 150v
         leitura_tensao_conv = ((leitura_tensao * 93)>>8);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3u",leitura_tensao_conv);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao >=437)&& (leitura_tensao<=411)){ // tensao maior ou igual 150v e menor ou igual a 140v
         leitura_tensao_conv = ((leitura_tensao * 93)>>8);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3u",leitura_tensao_conv);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao >=410)&& (leitura_tensao<=385)){ // tensao maior ou igual 140v e menor ou igual a 130v
         leitura_tensao_conv = ((leitura_tensao * 93)>>8);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3u",leitura_tensao_conv);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao >=384)&& (leitura_tensao<=359)){ // tensao maior ou igual 130v e menor ou igual a 120v
         leitura_tensao_conv = ((leitura_tensao * 93)>>8);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3u",leitura_tensao_conv);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao >=358)&& (leitura_tensao<=329)){ // tensao maior ou igual 120v e menor ou igual a 110v
         leitura_tensao_conv = ((leitura_tensao * 93)>>8);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3u",leitura_tensao_conv);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
                 
         
         if((leitura_tensao >=328)&& (leitura_tensao<=301)){ // tensao maior ou igual 110v e menor ou igual a 100v
         leitura_tensao_conv = ((leitura_tensao * 93)>>8);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3u",leitura_tensao_conv);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao >=300)&& (leitura_tensao<=272)){ // tensao maior ou igual 100v e menor ou igual a 90v
         leitura_tensao_conv = ((leitura_tensao * 93)>>8);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3u",leitura_tensao_conv);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         if((leitura_tensao <=272)){
         leitura_tensao_conv = ((leitura_tensao * 93)>>8); // tensao menor que 90v
                         
         delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3u",leitura_tensao_conv);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           


 }

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

Re: Como medir tensao e corrente ac com pic

Mensagempor ze » 27 Mar 2015 11:48

leitura_tensao_conv = ((leitura_tensao * 99)>>8); // o que vc pretendia com isso mesmo? 1/2 que nada a ver...

bom, esquece a conversão por enquanto. mostre no display o valor do ad quando em
0Vac
10
20
30
...
220Vac
Código: Selecionar todos
for(;;)
{
leitura_tensao=read_adc();
printf(lcd_dado,"%3u",leitura_tensao);
}

São 23 medições apenas (mas nem precisa disso tudo). Transfira os dados para o forum. Caso sejam lineares, bastará uma fórmula simples.
dica:1ªmente coloque em p.ex. 270Vac (ou sua máxima a ser medida) e ajuste o trimpot pra aparecer 1000..1020 no display
E nem toque mais no no trimpot!
É mole? Ou quer mais?
abç
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Re: Como medir tensao e corrente ac com pic

Mensagempor carlucio » 27 Mar 2015 16:23

Zé,

A formula usada
Código: Selecionar todos
eitura_tensao_conv = ((leitura_tensao * 99)>>8);
era a mesma coisa que
Código: Selecionar todos
    leitura_tensao_conv = ((leitura_tensao * 0.393));
.
Aprendi esta tecnica com o andre no projeto anterior meu do medidor de nivel com hcsr04. Esta tecnica é para dizer ao microcontrolador multiplicar por 0,393 sem utilizar o float.

A tabela da linearilização é essa abaixo:
Código: Selecionar todos
Vac                Vconvertida         ad         FM (fator de multiplicação)
220V                   2,74              561                   0.393   (220v / 561 )
210V                   2,66              544                   0.386
200V                   2,57              526                   0.380
190V                   2,47              509                   0,373
180V                   2,38              487                   0,370
170V                   2,27              464                   0,366
160V                   2,14              438                   0,365
150V                   2,01              411                   0,365
140V                   1,88              385                   0,364
130V                   1,75              359                   0,362
120V                   1,61              329                   0,365
110V                   1,47              301                   0,365
100V                   1,33              272                   0,368



Pode ver que o circuito "abaixador" é bem linear é eu ja via tentado uma formula que o valor saia no display mais acima de 15v a discrepância ficava alta.

A formula era essa.
Código: Selecionar todos
tensao=read_adc();
tensao= (tensao * 0.4);


Nos 220v ate 205v a diferença era de 3 a 5v. Voce acha que tem como usar uma formula simples, analizando a tabela acima?
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como medir tensao e corrente ac com pic

Mensagempor MOR_AL » 27 Mar 2015 16:27

Olha!
Dei uma rápida olhada em seu código. Não estou por dentro do CCS, mas conheço um pouco de matemática.
Acho que você está verificando, dentro dos IFs
Se Resultado da conversão for maior ou igual a um valor máximo E menor ou igual a um valor mínimo...
Isso nunca entrará dentro dos IFs
Veja se é isso.

Teria que ser...
Se Resultado da conversão for menor ou igual a um valor máximo E maior ou igual a um valor mínimo...
MOR_AL
"Para o triunfo do mal só é preciso que os bons homens não façam nada." Edmund Burke.
"Nunca discutas com pessoas estúpidas. Elas irão te arrastar ao nível delas e vencê-lo por possuir mais experiência em ser ignorante". Mark Twain
Avatar do usuário
MOR_AL
Dword
 
Mensagens: 2934
Registrado em: 19 Out 2006 09:38
Localização: Mangaratiba - RJ

Re: Como medir tensao e corrente ac com pic

Mensagempor ze » 27 Mar 2015 21:02

ah é. entendi . agora tudo a ver.

O bom é se vc conseguisse linearizar no circuito mesmo como é feito nos multimetros quando medem ac. Alguns cliques e vc deve achar. Eu mesmo já fiz isso há séculos com lm324. Como já disse, usei um ampop diferencial e um amplificador ideal que me deram o valor linear padrãozinho. Esquema? como disse o amigo kraft .. é para os fracos.

Bom, baseando-se na sua tabela, daria até pra deduzir mentalmente uma fórmula maluca, caso eu não tivesse bebido todas hoje. (ou é por isso que estou vendo ela meia distorcida na parede balançando)
Mas acho que se vc alimentar o excel com ela, consegue vislumbrar algo. Coloque os demais dados pra vc ver que bacana que fica. O gráfico te dá noção visual do que corrigir. Pode até ajudar voce montar a tabela ou fórmula. Depois vc faz o ad em 8 bits e indexa os 255 dados a partir do resultado ad

Mas antes analisa a teoria do moris...

hic!
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Re: Como medir tensao e corrente ac com pic

Mensagempor carlucio » 29 Mar 2015 00:26

Ze e moral,


Futricando e modificando consegui o display me mostrar 2 situaçoes : uma delas e que se a tensao ac de entrada oscilar de 0V a 215v o display agora me mostra o valor de conversão do ad (eu não planejei ter feito isso) e a outra situação e que se aumentar o variac e tensão ultrapassar os 215 a 222v o display mostra a tensão com um erro de +/- 2%.

ainda não consegui descobrir o porque do valores abaixo de 215v aparecerem os valores ad do pic. Fiz a modificação que o moral viu e exclui o seguinte detalhe:

exlcui do codigo este trecho
float leitura_tensao_conv;
e modiquei esta parte
leitura_tensao = ((leitura_tensao)* 0.393);
,
ficando a parte dos if da seguinte maneira:
Código: Selecionar todos
 if((leitura_tensao <=562)&& (leitura_tensao>=544)) // tensao maior ou igual 220v e menor ou igual a 210v
         leitura_tensao = ((leitura_tensao)* 0.393);
       
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3.1f",leitura_tensao);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           



Estou precisando de ajuda para tentar descobrir o que esta de errado ainda



Segue um video em anexo:

Lembrando:
* multimetro amarelo (VAC de entranda do circuito atenuador (variac) )
* multimetro azul (VCC convertida do circuito atenuador)
* display que deveria estar mostrando a mesma tensão ou proxima de VAC de entrada ( tensão da rede eletrica)







O codigo completo abaixo:



Código: Selecionar todos
#include <16F876A.h>
//#include "lcd.c"
#device adc=10
#include "lcd.c"
#use delay(clock=4000000)
#fuses xt,nolvp,nowdt



 
 
 //float leitura_tensao_conv;
float leitura_tensao;
 
 
 
 void main(void)
 {     
           
      inicializa_lcd();                       //Chama função de inicialização lcd     
     
           
      setup_adc(ADC_CLOCK_DIV_8);             // Configura clock da conversão
      setup_adc_ports(RA0_ANALOG);            // Configura A/D
      set_adc_channel(0);                     // Lê a entrada 0

      while(1)
      { 
         leitura_tensao=read_adc();
         
         if((leitura_tensao >=563)){  // tensao maior que 220v
         leitura_tensao = ((leitura_tensao)* 0.393);
         
         delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3.1f",leitura_tensao);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         if((leitura_tensao <=562)&& (leitura_tensao>=544)) // tensao maior ou igual 220v e menor ou igual a 210v
         leitura_tensao = ((leitura_tensao)* 0.393);
       
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3.1f",leitura_tensao);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao <=543)&& (leitura_tensao>=526)){ // tensao maior ou igual 210v e menor ou igual a 200v
         leitura_tensao = ((leitura_tensao) * 0.386);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3.1f",leitura_tensao);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao <=525)&& (leitura_tensao>=509)){ // tensao maior ou igual 200v e menor ou igual a 190v
         leitura_tensao = ((leitura_tensao) * 0.380);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3.1f",leitura_tensao);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao <=508)&& (leitura_tensao>=487)){ // tensao maior ou igual 190v e menor ou igual a 180v
         leitura_tensao = ((leitura_tensao) * 0.373);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3.1f",leitura_tensao);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao <=486)&& (leitura_tensao>=464)){ // tensao maior ou igual 180v e menor ou igual a 170v
         leitura_tensao = ((leitura_tensao) * 0.370);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3.1f",leitura_tensao);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao <=463)&& (leitura_tensao>=438)){ // tensao maior ou igual 170v e menor ou igual a 160v
         leitura_tensao = ((leitura_tensao) * 0.366);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3.1f",leitura_tensao);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao <=437)&& (leitura_tensao>=411)){ // tensao maior ou igual 160v e menor ou igual a 150v
         leitura_tensao = ((leitura_tensao) * 0.365);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3.1f",leitura_tensao);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao <=410)&& (leitura_tensao>=385)){ // tensao maior ou igual 150v e menor ou igual a 140v
         leitura_tensao = ((leitura_tensao) * 0.365);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3.1f",leitura_tensao);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao <=384)&& (leitura_tensao>=359)){ // tensao maior ou igual 140v e menor ou igual a 130v
         leitura_tensao = ((leitura_tensao) * 0.364);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3.1f",leitura_tensao);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao <=358)&& (leitura_tensao>=329)){ // tensao maior ou igual 130v e menor ou igual a 120v
         leitura_tensao = ((leitura_tensao) * 0.362);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3.1f",leitura_tensao);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
         if((leitura_tensao <=328)&& (leitura_tensao>=301)){ // tensao maior ou igual 120v e menor ou igual a 110v
         leitura_tensao = ((leitura_tensao) * 0.365);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3.1f",leitura_tensao);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
                 
         
         if((leitura_tensao <=300)&& (leitura_tensao>=272)){ // tensao maior ou igual 110v e menor ou igual a 100v
         leitura_tensao = ((leitura_tensao) * 0.368);
         
          delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3.1f",leitura_tensao);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           
         
         
       
               
         
         if((leitura_tensao <=272)){
         leitura_tensao = ((leitura_tensao) * 0.368); // tensao menor que 90v
                         
         delay_ms(3000);
         lcd_locate(1,0);
         printf(lcd_dado,"V=");
         lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
         printf(lcd_dado,"%3.1f",leitura_tensao);  //Mostra a tensão medida

         lcd_locate(2,0);
         printf(lcd_dado,"Monitorando...");
      }           


 }




No aguardo de uma nova orientação
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como medir tensao e corrente ac com pic

Mensagempor ze » 30 Mar 2015 11:07

isso pode não ajudar diretamente mas pode deixar o fonte e código mais enxuto.
Código: Selecionar todos
unsigned int leitura_tensao;//global
//...
void lineariza_e_mostra(void)
{
leitura_tensao=adcread();
if (leitura_tensao>=544) {(float)(leitura_tensao)*= 0.393;goto fim;}
if (leitura_tensao>=526) {(float)(leitura_tensao)*= 0.386;goto fim;}
if (leitura_tensao>=509) {(float)(leitura_tensao)*= 0.380;goto fim;}
//etc ...
fim:
delay_ms(3000); //que perda de tempo do carai
lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
printf(lcd_dado,"%3.1f",leitura_tensao);  //Mostra a tensão medida
}
void main(void)
{
//inicializa hw
lcd_locate(1,0);
printf(lcd_dado,"V=");
//etc
for(;;)
{
leitura_tensao=adcread();
lineariza_e_mostra();
}
}

ou algo do gênero

ok amigo. Agradeço a gentil m.p. Mas que tal deixar público? no futuro pode não ser totalmente inútil pra algum navegante...
esqueçamos fórmulas que não deve dar muito certo pra este mc. Agora me diga se teve mais algum progresso com a técnica acima...

Bom mas que tal se focarmos no hw? Mais um coisa que pode fazer é tirar aquele led do seu circuito e refazer as medições. Pode ficar mais linear ainda.

Ao googlar em converter ac em dc, achei o anexo. Como não deu pra linkar, salvei e cliquei em "adicionar um anexo" logo abaixo (tendeu?). Pode ser que dê um resultado melhor. Pode ser um lm324 alimentado com +5 e -5 (talvez um pouco +). Aplique o ac dividido por uns 20 depois do trafo na entrada E1. Me lembro vagamente de ter feito algo deste jeito.

E não esquenta com seu nível técnico. A divagar se vai ao longe. Afinal estamos aqui pra aprender juntos. Quanto a mim? só sei que nada sei
abç
Você não está autorizado a ver ou baixar esse anexo.
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Re: Como medir tensao e corrente ac com pic

Mensagempor carlucio » 01 Abr 2015 08:40

Ze,

Estou testando primeiro o codigo para depois tentar o circuito com amplificador.
No circuito que voce me repassou, o compilador não apareceu erro, mas apreceu em cada linha que tem >= (10linhas) a mensagem de warning com a seguir:

variable of this data type is never greater than this constant = variável deste tipo de dados nunca é maior do que esta constante
condition always false = condição sempre falsa


Tambem apresentou erro na apresentanção do display na parte do %3.1f, sendo que não erra este especificador que deveria usar (segundo o compilador) entao usei o %u e os dados que sao apresentados no display agora so variam de 0 a 255 independente do valor de tensao de entrada.

Veja o video abaixo:



Vou espera ver se encontro uma maneira correta de se usar o codigo abaixo e por enquanto vou testando o circuito com o amplificador repassado anteriormente sem o uc.

Código: Selecionar todos
#include <16F876A.h>

#device adc=10
#include "lcd.c"
#use delay(clock=4000000)
#fuses xt,nolvp,nowdt

 
unsigned int leitura_tensao;//global
 
 
 
void lineariza_e_mostra(void)
{
leitura_tensao=read_adc();


if (leitura_tensao<=561) {(float)(leitura_tensao)*= 0.393;goto fim;}
if (leitura_tensao>=544) {(float)(leitura_tensao)*= 0.386;goto fim;}
if (leitura_tensao>=526) {(float)(leitura_tensao)*= 0.380;goto fim;}
if (leitura_tensao>=509) {(float)(leitura_tensao)*= 0.373;goto fim;}
if (leitura_tensao>=487) {(float)(leitura_tensao)*= 0.370;goto fim;}
if (leitura_tensao>=464) {(float)(leitura_tensao)*= 0.366;goto fim;}
if (leitura_tensao>=438) {(float)(leitura_tensao)*= 0.365;goto fim;}
if (leitura_tensao>=411) {(float)(leitura_tensao)*= 0.365;goto fim;}
if (leitura_tensao>=385) {(float)(leitura_tensao)*= 0.364;goto fim;}
if (leitura_tensao>=359) {(float)(leitura_tensao)*= 0.362;goto fim;}
if (leitura_tensao>=329) {(float)(leitura_tensao)*= 0.365;goto fim;}
if (leitura_tensao>=301) {(float)(leitura_tensao)*= 0.365;goto fim;}
if (leitura_tensao>=272) {(float)(leitura_tensao)*= 0.368;goto fim;}


fim:
 
delay_ms(3000); //que perda de tempo do carai
lcd_locate(1,2);                     //Posiciona o cursor na segunda linha
printf(lcd_dado,"%3u",leitura_tensao);  //Mostra a tensão medida ----------->>>> modificado aqui
}


 
 void main(void)
 {     
           
      inicializa_lcd();                       //Chama função de inicialização lcd     
     
           
      setup_adc(ADC_CLOCK_DIV_8);             // Configura clock da conversão
      setup_adc_ports(RA0_ANALOG);            // Configura A/D
      set_adc_channel(0);                     // Lê a entrada 0

      while(1)
      { 
         {
//inicializa hw
lcd_locate(1,0);
printf(lcd_dado,"V=");
//etc
for(;;)
{
leitura_tensao=read_adc();
lineariza_e_mostra();
}
}
      }
 }



Os graficos anteriormente falados estao em anexo abaixo:
Você não está autorizado a ver ou baixar esse anexo.
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como medir tensao e corrente ac com pic

Mensagempor ze » 01 Abr 2015 09:58

Veja se a saída do adcread() é um unsigned int mesmo. Se for unsigned char é por isso o warning e 0 e 255. Sinto não poder ajudar ccsmente nisso. Chutadamente tente mudar os tipos para o tal int16
Também tem um errinho nosso
if (leitura_tensao<=561) {(float)(leitura_tensao)*= 0.393;goto fim;} tem que ser ">"
cá não consegui ver o video. + tarde tento em casa
Mas vc está no caminho certo. Quanto a mim, só Deus sabe.
abç
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Re: Como medir tensao e corrente ac com pic

Mensagempor carlucio » 04 Abr 2015 17:31

ZE e amigos,


Aparentemente acha que consegui alguma coisa :D . Ver o video abaixo.




O problema agora reside na tensão que normalmente ele vai ficar trabalhando que seria em torno de 210V, que é geralmente a tensao que recebo aqui minha regiao . Quando esta neste valor o display esta oscilando 210 ou 214 direto. Ainda não consengui resolver esta situação. :(

210v.jpg



227v.jpg





Ze ainda tambem vou testar com o circuito que voce me mandou com amplicador para ver o resultado de linearização do circuito.


Nos valores abaixo de 100 ate 40 e praticamente fiel ao que é apresentado no display, abaixo disso a discrepancia ja é grande como tambem acima de 220v a discrepancia chega a te 5v.



O pulo do gato foi nesta parte aqui. :idea:
leitura_conv=(read_adc()* fm1);goto fim;}


em conjunto com as constantes desta maneira:
float fm = 0.393;
float fm1 =0.393;
float fm2 =0.386;
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;


O codigo abaixo de como ficou:


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

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

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

//-------------constantes de conversão----------------------//

float fm = 0.393;
float fm1 =0.393;
float fm2 =0.386;
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_tensao=read_adc();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

//-------------------programa principal-----------------//
 
 void main(void)
 {     
           
      inicializa_lcd();                       //Chama função de inicialização lcd     
     
           
      setup_adc(ADC_CLOCK_DIV_8);             // Configura clock da conversão
      setup_adc_ports(RA0_ANALOG);            // Configura A/D
      set_adc_channel(0);                     // Lê a entrada 0

      while(1)
      { 
         {
//inicializa hw
lcd_locate(1,0);
printf(lcd_dado,"V=");

//etc
for(;;)
{
leitura_tensao=read_adc();
leitura_conv=leitura_tensao;
lineariza_e_mostra();
}
}
      }
 }
 
 
 
 //-----------------fim---------------//





Agora a primeira parte esta quase pronta (ler tensao alternada) faltando agora aprender um maneira de colocar um alarme por exemplo se tensao cair abaixo de 200v desligar / ligar um rele e so retornar (desligar / ligar) quanto a tensao estiver acima de 200v.

E depois de conseguindo tentar fazer a leitura de corrente com o acs712 de 30 amperes com o pic (com o arduino ja achei tanto coisa, mas é extremamente dificil achar um programa com este modulo com qualquer pic).

Ze muito obrigado pela parte de ter enxugado o codigo anterior que havia postado, ficou mais facil enxergar e descobrir algo. Ha e tambem pelas outras dicas :wink:
Você não está autorizado a ver ou baixar esse anexo.
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como medir tensao e corrente ac com pic

Mensagempor andre_luis » 04 Abr 2015 18:52

carlucio escreveu:Quando esta neste valor o display esta oscilando 210 ou 214 direto


O vídeo está dificiel de entender, pois a claridade do backlight do disply está tirando todo o contraste.
De qualquer modo, sem saber se há algum ripple do sinal lido no A/D não da pra saber muita coisa.
Já verificou no osciloscópio a forma de onda ?

Código: Selecionar todos
leitura_tensao=read_adc();


Outro detalhe é que voce não está tirando a média dos valores lidos, o que poderia garantia uma estabilidade extra nos valores. Um filtro passa-baixa implementado por uma média móvel poderia fazer isso. Nesse caso, experimenta algo desse tipo:

Substitui a linha acima pela chamada á função abaixo ( não testado ):

cpp code
unsigned int function_leitura_tensao ( void )
{
int valor_saida ;
static int media_leitura = 0 ;
static int media_anterior = 0 ;
static char cont = 0 ;
static int buffer_leitura [4] ; // média para 4 leituras consecutivas

buffer_leitura [cont+1] = read_adc();
buffer_leitura [cont] = buffer_leitura [cont+1] ;
media_leitura += buffer_leitura [cont] ;
if ( cont < 4 )
{
cont++ ;
}
else
{
media_anterior = media_leitura / 4 ;
media_leitura = 0 ;
cont = 0 ;
}
valor_saida = media_anterior ;
return ( valor_saida ) ;
}


Deve ter um modo mais simples de fazer isso...
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Como medir tensao e corrente ac com pic

Mensagempor ze » 05 Abr 2015 14:25

... e tem
Código: Selecionar todos
unsigned int read_media_adc()
{
unsigned int ad=0;
unsigned char i=4; //pra média de 4 leituras consecutivas (...8,16,32)
while(i--) {ad+=adcread();delay(xxx);}//um tempinho entre uma e outra
return ad/4;
}


Isso fica na ram e ocupa um espaço precioso
Código: Selecionar todos
float fm = 0.393;
float fm1 =0.393;
float fm2 =0.386;
float fm3 =0.380;
...

Tente...
Código: Selecionar todos
#define fm 0.393
#define fm1 0.393
#define fm2 0.386
#define fm3 0.380
...

Mesmo assim sugiro usar aquele macete do andré com ">>" pra trabalhar com unsigned int

Fico feliz por participar de seu sucesso parcial.
Abç e outros.
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Re: Como medir tensao e corrente ac com pic

Mensagempor carlucio » 08 Abr 2015 14:37

Caro andre e ze,


Voces deram uma sugestão pra mim fazer uma tentativa para melhorar a leitura de tensao no conversor ad do pic.

So que não entendi onde é pra implementar esta sugestão de voces.
É pra substituir o
leitura_tensao=read_adc();
por este trecho de codigos que voces postaram anteriormente?
O restante abaixo (os if de comparação) continuam?
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como medir tensao e corrente ac com pic

Mensagempor ze » 09 Abr 2015 12:15

bom acho que é tipo assim
Código: Selecionar todos
leitura_tensao=read_media_adc();

Que vai fazer a média de algumas leituras num determinado intervalo de tempo. Por isso que sugeri o delay(xxx) que pode ser de algumas dezenas de mS.
Mas o efeito da função acima é semelhante ao de um capacitor xute 10uF na entrada do pino ad do mc. Por hora não se ligue muito nela. Continue seus testes
abç
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Re: Como medir tensao e corrente ac com pic

Mensagempor carlucio » 21 Abr 2015 23:08

Desculpe a demora em postar novamente mas a tal da dengue ta acabando com o povo.

Ainda testando e ja querendo partir para outra parte, queria pedir a ajuda para medir corrente com o acs712 de 30A.
Ja andei vasculhando na internet e a unica publicacão para microcontrolador pic que achei foi esta abaixo no link. O resto que vi na pesquisa é tudo so de arduino.

http://embedded-lab.com/blog/?p=4529


Não entendi no caso a formula que ele usou, e por isso ainda nem tentei fazer algum tipo de adaptação.
Sera que alguem me da uma orientação?

No link acima o codigo esta em micro c.
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

AnteriorPróximo

Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

cron

x