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: 12335

Responder esta

Respostas a este tópico

Comprovação dos resultados - o resultado correto é 127 Volts.

Um  semiciclo (83 medições):

Dois Semiciclos ( um período - 166 medições): 

Numeros de medições variadas - induzem erros !

(100 medições) - cálculo errado !

(150 medições) - cálculo errado !

Taila,

Eu utilizo um processo diferente do seu, no meu caso tenho um comparador que informa qual é a polaridade do sinal, ele tem uma referência de vcc/2, a partir daí eu faço aproximadamente 100 leituras de cada semiciclo, tanto o positivo quanto do negativo "abaixo dos 2.5 volts", faço a média aritmética de cada semiciclo e depois faço a média de ambos, completando um ciclo, este resultado final é o Vavg, o average da onda completa, e o valor Vrms = Vavg/0.639

ou Vrms = Vavg * 1.106.

Após você obter estes resultados, basta apenas você fazer a correlação entre o Vrms e a corrente em baseado na relação de transferência do seu ACS712.

Um coisa importante o comparador gerar interrupções externa no processador de forma que eu consiga sincronizar o inicio das leituras e o fim delas por cada semiciclo, além de utilizar isto para gerar o pulso relógio atualizando as medidas acada segundo.

Espero que isto possa te dar uma luz, caso necessite de mais dados é só solicitar.

Bons projetos.

Em tempo, isto serve também para os sensores de corrente do tipo TC e outro detalhe importante, neste caso aqui, não se faz necessário o uso de librarias/bibliotecas.

Carlos , o seu algoritmo me parece ser muito bom !

Mas fiquei em dúvida sobre os fatores de cálculo. Achei valores um pouco diferentes. 

Poderia nos esclarecer ? 

Seria possível nos enviar o seu sketch ? 

Muito obrigado. 

http://www.rfcafe.com/references/electrical/sinewave-voltage-conver...

Relação aproximada da Tensão Eficaz (RMS)  com a Tensão de Pico (V pk) :

Relação aproximada da Tensão Média  (AVG)  com a Tensão de Pico (V pk): 

Fator de Forma - relação da Tensão Eficaz (RMS) com a Tensão Média (AVG) : 

https://en.wikipedia.org/wiki/Form_factor_(electronics)

http://www.electronics-tutorials.ws/accircuits/average-voltage.html

Em relação à periodicidade das medições, concordo que também é importante. Já li que o tempo entre as medições deve ser igual, para que o cálculo seja efetivo. No caso da rotina que estou estudando, a passagem por zero (zero cross) determina o início e fim das medições, para selecionar os semi-ciclos da senoide.

 

http://labdegaragem.com/forum/topics/ajuda-capturar-valor-sensor-de...

Após vários estudos sobre o sensor ACS712 e  cálculo de Tensão RMS, vou desenvolver um algoritmo que funcione adequadamente e seja confiável. 

Vou me basear no programa do https://github.com/openenergymonitor/EmonLib

A meu ver, é o programa mais correto que eu encontrei até agora. O programa e a biblioteca foram feitos para o sensor de bobina, mas poderão com certeza, ser adaptados para o sensor ACS712-30A.

Para simplificar, farei o programa para ser usado com Arduino que usa Atmega 328, Outras versões poderão ser implementadas posteriormente.

Como o programa deverá ser grande e complexo, pretendo fazê-lo em partes. Não sou especialista em programação. 

E muito menos, sei criar biblioteca. Quem sabe alguém possa ajudar na criação de uma. 

==========Primeira Parte : Medição e ou cálculo da Tensão Vcc.====================

Cheguei a conclusão (com a ajuda do colega Alexandre Nogueira) que a alimentação Vcc não precisa ser exatamente 5,00V, pois a mesma tensão é usada no sensor e  no  conversor ADC do Arduino. Mas para calculo da Tensão RMS, é preciso saber o valor da tensão de referência do Conversor ADC, no caso Vcc. A tensão Vcc poderá variar dependendo da alimentação do Arduino.

Nessa primeira etapa, o Arduino muda a seleção da tensão de Referencia do ADC para 1,1V ( tensão de referencia interna do ATmega 328) e faz algumas medições.  Não sei ainda quanto essa tensão é precisa. Farei testes. 

http://hacking.majenko.co.uk/making-accurate-adc-readings-on-arduino

http://provideyourown.com/2012/secret-arduino-voltmeter-measure-bat...

Amanhã eu colocarei o Sketch - estou cansado por hoje.....

 

 

Continuando 

==========Primeira Parte : Medição e ou cálculo da Tensão Vcc.====================

Esse é o sketch para medição do Vcc do Arduino . 

http://pastebin.com/5wSvManE

Segundo o data sheet do Atmega 328, a tensão de referência 1,1V pode variar até 1,2V. 

Por isso é importante calibrar o conversor ADC antes. 

Ao rodar o programa, despreze sempre a primeira leitura (isto esta no Data sheet). 

Primeiro rode o programa com essa linha :

result = 1126400L / result; // Primeiro cálculo do Vcc (in mV)  1126400 = 1.1*1024*1000

Faça uma medição do pino Vcc no seu Arduino, com um multimetro de precisão. 

E anote o valor Vcc medido pelo sketch. (readVcc).

No meu Arduino :

Primeiro readVcc = 4962 mV  e medido com multimetro = 5,01 V

Calcule a escala corrigida:

1.1Vrefcalc = 1.1 * Vcc1 (Multimetro) / Vcc2 (funcao readVcc)
escala = 1.1Vrefcalc * 1024 * 1000
escala = 1137254 ( no meu Arduino) 

Altere a linha novamente e refaça as medições :

result = 1137254L / result;       // Cálculo do Vcc (em mV) 1137254 = 1.1106*1024*1000

Após calibração => medido = 5,01 V e readVcc = 5,009 V (no meu Arduino) 

Boa Tarde a Todos.

Caro José,

Estou acompanhando o seu empenho nos estudos do ACS712-30A, inclusive estou com bastante dificuldades em relação a medição AC com esse sensor também. Desde já lhe parabenizo pelos seus estudos referentes a esse sensor especificamente.

Enfim, vejo que já chegou a várias conclusões sobre o sensor e o cálculo da tensão RMS.

Nessa primeira etapa do seu programa, vejo que está alterando a tensão de referência do ADC para 1,1V. O motivo dessa mudança para 1,1V devesse a variação da alimentação do Arduino, seria esse o motivo dessa alteração ? E tenho outra pergunta como eu faria para definir os limites das medições (para dessa forma conseguir uma maior estabilidade nos resultados) ? 

Abraço.

Vitor , obrigado pelos elogios. 

Basei-me no programa do OpenEnergy. 

A necessidade de alterar a referência temporariamente para 1,1V foi só para o Arduino medir a tensão de alimentação. Durante as medições de corrente, o Arduino usa essa  tensão de alimentação como referência.

Por isso,  é necessário medir essa tensão antes. 

http://labdegaragem.com/forum/topics/ajuda-capturar-valor-sensor-de...

O Open Energy, define o inicio e fim do semiciclo para fazer as medições de tensão, através do programa. 

https://github.com/openenergymonitor/EmonLib/blob/master/EmonLib.cpp

/ 1) Waits for the waveform to be close to 'zero' (mid-scale adc) part in sin curve.
//-------------------------------------------------------------------------------------------------------------------------
   boolean st=false; //an indicator to exit the while loop

   unsigned long start = millis(); //millis()-start makes sure it doesnt get stuck in the loop if there is an error.

while(st==false) //the while loop...
{
  startV = analogRead(inPinV); //using the voltage waveform
  if ((startV < (ADC_COUNTS*0.55)) && (startV > (ADC_COUNTS*0.45))) st=true; //check its within range
  if ((millis()-start)>timeout) st = true;
}

Estou no momento fazendo outros tipos de testes, tentando usar o optoacoplador HAA11A1 para detectar o início e o fim do semiciclo da senoide. Mas ainda não cheguei a bons resultados.

http://labdegaragem.com/forum/topics/ajuda-capturar-valor-sensor-de...

Bom Dia a Todos.

Caro José,

Essa sua tentativa em usar o optoacoplador HAA11A1 para detectar o início e o fim do semiciclo da senoide. Creio que seja mais fácil do que tentar adaptar o código da Open Energy para o ACS712, nesse ponto eu concordo com você, pois é complicado adaptar por conta da biblioteca. Gostaria de saber como anda os seus testes com esse optoacoplador e se eu posso substituir o HAA11A1 pelo MOC 3020 ?

Desde já grato.

Abraço!!!

Vitor, essa semana não tive disponibilidade para continuar os testes. 

Mas em breve, postarei os resultados. 

O MOC 3020 é usado para disparar TRIAC, e não se aplica á esse circuito de medição de corrente. 

Se não tem o HAA11A1 pode improvisar com um acoplador ótico com o um diodo invertido na entrada. Só que irá conseguir detectar um dos semiciclos. Mas acho que poderá dar certo.

http://electronics.stackexchange.com/questions/60435/zero-crossing-...

Ou então usar dois acopladores óticos com a entradas polarizadas inversamente uma da outra. 

http://www.microchip.com/forums/m603446.aspx

 

Obrigado José, pela sua resposta.

Será que eu poderia utilizar o 4N25 ou o 4N35 nesse caso ? E se eles substituiriam o HAA11A1 para essa aplicação ?

Abraço.

Creio que sim. 

Depois posso fazer o teste com o 4N25. tenho alguns em casa.

Nesta terça-feira próxima, você terá a sua resposta para o seu problema, peço-lhe que aguarde.

Obrigado!

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço