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 MOR_AL » 22 Abr 2015 20:12

O cara simplesmente substituiu a segunda equação (Vin) na primeira equação (Count).
Depois ele colocou em evidência a variável I.
Não li, mas parece que o sensor apresenta uma tensão quiescente igual a Vcc/2. Deve ser para poder tanto medir correntes positivas (acima de Vcc/2) como negativas (abaixo de Vcc/2).
A expressão que ele achou está relacionada com o valor da conversão de 10 bits. Caso a medida da tensão do CAd seja 512, então significa que a tensão do sensor era de Vcc/2, ou zero de corrente. I = qualquer coisa vezes (512 - 512) = 0A
Se a tensão desse zero, o resultado da conversão seria I = 0,0264 ( 0 - 512) = -13,52A
Se o resultado da conversão fosse 1024, que corresponde a 5V na entrada, o valor de I seria
I = 0,0264 (1024 - 512) = 0,0264 x 512 = +13,52A

Depois o cara fugiu de operação em ponto flutuante.
Em vez de multiplicar por 0,0264, multiplicou por 264, ou seja; além de inteiro, fornece o resultado multiplicado por 10.000. Isso faz com que os dígitos do lado direito da vírgula apareçam como inteiros.
Depois para corrigir, ele divide por 10 e o outro fator 1000 ele obtém dividindo o algarismo das centenas por 1000. O algarismo das dezenas por 100 e o algarismo das unidades por 10. Posso ter escorregado em algum zero a mais ou a menos, mas foi o que o cara fez. Eu já usei esta técnica com sucesso. Economiza bastante linhas de instruções e tempo de processamento, pois em vez de usar operações com ponto flutuante, usa operações com inteiros.
Acho que o 48 que ele introduziu foi para trocar o dígito (valor numérico do algarismo) pelo endereço do dígito na tabela ASCII.

... E eu nem gostaria de ver o outro lado da placa do cara. Acho que até aranha se perderia no emaranhado de fios que deve haver. Hehehe!

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 » 23 Abr 2015 08:47

amigo dengoso, ele usou os conceitos que te passamos aqui

ADC_Value = ADC_Read(0); //uma
ADC_Value = ADC_Value + ADC_Read(0); //duas
ADC_Value = ADC_Value + ADC_Read(0); //três
ADC_Value = ADC_Value/3; //média das três leituras anteriores
temp = (ADC_Value-512)*Factor ; //512 pra ele é 0A, o circuito provavelmente usa vcc/2 como referência, o factor 264 é o lance que o moris explicou
ADC_Value = temp/10;//ajusta pra mostrar no display
Display(ADC_Value);//mostra

Então, pelo que percebemos, o acs712 faz o trabalho sujo e te dá o valor linearzinho bunitinho bastando multiplicar por factor
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 » 24 Abr 2015 15:57

Caros Ze e moral,

Ate que entendi bem a parte que se refere-se a media de leituras para se apresentar o valor. O problema mesmo meu e que não entendi onde ele achou os 264. Estes 264 refere-se a saida do acs712 de 5A que é de 185mv /Ampere. Não entendi como ele chegou a esse valor. Creio que se compreender a maneira do calculo( para o acs712 de 30A a saida é de 66mv / ampere) conseguirei fazer o mesmo ler corrente.

Veja o quadro dos calculos abaixo:

Imagem


Alguem entendeu que possa me explicar?
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como medir tensao e corrente ac com pic

Mensagempor MOR_AL » 27 Abr 2015 18:30

carlucio escreveu:Caros Ze e moral,

Ate que entendi bem a parte que se refere-se a media de leituras para se apresentar o valor. O problema mesmo meu e que não entendi onde ele achou os 264. Estes 264 refere-se a saida do acs712 de 5A que é de 185mv /Ampere. Não entendi como ele chegou a esse valor. Creio que se compreender a maneira do calculo( para o acs712 de 30A a saida é de 66mv / ampere) conseguirei fazer o mesmo ler corrente.


Alguem entendeu que possa me explicar?


Siga o procedimento da minha explicação no post anterior que você chega lá direitinho. Mas tem que fazer para entender.

Repetindo:

O cara simplesmente substituiu a segunda equação (Vin) na primeira equação (Count).
Depois ele colocou em evidência a variável I.

Matemática elementar do segundo grau.
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 carlucio » 05 Mai 2015 14:26

Moral,

Infelizmente ate agora não consegui entender como o cara chegou ao 264, substiuindo valores e separando as equações não consegui chegar nesse fator de 264. Consegui valores bem distantes deste 264.

Diante disso passei para tentar um outra formula ou melhor adaptar uma formula do arduino para o pic.

o codigo do arduino é este abaixo:

Código: Selecionar todos
int sensorPin =A0;
 
int sensorValue_aux = 0;
float sensorValue = 0;
float currentValue = 0;
float voltsporUnidade = 0.004887586;// 5%1023
 
void setup() {
  Serial.begin(9600);
  pinMode(sensorPin, INPUT);
}
 
void loop() {
 
  for(int i=100; i>0; i--){
    sensorValue_aux = (analogRead(sensorPin) -511); // le o sensor na pino analogico A0 e ajusta o valor lido ja que a saída do sensor é (1023)vcc/2 para corrente =0
    sensorValue += pow(sensorValue_aux,2); // somam os quadrados das leituras.
  }
 
  sensorValue = (sqrt(sensorValue/ 100)) * voltsporUnidade; // finaliza o calculo da méida quadratica e ajusta o valor lido para volts
  currentValue = (sensorValue/66)*1000; // calcula a corrente considerando a sensibilidade do sernsor (66 mV por amper)
 
  // mostra o resultado no terminal
  Serial.print(currentValue,3);
  Serial.print(" A \n" );
 
  sensorValue =0;
 
  delay(100);
 
}




Diante do codigo acima fiz umas adaptaçoes para tentar usar com o pic sendo a parte principal esta abaixo:


inclusão nas variaveis globais de :
Código: Selecionar todos

int i;
#define  sensor_corrente pin_a1
float sensorValue_aux =0;
float sensorValue =0;
float currentValue =0;
float voltsporunidade = 0.0048828125;





para calcular a corrente ficou assim :

Código: Selecionar todos
for (i=100; i>0; i--)
{
sensorValue_aux = (read_adc()-511);
sensorValue += pow (2,sensorValue_aux);

sensorValue = (sqrt(sensorValue/500) * voltsporunidade);
currentValue = (sensorValue/66)*1000;



lcd_locate(1,8);                     //
printf(lcd_dado,"%2f",currentValue);





Minha duvida agora persiste em saber de que maneira eu declaro para o microcontrolador fazer a leitura de 2 canais analogicos.

Segue abaixo o codigo completo:

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;
int i;
#define  sensor_corrente pin_a1
float sensorValue_aux =0;
float sensorValue =0;
float currentValue =0;
float voltsporunidade = 0.0048828125;

//-------------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_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 linha
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(an0_an1_an3);            // Configura A/D
      set_adc_channel(0);         // Lê a entrada 0
      delay_ms(10);
      set_adc_channel(1);
      delay_ms(10);

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

lcd_locate(1,6);
printf(lcd_dado,"A=");

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


for (i=100; i>0; i--)
{
sensorValue_aux = (read_adc()-511);
sensorValue += pow (2,sensorValue_aux);

sensorValue = (sqrt(sensorValue/500) * voltsporunidade);
currentValue = (sensorValue/66)*1000;



lcd_locate(1,8);                     //Posiciona o cursor na segunda linha
printf(lcd_dado,"%2f",currentValue);

}

      }
     
 }
 //-----------------fim---------------//



Acredito eu ainda que deve ter alguma coisa acima errada. Quando simulo no proteus sem utilizar a parte de tensao uma leitura erronea da corrente pelo que vi esta sendo direcionada para o canal an0. Então como faço leitura em 2 canais analogicos?
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como medir tensao e corrente ac com pic

Mensagempor andre_luis » 05 Mai 2015 22:19

carlucio escreveu:Minha duvida agora persiste em saber de que maneira eu declaro para o microcontrolador fazer a leitura de 2 canais analogicos


Voce está selecionando o canal 1 do A/D apenas na inicialização, e ainda assim essa configuração é sobreposta por outros comandos que retornam a configuração ao canal 0. Em suma, está lendo e salvando apenas o canal 0.

O 16F876A possui apenas um S/H, o que significa que precisa fazer o processo completo de leitura e conversão pra cada canal.

cpp code
set_adc_channel(0);         // Lê a entrada 0
delay_ms(10);
set_adc_channel(1);
delay_ms(10);
"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 » 07 Mai 2015 16:08

vc pode escolher o canal e sair com resultado na mesma função. Mais eficiente.
Código: Selecionar todos
unsigned int adc_read(unsigned char channel)
{
    ADCON0 = (channel << 3) + 0x81;     // enable ADC, fosc/32
    delay(20);
    ADGO = 1;
    while(ADGO)
        continue;   // wait for conversion complete
    return ADRESH*256 + ADRESL;
}
...
//p.ex.
corrente=(adc_read(0)*50)/x;
tensao=(adc_read(1)*50)/y;
temperatura=(adc_read(2)*50)/z;
...

Para entender 100% vc teria que sujar as mãos dando uma olhadela no d.s. Faça sua escolha, caminho largo ou estreito
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 » 11 Mai 2015 19:40

Ze,

Este trecho de codigo que voce postou é para o ccs? mikro c ou hitech? Com relação ao datasheet do pic16f876a, não consiguo entender muito ate no que se refere a dois canais analogicos do pic, não encontrei esta informação lá.


Andre,

Tentei fazer a implementação do trecho do codigo que voce postou. Mas veja o video abaixo do que esta acontecendo:



O certo seria 2,5v indicar zero amperes, com um valor no adc de 611 o display deveria mostrar um corrente de acima de 1A sem mostrar valor negativo.
E tambem no lcd, coloquei duas casas antes de depois da virgula, mas não se acontecendo isso no codigo. Porque?
O que esta errado ver 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;
//int i;
#define  sensor_corrente pin_a1
float sensorValue_aux =0;
float sensorValue =0;
float currentValue =0.00;
float voltsporunidade = 0.0048828125;

//-------------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_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 linha
printf(lcd_dado,"%3lu",leitura_conv);  //Mostra a tensão medida
}

void corrente (void){

int i;

for (i=100; i>0; i--)
{
sensorValue_aux = (read_adc()-511);
sensorValue += pow (2,sensorValue_aux);

sensorValue = (sqrt(sensorValue/500) * voltsporunidade);
currentValue = (sensorValue/66)*1000;



lcd_locate(1,8);                     //Posiciona o cursor na segunda linha
printf(lcd_dado,"%2.2f",currentValue);

}
}




//-------------------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(an0_an1_an3);            // Configura A/D
 //     set_adc_channel(0);         // Lê a entrada 0
  //    delay_ms(10);
  //    set_adc_channel(1);
  //    delay_ms(10);

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

lcd_locate(1,6);
printf(lcd_dado,"A=");

//etc
for(;;)
{
set_adc_channel(0);         // Lê a entrada 0
      delay_ms(10);

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

set_adc_channel(1);
      delay_ms(10);
corrente();
}
}


tambem no proteus esta aparecendo uma mensagem que é a seguinte:

ADC conversion started before wait time has expired following previous conversion or channel change


O que isso esta querendo dizer?
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como medir tensao e corrente ac com pic

Mensagempor carlucio » 12 Mai 2015 11:18

Este é o erro que esta acontecendo no proteus.

ja pesquisei na internet e não consegui entender o que quer dizer. Alguem sabe o que é isto quer dizer?


erro proteus.pptx
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 » 12 Mai 2015 12:14

é hitech.
Prestenção nos bits...
Imagem
bit5,4,3 seleciona o canal. Por isso o "channel<<3"
0x81 = 0b10000001 ou seja velocidade F/32 e liga o AD
dá um tempinho delay(20);
Mandamos disparar a conversão ADGO=1; //status BIT2
e esperamos ela terminar while (ADGO); //espera sair do 1
fádimai da conta uai.
Por isso que sempre digo que dar uma olhadela no datashit não dói muito. Os mastigados do compilador te engessam um pouco.
O proteus está chiando porque acha que vc disparou o ad antes dele terminar a conversão. Vc deve dar um tempinho entre uma conversão e outra (por isso o delay(20). Deixa de ser afobado sô!
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 » 12 Mai 2015 23:30

Sobre os bits acima da tabela do datasheet acho que o ccs me diz dessa forma abaixo:

// Constants used in SETUP_ADC_PORTS() are:
#define NO_ANALOGS 7 // None
#define ALL_ANALOG 0 // A0 A1 A2 A3 A4
#define AN0_AN1_AN2_AN4_VSS_VREF 3 // A0 A1 A2 A4 VRefh=A3
#define AN0_AN1_AN3 4 // A0 A1 A3
#define AN0_AN1_VSS_VREF 5 // A0 A1 VRefh=A3
#define AN0_AN1_AN4_VREF_VREF 0x08 // A0 A1 A4 VRefh=A3 VRefl=A2
#define AN0_AN1_VREF_VREF 0x0D // A0 A1 VRefh=A3 VRefl=A2
#define AN0 0x0E // A0
#define AN0_VREF_VREF 0x0F // A0 VRefh=A3 VRefl=A2
#define ANALOG_RA3_REF 0x1 //!old only provided for compatibility
#define RA0_RA1_RA3_ANALOG 0x4 //!old only provided for compatibility
#define RA0_RA1_ANALOG_RA3_REF 0x5 //!old only provided for compatibility
#define ANALOG_RA3_RA2_REF 0x8 //!old only provided for compatibility
#define RA0_RA1_ANALOG_RA3_RA2_REF 0xD //!old only provided for compatibility
#define RA0_ANALOG 0xE //!old only provided for compatibility
#define RA0_ANALOG_RA3_RA2_REF 0xF //!old only provided for compatibility



Como sao duas entradas por isso que usei a 4 opção acima para poder utilizar 2 canais analogicos, pensando +/- no que voce quis me passar so que em um outra linguagem diferente.

Agora o proteus ta chiando eu tentei mudar algumas linhas mas não encontrei ainda o problema, que me parece estar neste trecho abaixo.

O problema continua ainda igual o video acima.
Código: Selecionar todos
//-------------------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(an0_an1_an3);            // Configura A/D
 

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

lcd_locate(1,6);
printf(lcd_dado,"A=");

//etc
for(;;)
{
set_adc_channel(0);         // Lê a entrada 0
      delay_ms(10);

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

set_adc_channel(1);
      delay_ms(10);
corrente();
delay_ms(250);
}
}



Eu não declarei trisX neste codigo, sera que isso influencia? Os canais setados deveriam aparecer abaixo do setup_ports(an0_an1_an3) ? Existe problema de ser colocados dentro deste "for" conforme exemplo acima no trecho do codigo?
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como medir tensao e corrente ac com pic

Mensagempor ze » 13 Mai 2015 15:07

percebo que vc chama readadc()...
leitura_tensao=read_adc(); // ... aqui e logo em seguida ...
leitura_conv=leitura_tensao;
lineariza_e_mostra(); //...aqui (lá dentro)
não precisa e não deve. Coloque a cabeç... ops... as coisas no lugar. Voce está chegando lá!!
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 » 22 Mai 2015 23:52

Zé,

Andei alterando e checando o que voce falou mas ficou pior a situação.

Não encontrei a solução do problema do proteus e vejo que agora o canal An0 esta com algum problema que não entendi, pois o mesmo quando altero o potenciometro simulando uma tensão diferente na entrada (no proteus), ele demora mais de 10 segundos para atualizar, sendo que quando retiro o segundo canal analogico o mesmo volta a funcionar imediamente como era.

Ainda continua a mensagem:

ADC conversion started before wait time has expired following previous conversion or channel change


Não encontrei na net ou alguem que explique que problema é esse que aparece no proteus que esta acontecendo na pratica.

Codigo é esse 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;
//int i;
#define  sensor_corrente pin_a1
float sensorValue_aux =0;
float sensorValue =0;
float currentValue =0.00;
float voltsporunidade = 0.0048828125;

//-------------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_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(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){

int i;

for (i=100; i>0; i--)
{
currentValue = (read_adc()-512)*0.059;
//sensorValue_aux =  (read_adc()-511);
//sensorValue += pow (2,sensorValue_aux);

//sensorValue = (sqrt(sensorValue/500) * voltsporunidade);
//currentValue = ((sensorValue/66)*1000);
//sensorValue_aux = currentValue;


lcd_locate(1,8);                     //Posiciona o cursor na segunda linha
printf(lcd_dado,"%2.2f",currentValue);
//sensorValue=0;
delay_ms(150);
}
}




//-------------------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(an0_an1_an3);            // Configura A/D
 //     set_adc_channel(0);         // Lê a entrada 0
   //  delay_us(20);
   //  set_adc_channel(1);
   //  delay_us(20);

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

lcd_locate(1,6);
printf(lcd_dado,"A=");

//etc
for(;;)
{
set_adc_channel(0);         // Lê a entrada 0
      delay_ms(30);

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

set_adc_channel(1);
      delay_ms(30);
corrente();
delay_ms(250);
}
}


//for (i=100; i>0; i--)
//{
//sensorValue_aux = (read_adc()-511);
//sensorValue += pow (2,sensorValue_aux);

//sensorValue = (sqrt(sensorValue/500) * voltsporunidade);
//currentValue = (sensorValue/66)*1000;



//lcd_locate(1,8);                     //Posiciona o cursor na segunda linha
//printf(lcd_dado,"%2f",currentValue);

//}





      }
     
     
 }
 //-----------------fim---------------//




Esperando ajuda pra entender o que esta errado.
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como medir tensao e corrente ac com pic

Mensagempor andre_luis » 23 Mai 2015 10:43

carlucio escreveu:
ADC conversion started before wait time has expired following previous conversion or channel change


Voce não informou em que linha do código está ocorrendo esse erro, mas meu palpite é que o motivo se deve ao fato de voce estár fazendo uma série de conversões do A/D consecutivas, sem dar um intervalo entre cada uma, como por exemplo no trecho abaixo:

Código: Selecionar todos
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;}


Experimente colocar um delay entre cada avaliação acima, que deve resolver.
"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 carlucio » 23 Mai 2015 17:39

Andre coloquei 1ms entre as conversoes e continua o problema, veja o anexo. Nem ajustei a pagina para ficar melhor de se enchergar o que esta escrito.
problema isis proteus.pptx



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;
//int i;
#define  sensor_corrente pin_a1
float sensorValue_aux =0;
float sensorValue =0;
float currentValue =0.00;
float voltsporunidade = 0.0048828125;

//-------------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_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){

int i;

for (i=100; i>0; i--)
{
currentValue = (read_adc()-512)*0.059;
//sensorValue_aux =  (read_adc()-511);
//sensorValue += pow (2,sensorValue_aux);

//sensorValue = (sqrt(sensorValue/500) * voltsporunidade);
//currentValue = ((sensorValue/66)*1000);
//sensorValue_aux = currentValue;
delay_ms(1);

lcd_locate(1,8);                     //Posiciona o cursor na segunda linha
printf(lcd_dado,"%2.2f",currentValue);
//sensorValue=0;
delay_ms(150);
}
}




//-------------------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(an0_an1_an3);            // Configura A/D
 

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

lcd_locate(1,6);
printf(lcd_dado,"A=");

//etc
for(;;)
{
set_adc_channel(0);         // Lê a entrada 0
      delay_ms(30);

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

set_adc_channel(1);
      delay_ms(30);
corrente();
delay_ms(250);
}
}



      }
     
     
 }
 //-----------------fim---------------//




Você não está autorizado a ver ou baixar esse anexo.
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: Google [Bot] e 1 visitante

x