Bom dia  

estou  montando um medidor de consumo de energia. 

mas não esta saindo  a informação que eu quero. 

gostaria que ele fisesse a leitura da corrente e com o valor da tensão ja pre determinado, o arduino me desse o valor da potencia e da energia consumida, multiplicando  a energia pelo valor da energia em dinheiro. e me desse esse valor acumulativo. 

porem não estou  conseguindo  fazer isso. 

alguem pode me ajudar. 

segue abaixo minha programação.

esta bem carregada de informações por que usei varias referencias para tentar fazer isso. quem puder me ajudar eu agradeço. 

#include <EEPROM.h>


//Baseado no programa exemplo da biblioteca EmonLib

//Carrega as bibliotecas

#include "EmonLib.h"
#include <LiquidCrystal.h>
#include <avr/eeprom.h>

#define eeprom_read_to(dst_p, eeprom_field, dst_size) eeprom_read_block(dst_p, (void *)offsetof(__eeprom_data, eeprom_field), MIN(dst_size, sizeof((__eeprom_data*)0)->eeprom_field))
#define eeprom_read(dst, eeprom_field) eeprom_read_to(&dst, eeprom_field, sizeof(dst))
#define eeprom_write_from(src_p, eeprom_field, src_size) eeprom_write_block(src_p, (void *)offsetof(__eeprom_data, eeprom_field), MIN(src_size, sizeof((__eeprom_data*)0)->eeprom_field))
#define eeprom_write(src, eeprom_field) { typeof(src) x = src; eeprom_write_from(&x, eeprom_field, sizeof(x)); }
#define MIN(x,y) ( x > y ? y : x )


EnergyMonitor emon1;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

//Tensao da rede eletrica
int rede = 110.0;

//Pino do sensor SCT
int pino_sct = 1;

struct __eeprom_data {
double flash_kwhtotal;
};

//Cria variaveis globais
double kwhTotal;
double vlreais;
double realPower;
unsigned long ltmillis, tmillis, timems, previousMillis, refresh;
char charBuf[30];
void setup()
{
Serial.begin(9600);
emon1.current(pino_sct, 29); //Pino, calibracao - Cur Const= Ratio/BurdenR. 1800/62 = 29.
eeprom_read(kwhTotal, flash_kwhtotal);
previousMillis = millis();
lcd.begin(16, 2);
lcd.clear();


//Informacoes iniciais display
lcd.setCursor(0,0);
lcd.print("A:");
lcd.setCursor(0,1);
lcd.print("(W):");
}
void loop()
{
// Calcula quantidade de tempo desde a última measurment realpower.
ltmillis = tmillis;
tmillis = millis();
timems = tmillis - ltmillis;
double Irms = emon1.calcIrms(1480); // Calculate Irms

// Calcular o número de hoje de kWh consumido.
kwhTotal = kwhTotal + ((realPower/1000.0) * 1.0/3600.0 * (timems/1000.0));

// Calcular o número de hoje de kWh consumido.
kwhTotal = (((Irms*127.0)/1000.0) * 1.0/3600.0 * (timems/1000.0));
vlreais = kwhTotal * 0.35;

Serial.print("Watts: ");
Serial.println(Irms*127.0); // potencia aparente
lcd.setCursor(10,1);
lcd.print(" ");
lcd.setCursor(10,1);
lcd.print(Irms*rede,1);

/* Serial.print("Current: ");
Serial.print(Irms); // Irms
lcd.setCursor(10,0);
lcd.print(Irms);*/

Serial.print("vlreais: ");
Serial.print(vlreais, 10);
Serial.print("");
lcd.print(" ");
lcd.setCursor(3,0);
lcd.print(vlreais, 10);

//grava na memoria a cada 1 minuto
if ((millis() - refresh)>= 100)
refresh = millis(); //actualiza a contagem.
{
Serial.println("Gravando na EEprom");
eeprom_write(kwhTotal, flash_kwhtotal);
previousMillis=millis();
}
//Multiplica pelo valor kilowatt hora R$ 0.35 Reais
//vlreais = kwhTotal * 0.35;
}

void printFloat(float value, int places) {
// this is used to cast digits
int digit;
float tens = 0.1;
int tenscount = 0;
int i;
float tempfloat = value;

// Se certificar de que arredondar corretamente. este poderia usar pow de <math.h>, mas não parece vale a importação
// Se esta etapa arredondamento não está aqui, o valor 54,321 imprime como 54,3209

// calcular arredondamento prazo d: 0,5 / pow (10, lugares)
float d = 0.5;
if (value < 0)
d *= -1.0;
// dividir por dez para cada casa decimal
for (i = 0; i < places; i++)
d/= 10.0;
// este pequeno disso, combinado com truncamento vai arredondar os nossos valores corretamente
tempfloat += d;

// Primeiro obter dezenas de valor para ser a grande potência de dez a menos do que o valor
// Tenscount não é necessário, mas seria útil se você queria saber depois desta quantos caracteres o número tomará

if (value < 0)
tempfloat *= -1.0;
while ((tens * 10.0) <= tempfloat) {
tens *= 10.0;
tenscount += 1;
}


// escrever o negativo, se necessário
if (value < 0)
Serial.print('-');

if (tenscount == 0)
Serial.print(0, DEC);

for (i=0; i< tenscount; i++) {
digit = (int) (tempfloat/tens);
Serial.print(digit, DEC);
tempfloat = tempfloat - ((float)digit * tens);
tens /= 10.0;
}

// se não há lugares após decimal, pare agora e retorno
if (places <= 0)
return;

// caso contrário, escreva o ponto e continuar
Serial.print('.');

// Agora, escrever cada casa decimal, deslocando um dígitos por uma, para o lugar queridos e escrever o valor truncado
for (i = 0; i < places; i++) {
tempfloat *= 10.0;
digit = (int) tempfloat;
Serial.print(digit,DEC);
// uma vez escrito, subtrair fora esse dígito
tempfloat = tempfloat - (float) digit;
delay(1000);
}
}

Exibições: 10988

Responder esta

Respostas a este tópico

Gustavo,

É o Proteus, mas ele tem um modulo chamado VSM ARDUINO, que traz a IDE do Arduino integrada, desta forma você escreve e compila no Proteus e depois se quiser pode upar no Arduino diretamente.

No site da www.labcenter.com tem mais informação.

De nada Gustavo.

Grande abraço.

Iago,

Como não tenho o sensor, não pude simular seu código, que creio tem erros, além de não conhecer a montagem eletrônica a fundo utilizada.

Mas fiz o seguinte, montei um Trafo no Proteus e usei este como referencia de alternada, e usei dois divisores de tensão em A0 e A1, desta forma até aqui obtive Corrente e Potencia, veja o vídeo.

https://www.youtube.com/watch?v=aS5GyNodlGc

Código: http://pastebin.com/tYC9ZByr

Agora em quanto tiver um tempo, vou fazer a conversão Kwh X R$, assim que tiver pronto posto tudo aqui.

Abraço.

Ok. 

ate ai eu consegui Carlos, tambem chego nos valores de Corrente e poencia. 

e ate de Kwh x R$ =vreal

o meu problema é que o valor referente ao resultado  vreal não acumula.

o meu lcd mostra apenas o valor daquele segundo, e não do tempo corrido.  

Ola Iago, teria como compartilhar o esquema da montagem do projeto ?? Queria realizar a montagem do medidor tb

seria possível disponibilizar o esquema é o código.

oi Iago,

testa este código, e depois conta como ficou?

Não coloquei ainda o resultado no LCD, somente no monitor serial.

Ele acumula em   

double kwhTotal_Acc;    e    double vlreais_Acc;

Rui


// http://labdegaragem.com/forum/topics/medidor-de-consumo-de-energia-1
#include <EEPROM.h>


//Baseado no programa exemplo da biblioteca EmonLib

//Carrega as bibliotecas

#include "EmonLib.h"
#include <LiquidCrystal.h>
#include <avr/eeprom.h>

#define eeprom_read_to(dst_p, eeprom_field, dst_size) eeprom_read_block(dst_p, (void *)offsetof(__eeprom_data, eeprom_field), MIN(dst_size, sizeof((__eeprom_data*)0)->eeprom_field))
#define eeprom_read(dst, eeprom_field) eeprom_read_to(&dst, eeprom_field, sizeof(dst))
#define eeprom_write_from(src_p, eeprom_field, src_size) eeprom_write_block(src_p, (void *)offsetof(__eeprom_data, eeprom_field), MIN(src_size, sizeof((__eeprom_data*)0)->eeprom_field))
#define eeprom_write(src, eeprom_field) { typeof(src) x = src; eeprom_write_from(&x, eeprom_field, sizeof(x)); }
#define MIN(x,y) ( x > y ? y : x )


EnergyMonitor emon1;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

//Tensao da rede eletrica
int rede = 110.0;

//Pino do sensor SCT
int pino_sct = 1;

struct __eeprom_data {
double flash_kwhtotal;
};

//Cria variaveis globais
double kwhTotal;
double kwhTotal_Acc;
double vlreais;
double vlreais_Acc;
double realPower;
unsigned long ltmillis, tmillis, timems, previousMillis, refresh;
char charBuf[30];
void setup()
{
Serial.begin(9600);
emon1.current(pino_sct, 29); //Pino, calibracao - Cur Const= Ratio/BurdenR. 1800/62 = 29.
eeprom_read(kwhTotal, flash_kwhtotal);
previousMillis = millis();
lcd.begin(16, 2);
lcd.clear();


//Informacoes iniciais display
lcd.setCursor(0,0);
lcd.print("A:");
lcd.setCursor(0,1);
lcd.print("(W):");
}
void loop()
{
// Calcula quantidade de tempo desde a última measurment realpower.
ltmillis = tmillis;
tmillis = millis();
timems = tmillis - ltmillis;
double Irms = emon1.calcIrms(1480); // Calculate Irms

// Calcular o número de hoje de kWh consumido.
//kwhTotal = kwhTotal + ((realPower/1000.0) * 1.0/3600.0 * (timems/1000.0));

// Calcular o número de hoje de kWh consumido.
kwhTotal = (((Irms*127.0)/1000.0) * 1.0/3600.0 * (timems/1000.0));
kwhTotal_Acc = kwhTotal_Acc + kwhTotal;
vlreais = kwhTotal * 0.35;
vlreais_Acc = vlreais_Acc + vlreais;

//Serial.print("Watts: ");
//Serial.println(Irms*127.0); // potencia aparente

Serial.print("kwhTotal_Acc: ");
Serial.println(kwhTotal_Acc, 10);


lcd.setCursor(10,1);
lcd.print(" ");
lcd.setCursor(10,1);
lcd.print(Irms*rede,1);

/* Serial.print("Current: ");
Serial.print(Irms); // Irms
lcd.setCursor(10,0);
lcd.print(Irms);*/

Serial.print("vlreais_Acc: ");
//Serial.print(vlreais, 10);
Serial.println(vlreais_Acc, 10);
Serial.print("");
lcd.print(" ");
lcd.setCursor(3,0);
lcd.print(vlreais, 10);

//grava na memoria a cada 1 minuto
if ((millis() - refresh)>= 100)
refresh = millis(); //actualiza a contagem.
{
//Serial.println("Gravando na EEprom");
eeprom_write(kwhTotal, flash_kwhtotal);
previousMillis=millis();
}
//Multiplica pelo valor kilowatt hora R$ 0.35 Reais
//vlreais = kwhTotal * 0.35;
}

void printFloat(float value, int places) {
// this is used to cast digits
int digit;
float tens = 0.1;
int tenscount = 0;
int i;
float tempfloat = value;

// Se certificar de que arredondar corretamente. este poderia usar pow de <math.h>, mas não parece vale a importação
// Se esta etapa arredondamento não está aqui, o valor 54,321 imprime como 54,3209

// calcular arredondamento prazo d: 0,5 / pow (10, lugares)
float d = 0.5;
if (value < 0)
d *= -1.0;
// dividir por dez para cada casa decimal
for (i = 0; i < places; i++)
d/= 10.0;
// este pequeno disso, combinado com truncamento vai arredondar os nossos valores corretamente
tempfloat += d;

// Primeiro obter dezenas de valor para ser a grande potência de dez a menos do que o valor
// Tenscount não é necessário, mas seria útil se você queria saber depois desta quantos caracteres o número tomará

if (value < 0)
tempfloat *= -1.0;
while ((tens * 10.0) <= tempfloat) {
tens *= 10.0;
tenscount += 1;
}


// escrever o negativo, se necessário
if (value < 0)
Serial.print('-');

if (tenscount == 0)
Serial.print(0, DEC);

for (i=0; i< tenscount; i++) {
digit = (int) (tempfloat/tens);
Serial.print(digit, DEC);
tempfloat = tempfloat - ((float)digit * tens);
tens /= 10.0;
}

// se não há lugares após decimal, pare agora e retorno
if (places <= 0)
return;

// caso contrário, escreva o ponto e continuar
Serial.print('.');

// Agora, escrever cada casa decimal, deslocando um dígitos por uma, para o lugar queridos e escrever o valor truncado
for (i = 0; i < places; i++) {
tempfloat *= 10.0;
digit = (int) tempfloat;
Serial.print(digit,DEC);
// uma vez escrito, subtrair fora esse dígito
tempfloat = tempfloat - (float) digit;
delay(1000);
}
}

Oi Rui,

Tomei a liberdade de testar no Proteus, se bem é um teste simulado, serve como indicador, parece que o problema é esse mesmo, vamos esperar o pronunciamento do Iago para conhecer o teste real.

segue link do vídeo, apenas coloquei um delay para mostrar mais lento o resultado.

https://www.youtube.com/watch?v=2e4hF6uT5Po

Abs.

chegando em casa vou testar. pela simulação esta conforme eu preciso. 

mas estarei testando em casa. 

assim que eu  testar estarei dando um retorno. 

Oi Iago,

no link que voce me indicou tem 2 sensores.

Um de corrente: SCT-013-000,

e o outro de tensão.  

Qual voce usou como sensor de tensão e quais circuitos usou para

detectar a corrente e a tensão?

Obrigado 

Rui

Rui, 

estou usando um detector de corrente SCT-013-000 

a tensão estou simulando como se fosse 127.0 

um valor fixo. 

não tenho detector de tenção. 

Oi Iago,

E voce está usando quele esquema com 2 resistores que na figura parecem ser de 10K, 1 capacitor de 10uf, e um outro resistor que parece ser de 100 ohms?

obrigado.

Rui

Rui, 

a programação funcionou, 

o valor esta acumulando. 

gostaria de entender agora um pouco mais da programação. 

por exemplo. 

na linha que faz os cauculos : 

kwhTotal = (((Irms*127.0)/1000.0) * 1.0/3600.0 * (timems/1000.0));

a primeira parte eu entendo que seja para encontrarmos o valor do Whats que esta utilizando (((Irms*127.0)/1000.0) , depois ele divide por segundos * 1.0/3600.0 . 

a partir dai  ja não consigo entender  essa parte * (timems/1000.0));

poderia me explicar ?? 

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço