Home Gas measuring..



  • Hello,

    I've made a circuit to readout my home gas usage.
    I took the water usage sketch from the mysensors site and changed S_WATER into S_GAS.

    The readout on my serial port of the arduino is good, i also see this in Domoticz, but some parts don't look fermiliar or in good order, and i like to add something but don't know how..

    This is the code:

    
    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Mark Verstappen
     * 
     * DESCRIPTION
     * Use this sensor to measure volume and flow of your house gasmeter.
     * You need to set the correct pulsefactor of your meter (pulses per m3).
     * The sensor starts by fetching current volume reading from gateway (VAR 1).
     * Reports both volume and flow back to gateway.
     *
     * Unfortunately millis() won't increment when the Arduino is in 
     * sleepmode. So we cannot make this sensor sleep if we also want  
     * to calculate/report flow.
     * http://www.mysensors.org/build/pulse_water
     */
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG 
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <Time.h>
    #include <TimeLib.h>
    
    #include <SPI.h>
    #include <MySensor.h>  
    
    #define DIGITAL_INPUT_SENSOR 3                  // The digital input you attached your sensor.  (Only 2 and 3 generates interrupt!)
    #define SENSOR_INTERRUPT DIGITAL_INPUT_SENSOR-2        // Usually the interrupt = pin -2 (on uno/nano anyway)
    
    #define PULSE_FACTOR 100                       // Nummber of blinks per m3 of your meter (One rotation/liter)
    
    #define SLEEP_MODE false                        // flowvalue can only be reported when sleep mode is false.
    
    #define MAX_FLOW 0,1                             // Max flow (l/min) value to report. This filters outliers.
    
    #define CHILD_ID 1                              // Id of the sensor child
    
    unsigned long SEND_FREQUENCY = 30000;           // Minimum time between send (in milliseconds). We don't want to spam the gateway.
    
    MyMessage flowMsg(CHILD_ID,V_FLOW);
    MyMessage volumeMsg(CHILD_ID,V_VOLUME);
    MyMessage lastCounterMsg(CHILD_ID,V_VAR1);
    
    double ppl = ((double)PULSE_FACTOR)/1000;        // Pulses per liter
    
    volatile unsigned long pulseCount = 0;   
    volatile unsigned long lastBlink = 0;
    volatile double flow = 0;  
    boolean pcReceived = false;
    unsigned long oldPulseCount = 0;                 
    unsigned long newBlink = 0;   
    double oldflow = 0;
    double volume =0;                     
    double oldvolume =3987.67;                              // Oude meterstand
    unsigned long lastSend =0;
    unsigned long lastPulse =0;
    
    void setup()  
    {  
      // initialize our digital pins internal pullup resistor so one pulse switches from high to low (less distortion) 
      pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP);
      
      pulseCount = oldPulseCount = 0;
    
      // Fetch last known pulse count value from gw
      request(CHILD_ID, V_VAR1);
    
      lastSend = lastPulse = millis();
    
      attachInterrupt(SENSOR_INTERRUPT, onPulse, FALLING);
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Gas Meter", "1.0");
    
      // Register this device as Gasflow sensor
      present(CHILD_ID, S_GAS);       
    }
    
    void loop()     
    { 
      unsigned long currentTime = millis();
          
      // Only send values at a maximum frequency or woken up from sleep
      if (SLEEP_MODE || (currentTime - lastSend > SEND_FREQUENCY))
      {
        lastSend=currentTime;
        
        Serial.println("--------- Debug void loop ------------");
        
        if (!pcReceived) {
          //Last Pulsecount not yet received from controller, request it again
          request(CHILD_ID, V_VAR1);
          return;
        }
    
        if (!SLEEP_MODE && flow != oldflow) {
          oldflow = flow;
    
          Serial.print("m3/min:");
          Serial.println(flow);
    
          // Check that we dont get unresonable large flow value. 
          // could hapen when long wraps or false interrupt triggered
          if (flow<((unsigned long)MAX_FLOW)) {
            send(flowMsg.set(flow, 2));                   // Send flow value to gw
          }  
        }
      
        // No Pulse count received in 2min 
        if(currentTime - lastPulse > 120000){
          flow = 0;
        } 
    
        // Pulse count has changed
        if ((pulseCount != oldPulseCount)||(!SLEEP_MODE)) {
          oldPulseCount = pulseCount;
          
          Serial.println("flow:   ");
          Serial.print(flow);
          
    //      Serial.println(Time.now()); 
          Serial.print("pulsecount:   ");
          Serial.println(pulseCount);
    
          send(lastCounterMsg.set(pulseCount));                  // Send  pulsecount value to gw in VAR1
    
          double volume = ((double)pulseCount/((double)PULSE_FACTOR));     
          if ((volume != oldvolume)||(!SLEEP_MODE)) {
            oldvolume = volume;
    
            Serial.print("volume:   ");
            Serial.println(volume, 3);
            Serial.println("---------------------------------------------------");
            
            send(volumeMsg.set(volume, 3));               // Send volume value to gw
          } 
        }
      }
      if (SLEEP_MODE) {
        sleep(SEND_FREQUENCY);
      }
    }
    
    void receive(const MyMessage &message) {
      if (message.type==V_VAR1) {
        unsigned long gwPulseCount=message.getULong();
        pulseCount += gwPulseCount;
        flow=oldflow=0;
        Serial.println("--------------- Debug void receive ---------------"); 
        Serial.print("Received last pulse count from gw:   ");
        Serial.println(pulseCount);
        Serial.println("---------------------------------------------------");
        pcReceived = true;
      }
    }
    
    void onPulse()     
    {
      if (!SLEEP_MODE)
      {
        unsigned long newBlink = micros();   
        unsigned long interval = newBlink-lastBlink;
        
        Serial.println("--------------- Debug void onPulse ---------------"); 
    //    Serial.println("newblink:   "); 
    //    Serial.print(newBlink);
    //    Serial.println("interval:   "); 
    //    Serial.print(interval);
    //    Serial.println();  
        
        if (interval!=0)
        {
          lastPulse = millis();
          if (interval<500000L) {         
            // Sometimes we get interrupt on RISING,  500000 = 0.5sek debounce ( max 120 l/min)
            return;   
          }
          flow = (60000000.0 /interval) / ppl;
          Serial.println("flow = (60000000.0 /interval) / ppl");
          Serial.println(flow);
          Serial.println("---------------------------------------------------");
        }
        lastBlink = newBlink;
      }
      pulseCount++; 
    }
    

    Domoticz shows this:

    0_1467033253720_upload-2b3c3885-4357-4dce-8133-6d11a40cbc64

    The sensor registers each cycle.

    • Pulse counts are 134 wich corrosponds to the 1.340 volume.
      1m3 = 100 counts. (1 count is 0.01m3 )

    • What does the 0.230 value represent ??

    • The real count is more, is there a way to incorporate a option, to send a
      command through the serial console, wich updates the counter?
      For example when in a couple of months something goes wrong, you could update
      the counter with the correct value without, changing the compleet sketch, and there
      bij stopping the arduino etc.
      So some kind of counter update (Adjust) command through the serial console.

    • The flow isn't updated instantly, but each five minuts?
      I want it to be triggerd when the flow starts, measure, remind all data and when the
      flow stops report al the data at once.

    • Mysensors uses V_VOLUME and V_FLOW just as bij S_WATER therefore it says
      waterflow. So how could you change the type of the sensor (both aren't correct)?

    The update (adjust) option would be nice not only for gas measuring but als for water and electricity. (If you want to do it now, you have to dive into the db of domoticz)



  • Hi @MarkV,

    I will try to answer your questions as i am also using these meters.

    • Pulse counts correspond to the #define PULSE_FACTOR 100
    • The value in the upper right corner is the usage of that day (in your case 0.230m3 or 230 liters)
    • yes, you could edit the meter in the utility tab of Domoticz to add an offset but i don't use it so not sure.
    • Correct! the SEND_FREQUENCY is the interval in milliseconds (so 300000 is 5 minutes). You could lower it. I am currently working on a more instant update for the flow rate. I will test that after i calibrated the sensors and implemented the new library.
    • I am not sure, but I think this is something of Domoticz and not MySensors. Maybe there is no gas flow widget and the water widget is reused.

    The edit and offset option also works for the kWh meter and Water meter.

    Hope it helps.


 

346
Online

7.9k
Users

8.7k
Topics

93.6k
Posts