Hallo
Door vragen die er zijn over energie verbruik en leveren door zonnepanelen, kwam ik deze microcontroller tegen. De lol die ik er aan heb om er mee te experimenteren brachten mij ertoe ea aan te schaffen. Na wat basis dingetjes, toch hier aan begonnen. Door verbouwen van reeds bestaande sketches begint er wat te dagen met kleine succesjes.
Met de verbouwing van een sketch, waarbij de slimme-meter uitgelezen kon worden, heb ik een database verbinding ingezet dat werkt. (vb Thinkpad slimme-meter).
Echter ik wil ook graag weten wat er verbruikt wordt als de zon volop schijnt. Daarvoor mis ik een belangrijke meting. Daar heb ik een kwh meterje voor in de voeding van de omvormer. Die geeft aan wat de productie is. Met de sketch van Rob Tllaart kunnen de pulsen gemeten worden. Deze moeten dan ook naar de database. Met wat reken werk moet ik grafieken kunnen maken.
Nu de sketch:
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = {0xDE, 0xAD, 0xBE, 0x30, 0x32, 0x31};
IPAddress ip(192, 168, 1, 000);
char serverName[] = "www.&&&&&.com";
EthernetClient client;
const int requestPin = 5;
char input; // incoming serial data (byte)
bool readnextLine = false;
#define BUFSIZE 75
char buffer[BUFSIZE]; //Buffer for serial data to find \n .
int bufpos = 0;
unsigned long mEVLT = 0; // consumption low tariff
unsigned long mEVHT = 0; // consumption high tariff
unsigned long mELLZ = 0; // produced low tariff
unsigned long mEHLZ = 0; // produced high tariff
unsigned long mEAV = 0; // Actual consumption
unsigned long mEAA = 0; // Actual ampere
unsigned long mEPV = 0; // Actual delivery
unsigned long mG = 0; // Gas
unsigned long kwh = 0;
unsigned long sum = 0;
unsigned long lastTime = 0; // will store last time
unsigned long interval = 60000; // interval at which to blink (milliseconds)60000
/* S0 kwh RobTillaart script*/
volatile unsigned long rpk = 0; // raw pulse kwh counter (private)
volatile unsigned long rpk_old = 0; // value of last read (private)
volatile boolean CS_kwh = false; // Critical Section for kwh meter (private)
// The interrupt routine
void Kirq()
{
rpk++; // just increment raw pulse counter.
if (rpk > 1000000000) // reset pulse counter after 10e9 pulse = 500.000 KW
{
if (false == CS_kwh) // in critical section? // assumption IRQ-call is handled atomic on arduino.
{
rpk -= rpk_old;
rpk_old = 0;
}
}
}
// returns kwh's since last reset
float readkwh1()
{
return rpk / 2000.0; // one pulse = 0.5 watt.
}
// returns kwh's since last call
float readkwh()
{
CS_kwh = true; // Start Critical Section - prevent interrupt Kirq() from changing rpk & rpk_old ;
long t = rpk; // store the raw pulse counter in a temp var.
long k = t - rpk_old; // subtract last measure to get delta
rpk_old = t; // remember old value
CS_kwh = false; // End Critical Section
return k / 2000.0; // return delta, one pulse = 0.5 watt.
}
/* einde eerste deel Kwh RobTillart*/
void setup()
{
Serial.begin(115200);
Serial.print("Start ");
Serial.println(__FILE__);
delay(1000);
Ethernet.begin(mac, ip);
delay(1000);
pinMode(4, OUTPUT); // SD select pin
digitalWrite(4, HIGH); // Explicitly disable SD
//Set RTS pin high, so smart meter will start sending telegrams
pinMode(requestPin, OUTPUT);
digitalWrite(requestPin, HIGH);
// kwh interrupt attached to IRQ 0 = pin2
attachInterrupt(0, Kirq, FALLING);
}
void loop()
{
decodeTelegram();
if (millis() - lastTime > interval) {
lastTime = millis();
// read the pulses
kwh = readkwh1();
sum += kwh;
// send new data
httpRequest();
//Reset variables to zero for next run
mEVLT = 0;
mEVHT = 0;
mELLZ = 0;
mEHLZ = 0;
mEAV = 0;
mEAA = 0;
mEPV = 0;
mG = 0;
}
}
bool decodeTelegram()
{
bool newData = false;
long tl = 0;
long tld = 0;
while (Serial.available())
{
input = Serial.read();
Serial.write(input);
buffer[bufpos++] = input & 127;
char inChar = (char)input;
if (input == '\n') // We received a new line (data up to \n)
{
newData = true;
// 1-0:1.8.1 = Elektra verbruik laag tarief (DSMR v4.0)
if (sscanf(buffer, "1-0:1.8.1(%ld.%ld" , &tl, &tld) == 2)
{
mEVLT = tl * 1000 + tld;
}
// 1-0:1.8.2 = Elektra verbruik hoog tarief (DSMR v4.0)
if (sscanf(buffer, "1-0:1.8.2(%ld.%ld" , &tl, &tld) == 2)
{
mEVHT = tl * 1000 + tld;
}
// 1-0:2.8.1 = Elektra levering laag tarief (DSMR v4.0)
if (sscanf(buffer, "1-0:2.8.1(%ld.%ld" , &tl, &tld) == 2)
{
mELLZ = tl * 1000 + tld;
}
// 1-0:2.8.2 = Elektra levering hoog tarief (DSMR v4.0)
if (sscanf(buffer, "1-0:2.8.2(%ld.%ld" , &tl, &tld) == 2)
{
mEHLZ = tl * 1000 + tld;
}
// 1-0:1.7.0 = Elektra huidig verbruik (DSMR v4.0)
if (sscanf(buffer, "1-0:1.7.0(%ld.%ld" , &tl , &tld) == 2)
{
mEAV = tl * 1000 + tld;
}
// 1-0:31.7.0 = Elektra stroom (DSMR v4.0)
if (sscanf(buffer, "1-0:31.7.0(%ld" , &tl) == 1)
{
mEAA = tl;
Serial.print("Ampere = ");
Serial.print(mEAA);
Serial.println(" ");
}
// 1-0:2.7.0 = Elektra geleverd (DSMR v4.0)
if (sscanf(buffer, "1-0:2.7.0(%ld.%ld" , &tl , &tld) == 2)
{
mEPV = tl * 1000 + tld;
}
// 0-1:24.2.1 = Gas (DSMR v4.0) on Kaifa MA105 meter
if (strncmp(buffer, "0-1:24.2.1", strlen("0-1:24.2.1")) == 0) {
if (sscanf(strrchr(buffer, '(') + 1, "%d.%d", &tl, &tld) == 2)
{
mG = tl * 1000 + tld;
}
}
// Empty buffer again (whole array)
for (int i = 0; i < 75; i++)
{
buffer[i] = 0;
}
bufpos = 0;
break;
}
}
return newData;
}
void httpRequest()
{
// if there's a successful connection:
if (client.connect(serverName, 80))
{ float kwh = readkwh();
float sum = readkwh1();
Serial.print("GET /datalogger/p3.php?mEVLT=");
Serial.print(mEVLT);
Serial.print("&mEVHT=");
Serial.print(mEVHT);
Serial.print("&mELLZ=");
Serial.print(mELLZ);
Serial.print("&mEHLZ=");
Serial.print(mEHLZ);
Serial.print("&mEAV=");
Serial.print(mEAV);
Serial.print("&mEAA=");
Serial.print(mEAA);
Serial.print("&mEPV=");
Serial.print(mEPV);
Serial.print("&kwh=");
Serial.print(kwh);
Serial.print("&sum=");
Serial.print(sum);
Serial.print("&mG=");
Serial.print(mG);
Serial.println(" HTTP/1.1");
Serial.println("Host: &&&&&.com");
Serial.println("User-Agent: arduino-ethernet");
Serial.println("Connection: stop/close");
Serial.println();
client.print("GET /datalogger/p3.php?mEVLT=");
client.print(mEVLT);
client.print("&mEVHT=");
client.print(mEVHT);
client.print("&mELLZ=");
client.print(mELLZ);
client.print("&mEHLZ=");
client.print(mEHLZ);
client.print("&mEAV=");
client.print(mEAV);
client.print("&mEAA=");
client.print(mEAA);
client.print("&mEPV=");
client.print(mEPV);
client.print("&kwh=");
client.print(kwh);
client.print("&sum=");
client.print(sum);
client.print("&mG=");
client.print(mG);
client.println(" HTTP/1.1");
client.println("Host: &&&&&.com");
client.println("User-Agent: arduino-ethernet");
client.println("Connection: close");
//Request complete; empty recieve buffer
while (client.available())
{
char c = client.read(); //gets byte from ethernet buffer
if (client.available() == false)
{
delay(25); // give some extra time for next packet to arrive
}
}
client.println();
Serial.println("Success!");
}
else
{
Serial.println("Failed");
}
client.stop();
}
De sketchen inclusief schrijven naar database werken ieders appart wel. Echter wil ik ze graag als 1 sketch.
De slimme-meter wordt keurig uitgelezen en in de database gezet.
Het kwh-meterje (even een andere want de zon doet het niet) telt niet er wordt wel 0 in database gezet.
help