Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. My Project
  3. Gas meter monitoring with optical sensor

Gas meter monitoring with optical sensor

Scheduled Pinned Locked Moved My Project
5 Posts 3 Posters 4.6k Views 4 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • rubyanR Offline
    rubyanR Offline
    rubyan
    wrote on last edited by
    #1

    Hi all,

    This project enables me to read the gas meter using an optical sensor, the TCRT5000. The last digit of the meter has a reflective '6' that triggers the optical circuit. The board is powered by the well known HLK-PM01, and uses an arduino pro mini (clone). The nrf24 is fitted into a board that provides a proper 3.3v voltage. The board can receive OTA firmware upgrades :)

    The sketch (that i adapted from Sandor Incze & Michel Schilthuizen) uses debounce, and raises the counter only if filtered pin value goes from 0 to 1. There is no problem if the meter stops at the '6'. If the sketch starts, it asks the controller for the last known value.

    I use domoticz to present the readings. At this moment, there seems to be a problem with the large numbers that my meter uses, I still need to figure this out.

    Future updates consist of using a fuse and thermistor with the power supply to make it more safe, and to create a nice casing.

    5_1473413948459_IMG_20160909_111734.JPG 4_1473413948458_IMG_20160909_110618.JPG 3_1473413948458_IMG_20160909_110324.JPG 2_1473413948458_IMG_20160909_110304.JPG 1_1473413948458_IMG_20160909_110255.JPG 0_1473413948458_domoticz.png

    code: github

    1 Reply Last reply
    4
    • E Offline
      E Offline
      ericvdb
      wrote on last edited by
      #2

      @rubyan , I used this method too many years ago, but it was not reliable in my case because the meter was located in the garage, and every time we turned on the light, it would add pulses.

      Can you post a picture of you complete gas meter? Depending on your meter I might have a better solution ;-)

      1 Reply Last reply
      0
      • I Offline
        I Offline
        insomnia
        wrote on last edited by insomnia
        #3

        Could you place the sketch here? Thanks

        1 Reply Last reply
        0
        • rubyanR Offline
          rubyanR Offline
          rubyan
          wrote on last edited by
          #4

          The code is on github:

          https://github.com/Rubyan/MySensors/blob/master/Meterkast/Meterkast.ino

          I 1 Reply Last reply
          0
          • rubyanR rubyan

            The code is on github:

            https://github.com/Rubyan/MySensors/blob/master/Meterkast/Meterkast.ino

            I Offline
            I Offline
            insomnia
            wrote on last edited by insomnia
            #5

            @rubyan

            Thanks, i have some trouble with adjusting it. I set the trct5000 when the 6 comes by the led goes on. When i use this sketch from the forum

            /**
             * 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 =550.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++; 
            }
            

            The counter goes up but it is still off with the gasmeter. Then i upload you're sketch and the counter doesn't go up and the serial monitor says Stable pin value different!
            Can you help?

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            10

            Online

            11.7k

            Users

            11.2k

            Topics

            113.0k

            Posts


            Copyright 2019 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • MySensors
            • OpenHardware.io
            • Categories
            • Recent
            • Tags
            • Popular