Ir ao conteúdo
  • Cadastre-se
Ernandes Sousa

Medidor de fator de potência com arduino

Recommended Posts

Ernandes,

Não conheço nenhum circuito pronto, mas não é difîcil de se fazer, basta observar que o fator de potência indica a defasagem da corrente em relação à tensão.

Uma maneira seria colocar uma pequena carga resistiva em série e medir 2 grandezas simultâneas : a tensão da rede e a tensão sobre a carga. Calcular a diferença de fase entre elas deve ser exatamente o fator de potência ( se eu ainda me lembro bem disso .... ).

Ou medir diretamente a corrente na carga e a tensão na carga, e calcular a defasagem entre elas......

Vamos ver se aparece mais alguma sugestão.

OBS : Achei um projeto interessante :

http://portal.fke.utm.my/fkelibrary/files/kuhendransoravandran/2012/372_KUHENDRANSORAVANDRAN2012.pdf

Paulo

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Prezados Senhores,

 

Hoje, depois de muito tempo da dúvida o Ernandes, estou enfrentando o mesmo problema que ele...

 

Preciso apresentar a minha faculdade um protótipo capaz de ler e corrigir o fator de potência de uma carga (140Ω + 300mH), e de detectar a sobrecorrente.

 

Ao longo do tempo que estou trabalhando nesse projeto, tentei pesquisar em várias fontes acadêmicas e tentei encontrar formas de resolver isso na minha própria faculdade, mas infelizmente, a impressão que tenho é que as pessoas, do meu convívio, que tem domínio de programação em C, são extremamente fechadas a compartilhar seus conhecimentos, se for alguém que tenha bons conhecimentos em C, somado a conhecimentos com Potências, essas então...

 

Pois bem, melancolias a parte, vamos ao que interessa:

 

Para isso estou usando um TC (SCT-013 - 20A/1V) e um sensor de tensão GPK-P8.

 

É somente isso que está permitido.

 

Considerando que a Potencia Ativa (W) é dada pela fórmula P=V.I.CosPhi, sem um Wattímetro, não encontro a possibilidade de executar a leitura do CosPhi, encontrando o fator de potência pelo método indireto.

 

Meu domínio do inglês é bastante restrito, o que me impede de consultar com afinco o forum arduino.cc, qual me desmotivou a finalizar esse projeto, mas então resolvi retormar e lembrei desse fórum.

 

Pois bem, minhas maiores dificuldades nesse momento são:

 

- EXECUTAR A LEITURA DO CosPhi, USANDO APENAS UM VOLTIMETRO E UM AMPERIMETRO;

 

       Definindo a detecção do CosPhi, acho que consigo montar a formula para detecção dos demais itens.


- CRIAR OS MENUS DOS POSSÍVEIS NÍVEIS DE CORRENTE USANDO O Switch

 

Tenho uma grande dificuldade para criar menus e submenus, a maioria deles, consigo criar, mas não consigo fazer com que ele volte ao nível acima.

 

Abaixo, estou colocando meu programa basicamente na íntegra, estou tirando apenas algumas informações pessoais e itens que definem a faculdade.


Muitas das soluções que encontrei, são adaptações de configurações que eu li na internet.

 

Se alguém pode me orientar, ficarei muito grato:
 

#include "EmonLib.h" 
#include <LiquidCrystal.h>
LiquidCrystal BEP(52,50,53,51,49,47);
EnergyMonitor emon1;

int SAC = analogRead(A0); //SAC = Sensor de tensão AC

//declaração de variáveis para o relé
int releCAP = 46; // Define pino do RELÉ DO CAPACITOR
int releGERAL = 48; // Define pino do RELÉ GERAL

// Informa o pino do sensor SCT-013 20A/1V
  int pino_sct = A1;

float fundoEscala = 0.030;

//****************INICIO DAS FUNCOES DO TECLADO********************

//variávies (posições na memória)

char tecla=0;
byte case2=1;
byte limite=3;

//*********** FUNÇÕES DO TECLADO *****************
// ESSE PROGRAMA DISPENSA O USO DE UMA BIBLIOTECA PARA O TECLADO

void teclado()      /*Função para teclado matricial
                    A linguagem C, permite o uso do número entre apóstrofes para manter o padrão da TABELA ASCII, portanto esse programa não foge a tabela padrão.
                    Se for usada em PIC, deve alterar para o padrão de programação DECIMAL, BINÁRIO ou HEXADECIMAL, conforme tabela ASCII*/

{ //INICIO DA FUNÇÃO

// definir os pinos de saída como nível alto.

 digitalWrite(31,HIGH);
 digitalWrite(33,HIGH);
 digitalWrite(35,HIGH);
 digitalWrite(37,HIGH);

// Varredura de linha 1
 digitalWrite(31,LOW);
 if (digitalRead(39)==LOW) {tecla='1';return;}// UM
 if (digitalRead(41)==LOW) {tecla='2';return;}// DOIS
 if (digitalRead(43)==LOW) {tecla='3';return;}// TRES
 if (digitalRead(45)==LOW) {tecla='A';return;}// A
digitalWrite(31,HIGH);
//**************************
 
// Varredura de linha 2
 digitalWrite(33,LOW);
 if (digitalRead(39)==LOW) {tecla='4';return;}// QUATRO
 if (digitalRead(41)==LOW) {tecla='5';return;}// CINCO
 if (digitalRead(43)==LOW) {tecla='6';return;}// SEIS
 if (digitalRead(45)==LOW) {tecla='B';return;}// B
digitalWrite(33,HIGH);
//**************************

// Varredura de linha 3
 digitalWrite(35,LOW);
 if (digitalRead(39)==LOW) {tecla='7';return;}// SETE
 if (digitalRead(41)==LOW) {tecla='8';return;}// OITO
 if (digitalRead(43)==LOW) {tecla='9';return;}// NOVE
 if (digitalRead(45)==LOW) {tecla='C';return;}// C
digitalWrite(35,HIGH);
//**************************

// Varredura de linha 4
 digitalWrite(37,LOW);
 if (digitalRead(39)==LOW) {tecla='*';return;}// *
 if (digitalRead(41)==LOW) {tecla='0';return;}// ZERO
 if (digitalRead(43)==LOW) {tecla='#';return;}// #
 if (digitalRead(45)==LOW) {tecla='D';return;}// D
digitalWrite(37,HIGH);
//*********************

tecla=' '; // Considera que o teclado não está acionado
//**************************

} // FINAL DA FUNÇÃO

//******************FINAL DAS FUNCOES DO TECLADO************************


void setup()
{
Serial.begin(9600);               // Ativa o serial para funcionar a porta analogica
  pinMode(releCAP, OUTPUT);         // Declara pino do rele1 como saída
  pinMode(releGERAL, OUTPUT);         // Declara pino do rele2 como saída     
  pinMode(releCAP, LOW);           // Define o início em nível baixo
  pinMode(releGERAL, LOW);           // Define o início em nível baixo     
  BEP.begin(16,2);                // Ativa o LCD
  emon1.current(pino_sct, 24);    /* Essa é a calibração da constante da corrente.*/

//*********INICIO DO PROGRAMA QUE ATIVA O TECLADO***************

// definição das linhas como saída
 pinMode(31,OUTPUT);
 pinMode(33,OUTPUT);
 pinMode(35,OUTPUT);
 pinMode(37,OUTPUT);
// definição das colunas como entrada
// ativação dos resistores de pull up do Arduíno
// exemplo:
//    pinMode(39,INPUT); considera o pino como entrada
//    digitalWrite(6,HIGH); informa ao Arduíno que se não estiver nenhuma entrada, considerar com nível alto.
 pinMode(39,INPUT);digitalWrite(39,HIGH);
 pinMode(41,INPUT);digitalWrite(41,HIGH);
 pinMode(43,INPUT);digitalWrite(43,HIGH);
 pinMode(45,INPUT);digitalWrite(45,HIGH);

//*********FINAL DO PROGRAMA QUE ATIVA O TECLADO***************
  }

void loop()
{
teclado();    //Carrega o programa do teclado
switch(tecla) //variável que trás informações
// INICIO DOS MENUS

// INICIO DO CASE "0"
   
   {    // ESSA CHAVE INICIA OS CASES
      
      case ' ': //aqui é dois pontos
                // Esse case lê que o teclado não foi acionado.
         BEP.setCursor(0,0);BEP.print("B1-AC   B3-COR");
         BEP.setCursor(0,1);BEP.print("B2-FP   B4-S.COR");

      break; 

// INICIO DO CASE "1"

        case '1':           //DEFINE O BOTÃO QUE FOI ACIONADO
          BEP.clear();      // Limpa LCD
          while(case2==1)   // ele considera o zero
          {
              pinMode(releGERAL,HIGH);
              float Irms = emon1.calcIrms(1480);     // Calculo da Corrente RMS
              int SAC = analogRead(A0);
              int Pap = (SAC*Irms);         // POTENCIA APARENTE (VA)
              int Pat = (Pap*(Irms*Irms));  // POTENCIA ATIVA (W)
              Serial.println(SAC);
              delay(1000); 
              BEP.clear();
              BEP.setCursor(0,0);
              BEP.print("AC");
              BEP.setCursor(0,1);
              BEP.print(SAC);
              BEP.setCursor(5,0);
              BEP.print("A");
              BEP.setCursor(4,1);
              BEP.print(Irms);
              BEP.setCursor(9,0);
              BEP.print("VA");
              BEP.setCursor(9,1);
              BEP.print(Pap,1); // O Argumento "1" é limitador o limitador de casas decimais exibidas.
              BEP.setCursor(13,0);
              BEP.print("'D'");
              BEP.setCursor(13,1);
              
              teclado();
              if(tecla=='D')                {case2=0;}
              }// ESSA CHAVE FECHA O WHILE DO CASE 1
              pinMode(releGERAL,LOW);
          case2=1;
          BEP.clear();
          break;
// FINAL DO CASE "1"

// INICIO DO CASE "2"

        case '2':           //DEFINE O BOTÃO A SER ACIONADO
          BEP.clear();      //Limpa LCD
          while(case2==1)   // ele considera o zero
          
          { // ESSA CHAVE PERTENCE AO CASE 2
            
 float Irms = emon1.calcIrms(1480);     // Calculo da Corrente RMS

    pinMode(releGERAL,HIGH); //ACIONA O RELÉ PARA LEITURA DA TENSÃO DE REDE
    
      if (Irms <= fundoEscala) 
        { //CHAVE DO IF        
        BEP.clear();BEP.setCursor(0,0);BEP.print("SEM LEITURA OU");BEP.setCursor(0,1);BEP.print("INFERIOR A 30mA");
        } // CHAVE DO IF
  
  else{
    
    int SAC = analogRead(A0);
    int Pap = (SAC*Irms);         // POTENCIA APARENTE (VA)
    int Pat = (Pap*(Irms*Irms));  // POTENCIA ATIVA (W)
    Serial.println(SAC);
    delay(1000); 
    BEP.clear();
    // Exibe a corrente (A)
    BEP.setCursor(0,0);
    BEP.print("A:");
    BEP.print(Irms, 3);   // O Argumento "3" é limitador o limitador de casas decimais exibidas.
    // Exibe o valor da Potência em Volt-Amperes (VA)
    BEP.setCursor(9,0);
    BEP.print("W: ");
    BEP.print((Pat), 1);   // O Argumento "1" é limitador o limitador de casas decimais exibidas.
    //Exibe o Fator de Potência
    BEP.setCursor(0,1);
    BEP.print("FP:");
    BEP.print((Pat)/(Pap));   // O Argumento "1" é limitador o limitador de casas decimais exibidas.
    // Retorna
    BEP.setCursor(8,1);
    BEP.print("   D-RET");
    delay(50); 
    }// ESSA CHAVE FECHA O ELSE
                       teclado();
                       if(tecla=='D')                {case2=0;}
                       }      // ESSA CHAVE FECHA O CASE 2 - VERIFICAR SE É NECESSÁRIO
          pinMode(releGERAL,LOW); // DESLIGA A REDE POR SEGURANÇA
          case2=1;
          BEP.clear();
          break;

// INICIO DO PROGRAMA PARA CORRIGIR A CARGA - CASE 3

          case '3':           //DEFINE O BOTÃO A SER ACIONADO
          BEP.clear();      //Limpa LCD
          pinMode(releGERAL,HIGH); //LIGA O RELE GERAL
          while(case2==1)   // ele considera o zero
          {// aA CHAVE ABAIXO PERTENCE AO CASE 3
          float Irms = emon1.calcIrms(1480);     // Calculo da Corrente RMS
          if (Irms <= fundoEscala)
          { //CHAVE DO IF        
          BEP.clear();BEP.setCursor(0,0);BEP.print("SEM LEITURA OU");BEP.setCursor(0,1);BEP.print("INFERIOR A 30mA");
          } // CHAVE DO IF
  
          else
          {
          int SAC = analogRead(A0);
          int Pap = (SAC*Irms);         // POTENCIA APARENTE (VA)
          int Pat = (Pap*(Irms*Irms));  // POTENCIA ATIVA (W)
          Serial.println(SAC);
          delay(1000); 
          BEP.clear();
          BEP.setCursor(0,0);
          BEP.print("AC: ");
          BEP.print(SAC);
          BEP.print("V");
          BEP.setCursor(0,1);
          BEP.print("I:");
          BEP.print(Irms, 3);   // O Argumento "3" é limitador o limitador de casas decimais exibidas.
          BEP.print("A");
          BEP.setCursor(8,0);
          BEP.print("FP:");
          BEP.print((Pat)/(Pap), 1);   // O Argumento "1" é limitador o limitador de casas decimais exibidas.
          BEP.setCursor(13,0);
          BEP.print("'D'");
          BEP.setCursor(8,1);
          BEP.print("   A-COR");
          delay(50);
          } // ESSA CHAVE FECHA O ELSE
                       teclado();
                       if(tecla=='A')    {
                                          //NÃO ESTOU ENCONTRANDO A CONDIÇÃO CERTA PARA SAIR DESSA TELA
                                          while(case2==1)
                                          {
                                          pinMode(releCAP,HIGH);
                                          int SAC = analogRead(A0);
                                          int Pap = (SAC*Irms);         // POTENCIA APARENTE (VA)
                                          int Pat = (Pap*(Irms*Irms));  // POTENCIA ATIVA (W)
                                          Serial.println(SAC);
                                          BEP.clear();
                                          BEP.setCursor(0,1);
                                          BEP.print("F.P.:");
                                          BEP.print((Pat)/(Pap), 1);
                                          BEP.setCursor(0,0);
                                          BEP.print("F.P. CORRIGIDO");
                                          delay(2000);
                                          BEP.setCursor(0,0);
                                          BEP.print("140ohms + 300mH");
                                          delay(2000);
                                          if(tecla=='D')    {case2=0;}
                                          } // FECHA O WHILE
                                          } // FECHA O IF DA TECLA A
                       if(tecla=='D')    {case2=0;}
          } // ESSA CHAVE FECHA O CASE 3
          pinMode(releGERAL,LOW); // DESLIGA A REDE POR SEGURANÇA
          pinMode(releCAP,LOW);   // DESLIGA O CAPACITOR POR SEGURANÇA
          case2=1;
          BEP.clear();
          break;

// FINAL DO PROGRAMA PARA CORRIGIR O FATOR DE POTENCIA DA CARGA

// INICIO DO CASE "4" - SOBRECORRENTE

case '4':           //DEFINE O BOTÃO QUE FOI ACIONADO
          BEP.clear();      // Limpa LCD
          while(case2==1)   // ele considera o zero
          {
              pinMode(releGERAL,HIGH);
              float Irms = emon1.calcIrms(1480);     // Calculo da Corrente RMS
              int SAC = analogRead(A0);
              int Pap = (SAC*Irms);         // POTENCIA APARENTE (VA)
              int Pat = (Pap*(Irms*Irms));  // POTENCIA ATIVA (W)
              Serial.println(SAC);
              delay(1000); 
              BEP.clear();
              BEP.setCursor(0,0);
              BEP.print("Corrente: ");
              BEP.print(Irms);
              BEP.print("A");
              BEP.setCursor(13,1);
              BEP.print("'D'");
               
              teclado();
              // NÃO CONSEGUI DEFINIR OS MENUS
              /*if(tecla=='A')    {pinMode(releCAP,HIGH);
                                          BEP.clear();
                                          BEP.setCursor(0,0);
                                          BEP.print("F.P. CORRIGIDO");
                                          BEP.setCursor(0,1);
                                          BEP.print("CARGA 140Ω+300mH");
                                          delay(1000);
                                          }*/
              if(tecla=='D')                {case2=0;}
              }// ESSA CHAVE FECHA O WHILE DO CASE 1
              pinMode(releGERAL,LOW);
          case2=1;
          BEP.clear();
          break;

// FINAL DO CASE "4"
                    
  } // ESSA CHAVE FECHA OS CASES
  } // ESSA CHAVE FECHA O VOID LOOP, FINAL DO PROGRAMA

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Kamus Of Aquarius ,

 

Veja neste post :

 

Quase ao final eu postei uma simulação no Proteus, com o código fonte em linguagem Basic, onde meço o fator de potência e mostro em um display.

 

Você tem de ficar lendo tanto o sensor de tensão, como o sensor de corrente, para ver os instantes em que cada um deles passa por uma inversão de polaridade, essa diferença de tempo é a que te fornece o angulo de fase ok ?

 

Paulo

Compartilhar este post


Link para o post
Compartilhar em outros sites
10 minutos atrás, aphawk disse:

@Kamus Of Aquarius ,

 

Veja neste post :

 

Quase ao final eu postei uma simulação no Proteus, com o código fonte em linguagem Basic, onde meço o fator de potência e mostro em um display.

 

Você tem de ficar lendo tanto o sensor de tensão, como o sensor de corrente, para ver os instantes em que cada um deles passa por uma inversão de polaridade, essa diferença de tempo é a que te fornece o angulo de fase ok ?

 

Paulo

 

 

Vou analisar e posto o resultado.

 

Obrigado...

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
6 horas atrás, Kamus Of Aquarius disse:

 

 

Vou analisar e posto o resultado.

 

Obrigado...

 

 

 

É meu amigo... Visualizei tudo...

 

É muito legal como tudo funciona corretamente no Protheus.

 

Fiz a simulação, só precisei indicar ao microcontrolador onde estava o arquivo de máquina, pois o Protheus estava apontando para seu diretório local.

 

Simulei e vi o funcionamento.

 

Acessei o código fonte e está em linguagem de baixo nível, como infelizmente sou inciante na área de programação, muita, mas muita coisa não entendi como funciona, poucos comandos achei semelhantes ao C, pois os endereçamentos são diferentes.

 

Não que eu nunca tivesse visto isso anteriormente, mas não tenho familiaridade nenhuma.

 

Contudo, agradeço sua partilha e foi ótima a experiência de ver tudo funcionando no Protheus.

 

Forte abraço....

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá, boa tarde.

 

Kamus, que a Deusa Athena nos abençoe. Se você reduzir seu problema de medição de fator de potência ao de medição de defasagem entre formas de onda, seu trabalho fica muito simples. Você vai precisar de:

 

1. Um circuito para detectar a passagem pelo zero da forma de onda da tensão, como os desse tópico. A diferença pro seu projeto é que você só precisa detectar quando a tensão passa do negativo para o positivo. Não consegui achar nada sobre o sensor que você citou mais acima. O circuito deste link deve servir, ligado a uma porta digital do arduino.

 

2. Um circuito pra detectar a passagem pelo zero do sinal de corrente. Para o seu sensor, o pessoal do Emmonlib disponibiliza uns circuitos de exemplo, como este aqui. Para o seu sensor, o resistor indicado como Burden já está integrado ao sensor, convertendo a corrente de secundário na tensão (esse 1V que você descreveu). Você pode montar esse circuito e ligar em uma das portas analógicas do arduino.

 

3. O algoritmo a seguir: depois de realizar o setup, o código fica esperando por uma transição do nível 0 (LOW) para o nível 1 (HIGH) na porta do detector de tensão. Quando isso acontecer, você marca o tempo com a função micros, guardando o valor em uma variável (tempo1). O segundo passo é esperar a corrente transitar do negativo para o positivo. Com o circuito da emmonlib, você espera que a transição ocorra de uma tensão menor que 2.5V para uma tensão maior que 2.5V. Quando isso ocorrer, marque o tempo com a função micros e guarde o valor em uma segunda variável (tempo2). Use a diferença tempo2-tempo1 para calcular o fator de potência.

 

A função micros do Arduino retorna o tempo decorrido desde quando o microcontrolador foi ligado em microssegundos. A diferença tempo2-tempo1 equivale à quantidade de tempo passada entre os dois eventos que descrevi acima.

 

Uma senoide em 60Hz possui como período 16666 us. Metade disso são 8333 us. Se você medir 8333 us na diferença tempo2-tempo1, você tem FP = 0. Se a diferença for 0 us, FP = 1. Valores intermediários podem ser obtidos com regra de três. O FP assim medido, para defasagens entre 0 e 8333us, é classificado como indutivo. Se a diferença ficar entre 8333 e 16666us, o FP é capacitivo. Favor verificar a veracidade disto.

 

Devo alertá-lo que este método não é perfeito, funcionando apenas com cargas lineares, por exemplo. Caso a corrente de carga seja muito pequena, você terá problemas para identificar corretamente as transições. Não me preocupei com circuitos de proteção para o Arduino, um diodo zener de 5V entre a porta analógica e o terra pode ser útil, por exemplo. Caso esteja disposto, recomendo ler este material da Atmel: link aqui. Neste link, eles sugerem uma forma diferente para calcular o fator de potência, mostram um circuito completo e indicam como deve ser o código. O código pronto pode ser encontrado no google, mas não possuo o link.

 

Espero ter ajudado. Outras questões, como a programação em Arduino, podem ser resolvidas com buscas ao Google.

 

Esta postagem pode conter erros. caso os encontre, favor alertar através de comentários.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Kamus Of Aquarius ,

 

Opa, bom que te serviu para alguma coisa !

 

Mas não concordo com "linguagem de baixo nível" por não se tratar de C.... baixo nível é Assembly, o Basic do Bascom possui comandos de nível mais alto do que o C, pois tratam diretamente o hardware dos mirocontroladores, evitando que eu tenha de ficar configurando os registradores um a um para fazer o hardware funcionar como eu preciso. Isto sim , é baixo nível, não importa em qual linguagem seja feito !

 

Mas se você precisar de alguma informação sobre o que o programa faz, é só perguntar, ok ?

 

Paulo

 

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

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

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×