Go Down

Topic: Slimme-meter en S0-bus uitlezen en naar Database (Read 10199 times) previous topic - next topic

arnaudarduino

#15
Dec 10, 2015, 04:56 pm Last Edit: Dec 10, 2015, 07:44 pm by arnaudarduino
Nu krijg ik best wel aardig wat data binnen met deze sketch.
Maar de arduino of netwerkshield of sketch stopt met regelmaat.
Dan moet ik de voeding even loskoppelen en weer opstarten.
Dan werkt het weer poosje ene keer aantal dagen dan weer een uur of 10.

Wat raden jullie aan om als voeding te gebruiken.?

Nu heb ik er een usb-lader als voeding.

En ik krijg nog steeds niet voor elkaar om met een mills timer de variabele  rpk naar 0 te zetten na (omgerekend) 23:55 uur


shooter

ik verdenk je programma, zoals declaraties die je in de loop hebt staan, beter is om dat boven de setup te doen, dan blijven ze vast staan ipv dat ze steeds aangemaakt worden.
stel even je maakt een byte aan, dan maak je nog een byte aan, dan maak je een word aan, vervolgens maak je die eerste byte weer aan, waardoor de byte vrijkomt en op een andereplaats weer gemaakt wordt, dit was vroeger in basic een probleem.

paul deelen
shooter@home.nl
making controls with codesys PLC and arduino

arnaudarduino

#17
Dec 10, 2015, 07:58 pm Last Edit: Dec 10, 2015, 08:15 pm by arnaudarduino
Zucht, dat snap ik wel, maar om dat dan aan te passen?.?.?.?.?
Geen idee. Was al blij dat de arduino nu meet wat die moet meten.
Dacht er al aan om nog er nog een kwh bij te plaatsen, maar toch maar even niet.
Maar nu is die niet meer stabiel. Ik dacht misschien dat de usb adaptervoeding het probleem zou zijn.



nicoverduin

Zucht, dat snap ik wel, maar om dat dan aan te passen?.?.?.?.?
Geen idee. Was al blij dat de arduino nu meet wat die moet meten.
Dacht er al aan om nog er nog een kwh bij te plaatsen, maar toch maar even niet.
Maar nu is die niet meer stabiel. Ik dacht misschien dat de usb adaptervoeding het probleem zou zijn.



Tja dat is nu eenmaal het verschil tussen iemand die een keer iets bouwt en de vakman die nadenkt over architectuur, memory management, structuur enz. Maar mocht je denken dat je de enige was, dan kan ik je teleurstellen. Zie het zo, van je fouten kun je leren. :)
Met vriendelijke groet / kindest regards
Nico Verduin
www.verelec.nl
Do not PM me for personal consultancy unless you are willing to pay for it.

MAS3

Ik raad je aan om het toch op te lossen.
Je mag er bij zuchten en je mag er ook best bij tieren, ik ga dat toch niet horen.
Maar je leert er echt wat van als je het kunt oplossen, en je mag dan ook trots zijn op jezelf (nog meer dan je nu al (terecht) bent).

De volgende keer dat je een projectje bedenkt, zul je er dankbaar gebruik van maken, wellicht zonder er echt bij stil te staan.

Ik moest, net als de andere respondenten, meteen denken aan het vollopen van het beperkte geheugen.
Je hebt je proof of concept, nu nog de puntjes op de ï zetten.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

arnaudarduino

Zo, nu dat hij weer gestopt was zag ik dat die dat deed na dat de pulsenteller zich resette ( waarom ??).
Hij ging op 0 daarna was de arduino gestopt met schrijven naar de database.
Ik heb de pulsenteller nu losgekoppeld dwz + draad van de s0 af, arduino weer aan gezet.
Nu eerst maar eens afwachten of die weer gaat stoppen. Ik denk het niet.
Als die na 3 dagen nog doorloopt weet ik dat het probleem zich niet voor doet in het deel van de slimmemeter sketch.

Wordt vervolgt:

MAS3

Hoeveel pulsen waren er geteld toen ie resette ?
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

arnaudarduino

#22
Dec 12, 2015, 10:58 am Last Edit: Dec 12, 2015, 04:50 pm by arnaudarduino
(8:10)  De waarde van sum (optelling van kwhpulsen) 2.80500 daarna ging die op 0.
Het zit hem echt in de sketch pulsenteller, maar dan wel de manier waarop het samen gevoegd is.
Want standalone loopt die ook niet vast/reset.
Ik wacht het nog even paar dagen af.
Paar dagen lukt niet eens want,
(8:23)  Hij is alweer gestopt. Ik ga de sketch met de pulsenteller er tussen uit halen eens zien of hij dan blijft doorlopen.
Weer proberen.
 

arnaudarduino

Sketch blijft nu alweer 2 dagen doorlopen zonder fout.

Dus , ik had (met hulp) 2 sketch en samen gevoegd maar het bijt elkaar blijkbaar.
Los van elkaar lopen ze beide prima.

In de vakantie nog maar eens een poging wagen. Of iemand moet hier zeggen, ooh daar zit het.

Bedankt alvast.

nicoverduin

Als ik de sketch wat snel scan, dan zie ik een mogelijke verstoorder in het gebruik van buffer.
a) het is een string veld, maar hij wordt niet afgesloten door een '\0'. De kans bestaat dat je buiten het buffer gebied kom. Daarnaast  test je niet of je over de 74 tekens gaat. Theoretisch kun je dus buiten de buffer komen en andere variabelen overschrijven.
Tenslotte hoef je niet de buffer helemaal op 0 te zetten. Als je de allereerste byte op '\0' zet is de string afgesloten met een lengte 0.
Met vriendelijke groet / kindest regards
Nico Verduin
www.verelec.nl
Do not PM me for personal consultancy unless you are willing to pay for it.

arnaudarduino

Het buffergebied van 74 waarom 74 en 125 ofzo.?
Vandaag meerdere malen gemerkt dat een belasting van 25watt een uur lang registreerde en dan stopte. Nu heb ik bij wijze van een test de buffer op 125 gezet ,nu loopt hij al 2 3/4 uur door.
Kan iemand mij daar wat over uitleggen?

Fijne kerst allemaal

nicoverduin

Het buffergebied is waar je de messages in zet. Dat is gewoon een array. Maar wat doe je nu als de message langer is dan die 74? Als je nergens test of je meer ontvangt, dan wordt het geheugen achter de 74'ste byte gewoon overschreven. En als daar nu net een variabele staat die jouw programma nodig heeft, heb je, zachtjes uitgedrukt, een groot probleem. Als hij nu met een grotere buffer wel langer werkt, zou het kunnen dat dit inderdaad de oorzaak is. Neemt niet weg dat, wat doe je als je nog langere boodschappen binnen krijg.
Met vriendelijke groet / kindest regards
Nico Verduin
www.verelec.nl
Do not PM me for personal consultancy unless you are willing to pay for it.

arnaudarduino

#27
Jan 06, 2016, 07:49 pm Last Edit: Oct 19, 2016, 09:22 pm by arnaudarduino
Allemaal veel goeds gewenst voor 2016.

De arduino sketch blijft nu mooi doorlopen, ik heb de buffer naar 500 gezet.
'S nachts gaat de arduino dmv een klok in de meterkast 5 minuten uit.
Daarmee gaat de pulsteller op 0.
Dan kan ik nu denken aan of ik er nog een kwh meter aan ga hangen, en ik moet een pcb er voor gaan maken, in de vorm van een shield. Zal de sketch nog aanpassen zoals die nu werkt, en hier plaatsen.
Code: [Select]

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0x30, 0x32, 0x31};
IPAddress ip(192, 168, 2, 114);
char serverName[] = "www.eigensite.com";

EthernetClient client;

const int requestPin = 5;
char input;                     // incoming serial data (byte)
bool readnextLine = false;

#define BUFSIZE 500
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 kwh = 0;          // pulse
unsigned long sum = 0;          // sum pulse
unsigned long mG = 0;           // Gas
unsigned long lastTime = 0;     // will store last time
unsigned long interval = 60000; // interval at which to blink (milliseconds)60000


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.
}



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 /logger/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, 4);
   Serial.print("&sum=");
   Serial.print(sum, 4);
   Serial.print("&mG=");
   Serial.print(mG);
   Serial.println(" HTTP/1.1");
   Serial.println("Host: eigensite.com");
   Serial.println("User-Agent: arduino-ethernet");
   Serial.println("Connection: stop/close");
   Serial.println();
   Serial.println("web ");

   client.print("GET /logger/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, 4);
   client.print("&sum=");
   client.print(sum, 4);
   client.print("&mG=");
   client.print(mG);
   client.println(" HTTP/1.1");
   client.println("Host: eigensite.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();

}

arnaudarduino

#28
Jan 06, 2016, 08:42 pm Last Edit: Jan 06, 2016, 09:06 pm by arnaudarduino
Het p3.php bestand, die de gegevens naar de database schrijft.

Code: [Select]
<?php
error_reporting
(E_ALL);

//Connect to database
include 'config.php';
include 
'opendb.php';

//Waardes van vorige wegschrijf actie ophalen
$query mysql_query("SELECT laag_tarief, hoog_tarief, laag_tarief_geleverd, hoog_tarief_geleverd, huidig_verbruik, stroom_verbruik, huidig_geleverd, gas, NLE tarief, ZON tarief  FROM `readings` ORDER BY `readings`.`time`  DESC LIMIT 1");
$row mysql_fetch_array($query);
$previous_laag_tarief $row[0];
$previous_hoog_tarief $row[1];
$previous_laag_tarief_geleverd $row[2];
$previous_hoog_tarief_geleverd $row[3];
$previous_huidig $row[4];
$previous_huidig_geleverd $row[5];
$previous_gas $row[6];
$min_vermogen 0;
$max_vermogen 230*25//Maximale vermogen = 230V * vermogen hoofdzekering (1x25A)

//Alle opgehaalde variabelen op type 'INTEGER' zetten ivm vergelijken zometeen
settype($previous_elektra"integer");
settype($previous_huidig"integer");
settype($previous_huidig_geleverd"integer");
settype($previous_gas"integer");

//GET variabelen naar andere variabele schrijven
$mEVLT $_GET["mEVLT"];
$mEVHT $_GET["mEVHT"];
$mELLZ $_GET["mELLZ"];
$mEHLZ $_GET["mEHLZ"];
$mEAV $_GET["mEAV"];
$mEAA $_GET["mEAA"];
$mEPV $_GET["mEPV"];
$mG $_GET["mG"];

//GET variabelen op 'integer' zetten 
settype($mEVLT"integer");
settype($mEVHT"integer");
settype($mELLZ"integer");
settype($mEHLZ"integer");
settype($mEAV"integer");
settype($mEAA"integer");
settype($mEPV"integer");
settype($mG"integer");


//Checken of binnengekomen standen voldoen aan eisen (meterstand = hoger dan vorige, huidig verbruik > minimale vermogen, kleiner dan maximale vermogen) om incorrecte waarden te negeren
if (
    
$mEVLT >= $previous_laag_tarief
    
&& $mEVHT >= $previous_hoog_tarief 
    
&& $mG >= $previous_gas //Inkomende meterstand moet groter zijn dan vorige meterstand
    
&& $mG <= ($mG 6000//Gasmeter is type 'G6', which stands for max. 6m3/hour. So value can never be bigger than value + 6000
    
&& $mEAV >= $min_vermogen //Huidig verbruik moet groter zijn dan minimale verbruik (nachtverbruik)
    
&& $mEAV <= $max_vermogen //Huidig verbruik moet kleiner zijn dan max. vermogen 1fase aansluiting
    


    
$SQL "INSERT INTO md30db33.readings (id, time, laag_tarief, hoog_tarief, laag_tarief_geleverd, hoog_tarief_geleverd, huidig_verbruik, stroom_verbruik, huidig_geleverd, gas) VALUES (NULL, NULL, '".$mEVLT."', '".$mEVHT."', '".$mELLZ."', '".$mEHLZ."', '".$mEAV."', '".$mEAA."', '".$mEPV."', '".$mG."')";     
    
mysql_query($SQL);

}
else { 

    
//Foutieve waarden wegschrijven naar tabel voor latere debugging
    
$SQL "INSERT INTO md30db33.faulty_readings (id, time, laag_tarief, hoog_tarief, laag_tarief_geleverd, hoog_tarief_geleverd, huidig_verbruik,  huidig_geleverd, gas) VALUES           (NULL, NULL, '".$mEVLT."', '".$mEVHT."', '".$mELLZ."', '".$mEHLZ."', '".$mEAV."', '".$mEAA."', '".$mEPV."', '".$mG."')";    
    
mysql_query($SQL);
}


?>



De tabel voor de database ,readings
Code: [Select]
CREATE TABLE  `md309341db332687`.`readings` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT ,
 `time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
 `laag_tarief` DECIMAL( 11, 0 ) NOT NULL ,
 `hoog_tarief` INT( 11 ) NOT NULL ,
 `laag_tarief_geleverd` INT( 11 ) NOT NULL ,
 `hoog_tarief_geleverd` INT( 11 ) NOT NULL ,
 `huidig_verbruik` DECIMAL( 11, 0 ) NOT NULL ,
 `stroom_verbruik` DECIMAL( 11, 0 ) NOT NULL ,
 `huidig_geleverd` DECIMAL( 11, 0 ) NOT NULL ,
 `kwh` VARCHAR( 11 ) CHARACTER SET utf8 NOT NULL ,
 `sum` VARCHAR( 11 ) CHARACTER SET utf8 NOT NULL ,
 `gas` INT( 11 ) NOT NULL ,
PRIMARY KEY (  `id` )
) ENGINE = INNODB DEFAULT CHARSET = latin1;


Zo werkt het bij mij.

arnaudarduino

#29
Jan 17, 2016, 07:47 pm Last Edit: Apr 24, 2016, 04:27 pm by arnaudarduino
En nog steeds zonder ongewenst uitvallen.
Werkt nog steeds noukeurig.
(Deze uitlezing laat ik uiteindelijk door een raspberry doen).

Go Up