Power Factor Meansurement

Dear all,

I'm developing a system to measure the power factor between two waves and using a XOR to get the time between them.

The programming and the circuit seems fine but some times I get the power factor as 1 and I don't know from where it comes.

Below is the code that I developed and the proteus circuit.

/********************************************************
 * Aluno: Daniel Oliveira Barbosa
 * RA: 21485122
 * Curso: Engenharia Elétrica
 * Trabalho de Conclusão de Curso
 * Medidor de Fator de Potência
 * *******************************************************
 */

#include <LiquidCrystal.h> // Adiciona a biblioteca para o display LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // Define as pinagens nas quais o LCD será conectado

int sinal_4030 = 13; // Define o pino 13 como a entrada do sinal do CI 4030
float radianos = (180/PI); // Realiza a conversão de radianos para graus
float graus = 360; // Define como 360 o grau máximo para um período
float frequencia = 60; // Define a frequência do sistema
float periodo = (1/frequencia);// Define o período em microssegundos
unsigned long timeout = periodo*(1*pow(10,6));
int tensao = 220; // Define a tensão do sistema

float fp; // Define a variável fator de potência
float angulo; // Define a variável ângulo
int amostras; // Define uma variável de amostras
float duracao;
float duracao_ms;

void setup() {
  pinMode(sinal_4030, INPUT); // Define o pino sinal_4030 como entrada
  lcd.begin(16,2); // Inicia o LCD 16x2
}

void loop() 
{
  medicao_fp();
}

void medicao_fp()
{
    for (amostras = 0; amostras <= 10000; amostras++); // Colhe 10000 amostras do sinal
  {
    
    // Realiza o cálculo para encontrar o ângulo com a seguinte fórmula
    // angulo = ((duracao * 360)/(período))
    duracao = pulseInLong(sinal_4030, HIGH,10000000); // Colhe a duração do pulso de entrada
    duracao_ms = duracao/1000; // Realiza a conversão do pulso para milissegundos
    angulo = (((duracao_ms*graus)/periodo)/1000); // Calcula o ângulo conforme a equação do ângulo descrito
    fp = cos(angulo/radianos); // Calcula o fator de potência
    delay(500); // Aguarda o tempo de 0,5 segundo para a próxima iteração do laço for
   }
   lcd.print("FP ="); // Imprime na tela do LCD "FP ="
   lcd.setCursor(5,0); // Seleciona a posição 5,0 (col,lin) no LCD para imprimir "FP ="
   lcd.print(fp); // Imprime a variável fp
   lcd.setCursor(0,1); // Seleciona a posição 0,1 (col,1) no LCD para imprimir o valor do fp
   lcd.print("Angulo ="); // Imprime na tela do LCD "Angulo ="
   lcd.setCursor(9,1); // Seleciona a posição 9,1 (col,lin) no LCD para imprimir "Angulo ="
   lcd.print(angulo); // Imprime a variável angulo
   delay(1000);
   lcd.clear();
}

When you have any code line like this:

duracao_ms = duracao/1000; // Realiza a conversão do pulso para milissegundos

You will get a temporary integer result which will then be moved into the float duraco_ms.

So, change all similar calculations for be like this:

duracao_ms = duracao/1000.0; // Realiza a conversão do pulso para milissegundos

There are several in your program.

See if that helps.

Paul

I did the correction where I had to do it and the results remains the same.

I'll post the code with the changes and the result at proteus.

I don't know if it is an error in the pulseInLong function. I tried to use some kind of media of the values that I collect but without results as well.

Kind regards,
Daniel Oliveira Barbosa

/********************************************************
 * Aluno: Daniel Oliveira Barbosa
 * RA: 21485122
 * Curso: Engenharia Elétrica
 * Trabalho de Conclusão de Curso
 * Medidor de Fator de Potência
 * *******************************************************
 */

#include <LiquidCrystal.h> // Adiciona a biblioteca para o display LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // Define as pinagens nas quais o LCD será conectado

int sinal_4030 = 13; // Define o pino 13 como a entrada do sinal do CI 4030
float radianos = (180/PI); // Realiza a conversão de radianos para graus
int graus = 360; // Define como 360 o grau máximo para um período
int frequencia = 60; // Define a frequência do sistema
float periodo = (1/frequencia);// Define o período em microssegundos
unsigned long timeout = periodo*(1*pow(10,6));
int tensao = 220; // Define a tensão do sistema

float fp; // Define a variável fator de potência
float angulo; // Define a variável ângulo
int amostras; // Define uma variável de amostras
float duracao;
float duracao_ms;

void setup() {
  pinMode(sinal_4030, INPUT); // Define o pino sinal_4030 como entrada
  lcd.begin(16,2); // Inicia o LCD 16x2
}

void loop() 
{
  medicao_fp();
}

void medicao_fp()
{
    for (amostras = 0; amostras <= 10000; amostras++); // Colhe 10000 amostras do sinal
  {
    
    // Realiza o cálculo para encontrar o ângulo com a seguinte fórmula
    // angulo = ((duracao * 360)/(período))
    duracao = pulseInLong(sinal_4030, HIGH,10000000); // Colhe a duração do pulso de entrada
    duracao_ms = duracao/1000.0; // Realiza a conversão do pulso para milissegundos
    angulo = (((duracao_ms*graus)/periodo)/1000.0); // Calcula o ângulo conforme a equação do ângulo descrito
    fp = cos(angulo/radianos); // Calcula o fator de potência
    delay(500); // Aguarda o tempo de 0,5 segundo para a próxima iteração do laço for
   }
   lcd.print("FP ="); // Imprime na tela do LCD "FP ="
   lcd.setCursor(5,0); // Seleciona a posição 5,0 (col,lin) no LCD para imprimir "FP ="
   lcd.print(fp); // Imprime a variável fp
   lcd.setCursor(0,1); // Seleciona a posição 0,1 (col,1) no LCD para imprimir o valor do fp
   lcd.print("Angulo ="); // Imprime na tela do LCD "Angulo ="
   lcd.setCursor(9,1); // Seleciona a posição 9,1 (col,lin) no LCD para imprimir "Angulo ="
   lcd.print(angulo); // Imprime a variável angulo
   delay(1000);
   lcd.clear();
}

IF you were using a real Arduino with real power signals we might be able to debug your program, but Proteus, I have never seen or touched.

Can you tell me the formula you are trying to implement? To me the power factor is the time difference for zero crossing of the voltage sine wave and the current sine wave. I have to pay an electrical power bill every month with that factored in.

Paul