Como medir corrente trifásica no Arduino?

Pessoal, espero que encontre uma ajuda aqui com vocês.
Estou tentando desenvolver um monitoramento online de correntes de um motor trifásico. Já olhei em diversos sites, já olhei diversos fóruns, mas pelo que vi, ninguém nestes sites e fóruns obteve sucesso na leitura trifásica com Arduino.
Vou listar aqui as minhas tentativas:
1°) Declarei 3 instâncias distintas para EnergyMonitor:
EnergyMonitor emon1;
EnergyMonitor emon2;
EnergyMonitor emon3;

Daí declarei 3 correntes a serem medidas
Double Irms1;
Double Irms2;
Double Irms3;

Fiz a calibração para meu circuito com um resistor de carga de 150k, o que faz com que tenha um fator de calibração 2000 enrolamentos/150k = 13.333

No setup então eu calibrei o sensor para cada entrada analógica:
emon1.current(A0, 13.333);
emon2.current(A1, 13.333);
emon3.current(A2, 13.333);

Então entra o cálculo da corrente propriamente dito:
Irms1 = emon1.calcIrms(1996);
Irms2 = emon2.calcIrms(1996);
Irms3 = emon3.calcIrms(1996);

1996 é o valor correto a ser aplicado em medições de redes 60Hz, normalmente vemos o valor 1480, que é para 50Hz.

Pois bem... neste caso somente uma corrente é lida, as demais ficam em ZERO ou valores próximos a ZERO.

2°) Declarei as instâncias como vetor:
EnergyMonitor emon[4];

Daí declarei 3 correntes a serem medidas:
Double Irms1;
Double Irms2;
Double Irms3;

No setup então eu calibrei o sensor para cada entrada analógica:
emon[0].current(A0, 13.333);
emon[1].current(A1, 13.333);
emon[2].current(A2, 13.333);

Então entra o cálculo da corrente propriamente dito:
Irms1 = emon[0].calcIrms(1996);
Irms2 = emon[1].calcIrms(1996);
Irms3 = emon[2].calcIrms(1996);

Não deu certo também, acredito que quando transformei em vetor peguei pedaços do valor da instância, pois gerou medições sem sentido.

3°) Declarei somente uma instância para 3 correntes:
EnergyMonitor emon1;

Daí declarei 3 correntes a serem medidas
Double Irms1;
Double Irms2;
Double Irms3;

No setup então eu calibrei o sensor para cada entrada analógica:
emon1.current(A0, 13.333);
emon1.current(A1, 13.333);
emon1.current(A2, 13.333);

Então entra o cálculo da corrente propriamente dito:
Irms1 = emon1.calcIrms(1996);
Irms2 = emon1.calcIrms(1996);
Irms3 = emon1.calcIrms(1996);

4°) Pensando que possivelmente o tempo pudesse ser um problema na medição de tantas correntes, eu fiz todas as tentativas acima colocando uma variável de contagem que fazia com que somente um sensor fosse lido por vez em cada loop, mais ou menos assim:

Declarei int looping = 0;

looping;
if (looping > 2){
looping = 0;
}
else{
looping;
}

switch (looping){
case 0:
Irms1 = emon[0].calcIrms(1996);
break;
case 1:
Irms2 = emon[1].calcIrms(1996);
break;
case 2:
Irms3 = emon[2].calcIrms(1996);
break;
}
}

Neste caso vai variando o valor de looping e mede somente a corrente ligada ao valor Irms de 0 a 2.

Como podem ver, tentei até coisas que eu sabia que daria errado, mas para saturar tudo que eu podia, eu tentei de tudo para ver se dava a sorte de acertar no que eu achava que era errado rs.

Educadamente, solicito o apoio dos "universitários" neste caso, pois tenho um trabalho importantíssimo para finalizar e não consigo. Estressei tudo que eu pude imaginar antes de vir gerar um questionamento. Olhei também alguns posts aqui no fórum, mas nenhum conseguiu fazer essas 3 correntes serem medidas.

Obrigado!

Que biblioteca estás a utilizar? Eu vejo alguns exemplos com essas funções, mas não consigo fazer download dessa biblioteca em específico.

Podes tentar uma chamada EmonLib (também da OpenEnergyMonitor).

Quando a medires as três fases do motor, qual é o propósito da medição? O motivo é que se queres detectar fase entre as correntes vai ser difícil porque o Arduino não mede as três ao mesmo tempo, logo é preciso um pouco mais de teste para acertar exactamente com as medições. Se apenas queres ver se há uma fase que está sobrecarregada, isso deve funcionar bem.

Coloca também o código todo aqui para ver se existirá algo mais que está a causar problemas.

Desculpe, esqueci de informar! Estou utilizando a Emonlib.h. Se souber outra que seja melhor, posso tentar aprender a mesma.

Estou querendo medir as 3 fases de 2 motores elétricos de dois compressores de uma central de ar condicionado para fazer monitoramento online via protocolo modbus que joga os dados em um banco de dados MySQL. Esse banco de dados eu espelho no Grafana para que a gente comece a fazer manutenções baseadas na condição do equipamento. Essa parte do código de comunicação está funcionando tudo normal, só a medição das correntes que só aparece em um único medidor ou replica todas as medições iguais a da primeira medição.

Serei extremamente grato se souber como resolver este problema ou verificar alguma falha no código. Eu preciso criar um histórico de medições corretas da corrente para que no futuro entremos com uma inteligência artificial para tomar ações, mas em princípio preciso enxergar as correntes para ver se há ou não alguma alteração em alguma das fases do compressor, o que implicaria que o equipamento está com algum problema mecânico a ser corrigido pela equipe de manutenção.

DESDE JÁ AGRADEÇO!

Segue tudo do código referente a parte da medição de correntes (Deixei a outra opção comentada "/* ... */"):

/____________________________________________________________________________________________
/////////////////////////////////////////////////////DADOS INICIAIS/////////////////////////
____________________________________________________________________________________________
/

/////////////////////////////////////////////////////SELECAO DE DEBUG//////////////////////////
#define DEBUG //Habilita o monitor serial para debugar

/////////////////////////////////////////////////////BIBLIOTECAS//////////////////////////////
#include <EmonLib.h> //Habilita a biblioteca do sensor SCT-013-000 para medicao de corrente

/////////////////////////////////////////////////////DEFINICOES DO SENSOR DE CORRENTE//////
#define sctPin1 A0 //Define o pino de entrada do sensor
#define sctPin2 A1
#define sctPin3 A2
#define sctPin4 A3
#define sctPin5 A4
#define sctPin6 A5

//EnergyMonitor i[7];
EnergyMonitor emon1;
EnergyMonitor emon2;
EnergyMonitor emon3;
EnergyMonitor emon4;
EnergyMonitor emon5;
EnergyMonitor emon6;
//int contagem_corrente1 = 0;
//int contagem_corrente2 = 0;

typedef struct
{
double Irms1;//variavel que traz a corrente de cada sensor
double Irms2;
double Irms3;
double Irms4;
double Irms5;
double Irms6;
} dados;
dados Quadro;

void setup() {
// put your setup code here, to run once:
Serial.begin(115200); //Inicia o monitor serial

pinMode(sctPin1, INPUT); //Sei que não é necessário declarar pinos analógicos, mas coloquei para ver se mudava alguma coisa: Não deu certo!
pinMode(sctPin2, INPUT);
pinMode(sctPin3, INPUT);
pinMode(sctPin4, INPUT);
pinMode(sctPin5, INPUT);
pinMode(sctPin6, INPUT);

emon1.current(sctPin1, 13.333);
emon2.current(sctPin2, 13.333);
emon3.current(sctPin3, 13.333);
emon4.current(sctPin4, 13.333);
emon5.current(sctPin5, 13.333);
emon6.current(sctPin6, 13.333);
}

void loop() {
// Compressor 01
Quadro.Irms1 = emon1.calcIrms(1996);//Para 50Hz 1480 e para 60Hz 1996
Quadro.Irms2 = emon2.calcIrms(1996);
Quadro.Irms3 = emon3.calcIrms(1996);

Serial.print("Irms1 = ");
Serial.println(Quadro.Irms1);
Serial.print("Irms2 = ");
Serial.println(Quadro.Irms2);
Serial.print("Irms3 = ");
Serial.println(Quadro.Irms3);

// Compressor 2
Quadro.Irms4 = emon4.calcIrms(1996);
Quadro.Irms5 = emon5.calcIrms(1996);
Quadro.Irms6 = emon6.calcIrms(1996);

Serial.print("Irms4 = ");
Serial.println(Quadro.Irms4);
Serial.print("Irms5 = ");
Serial.println(Quadro.Irms5);
Serial.print("Irms6 = ");
Serial.println(Quadro.Irms6);

// Outra opcao testada no codigo
//comp1();
//comp2();
}

/*void comp1(){
contagem_corrente1;
if (contagem_corrente1 > 2){
contagem_corrente1 = 0;
}
else{
contagem_corrente1;
}
switch (contagem_corrente1){
case 0:
//Quadro.Irms1 = i[0].calcIrms(1996);
Quadro.Irms1 = emon1.calcIrms(1996);
break;

case 1:
//Quadro.Irms2 = i[1].calcIrms(1996);
Quadro.Irms2 = emon1.calcIrms(1996);
break;

case 2:
//Quadro.Irms3 = i[2].calcIrms(1996);
Quadro.Irms3 = emon1.calcIrms(1996);
break;

case 3:
Quadro.Irms4 = emon1.calcIrms(1996);
break;

case 4:
Quadro.Irms5 = emon1.calcIrms(1996);
break;

case 5:
Quadro.Irms6 = emon1.calcIrms(1996);
break;
}
contagem_corrente1++;
Serial.print("contagem_corrente1 = ");
Serial.println(contagem_corrente1);
Serial.print("Corrente1 = ");
Serial.println(Quadro.Irms1);
Serial.print("Corrente2 = ");
Serial.println(Quadro.Irms2);
Serial.print("Corrente3 = ");
Serial.println(Quadro.Irms3);
Serial.print("contagem_corrente2 = ");
Serial.println(contagem_corrente2);
Serial.print("Corrente4 = ");
Serial.println(Quadro.Irms4);
Serial.print("Corrente5 = ");
Serial.println(Quadro.Irms5);
Serial.print("Corrente6 = ");
Serial.println(Quadro.Irms6);
Serial.print("contagem_corrente2 = ");
Serial.println(contagem_corrente2);
}

void comp2(){
contagem_corrente2;
if (contagem_corrente2 > 2){
contagem_corrente2 = 0;
}
else{
contagem_corrente2;
}
switch (contagem_corrente2){
case 0:
//Quadro.Irms4 = i[3].calcIrms(1996);
Quadro.Irms4 = emon1.calcIrms(1996);
break;

case 1:
//Quadro.Irms5 = i[4].calcIrms(1996);
Quadro.Irms5 = emon1.calcIrms(1996);
break;

case 2:
//Quadro.Irms6 = i[5].calcIrms(1996);
Quadro.Irms6 = emon1.calcIrms(1996);
break;
}
contagem_corrente2++;
}*/

Conforme falei, tentei esse código declarando a instância Energy monitor somente como emon1 e também tentei com emon1, emon2, emon3, emon4, emon5 e emon6.

Tentei diversas formas diferentes de declarar a instância EnergyMonitor, tentei entender o código dentro da biblioteca, mas é um pouco avançado para meus conhecimentos. Vi que eles trabalham também com umas funções que terminam com TX, que parece ser para circuito trifásico, mas não consegui entender o código dentro da biblioteca.

Respondendo:

"Se apenas queres ver se há uma fase que está sobrecarregada, isso deve funcionar bem."

Justamente isso! Isso que preciso!

Olhando ao código nada me parece errado.
Eu experimentei num Arduino aqui em casa e os canais mudam, logo o problema que vês não tem a ver com o código.

Os sensores são iguais? Como chegaste ao valor de 13.33?

Os sensores são todos iguais do tipo SCT-013-000.

O valor 13.333 eu cheguei em função da limitação de corrente que coloquei de 22A, que me faz utilizar um resistor de carga de 150k. Como o SCT-013-000 tem 2000 enrolamentos, fiz: 2000/150 = 13.333.

Este cálculo eu segui as instruções do site OpenEnergyMonitor e vi que é muito difundido.

A medição de uma única fase fica perfeita. Coloquei um ferro de passar roupa e o alicate amperímetro pegou medição de 4,7A e o meu programa mediu 4,65A. O problema é se eu pego e coloco os outros sensores para medir a mesma coisa e eles ficam em zero.

Fiz um analogRead(pinos) em cada pino e vi que ele manda um sinal com informação de 516 para o Arduino em cada sensor. Eu realmente não sei mais o que fazer... perguntei para pessoas experientes como você sobre o assunto e todo mundo fala que faria do mesmo jeito. Estou com a "corda no pescoço" para finalizar este trabalho e gerar resultado.

Quando você rodou o programa, quais as informações que te geraram? Será que é uma limitação do Arduino que eu não vou conseguir superar?

O mais engraçado é que não tem um sensor específico que mede a corrente correta. Uma hora é a segunda fase do compressor 1, outra hora é a terceira fase do compressor 2. A coisa mais louca!

Ola,
Só para esclarecer e dar uma pista:
Testou os sensores usando a mesma fase (teste do ferro de passar)?
Ou, em vez de usar a biblioteca, escrever uma rotina de teste usando o analogread() para ler uma boa amostra e calcular a média?

pksato, beleza?
Cara, testei com o ferro de passar sim. Coloquei o alicate amperímetro, mediu 4,70A e o Arduino estava lendo sempre 0,05 a menos em uma das fases. Esse é o problema, só lê uma das fases.
Fiz o analogRead em cada pino e o que me retornou foi o valor 512 em cada pino, daí quando o ferro ligava, somente um pino saia deste valor.
Estou refazendo o circuito impresso, com novos componentes para ver se o problema é no circuito.
Já teve este problema?

Refiz meu circuito, e o analogRead em cada pino ficou na faixa de 510 a 518. Achei Ok!
Com a biblioteca Emonlib, lê somente duas correntes, que representam a primeira de cada circuito trifásico simulado, porque estou utilizando um único fio com todos os sensores ligados nele. Se pudesse enviava uma foto, mas aqui não dá esta opção.

Como estou simulando a medição de 3 fases por compressor em uma única fase, existe o risco de uma corrente se anular com a outra e esse ser o motivo de ler somente a primeira leitura de cada circuito trifásico simulado numa única fase? Estou desconfiado que a leitura de 4 sensores se anula entre si.

Pessoal, olá!

Realmente, o problema não era o programa, era o hardware. Especificamente utilizar o conector jack que vem no sensor. Arranquei fora o mesmo, liguei direto os fios na placa e fez a leitura das 3 fases.

Segue código:

#include <EmonLib.h> //Habilita a biblioteca do sensor SCT-013-000 para medicao de corrente

#define sctPin1 A8 //Define o pino de entrada do sensor
#define sctPin2 A9
#define sctPin3 A10
#define sctPin4 A11
#define sctPin5 A12
#define sctPin6 A13

EnergyMonitor emon1, emon2, emon3, emon4, emon5, emon6;

double Irms1, Irms2, Irms3, Irms4, Irms5, Irms6;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
emon1.current(sctPin1, 60.606);
emon2.current(sctPin2, 60.606);
emon3.current(sctPin3, 60.606);
emon4.current(sctPin4, 60.606);
emon5.current(sctPin5, 60.606);
emon6.current(sctPin6, 60.606);
}

void loop() {
// put your main code here, to run repeatedly:
Irms1 = emon1.calcIrms(1480);//Para 50Hz 1480 e para 60Hz 1996
Serial.print("Irms1 = ");
Serial.println(Irms1);

Irms2 = emon2.calcIrms(1480);
Serial.print("Irms2 = ");
Serial.println(Irms2);

Irms3 = emon3.calcIrms(1480);
Serial.print("Irms3 = ");
Serial.println(Irms3);

Irms4 = emon4.calcIrms(1480);
Serial.print("Irms4 = ");
Serial.println(Irms4);

Irms5 = emon5.calcIrms(1480);
Serial.print("Irms5 = ");
Serial.println(Irms5);

Irms6 = emon6.calcIrms(1480);
Serial.print("Irms6 = ");
Serial.println(Irms6);
delay(1000);
}