LusoRobótica - Robótica em Português
Sistemas específicos => Arduino / AVR => Tópico iniciado por: dennis_boy em 21 de Abril de 2018, 11:51
-
Bom dia.
Estou com um SCT-013.
Já procurei rebusquei tudo no Google.
Gostava de gravar e ler os kwh na memoria mas não sei como.
No projecto que estou a fazer utilizo para a eeprom:
void i2c_eeprom_write_byte ...
byte i2c_eeprom_read_byte ...
-
Dás muito pouca informação para que seja possível ajudar-te.
Elabora mais um bocado.
-
Pressupondo que calcular os KWh não é o problema, gravar na memória com quê? Arduino?
SC
-
Manipulação para o AT24C256 esta complicado.
kwhTotal = kwhTotal + (((Irms*rede)/1000.0) * 1.0/3600.0 * (timems/1000.0));
Ate aqui esta tudo bem.
Pior é gravar o float.
Depois ler.
Tenho ate isto ( dtostrf(kwhTotal,4, 5, outstr) ) para me mostrar mais casas decimais.
desde já obrigado para compreensão.
-
Desculpa se a ideia é estúpida, mas porque não gravar a string ?
Certamente que gravar o float ocupa menos bytes, mas se não estiveres aflito de espaço o mais fácil será gravares a string. (penso eu de quê) :-D
-
De uma forma simplificada, precisas de uma função que te grave/leia um nº arbitrário de bytes na EEPROM. Exemplo de cabeça e incompleto para a escrita (não conheço a assinatura das funções de escrita em EEPROM por i2c, terás que adaptar):
static void writeArrayToI2cEeprom (uint8_t i2c_addr, uint16_t eeprom_addr, void* data, int16_t data_size)
{
uint8_t* ptr = (uint8_t*)data;
while (--data_size >= 0)
{
i2c_eeprom_write_byte (i2c_addr, eeprom_addr++, *ptr++);
}
}
Depois já podes gravar o que quiseres, tendo sempre em conta o endereço da EEPROM e se há espaço que chegue. Por exemplo, gravar uma variável float:
float kwh;
...
writeArrayToI2cEeprom (0x17, 0x01, &kwh, sizeof(kwh));
-
Obrigado pela ajuda!! ;)
Hoje tive para aqui a refazer métodos cheguei a este.
#include "Wire.h"
#include "EmonLib.h"
#define disk1 0x50
#define AddressKwhDay 0
EnergyMonitor emon1;
float rede = 230.0;
double kwhTotal;
union kWh_Float_Byte {
float floatkWh;
byte bytekWh[4];
} TOTAL_kWh;
unsigned long ltmillis, tmillis, timems, previousMillis;
void setup()
{
Serial.begin(9600);
Wire.begin();
emon1.current(1, 2.7); //760?
if (i2c_eeprom_read_byte(disk1, AddressKwhDay) != 0xFF) {
for (int i=0; i<4; i++) {
TOTAL1_kWh.bytekWh[i] = i2c_eeprom_read_byte(disk1, AddressKwhDay+i);
}
kwhTotal = TOTAL_kWh.floatkWh;
}
previousMillis = millis();
}
void loop()
{
ltmillis = tmillis;
tmillis = millis();
timems = tmillis - ltmillis;
double Irms = emon1.calcIrms(1484);
if (Irms < 0.02) Irms = 0;
kwhTotal = kwhTotal + (((Irms*rede)/1000.0) * 1.0/3600.0 * (timems/1000.0));
double potencia = Irms * rede;
Serial.print("Potencia = ");
Serial.print(potencia);
Serial.print(" Irms = ");
Serial.print(Irms);
Serial.print(" Kwh = ");
Serial.print(kwhTotal);
Serial.print(" ");
Serial.println();
if ((millis() - previousMillis)>4000)
{
TOTAL1_kWh.floatkWh = kwhTotal;
for (int i=0; i<4; i++) {
i2c_eeprom_write_byte(disk1, AddressKwhDay+i, TOTAL_kWh.bytekWh[i]);
delay(5);
}
previousMillis=millis();
}
}
void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
int rdata = data;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.write(rdata);
Wire.endTransmission();
}
byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
byte rdata = 0xFF;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
if (Wire.available()) rdata = Wire.read();
return rdata;
}
Um único problema que encontro é só grava 2 casas decimais e para a continuação da soma fico muito duvidoso que bata certo...
-
Simplifica a tua formula, porque tens ai montes de divisões enormes que só estão a matar a resolução..
-
Não sei ao que te referes, este é só teste de bancada porque resultado final é com um LCD.
Como agora estou com um SCT-013 100Amp mas quero comprar um de 20Amp penso ter menos erro nas leituras
como também estou a espera do da voltagem.
-
(((Irms*rede)/1000.0) * 1.0/3600.0 * (timems/1000.0))
Parece-me estar tudo a multiplicar, logo pode ficar:
Irms*rede*1*timems/(1000*3600*1000)
Faz-me confusão estares a dividir por um valor tao elevado.
-
eu apanhei este exemplo mas parece estar mais correcto o calculo que estas a dar faz resultados negativo
resultados:
Potencia = 312.10 Irms = 1.36 Kwh = -5.1658263206 (pico da ligação da corrente)
Potencia = 0.00 Irms = 0.00 Kwh = -63.5444564819 (depois desligado)
-
Porque é que estás a dividir o tempo por 1000, se já está em ms?
O negativo deve ser por teres underflow, é que é uma divisão tão grande.
-
Obrigado a todos pela participação.
O método para o eeprom esta a registar e a ler bem.
Aprendi com a ( union ) podemos manipular registos era o que pretendia aprender.
Eu Não tenho curso em programação ou frequentei algo do género só que gosto de aprender porque a minha área é electricidade residencial.
Mas como viram não vim aqui pedir códigos mas uma ideia para pegar como cheguei la. ;)