Ajuda - Capturar Valor - Sensor de Corrente ACS712 30a

Bom dia Pessoal,

Estou com uma grande dificuldade em conseguir capturar o valor do sensor.

Já tentei inúmeros algoritmos disponibilizados, porém o valor aparece sempre "fixo", ou seja, com algum aparelho ligado ou não, o valor permanece o mesmo.

Alguém sabe como pegar esse valor mais próximo do real possível??

Algoritmos testados que não deram certos:

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/0.185); // calcula a corrente considerando a sensibilidade do sernsor (185 mV por amper)

// mostra o resultado no terminal
Serial.print(currentValue,3);
Serial.print(" A \n" );

sensorValue =0;

delay(100);

}
###########################################################################################################3

void setup() {
// inicializa a comunicação seral a 9600 bits por segundo:
Serial.begin(9600);
}

void loop() {
// leitura input no analog pin 0:

//aqui a leitura é mostrada entre 0 e 1023
int sensorValue = analogRead(A0);

//podemos fazer transformações para mostrar em Amperes

//O código a seguir diz para o Arduino que o valor lido pelo sensor deve ser transformado de 0 a 1023 para -30 a +30.

int outputValue = map(sensorValue, 0, 1023, -30, 30);
// mostrar valor lido pelo sensor:

Serial.print("Sensor: ");

Serial.print(sensorValue);

//mostrar valor transformado em amperes:

Serial.print(" - mA: ");

Serial.println(outputValue);

delay(3000); // Tempo entre leituras
}

#########################################################

#define Rele1 7 // Define pino de saida para rele 1
#define Rele2 8 // Define pino de saida para rele 2
const int sensorPin = A0;
float sensorValue_aux = 0;
float sensorValue = 0;
float currentValue = 0;
float voltsporUnidade = 0.0048828125;

int st_rl = 0;
String st_lamp = 0;

void setup(){
pinMode(Rele1,OUTPUT);
pinMode(Rele2,OUTPUT);
Serial.begin(9600);
}

void loop(){
char c = Serial.read();

for(int i=500; 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 é vcc/2 para corrente =0
sensorValue += pow(sensorValue_aux,2); // soam os quadardos das leituras no laco
}

sensorValue = (sqrt(sensorValue/ 500)) * 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)


if (currentValue < 0.10){
st_lamp = "Lampada apagada";
}
else{
st_lamp = "Lampada ligada";
}

if (c == 's'){
Serial.print ("Valor do st: ");
Serial.print (st_rl);
Serial.print (" Corrente: ");
Serial.print (currentValue);
Serial.print (" Status da lampada: ");
Serial.println (st_lamp);
}
if (c == 'a'){
if (st_rl == 0){
digitalWrite(Rele1, HIGH);
Serial.print ("Valor anterior do st: ");
Serial.print (st_rl);
Serial.print (" Status anterior da lampada: ");
Serial.print (st_lamp);
st_rl = 1;
Serial.print (" Valor do st mudado para: ");
Serial.print (st_rl);
Serial.print (" Status atual da lampada: ");
Serial.println (st_lamp);
}
else{
digitalWrite(Rele1, LOW);
Serial.print ("Valor do st: ");
Serial.print (st_rl);
st_rl = 0;
Serial.print (" Valor do st mudado para: ");
Serial.print (st_rl);
Serial.print (" Status da Lampada: ");
}
}


delay(5000);

}

#############################################

int VQ; //2.5 volts na saída quando corrente for 0A
int ACSPin = A2;
void setup() {
Serial.begin(9600);
VQ = determineVQ(ACSPin);
delay(1000);
}
void loop() {
Serial.print("ACS712@A2:");Serial.print(readCurrent(ACSPin),3);Serial.println(" mA");
delay(150);
}
int determineVQ(int PIN) {
Serial.print("estimating avg. quiscent voltage:");
long VQ = 0;
//read 5000 samples to stabilise value
for (int i=0; i<10000; i++)
{
VQ += abs(analogRead(PIN));
delay(1);
}

VQ /= 10000;
Serial.print(map(VQ, 0, 1023, 0, 5000));Serial.println(" mV");
return int(VQ);
}
float readCurrent(int PIN) {
int current = 0;
int sensitivity = 66;//sensibilidade para o sensor de 30 A
for (int i=0; i<50; i++)
{
current += abs(analogRead(PIN)) - VQ;
delay(1);
}
current = map(current/50, 0, 1023, 0, 5000);
return float(current)/sensitivity;
}

############################################################

const int sensorPin = A4;
float sensorValue_aux = 0;
float sensorValue = 0;
float currentValue = 0;
float voltsporUnidade = 0.0048828125;


void setup() {

Serial.begin(9600);
}


void loop() {


for(int i=500; 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 é vcc/2 para corrente =0
sensorValue += pow(sensorValue_aux,2); // soam os quadardos das leituras no laco
}

sensorValue = (sqrt(sensorValue/ 500)) * voltsporUnidade; // finaliza o calculo da méida quadratica e ajusta o valor lido para volts
currentValue = (sensorValue/185)*1000 ; // calcula a corrente considerando a sensibilidade do sernsor (185 mV por amper)

// mostra o resultado no terminal
Serial.print(currentValue);
Serial.print("\n" );

sensorValue =0;
delay(1000);
}

Exibições: 12339

Responder esta

Respostas a este tópico

Sim corrigir sim
Como eu já te falei a rede elétrica aqui é 220V então o erro percebido por você fica ainda maior.
Terei que testa cm um de 5A

Eu também irei comprar um ACS712-05A.

Depois a gente troca informações sobre os testes.

Abraços,

Blz

Relendo o datasheet do ACS712-30A , pode-se constatar que o erro de leitura pode ser de até 1,5%, para uma corrente de 30 A. 

Para 30 A >>> 30 A x 0,0015 = 45 mA 

Para 5 A >>>  5 A x  0,0015  =  7,5 mA 

Para 1 A >>>  1 A x 0,0015 = 1,5 mA 

Mais uma informação  sobre a leitura do sensor ACS712-30A com o conversor ADC do Arduino. 

Esta no datasheet do ATmega 328 :

http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-AT...

Precisão absoluta de +ou- 2 bits LSB ! Isso é pessimo !

Sabendo-se que apenas um bit produz uma variação relativamente expressiva na leitura final da corrente. 

A precisão das medições pioram ainda mais com essas informações.

Vitor, estou fazendo testes exaustivos com o conversor ADC do Arduino.

Coloquei na entrada A0 , uma referencia precisa de tensão de 4096 mV (MCP1541) com um potenciometro para variar essa tensão. 

Por exemplo - ajustei o POT para 3753 mV (constante) 

Veja as medições abaixo ! 

1 LSB = 5000 mv / 1024 = 4,88 mV 

Essa é a resolução mínima, que é grande para o ACS712-30A.

E ainda mais tem os +- 2 bits de variação na precisão.

Tá dificil medir com um conversor de apenas 10 bits.

Teremos que usar um ADC de 12 bits !

Medicao Maxima = 767
Tensao de Pico = 3749 mV
Vmax ACS712 = 1246 mV
V RMS ACS712 = 881 mV
I RMS ACS712 = 13.394 A

Medicao Maxima = 768
Tensao de Pico = 3754 mV
Vmax ACS712 = 1251 mV
V RMS ACS712 = 885 mV
I RMS ACS712 = 13.446 A

 

Não vai dar para ser feliz com esse conversor ADC de 10 bits do Arduino ATmega 328.

Tenho dois ADCs I2C de 12 bits e um Arduino DUE com ADC 12 bits. 

Irei providenciar testes com eles....

Finalmente chegou um ACS712 - 30A!!!Fiz uns testes rápidos com lampadas incandescentes de 100W de 60W e de 42W X 127V, achei os resultados iniciais bastantes promissores levando em consideração as limitações que o José Gustavo já identificou, e as baixas correntes para este modelo 30A... fiz uma medida inicial sem carga e chamei de vmediacapturado, para melhorar os cálculos rms... 

// Medição da Tensão Vcc do Arduino LEKOBH 05-09-15 baseado em- Gustavo Murta 01/ago/2015 //Para definir o tipo do sensor descomente o sensor que ira ser usado e deixe comentado os outros.
// #define ACS712x05B // Usar para sensor 5 Amperes
//#define ACS712x20A // Usar para sensor 20 Amperes
#define ACS712x30A // Usar para sensor 30 Amperes


float vmediacapturado= 2.48778; //valor media sem carga ligada capturar para cada sensor!!!!

long VCC = 0.00;
float VCCR = 0.00;
void setup() {
Serial.begin(9600);

}
void loop() {

float corrente = converteI(captura());

Serial.print("IRMS= " );
Serial.print( corrente, 4 );
Serial.print(" A" );

Serial.print(", Potencia= " );
Serial.print( float(corrente*127), 1 ); //PARA 127 Volts
Serial.print(" Watts" );

}


//--------------------------------------------------------------------------------------------
// Recebe o ADC e converte em tensão
//--------------------------------------------------------------------------------------------
float scalaACS (long valor, float vcc) {
float Viout = float(valor * (5.000 / 1023.000));
return Viout; // retorna o valor equivalente VIout para 5 V em millivolts
}

//--------------------------------------------------------------------------------------------
//Recebe o valor em tensão e converte para corrente
//Garantir antes de usar que os valores ja foram ajustados como se fosse 5.00V
//--------------------------------------------------------------------------------------------
float converteI (float valor) {
#if defined (ACS712x05B)
float Sens = 0.185; //v por A;
#elif defined (ACS712x20A)
float Sens = 0.104; //v por A;
#elif defined (ACS712x30A)
float Sens = 0.066; //v por A;
#else
int Sens = 0;
#endif

float Iout = float(valor/Sens); // retorna o valor do acs como ajustado para 5v
return Iout; // retorna o valor equivalente VIout para 5 V em millivolts
}

//--------------------------------------------------------------------------------------------
//Aguarda passagem por zero (TRAVA)
//Melhora a chance de uma boa captura de dados
//--------------------------------------------------------------------------------------------
void passagem () {
boolean st=false; //an indicator to exit the while loop
unsigned long start = millis(); //Guarda tempo para timeout segurança.
while(st==false) //the while loop...
{
int startV = analogRead(A0); //le o valor de A0
if ((startV < (520)) && (startV > (510))) st=true; //testa se esta proximo de zero
if ((millis()-start)>200){
st = true; // se passou mais de 200ms deixa seguir TIMEOUT
Serial.print(" time OUT" );

}
}
}

//--------------------------------------------------------------------------------------------
//Captura os Dados "supondo algo proximo à 10KSPS"
//Captura n amostras rapidamente e depois trata os dados
//--------------------------------------------------------------------------------------------
float captura () {
#define amost 800 //define o numero de amostras
float VCCR = 5.000;
int amostras[amost]; //cria o buffer de dados para guardar os dados
passagem (); //espera um momento baum para iniciar a captura ou time out
for (int i = 0; i<amost; i++) { //loop guardar os valores sem interferencias ou delays
amostras[i] = analogRead(A0);
}
// Inicializa as variaveis locais
long int mediacap = 0;
int maximo = 0;
int minimo = 1023;
int borda = 0;
float vrms;
//loop calcular max e min e achar a ultima passagem pelo valor inicial
for (int i = 0; i<amost; i++) {

maximo = max(maximo, amostras[i]);
minimo = min(minimo, amostras[i]);
if ( ((amostras[i] > amostras[0]) && (amostras[i+1] <= amostras[0])) || ((amostras[i] < amostras[0]) && (amostras[i+1] >= amostras[0]))){
if (i < amost-2) borda = i;
}
}
float vpp = scalaACS((maximo-minimo), VCCR); //Calcula tensao pico a pico ajustada baseado no VCC real
Serial.print(", vpp =" );
Serial.println( vpp,4 );
if (vpp<=0.02) vpp=0.000;
//loop calcular valor médio dentro da janela correta
for (int i = 0; i<borda; i++) { //loop ate o valor da ultima borda (passagem por zero)
mediacap += amostras[i]; //Soma todos os valoras da janela
}
mediacap = mediacap/(borda); //Calculo da media dos valores
float vmediacap = scalaACS(mediacap, 5.000); // Ajuste o valor baseado no VCC real
Serial.print(", vmediacap=" );
Serial.println( vmediacap, 5 );

//loop calcular valor RMS ALTERNADO dentro da janela correta
float rms = 0.00;
for (int i = 0; i<borda; i++) { //loop ate o valor da ultima borda (passagem por zero)
float vrms = float(scalaACS(amostras[i], 5.000)- vmediacap); // Ajuste o valor de cada amostra baseado no VCC real
rms += (vrms*vrms);
}
rms = sqrt(rms/borda); //Calcula o valor RMS Alternado


Serial.print(", vpp =" );
Serial.println( vpp,4 );


if (vpp > 0.000){
vrms =rms + (vmediacap-vmediacapturado);// Alternado + continuo TRUE RMS
} else {
vrms = float(vmediacap-vmediacapturado);// Somente continuo
}

return vrms; // retorna o valor rms alternado + continuo
}


Alex parabéns ! 
vou dar uma estudada no seu sketch.

Minhas recomendações para aferição :

- coloque um capacitor de 0,1 uF no pino Aref do Arduino 

- Meça essa tensão de referência (+5V) com um multimetro preciso e use no seu Sketch.

- Meça a tensão de Vout do ACS712 sem carga (+2,5V)  com um multimetro compare com o seu resultado obtido.

- Faça ajustes no valor do coeficiente de 66mV/A se achar necessário 

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço