Advertisement
frankiepankie

P1 reader

Aug 5th, 2014
2,103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.29 KB | None | 0 0
  1. /* Arduino 'slimme meter' P1 port reader.
  2.  
  3. This sketch reads data from a Dutch smart meter that is equipped with a P1 port.
  4. Connect 'RTS' from meter to Arduino +5V
  5. Connect 'GND' from meter to Arduino GND
  6. Connect 'RxD' from meter to Arduino pin 8 (Digital)
  7.  
  8. Baudrate 115200, 8N1.
  9. BS170 transistor & 10k resistor is needed to make data readable if meter spits out inverted data
  10.  
  11. A .php file is requested (with consumption numbers in the GET request) everytime a telegram from the meter is received (every 10s)
  12.  
  13. created 2014
  14. by 'ThinkPad' @ Tweakers.net
  15.  
  16. http://gathering.tweakers.net/forum/list_messages/1601301
  17.  */
  18.  
  19. #include <AltSoftSerial.h>
  20. #include <SPI.h>
  21. #include <Ethernet.h>
  22. // AltSoftSerial always uses these pins:
  23. //
  24. // Board          Transmit  Receive   PWM Unusable
  25. // -----          --------  -------   ------------
  26. // Teensy 2.0         9        10       (none)
  27. // Teensy++ 2.0      25         4       26, 27
  28. // Arduino Uno        9         8         10
  29. // Arduino Mega      46        48       44, 45
  30. // Wiring-S           5         6          4
  31. // Sanguino          13        14         12
  32.  
  33. AltSoftSerial altSerial;
  34.  
  35. byte mac[] = {
  36.   0xDE, 0xAD, 0xBE, 0x30, 0x32, 0x31};
  37. IPAddress ip(192,168,4,7);
  38. IPAddress server(192,168,4,4);
  39. EthernetClient client;
  40.  
  41. const int requestPin =  4;        
  42. char input; // incoming serial data (byte)
  43. bool readnextLine = false;
  44. #define BUFSIZE 75
  45. char buffer[BUFSIZE]; //Buffer for serial data to find \n .
  46. int bufpos = 0;
  47. long mEVLT = 0; //Meter reading Electrics - consumption low tariff
  48. long mEAV = 0;  //Meter reading Electrics - Actual consumption
  49. long mG = 0;   //Meter reading Gas
  50.  
  51. void setup() {
  52.   Serial.begin(9600);
  53.   delay(1000);
  54.  
  55.   altSerial.begin(115200);
  56.   delay(1000);
  57.  
  58.   Ethernet.begin(mac, ip);
  59.   delay(1000);
  60.   Serial.print("My IP address: ");
  61.   Serial.println(Ethernet.localIP());
  62.   Serial.print("Server IP address: ");
  63.   Serial.println(server);
  64.  
  65.   pinMode(4, OUTPUT);                  // SD select pin
  66.   digitalWrite(4, HIGH);               // Explicitly disable SD
  67.  
  68.   //Set RTS pin high, so smart meter will start sending telegrams
  69.   pinMode(requestPin, OUTPUT);
  70.   digitalWrite(requestPin, HIGH);
  71. }
  72.  
  73. void loop() {
  74.  
  75.   decodeTelegram();
  76.  
  77. } //Einde loop
  78.  
  79. void decodeTelegram() {
  80.   long tl = 0;
  81.   long tld =0;
  82.  
  83.   if (altSerial.available()) {
  84.     input = altSerial.read();
  85.  
  86.     char inChar = (char)input;
  87.     // Fill buffer up to and including a new line (\n)
  88.     buffer[bufpos] = input&127;
  89.     bufpos++;
  90.  
  91.     if (input == '\n') { // We received a new line (data up to \n)
  92.       if (sscanf(buffer,"1-0:1.8.1(%ld.%ld" ,&tl, &tld)==2){
  93.         tl *= 1000;
  94.         tl += tld;
  95.         mEVLT = tl;
  96.         if (mEVLT > 0) {
  97.           Serial.println("*** BEGIN LOOP ***");
  98.           Serial.print("Elektra - meterstand verbruik LAAG tarief: ");
  99.           Serial.println(mEVLT);
  100.  
  101.         }
  102.       }
  103.  
  104.       // 1-0:1.7.0 = Electricity consumption actual usage (DSMR v4.0)
  105.       if (sscanf(buffer,"1-0:1.7.0(%ld.%ld" ,&tl , &tld) == 2)
  106.       {
  107.         mEAV = (tl*1000)+tld;
  108.         if (mEAV > 0) {
  109.           Serial.print("Elektra - actueel verbruik (W): ");
  110.           Serial.println(mEAV);
  111.         }
  112.       }
  113.  
  114.       // 0-1:24.2.1 = Gas (DSMR v4.0) on Kaifa MA105 meter
  115.       if (strncmp(buffer, "0-1:24.2.1", strlen("0-1:24.2.1")) == 0) {
  116.         if (sscanf(strrchr(buffer, '(') + 1, "%d.%d", &tl, &tld) == 2) {
  117.           mG = (tl*1000)+tld;
  118.           Serial.print("Gas - meterstand (liters): ");
  119.           Serial.println(mG);
  120.           Serial.println("");
  121.         }
  122.       }
  123.  
  124.       // Empty buffer again (whole array)
  125.       for (int i=0; i<75; i++)
  126.       {
  127.         buffer[i] = 0;
  128.       }
  129.       bufpos = 0;
  130.  
  131.     }
  132.  
  133.     if (input == '!') {   //uitroepteken geeft einde van telegram aan, dus we gaan data versturen
  134.       httpRequest();
  135.       mEVLT = 0;
  136.       mEAV = 0;
  137.       mG = 0;
  138.       client.stop();
  139.     } //Einde vraagteken detectie  
  140.  
  141.   } //Einde 'if AltSerial.available'
  142.  
  143. } //Einde 'decodeTelegram()' functie
  144.  
  145. void httpRequest() {
  146.   // if there's a successful connection:
  147.   if (client.connect(server, 80)) {
  148.     client.print("GET /www/slimmemeter/p1.php?mEVLT=");
  149.     client.print(mEVLT);
  150.     client.print("&mEAV=");
  151.     client.print(mEAV);
  152.     client.print("&mG=");
  153.     client.print(mG);
  154.     client.println(" HTTP/1.1");
  155.     client.println("Host: 192.168.4.4");
  156.     client.println("User-Agent: arduino-ethernet");
  157.     client.println("Connection: close");
  158.     client.println();
  159.     //Request complete; empty recieve buffer
  160.     while (client.available()) { //data available
  161.       char c = client.read(); //gets byte from ethernet buffer
  162.     }
  163.     client.println();
  164.     Serial.println("----------------------------Versturen naar database--------------------------");
  165.     Serial.println("Connection OK!");
  166.     Serial.print("GET /www/slimmemeter/p1.php?mEVLT=");
  167.     Serial.print(mEVLT);
  168.     Serial.print("&mEAV=");
  169.     Serial.print(mEAV);
  170.     Serial.print("&mG=");
  171.     Serial.println(mG);
  172.     Serial.println("-----------------------------------------------------------------------------");
  173.     Serial.println();
  174.     Serial.println("*** EINDE LOOP - Wachten op volgende telegram vanuit slimme meter ***");
  175.   }
  176.   else {
  177.     Serial.println("Connection failed");
  178.     client.stop();
  179.   }
  180. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement