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. Development
  3. combining pulse counters

combining pulse counters

Scheduled Pinned Locked Moved Development
19 Posts 4 Posters 5.8k Views 3 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.
  • htcaH Offline
    htcaH Offline
    htca
    wrote on last edited by
    #1

    I am trying to combine 3 pulse counters on 1 nano. I have a regular pulse counter based on a LDR, which counts the led pulses on the electricity meter and I have two pulse counters (one on the gas and one on the watermeter) counting the mirrors passages on the wheels.
    I would like to combine those on one nano and I started with the example of the electricity meter and modified it for 3 sensors. Than I got stuck...

    My errors starts here:

    MyMessage flowMsg(CHILD_ID_g,V_FLOW);
    MyMessage volumeMsg(CHILD_ID_g,V_VOLUME);
    MyMessage lastCounterMsg(CHILD_ID_g,V_VAR3);
    

    The full script:

    /**
     * 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 - Henrik EKblad
     * 
     * DESCRIPTION
     * This sketch provides an example how to implement a distance sensor using HC-SR04 
     * Use this sensor to measure KWH and Watt of your house meeter
     * You need to set the correct pulsefactor of your meeter (blinks per KWH).
     * The sensor starts by fetching current KWH value from gateway.
     * Reports both KWH and Watt 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 watt-number.
     * http://www.mysensors.org/build/pulse_power
     */
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <MySensors.h>  
    #define SLEEP_MODE false        // values can only be reported when sleep mode is false.
    
    //electriciteit
    #define DIGITAL_INPUT_SENSOR_e 2  // The digital input you attached your light sensor.  (Only 2 and 3 generates interrupt!)
    #define PULSE_FACTOR_e 1000       // Nummber of blinks per KWH of your meeter
    #define MAX_WATT_e 10000          // Max watt value to report. This filetrs outliers.
    #define CHILD_ID_e 1              // Id of the sensor child
    
    //water
    #define DIGITAL_INPUT_SENSOR_w 3  // The digital input you attached your light sensor.  (Only 2 and 3 generates interrupt!)
    #define PULSE_FACTOR_w 1000       // Nummber of blinks per KWH of your meeter
    #define MAX_WATER 10000          // Max watt value to report. This filetrs outliers.
    #define CHILD_ID_w 2              // Id of the sensor child
    
    //gas
    #define DIGITAL_INPUT_SENSOR_g 4  // The digital input you attached your light sensor.  (Only 2 and 3 generates interrupt!)
    #define PULSE_FACTOR_g 1000       // Nummber of blinks per KWH of your meeter
    #define MAX_GAS 10000          // Max watt value to report. This filetrs outliers.
    #define CHILD_ID_g 3              // Id of the sensor child
    
    
    unsigned long SEND_FREQUENCY = 20000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway.
    double ppwh_e = ((double)PULSE_FACTOR_e)/1000; // Pulses per watt hour
    double ppwh_w = ((double)PULSE_FACTOR_w)/1000; // Pulses per watt hour
    double ppwh_g = ((double)PULSE_FACTOR_g)/1000; // Pulses per watt hour
    bool pcReceived = false;
    volatile unsigned long pulseCount_e = 0;   
    volatile unsigned long pulseCount_w = 0;   
    volatile unsigned long pulseCount_g = 0;   
    volatile unsigned long lastBlink_e = 0;
    volatile unsigned long lastBlink_w = 0;
    volatile unsigned long lastBlink_g = 0;
    volatile unsigned long watt = 0;
    volatile unsigned long waterflow = 0;
    volatile unsigned long gasflow = 0;
    unsigned long oldPulseCount_e = 0;   
    unsigned long oldPulseCount_w = 0;   
    unsigned long oldPulseCount_g = 0;   
    unsigned long oldWatt = 0;
    unsigned long oldWater = 0;
    unsigned long oldGas = 0;
    double oldKwh;
    double oldwater;
    double oldgas;
    unsigned long lastSend;
    MyMessage wattMsg(CHILD_ID_e,V_WATT);
    MyMessage kwhMsg(CHILD_ID_e,V_KWH);
    MyMessage pcMsg(CHILD_ID_e,V_VAR1);
    MyMessage flowMsg(CHILD_ID_w,V_FLOW);
    MyMessage volumeMsg(CHILD_ID_w,V_VOLUME);
    MyMessage lastCounterMsg(CHILD_ID_w,V_VAR2);
    
    MyMessage flowMsg(CHILD_ID_g,V_FLOW);
    MyMessage volumeMsg(CHILD_ID_g,V_VOLUME);
    MyMessage lastCounterMsg(CHILD_ID_g,V_VAR3);
    
    
    void setup()  
    {  
      // Fetch last known pulse count value from gw
      request(CHILD_ID_e, V_VAR1);
      request(CHILD_ID_w, V_VAR2);
      request(CHILD_ID_g, V_VAR3);
    
      // Use the internal pullup to be able to hook up this sketch directly to an energy meter with S0 output
      // If no pullup is used, the reported usage will be too high because of the floating pin
      pinMode(DIGITAL_INPUT_SENSOR_e,INPUT_PULLUP);
      pinMode(DIGITAL_INPUT_SENSOR_w,INPUT_PULLUP);
      pinMode(DIGITAL_INPUT_SENSOR_g,INPUT_PULLUP);
    
      attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR_e), onPulse_e, RISING);
      attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR_w), onPulse_w, RISING);
      attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR_g), onPulse_g, RISING);
      lastSend=millis();
    }
    
    void presentation() {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Marcel Meterkast", "1.0");
    
      // Register this device as power sensor
      present(CHILD_ID_e, S_POWER);
      present(CHILD_ID_w, S_WATER);
      present(CHILD_ID_g, S_GAS);
    }
    
    void loop()     
    { 
      unsigned long now = millis();
      // Only send values at a maximum frequency or woken up from sleep
      bool sendTime = now - lastSend > SEND_FREQUENCY;
      if (pcReceived && (SLEEP_MODE || sendTime)) {
        // New watt value has been calculated  
        // electricity first
        if (!SLEEP_MODE && watt != oldWatt) {
          // Check that we dont get unresonable large watt value. 
          // could hapen when long wraps or false interrupt triggered
          if (watt<((unsigned long)MAX_WATT)) {
            send(wattMsg.set(watt));  // Send watt value to gw 
          }  
          Serial.print("Watt:");
          Serial.println(watt);
          oldWatt = watt;
        }
        // send water
        if (!SLEEP_MODE && waterflow != oldWater) {
          // Check that we dont get unresonable large watt value. 
          // could hapen when long wraps or false interrupt triggered
          if (waterflow<((unsigned long)MAX_WATER)) {
            send(wattMsg.set(waterflow));  // Send watt value to gw 
          }  
          Serial.print("Gas:");
          Serial.println(gasflow);
          oldWater = waterflow;
        }
    
        // send gas
        if (!SLEEP_MODE && gasflow != oldGas) {
          // Check that we dont get unresonable large watt value. 
          // could hapen when long wraps or false interrupt triggered
          if (gasflow<((unsigned long)MAX_GAS)) {
            send(wattMsg.set(gasflow));  // Send watt value to gw 
          }  
          Serial.print("gas:");
          Serial.println(gasflow);
          oldGas = gasflow;
        }
        
        // Pulse cout has changed
        if (pulseCount_e != oldPulseCount_e) {
          send(pcMsg.set(pulseCount_e));  // Send pulse count value to gw 
          double kwh = ((double)pulseCount_e/((double)PULSE_FACTOR_e));     
          oldPulseCount_e = pulseCount_e;
          if (kwh != oldKwh) {
            send(kwhMsg.set(kwh, 4));  // Send kwh value to gw 
            oldKwh = kwh;
          }
        }
        if (pulseCount_w != oldPulseCount_w) {
          send(pcMsg.set(pulseCount_w));  // Send pulse count value to gw 
          double water = ((double)pulseCount_w/((double)PULSE_FACTOR_w));     
          oldPulseCount_w = pulseCount_w;
          if (water != oldwater) {
            send(kwhMsg.set(kwh, 4));  // Send kwh value to gw 
            oldwater = water;
          }
        }
        if (pulseCount_g != oldPulseCount_g) {
          send(pcMsg.set(pulseCount_g));  // Send pulse count value to gw 
          double gas = ((double)pulseCount_g/((double)PULSE_FACTOR_g));     
          oldPulseCount_g = pulseCount_g;
          if (gas != oldgas) {
            send(kwhMsg.set(gas, 4));  // Send kwh value to gw 
            oldgas = gas;
          }
        }    
        lastSend = now;
      } else if (sendTime && !pcReceived) {
        // No count received. Try requesting it again
        request(CHILD_ID_e, V_VAR1);
        request(CHILD_ID_w, V_VAR2);
        request(CHILD_ID_g, V_VAR3);
        lastSend=now;
      }
    
      if (SLEEP_MODE) {
        sleep(SEND_FREQUENCY);
      }
    }
    
    void receive(const MyMessage &message) {
      if (message.type==V_VAR1) {  
        pulseCount = oldPulseCount = message.getLong();
        Serial.print("Received last pulse count from gw for:");
        Serial.println(pulseCount);
        pcReceived = true;
      }
    }
    
    void onPulse_e()     
    { 
      if (!SLEEP_MODE) {
        unsigned long newBlink = micros();  
        unsigned long interval = newBlink_e-lastBlink_e;
        if (interval<10000L) { // Sometimes we get interrupt on RISING
          return;
        }
        watt = (3600000000.0 /interval) / ppwh_e;
        lastBlink_e = newBlink_e;
      } 
      pulseCount_e++;
    }
    
    void onPulse_w()     
    { 
      if (!SLEEP_MODE) {
        unsigned long newBlink = micros();  
        unsigned long interval = newBlink-lastBlink_w;
        if (interval<10000L) { // Sometimes we get interrupt on RISING
          return;
        }
        waterflow = (3600000000.0 /interval) / ppwh_w;
        lastBlink_w = newBlink;
      } 
      pulseCount_w++;
    }
    
    void onPulse_g()     
    { 
      if (!SLEEP_MODE) {
        unsigned long newBlink = micros();  
        unsigned long interval = newBlink-lastBlink_g;
        if (interval<10000L) { // Sometimes we get interrupt on RISING
          return;
        }
        gasflow = (3600000000.0 /interval) / ppwh_g;
        lastBlink_g = newBlink;
      } 
      pulseCount_w++;
    }
    
    mfalkviddM 1 Reply Last reply
    0
    • htcaH htca

      I am trying to combine 3 pulse counters on 1 nano. I have a regular pulse counter based on a LDR, which counts the led pulses on the electricity meter and I have two pulse counters (one on the gas and one on the watermeter) counting the mirrors passages on the wheels.
      I would like to combine those on one nano and I started with the example of the electricity meter and modified it for 3 sensors. Than I got stuck...

      My errors starts here:

      MyMessage flowMsg(CHILD_ID_g,V_FLOW);
      MyMessage volumeMsg(CHILD_ID_g,V_VOLUME);
      MyMessage lastCounterMsg(CHILD_ID_g,V_VAR3);
      

      The full script:

      /**
       * 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 - Henrik EKblad
       * 
       * DESCRIPTION
       * This sketch provides an example how to implement a distance sensor using HC-SR04 
       * Use this sensor to measure KWH and Watt of your house meeter
       * You need to set the correct pulsefactor of your meeter (blinks per KWH).
       * The sensor starts by fetching current KWH value from gateway.
       * Reports both KWH and Watt 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 watt-number.
       * http://www.mysensors.org/build/pulse_power
       */
      
      // Enable debug prints
      #define MY_DEBUG
      
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      //#define MY_RADIO_RFM69
      
      #include <MySensors.h>  
      #define SLEEP_MODE false        // values can only be reported when sleep mode is false.
      
      //electriciteit
      #define DIGITAL_INPUT_SENSOR_e 2  // The digital input you attached your light sensor.  (Only 2 and 3 generates interrupt!)
      #define PULSE_FACTOR_e 1000       // Nummber of blinks per KWH of your meeter
      #define MAX_WATT_e 10000          // Max watt value to report. This filetrs outliers.
      #define CHILD_ID_e 1              // Id of the sensor child
      
      //water
      #define DIGITAL_INPUT_SENSOR_w 3  // The digital input you attached your light sensor.  (Only 2 and 3 generates interrupt!)
      #define PULSE_FACTOR_w 1000       // Nummber of blinks per KWH of your meeter
      #define MAX_WATER 10000          // Max watt value to report. This filetrs outliers.
      #define CHILD_ID_w 2              // Id of the sensor child
      
      //gas
      #define DIGITAL_INPUT_SENSOR_g 4  // The digital input you attached your light sensor.  (Only 2 and 3 generates interrupt!)
      #define PULSE_FACTOR_g 1000       // Nummber of blinks per KWH of your meeter
      #define MAX_GAS 10000          // Max watt value to report. This filetrs outliers.
      #define CHILD_ID_g 3              // Id of the sensor child
      
      
      unsigned long SEND_FREQUENCY = 20000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway.
      double ppwh_e = ((double)PULSE_FACTOR_e)/1000; // Pulses per watt hour
      double ppwh_w = ((double)PULSE_FACTOR_w)/1000; // Pulses per watt hour
      double ppwh_g = ((double)PULSE_FACTOR_g)/1000; // Pulses per watt hour
      bool pcReceived = false;
      volatile unsigned long pulseCount_e = 0;   
      volatile unsigned long pulseCount_w = 0;   
      volatile unsigned long pulseCount_g = 0;   
      volatile unsigned long lastBlink_e = 0;
      volatile unsigned long lastBlink_w = 0;
      volatile unsigned long lastBlink_g = 0;
      volatile unsigned long watt = 0;
      volatile unsigned long waterflow = 0;
      volatile unsigned long gasflow = 0;
      unsigned long oldPulseCount_e = 0;   
      unsigned long oldPulseCount_w = 0;   
      unsigned long oldPulseCount_g = 0;   
      unsigned long oldWatt = 0;
      unsigned long oldWater = 0;
      unsigned long oldGas = 0;
      double oldKwh;
      double oldwater;
      double oldgas;
      unsigned long lastSend;
      MyMessage wattMsg(CHILD_ID_e,V_WATT);
      MyMessage kwhMsg(CHILD_ID_e,V_KWH);
      MyMessage pcMsg(CHILD_ID_e,V_VAR1);
      MyMessage flowMsg(CHILD_ID_w,V_FLOW);
      MyMessage volumeMsg(CHILD_ID_w,V_VOLUME);
      MyMessage lastCounterMsg(CHILD_ID_w,V_VAR2);
      
      MyMessage flowMsg(CHILD_ID_g,V_FLOW);
      MyMessage volumeMsg(CHILD_ID_g,V_VOLUME);
      MyMessage lastCounterMsg(CHILD_ID_g,V_VAR3);
      
      
      void setup()  
      {  
        // Fetch last known pulse count value from gw
        request(CHILD_ID_e, V_VAR1);
        request(CHILD_ID_w, V_VAR2);
        request(CHILD_ID_g, V_VAR3);
      
        // Use the internal pullup to be able to hook up this sketch directly to an energy meter with S0 output
        // If no pullup is used, the reported usage will be too high because of the floating pin
        pinMode(DIGITAL_INPUT_SENSOR_e,INPUT_PULLUP);
        pinMode(DIGITAL_INPUT_SENSOR_w,INPUT_PULLUP);
        pinMode(DIGITAL_INPUT_SENSOR_g,INPUT_PULLUP);
      
        attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR_e), onPulse_e, RISING);
        attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR_w), onPulse_w, RISING);
        attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR_g), onPulse_g, RISING);
        lastSend=millis();
      }
      
      void presentation() {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Marcel Meterkast", "1.0");
      
        // Register this device as power sensor
        present(CHILD_ID_e, S_POWER);
        present(CHILD_ID_w, S_WATER);
        present(CHILD_ID_g, S_GAS);
      }
      
      void loop()     
      { 
        unsigned long now = millis();
        // Only send values at a maximum frequency or woken up from sleep
        bool sendTime = now - lastSend > SEND_FREQUENCY;
        if (pcReceived && (SLEEP_MODE || sendTime)) {
          // New watt value has been calculated  
          // electricity first
          if (!SLEEP_MODE && watt != oldWatt) {
            // Check that we dont get unresonable large watt value. 
            // could hapen when long wraps or false interrupt triggered
            if (watt<((unsigned long)MAX_WATT)) {
              send(wattMsg.set(watt));  // Send watt value to gw 
            }  
            Serial.print("Watt:");
            Serial.println(watt);
            oldWatt = watt;
          }
          // send water
          if (!SLEEP_MODE && waterflow != oldWater) {
            // Check that we dont get unresonable large watt value. 
            // could hapen when long wraps or false interrupt triggered
            if (waterflow<((unsigned long)MAX_WATER)) {
              send(wattMsg.set(waterflow));  // Send watt value to gw 
            }  
            Serial.print("Gas:");
            Serial.println(gasflow);
            oldWater = waterflow;
          }
      
          // send gas
          if (!SLEEP_MODE && gasflow != oldGas) {
            // Check that we dont get unresonable large watt value. 
            // could hapen when long wraps or false interrupt triggered
            if (gasflow<((unsigned long)MAX_GAS)) {
              send(wattMsg.set(gasflow));  // Send watt value to gw 
            }  
            Serial.print("gas:");
            Serial.println(gasflow);
            oldGas = gasflow;
          }
          
          // Pulse cout has changed
          if (pulseCount_e != oldPulseCount_e) {
            send(pcMsg.set(pulseCount_e));  // Send pulse count value to gw 
            double kwh = ((double)pulseCount_e/((double)PULSE_FACTOR_e));     
            oldPulseCount_e = pulseCount_e;
            if (kwh != oldKwh) {
              send(kwhMsg.set(kwh, 4));  // Send kwh value to gw 
              oldKwh = kwh;
            }
          }
          if (pulseCount_w != oldPulseCount_w) {
            send(pcMsg.set(pulseCount_w));  // Send pulse count value to gw 
            double water = ((double)pulseCount_w/((double)PULSE_FACTOR_w));     
            oldPulseCount_w = pulseCount_w;
            if (water != oldwater) {
              send(kwhMsg.set(kwh, 4));  // Send kwh value to gw 
              oldwater = water;
            }
          }
          if (pulseCount_g != oldPulseCount_g) {
            send(pcMsg.set(pulseCount_g));  // Send pulse count value to gw 
            double gas = ((double)pulseCount_g/((double)PULSE_FACTOR_g));     
            oldPulseCount_g = pulseCount_g;
            if (gas != oldgas) {
              send(kwhMsg.set(gas, 4));  // Send kwh value to gw 
              oldgas = gas;
            }
          }    
          lastSend = now;
        } else if (sendTime && !pcReceived) {
          // No count received. Try requesting it again
          request(CHILD_ID_e, V_VAR1);
          request(CHILD_ID_w, V_VAR2);
          request(CHILD_ID_g, V_VAR3);
          lastSend=now;
        }
      
        if (SLEEP_MODE) {
          sleep(SEND_FREQUENCY);
        }
      }
      
      void receive(const MyMessage &message) {
        if (message.type==V_VAR1) {  
          pulseCount = oldPulseCount = message.getLong();
          Serial.print("Received last pulse count from gw for:");
          Serial.println(pulseCount);
          pcReceived = true;
        }
      }
      
      void onPulse_e()     
      { 
        if (!SLEEP_MODE) {
          unsigned long newBlink = micros();  
          unsigned long interval = newBlink_e-lastBlink_e;
          if (interval<10000L) { // Sometimes we get interrupt on RISING
            return;
          }
          watt = (3600000000.0 /interval) / ppwh_e;
          lastBlink_e = newBlink_e;
        } 
        pulseCount_e++;
      }
      
      void onPulse_w()     
      { 
        if (!SLEEP_MODE) {
          unsigned long newBlink = micros();  
          unsigned long interval = newBlink-lastBlink_w;
          if (interval<10000L) { // Sometimes we get interrupt on RISING
            return;
          }
          waterflow = (3600000000.0 /interval) / ppwh_w;
          lastBlink_w = newBlink;
        } 
        pulseCount_w++;
      }
      
      void onPulse_g()     
      { 
        if (!SLEEP_MODE) {
          unsigned long newBlink = micros();  
          unsigned long interval = newBlink-lastBlink_g;
          if (interval<10000L) { // Sometimes we get interrupt on RISING
            return;
          }
          gasflow = (3600000000.0 /interval) / ppwh_g;
          lastBlink_g = newBlink;
        } 
        pulseCount_w++;
      }
      
      mfalkviddM Offline
      mfalkviddM Offline
      mfalkvidd
      Mod
      wrote on last edited by mfalkvidd
      #2

      @htca welcome to the MySensors community!

      What errors are you getting? Knowing the errors would make it much easier to troubleshoot the problem.

      1 Reply Last reply
      0
      • htcaH Offline
        htcaH Offline
        htca
        wrote on last edited by htca
        #3

        I managed to have the script compiled without errors. But I found out that the 3rd sensor is not checked or giving interrupts (the led on the sensor indicates that there are pulses). With playing around and checking some regular sketches, I made a mistake on my breadboard and I burnt my nano :-(. So I ordered a new one.....
        Script so far is shown below, but it might be that I have to built a script from scratch with mysensors api. If anyone has any directions to follow on this, it would be great!

        /**
         * 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 - Henrik EKblad
         * 
         * DESCRIPTION
         * This sketch provides an example how to implement a distance sensor using HC-SR04 
         * Use this sensor to measure KWH and Watt of your house meeter
         * You need to set the correct pulsefactor of your meeter (blinks per KWH).
         * The sensor starts by fetching current KWH value from gateway.
         * Reports both KWH and Watt 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 watt-number.
         * http://www.mysensors.org/build/pulse_power
         */
        
        // Enable debug prints
        #define MY_DEBUG
        
        // Enable and select radio type attached
        #define MY_RADIO_NRF24
        //#define MY_RADIO_RFM69
        
        #include <MySensors.h>  
        #define SLEEP_MODE false        // values can only be reported when sleep mode is false.
        
        //electriciteit
        #define DIGITAL_INPUT_SENSOR_e 2  // The digital input you attached your light sensor.  (Only 2 and 3 generates interrupt!)
        #define PULSE_FACTOR_e 1000       // Nummber of blinks per KWH of your meeter
        #define MAX_WATT 10000          // Max watt value to report. This filetrs outliers.
        #define CHILD_ID_e 1              // Id of the sensor child
        
        //water
        #define DIGITAL_INPUT_SENSOR_w 3  // The digital input you attached your light sensor.  (Only 2 and 3 generates interrupt!)
        #define PULSE_FACTOR_w 1000       // Nummber of blinks per KWH of your meeter
        #define MAX_WATER 10000          // Max watt value to report. This filetrs outliers.
        #define CHILD_ID_w 2              // Id of the sensor child
        
        //gas
        #define DIGITAL_INPUT_SENSOR_g 4  // The digital input you attached your light sensor.  (Only 2 and 3 generates interrupt!)
        #define PULSE_FACTOR_g 1000       // Nummber of blinks per KWH of your meeter
        #define MAX_GAS 10000          // Max watt value to report. This filetrs outliers.
        #define CHILD_ID_g 3              // Id of the sensor child
        
        
        unsigned long SEND_FREQUENCY = 20000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway.
        double ppwh_e = ((double)PULSE_FACTOR_e)/1000; // Pulses per watt hour
        double ppwh_w = ((double)PULSE_FACTOR_w)/1000; // Pulses per watt hour
        double ppwh_g = ((double)PULSE_FACTOR_g)/1000; // Pulses per watt hour
        bool pcReceived = false;
        volatile unsigned long pulseCount_e = 0;   
        volatile unsigned long pulseCount_w = 0;   
        volatile unsigned long pulseCount_g = 0;   
        volatile unsigned long lastBlink_e = 0;
        volatile unsigned long lastBlink_w = 0;
        volatile unsigned long lastBlink_g = 0;
        volatile unsigned long watt = 0;
        volatile unsigned long waterflow = 0;
        volatile unsigned long gasflow = 0;
        unsigned long oldPulseCount_e = 0;   
        unsigned long oldPulseCount_w = 0;   
        unsigned long oldPulseCount_g = 0;   
        unsigned long oldWatt = 0;
        unsigned long oldWaterf = 0;
        unsigned long oldgasf = 0;
        double oldKwh;
        double oldwater;
        double oldgas;
        unsigned long lastSend;
        MyMessage wattMsg(CHILD_ID_e,V_WATT);
        MyMessage kwhMsg(CHILD_ID_e,V_KWH);
        MyMessage pcMsg(CHILD_ID_e,V_VAR1);
        
        MyMessage waterMsg(CHILD_ID_w,V_FLOW);
        MyMessage watervolumeMsg(CHILD_ID_w,V_VOLUME);
        MyMessage lastCounterwaterMsg(CHILD_ID_w,V_VAR2);
        
        MyMessage gasMsg(CHILD_ID_g,V_FLOW);
        MyMessage gasvolumeMsg(CHILD_ID_g,V_VOLUME);
        MyMessage lastCountegasrMsg(CHILD_ID_g,V_VAR3);
        
        
        void setup()  
        {  
          // Fetch last known pulse count value from gw
          request(CHILD_ID_e, V_VAR1);
          request(CHILD_ID_w, V_VAR2);
          request(CHILD_ID_g, V_VAR3);
        
          // Use the internal pullup to be able to hook up this sketch directly to an energy meter with S0 output
          // If no pullup is used, the reported usage will be too high because of the floating pin
          pinMode(DIGITAL_INPUT_SENSOR_e,INPUT_PULLUP);
          pinMode(DIGITAL_INPUT_SENSOR_w,INPUT_PULLUP);
          pinMode(DIGITAL_INPUT_SENSOR_g,INPUT_PULLUP);
        
          attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR_e), onPulse_e, RISING);
          attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR_w), onPulse_w, RISING);
          attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR_g), onPulse_g, RISING);
          lastSend=millis();
        
        }
        
        void presentation() {
          // Send the sketch version information to the gateway and Controller
          sendSketchInfo("Marcel Meterkast", "1.0");
        
          // Register this device as power sensor
          present(CHILD_ID_e, S_POWER);
          present(CHILD_ID_w, S_WATER);
          present(CHILD_ID_g, S_GAS);
        
        }
        
        void loop()     
        { 
          
          unsigned long now = millis();
          
          // Only send values at a maximum frequency or woken up from sleep
          bool sendTime = now - lastSend > SEND_FREQUENCY;
          if (pcReceived && (SLEEP_MODE || sendTime)) {
            // New watt value has been calculated  
            // electricity first
            if (!SLEEP_MODE && watt != oldWatt) {
              // Check that we dont get unresonable large watt value. 
              // could hapen when long wraps or false interrupt triggered
              if (watt<((unsigned long)MAX_WATT)) {
                send(wattMsg.set(watt));  // Send watt value to gw 
              }  
              Serial.print("Watt:");
              Serial.println(watt);
              oldWatt = watt;
            }
            // send water
            if (!SLEEP_MODE && waterflow != oldWaterf) {
              // Check that we dont get unresonable large watt value. 
              // could hapen when long wraps or false interrupt triggered
              if (waterflow<((unsigned long)MAX_WATER)) {
                send(wattMsg.set(waterflow));  // Send watt value to gw 
              }  
              Serial.print("water:");
              Serial.println(waterflow);
              oldWaterf = waterflow;
            }
        
            // send gas
            if (!SLEEP_MODE && gasflow != oldgasf) {
              // Check that we dont get unresonable large watt value. 
              // could hapen when long wraps or false interrupt triggered
              if (gasflow<((unsigned long)MAX_GAS)) {
                send(wattMsg.set(gasflow));  // Send watt value to gw 
              }  
              Serial.print("gas:");
              Serial.println(gasflow);
              oldgas = gasflow;
            }
            
            // Pulse cout has changed
            if (pulseCount_e != oldPulseCount_e) {
              send(pcMsg.set(pulseCount_e));  // Send pulse count value to gw 
              double kwh = ((double)pulseCount_e/((double)PULSE_FACTOR_e));     
              oldPulseCount_e = pulseCount_e;
              if (kwh != oldKwh) {
                send(kwhMsg.set(kwh, 4));  // Send kwh value to gw 
                oldKwh = kwh;
              }
            }
            if (pulseCount_w != oldPulseCount_w) {
              send(pcMsg.set(pulseCount_w));  // Send pulse count value to gw 
              double water = ((double)pulseCount_w/((double)PULSE_FACTOR_w));     
              oldPulseCount_w = pulseCount_w;
              if (water != oldwater) {
                send(watervolumeMsg.set(water, 4));  // Send watervolume value to gw 
                oldwater = water;
              }
            }
            if (pulseCount_g != oldPulseCount_g) {
              send(pcMsg.set(pulseCount_g));  // Send pulse count value to gw 
              double gas = ((double)pulseCount_g/((double)PULSE_FACTOR_g));     
              oldPulseCount_g = pulseCount_g;
              if (gas != oldgas) {
                send(gasvolumeMsg.set(gas, 4));  // Send gas value to gw 
                oldgas = gas;
              }
            }    
            lastSend = now;
          } else if (sendTime && !pcReceived) {
            // No count received. Try requesting it again
            request(CHILD_ID_e, V_VAR1);
            request(CHILD_ID_w, V_VAR2);
            request(CHILD_ID_g, V_VAR3);
            lastSend=now;
          }
        
          if (SLEEP_MODE) {
            sleep(SEND_FREQUENCY);
          }
        }
        
        void receive(const MyMessage &message) {
          if (message.type==V_VAR1) {  
            pulseCount_e = oldPulseCount_e = message.getLong();
            Serial.print("Received last pulse count from gw for:");
            Serial.println(pulseCount_e);
            pcReceived = true;
          }
        }
        
        void onPulse_e()     
        { 
          Serial.println("electricity pulse!");
          if (!SLEEP_MODE) {
            unsigned long newBlink = micros();  
            unsigned long interval = newBlink-lastBlink_e;
            if (interval<10000L) { // Sometimes we get interrupt on RISING
              return;
            }
            watt = (3600000000.0 /interval) / ppwh_e;
            lastBlink_e = newBlink;
          } 
          pulseCount_e++;
        }
        
        void onPulse_w()     
        { 
          Serial.println("water pulse!");
          if (!SLEEP_MODE) {
            unsigned long newBlink = micros();  
            unsigned long interval = newBlink-lastBlink_w;
            if (interval<10000L) { // Sometimes we get interrupt on RISING
              return;
            }
            waterflow = (3600000000.0 /interval) / ppwh_w;
            lastBlink_w = newBlink;
          } 
          pulseCount_w++;
        }
        
        void onPulse_g()     
        { 
          Serial.println("gas pulse!");
          if (!SLEEP_MODE) {
            unsigned long newBlink = micros();  
            unsigned long interval = newBlink-lastBlink_g;
            if (interval<10000L) { // Sometimes we get interrupt on RISING
              return;
            }
            gasflow = (3600000000.0 /interval) / ppwh_g;
            lastBlink_g = newBlink;
          } 
          pulseCount_w++;
        }```
        1 Reply Last reply
        0
        • E Offline
          E Offline
          ericvdb
          wrote on last edited by
          #4

          There are only 2 interrupts available, thats why you are not seeing the pulses from the 3th

          htcaH 1 Reply Last reply
          1
          • E ericvdb

            There are only 2 interrupts available, thats why you are not seeing the pulses from the 3th

            htcaH Offline
            htcaH Offline
            htca
            wrote on last edited by
            #5

            @ericvdb but it should be possible to make a 3rd one available I think?

            1 Reply Last reply
            0
            • E Offline
              E Offline
              ericvdb
              wrote on last edited by
              #6

              yes but not interrupt based.

              Have a look at button sketch

              htcaH 1 Reply Last reply
              0
              • E ericvdb

                yes but not interrupt based.

                Have a look at button sketch

                htcaH Offline
                htcaH Offline
                htca
                wrote on last edited by
                #7

                @ericvdb So the only solution is to use 2 nano's?

                1 Reply Last reply
                0
                • E Offline
                  E Offline
                  ericvdb
                  wrote on last edited by
                  #8

                  No, use 1 nano, use interrupts for electricity and gas, and use digital input for water.
                  Unless you want everything interrupt based, then you will need 2 x nano (or a mega)

                  htcaH 1 Reply Last reply
                  0
                  • E ericvdb

                    No, use 1 nano, use interrupts for electricity and gas, and use digital input for water.
                    Unless you want everything interrupt based, then you will need 2 x nano (or a mega)

                    htcaH Offline
                    htcaH Offline
                    htca
                    wrote on last edited by
                    #9

                    @ericvdb What's the difference between a interrupt and a digital input (I am a civil engineer with some programming background)

                    1 Reply Last reply
                    0
                    • E Offline
                      E Offline
                      ericvdb
                      wrote on last edited by
                      #10

                      Interrupt: whenever you input changes from low-to-high or high-to-low, the atmega will fire the method you told it to do.
                      Digital IO: if you want to know the state of the digital io, you have to constantly poll the io.

                      Regarding 3 counters on 1 nano, have a look at 12 input pulse counter

                      1 Reply Last reply
                      0
                      • E Offline
                        E Offline
                        ericvdb
                        wrote on last edited by
                        #11

                        Here is the difference in code.

                        Digital IO polling:

                        int inPin = 7;   // pushbutton connected to digital pin 7
                        int val = 0;     // variable to store the read value
                        
                        void setup()
                        {
                          pinMode(inPin, INPUT);      // sets the digital pin 7 as input
                        }
                        
                        void loop()
                        {
                          val = digitalRead(inPin);   // read the input pin
                        }
                        

                        Interrupt based:

                        const byte interruptPin = 2;
                        volatile byte state = LOW;
                        
                        void setup() {
                          pinMode(interruptPin, INPUT_PULLUP);
                          attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
                        }
                        
                        void loop() {
                          // do whatever you want here
                        }
                        
                        void blink() {
                          // this gets called whenever the input changes
                          state = !state;
                        }
                        
                        1 Reply Last reply
                        0
                        • Nca78N Offline
                          Nca78N Offline
                          Nca78
                          Hardware Contributor
                          wrote on last edited by
                          #12

                          Hello, a digital input allows you to read a digital signal value. You call "digitalRead" and then you get the current value of the pin.
                          An interrupt will ... interrupt your code to call the method you have associated to the interrupt. On atmega328 which is used by the nano you have only 2 external interrupts.
                          You could also use the pin change interrupts but it's much more complicated, and if you're not clear with the concept of the interrupt yet it's better to read and learn about it first.
                          Another solution is to use an arduino mega which has 6 external interrupts.

                          Also, interrupt methods should execute as fast as possible, you should never have a serial.write inside an interrupt. Instead, set a flag, and check the flag in the loop method: if flag is set do the serial.write and reset the flag.

                          1 Reply Last reply
                          0
                          • htcaH Offline
                            htcaH Offline
                            htca
                            wrote on last edited by
                            #13

                            Thanks! I ordered 2 mega's to experiment....

                            1 Reply Last reply
                            0
                            • htcaH Offline
                              htcaH Offline
                              htca
                              wrote on last edited by
                              #14

                              I managed to get it working. First issue was to get the Mega working with the mega.

                              I needed to change MyConfig.h:

                              #define MY_RF24_CS_PIN 53
                              

                              I used CE on pin 9 (and not 40) and further more:
                              alt text

                              My sketch:

                              
                              // Enable debug prints
                              #define MY_DEBUG
                              
                              // Enable and select radio type attached
                              #define MY_RADIO_NRF24
                              
                              #include <MySensors.h>  
                              // electricity
                              #define DIGITAL_INPUT_SENSOR_e 18  // The digital input you attached your light sensor.  (Only 2 and 3 generates interrupt!)
                              #define PULSE_FACTOR_e 1000        // Nummber of blinks per KWH of your meeter
                              #define SLEEP_MODE false           // Watt-value can only be reported when sleep mode is false.
                              #define MAX_WATT_e 10000           // Max watt value to report. This filetrs outliers.
                              #define CHILD_ID_e 1               // Id of the sensor child
                              
                              // Water
                              #define DIGITAL_INPUT_SENSOR_w 19                 // The digital input you attached your sensor.  (Only 2 and 3 generates interrupt!)
                              #define PULSE_FACTOR_w 1000                       // Nummber of blinks per m3 of your meter (One rotation/liter)
                              #define MAX_FLOW_w 40                             // Max flow (l/min) value to report. This filters outliers.
                              #define CHILD_ID_w 2                              // Id of the sensor child
                              
                              
                              // Gas
                              #define DIGITAL_INPUT_SENSOR_g 20                 // The digital input you attached your sensor.  (Only 2 and 3 generates interrupt!)
                              #define PULSE_FACTOR_g 1000                       // Nummber of blinks per m3 of your meter (One rotation/liter)
                              #define MAX_FLOW_g 40                             // Max flow (l/min) value to report. This filters outliers.
                              #define CHILD_ID_g 3                              // Id of the sensor child
                              
                              
                              unsigned long SEND_FREQUENCY = 30000;           // Minimum time between send (in milliseconds). We don't want to spam the gateway.
                              //unsigned long SEND_FREQUENCY = 20000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway.
                              
                              
                              double ppwh = ((double)PULSE_FACTOR_e)/1000; // Pulses per watt hour
                              double pplw = ((double)PULSE_FACTOR_w)/1000; 
                              double pplg = ((double)PULSE_FACTOR_g)/1000; 
                              
                              //electricity
                              bool pcReceived_e = false;
                              volatile unsigned long pulseCount_e = 0;   
                              volatile unsigned long lastBlink_e = 0;
                              volatile unsigned long watt = 0;
                              unsigned long oldPulseCount_e = 0;   
                              unsigned long oldWatt = 0;
                              double oldKwh;
                              unsigned long lastSend_e;
                              
                              
                              // water
                              volatile unsigned long pulseCount_w = 0;   
                              volatile unsigned long lastBlink_w = 0;
                              volatile double flow_w = 0;  
                              bool pcReceived_w = false;
                              unsigned long oldPulseCount_w = 0;
                              unsigned long newBlink_w = 0;   
                              double oldflow_w = 0;
                              double volume_w =0;                     
                              double oldvolume_w =0;
                              unsigned long lastSend_w =0;
                              unsigned long lastPulse_w =0;
                              
                              // gas
                              volatile unsigned long pulseCount_g = 0;   
                              volatile unsigned long lastBlink_g = 0;
                              volatile double flow_g = 0;  
                              bool pcReceived_g = false;
                              unsigned long oldPulseCount_g = 0;
                              unsigned long newBlink_g = 0;   
                              double oldflow_g = 0;
                              double volume_g =0;                     
                              double oldvolume_g =0;
                              unsigned long lastSend_g =0;
                              unsigned long lastPulse_g =0;
                              
                              
                              // electricity
                              MyMessage wattMsg(CHILD_ID_e,V_WATT);
                              MyMessage kwhMsg(CHILD_ID_e,V_KWH);
                              MyMessage pcMsg(CHILD_ID_e,V_VAR1);
                              // Water
                              MyMessage waterflowMsg(CHILD_ID_w,V_FLOW);
                              MyMessage watervolumeMsg(CHILD_ID_w,V_VOLUME);
                              MyMessage waterlastCounterMsg(CHILD_ID_w,V_VAR2);
                              // Gas
                              MyMessage gasflowMsg(CHILD_ID_g,V_FLOW);
                              MyMessage gasvolumeMsg(CHILD_ID_g,V_VOLUME);
                              MyMessage gaslastCounterMsg(CHILD_ID_g,V_VAR3);
                              
                              
                              
                              void setup()  
                              {  
                                // Fetch last known pulse count value from gw
                                request(CHILD_ID_e, V_VAR1);
                                request(CHILD_ID_w, V_VAR2);
                                request(CHILD_ID_g, V_VAR3);
                              
                                // Use the internal pullup to be able to hook up this sketch directly to an energy meter with S0 output
                                // If no pullup is used, the reported usage will be too high because of the floating pin
                                pinMode(DIGITAL_INPUT_SENSOR_e,INPUT_PULLUP);
                                pinMode(DIGITAL_INPUT_SENSOR_w,INPUT_PULLUP);
                                pinMode(DIGITAL_INPUT_SENSOR_g,INPUT_PULLUP);
                              
                                attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR_e), onPulse_e, RISING);
                                attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR_w), onPulse_w, RISING);
                                attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR_g), onPulse_g, RISING);
                                lastSend_e=millis();
                                lastSend_w=millis();
                                lastSend_g=millis();
                              }
                              
                              void presentation() {
                                // Send the sketch version information to the gateway and Controller
                                sendSketchInfo("Meterkast Marcel", "1.0");
                              
                                // Register this device as power sensor
                                present(CHILD_ID_e, S_POWER);
                                present(CHILD_ID_w, S_WATER);
                                present(CHILD_ID_g, S_GAS);
                              }
                              
                              void loop()     
                              { 
                                unsigned long now = millis();
                                // Only send values at a maximum frequency or woken up from sleep
                                bool sendTime = now - lastSend_e > SEND_FREQUENCY;
                                if (pcReceived_e && (SLEEP_MODE || sendTime)) {
                                  // New watt value has been calculated  
                                  if (!SLEEP_MODE && watt != oldWatt) {
                                    // Check that we dont get unresonable large watt value. 
                                    // could hapen when long wraps or false interrupt triggered
                                    if (watt<((unsigned long)MAX_WATT_e)) {
                                      send(wattMsg.set(watt));  // Send watt value to gw 
                                    }  
                                    Serial.print("Watt:");
                                    Serial.println(watt);
                                    oldWatt = watt;
                                  }
                              
                                  // Pulse count has changed
                                  if (pulseCount_e != oldPulseCount_e) {
                                    send(pcMsg.set(pulseCount_e));  // Send pulse count value to gw 
                                    double kwh = ((double)pulseCount_e/((double)PULSE_FACTOR_e));     
                                    oldPulseCount_e = pulseCount_e;
                                    if (kwh != oldKwh) {
                                      send(kwhMsg.set(kwh, 4));  // Send kwh value to gw 
                                      oldKwh = kwh;
                                    }
                                  }    
                                  lastSend_e = now;
                                } else if (sendTime && !pcReceived_e) {
                                  // No count received. Try requesting it again
                                  request(CHILD_ID_e, V_VAR1);
                                  lastSend_e=now;
                                }
                              
                                  unsigned long currentTime = millis();
                              
                                  // Only send values at a maximum frequency or woken up from sleep
                                if (SLEEP_MODE || (currentTime - lastSend_w > SEND_FREQUENCY))
                                {
                                  lastSend_w=currentTime;
                              
                                  if (!pcReceived_w) {
                                    //Last Pulsecount not yet received from controller, request it again
                                    request(CHILD_ID_w, V_VAR2);
                                    return;
                                  }
                              
                                  if (!SLEEP_MODE && flow_w != oldflow_w) {
                                    oldflow_w = flow_w;
                              
                                    Serial.print("l/min:");
                                    Serial.println(flow_w);
                              
                                    // Check that we dont get unresonable large flow value. 
                                    // could hapen when long wraps or false interrupt triggered
                                    if (flow_w<((unsigned long)MAX_FLOW_w)) {
                                      send(waterflowMsg.set(flow_w, 2));                   // Send flow value to gw
                                    }  
                                  }
                              
                                  // No Pulse count received in 2min 
                                  if(currentTime - lastPulse_w > 120000){
                                    flow_w = 0;
                                  } 
                              
                                  // Pulse count has changed
                                  if ((pulseCount_w != oldPulseCount_w)||(!SLEEP_MODE)) {
                                    oldPulseCount_w = pulseCount_w;
                              
                                    Serial.print("pulsecount_w:");
                                    Serial.println(pulseCount_w);
                              
                                    send(waterlastCounterMsg.set(pulseCount_w));                  // Send  pulsecount value to gw in VAR1
                              
                                    double volume_w = ((double)pulseCount_w/((double)PULSE_FACTOR_w));     
                                    if ((volume_w != oldvolume_w)||(!SLEEP_MODE)) {
                                      oldvolume_w = volume_w;
                              
                                      Serial.print("volume_w:");
                                      Serial.println(volume_w, 3);
                              
                                      send(watervolumeMsg.set(volume_w, 3));               // Send volume value to gw
                                    } 
                                  }
                                }
                              
                                  // Only send values at a maximum frequency or woken up from sleep
                                if (SLEEP_MODE || (currentTime - lastSend_g > SEND_FREQUENCY))
                                {
                                  lastSend_g=currentTime;
                              
                                  if (!pcReceived_g) {
                                    //Last Pulsecount not yet received from controller, request it again
                                    request(CHILD_ID_g, V_VAR3);
                                    return;
                                  }
                              
                                  if (!SLEEP_MODE && flow_g != oldflow_g) {
                                    oldflow_g = flow_g;
                              
                                    Serial.print("l/min:");
                                    Serial.println(flow_g);
                              
                                    // Check that we dont get unresonable large flow value. 
                                    // could hapen when long wraps or false interrupt triggered
                                    if (flow_g<((unsigned long)MAX_FLOW_g)) {
                                      send(gasflowMsg.set(flow_g, 2));                   // Send flow value to gw
                                    }  
                                  }
                              
                                  // No Pulse count received in 2min 
                                  if(currentTime - lastPulse_g > 120000){
                                    flow_g = 0;
                                  } 
                              
                                  // Pulse count has changed
                                  if ((pulseCount_g != oldPulseCount_g)||(!SLEEP_MODE)) {
                                    oldPulseCount_g = pulseCount_g;
                              
                                    Serial.print("pulsecount_g:");
                                    Serial.println(pulseCount_g);
                              
                                    send(gaslastCounterMsg.set(pulseCount_g));                  // Send  pulsecount value to gw in VAR1
                              
                                    double volume_g = ((double)pulseCount_g/((double)PULSE_FACTOR_g));     
                                    if ((volume_g != oldvolume_g)||(!SLEEP_MODE)) {
                                      oldvolume_g = volume_g;
                              
                                      Serial.print("volume_g:");
                                      Serial.println(volume_g, 3);
                              
                                      send(gasvolumeMsg.set(volume_g, 3));               // Send volume value to gw
                                    } 
                                  }
                                }
                                
                                
                                if (SLEEP_MODE) {
                                  sleep(SEND_FREQUENCY);
                                }
                              }
                              
                              void receive(const MyMessage &message) {
                                if (message.type==V_VAR1) {  
                                  pulseCount_e = oldPulseCount_e = message.getLong();
                                  Serial.print("Received last pulse count from gw_e:");
                                  Serial.println(pulseCount_e);
                                  pcReceived_e = true;
                                }
                                if (message.type==V_VAR2) {
                                  unsigned long gwPulseCount_w=message.getULong();
                                  pulseCount_w += gwPulseCount_w;
                                  flow_w=oldflow_w=0;
                                  Serial.print("Received last pulse count from gw_w:");
                                  Serial.println(pulseCount_w);
                                  pcReceived_w = true;
                                }
                                if (message.type==V_VAR3) {
                                  unsigned long gwPulseCount_g=message.getULong();
                                  pulseCount_g += gwPulseCount_g;
                                  flow_g=oldflow_g=0;
                                  Serial.print("Received last pulse count from gw_g:");
                                  Serial.println(pulseCount_g);
                                  pcReceived_g = true;
                                }
                                
                              }
                              
                              void onPulse_e()     
                              { 
                                if (!SLEEP_MODE) {
                                  unsigned long newBlink_e = micros();  
                                  unsigned long interval_e = newBlink_e-lastBlink_e;
                                  if (interval_e<10000L) { // Sometimes we get interrupt on RISING
                                    return;
                                  }
                                  watt = (3600000000.0 /interval_e) / ppwh;
                                  lastBlink_e = newBlink_e;
                                } 
                                pulseCount_e++;
                              }
                              
                              void onPulse_w()     
                              {
                                if (!SLEEP_MODE)
                                {
                                  unsigned long newBlink_w = micros();   
                                  unsigned long interval_w = newBlink_w-lastBlink_w;
                              
                                  if (interval_w!=0)
                                  {
                                    lastPulse_w = millis();
                                    if (interval_w<500000L) {
                                      // Sometimes we get interrupt on RISING,  500000 = 0.5sek debounce ( max 120 l/min)
                                      return;   
                                    }
                                    flow_w = (60000000.0 /interval_w) / pplw;
                                  }
                                  lastBlink_w = newBlink_w;
                                }
                                pulseCount_w++; 
                              }
                              
                              void onPulse_g()     
                              {
                                if (!SLEEP_MODE)
                                {
                                  unsigned long newBlink_g = micros();   
                                  unsigned long interval_g = newBlink_g-lastBlink_g;
                              
                                  if (interval_g!=0)
                                  {
                                    lastPulse_g = millis();
                                    if (interval_g<500000L) {
                                      // Sometimes we get interrupt on RISING,  500000 = 0.5sek debounce ( max 120 l/min)
                                      return;   
                                    }
                                    flow_g = (60000000.0 /interval_g) / pplg;
                                  }
                                  lastBlink_g = newBlink_g;
                                }
                                pulseCount_g++; 
                              }
                              

                              I still got one issue; my led on the meter does not give enough light to have a n interrupt. does anybody have a suggestion how to get the interrupt?

                              mfalkviddM 1 Reply Last reply
                              0
                              • htcaH htca

                                I managed to get it working. First issue was to get the Mega working with the mega.

                                I needed to change MyConfig.h:

                                #define MY_RF24_CS_PIN 53
                                

                                I used CE on pin 9 (and not 40) and further more:
                                alt text

                                My sketch:

                                
                                // Enable debug prints
                                #define MY_DEBUG
                                
                                // Enable and select radio type attached
                                #define MY_RADIO_NRF24
                                
                                #include <MySensors.h>  
                                // electricity
                                #define DIGITAL_INPUT_SENSOR_e 18  // The digital input you attached your light sensor.  (Only 2 and 3 generates interrupt!)
                                #define PULSE_FACTOR_e 1000        // Nummber of blinks per KWH of your meeter
                                #define SLEEP_MODE false           // Watt-value can only be reported when sleep mode is false.
                                #define MAX_WATT_e 10000           // Max watt value to report. This filetrs outliers.
                                #define CHILD_ID_e 1               // Id of the sensor child
                                
                                // Water
                                #define DIGITAL_INPUT_SENSOR_w 19                 // The digital input you attached your sensor.  (Only 2 and 3 generates interrupt!)
                                #define PULSE_FACTOR_w 1000                       // Nummber of blinks per m3 of your meter (One rotation/liter)
                                #define MAX_FLOW_w 40                             // Max flow (l/min) value to report. This filters outliers.
                                #define CHILD_ID_w 2                              // Id of the sensor child
                                
                                
                                // Gas
                                #define DIGITAL_INPUT_SENSOR_g 20                 // The digital input you attached your sensor.  (Only 2 and 3 generates interrupt!)
                                #define PULSE_FACTOR_g 1000                       // Nummber of blinks per m3 of your meter (One rotation/liter)
                                #define MAX_FLOW_g 40                             // Max flow (l/min) value to report. This filters outliers.
                                #define CHILD_ID_g 3                              // Id of the sensor child
                                
                                
                                unsigned long SEND_FREQUENCY = 30000;           // Minimum time between send (in milliseconds). We don't want to spam the gateway.
                                //unsigned long SEND_FREQUENCY = 20000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway.
                                
                                
                                double ppwh = ((double)PULSE_FACTOR_e)/1000; // Pulses per watt hour
                                double pplw = ((double)PULSE_FACTOR_w)/1000; 
                                double pplg = ((double)PULSE_FACTOR_g)/1000; 
                                
                                //electricity
                                bool pcReceived_e = false;
                                volatile unsigned long pulseCount_e = 0;   
                                volatile unsigned long lastBlink_e = 0;
                                volatile unsigned long watt = 0;
                                unsigned long oldPulseCount_e = 0;   
                                unsigned long oldWatt = 0;
                                double oldKwh;
                                unsigned long lastSend_e;
                                
                                
                                // water
                                volatile unsigned long pulseCount_w = 0;   
                                volatile unsigned long lastBlink_w = 0;
                                volatile double flow_w = 0;  
                                bool pcReceived_w = false;
                                unsigned long oldPulseCount_w = 0;
                                unsigned long newBlink_w = 0;   
                                double oldflow_w = 0;
                                double volume_w =0;                     
                                double oldvolume_w =0;
                                unsigned long lastSend_w =0;
                                unsigned long lastPulse_w =0;
                                
                                // gas
                                volatile unsigned long pulseCount_g = 0;   
                                volatile unsigned long lastBlink_g = 0;
                                volatile double flow_g = 0;  
                                bool pcReceived_g = false;
                                unsigned long oldPulseCount_g = 0;
                                unsigned long newBlink_g = 0;   
                                double oldflow_g = 0;
                                double volume_g =0;                     
                                double oldvolume_g =0;
                                unsigned long lastSend_g =0;
                                unsigned long lastPulse_g =0;
                                
                                
                                // electricity
                                MyMessage wattMsg(CHILD_ID_e,V_WATT);
                                MyMessage kwhMsg(CHILD_ID_e,V_KWH);
                                MyMessage pcMsg(CHILD_ID_e,V_VAR1);
                                // Water
                                MyMessage waterflowMsg(CHILD_ID_w,V_FLOW);
                                MyMessage watervolumeMsg(CHILD_ID_w,V_VOLUME);
                                MyMessage waterlastCounterMsg(CHILD_ID_w,V_VAR2);
                                // Gas
                                MyMessage gasflowMsg(CHILD_ID_g,V_FLOW);
                                MyMessage gasvolumeMsg(CHILD_ID_g,V_VOLUME);
                                MyMessage gaslastCounterMsg(CHILD_ID_g,V_VAR3);
                                
                                
                                
                                void setup()  
                                {  
                                  // Fetch last known pulse count value from gw
                                  request(CHILD_ID_e, V_VAR1);
                                  request(CHILD_ID_w, V_VAR2);
                                  request(CHILD_ID_g, V_VAR3);
                                
                                  // Use the internal pullup to be able to hook up this sketch directly to an energy meter with S0 output
                                  // If no pullup is used, the reported usage will be too high because of the floating pin
                                  pinMode(DIGITAL_INPUT_SENSOR_e,INPUT_PULLUP);
                                  pinMode(DIGITAL_INPUT_SENSOR_w,INPUT_PULLUP);
                                  pinMode(DIGITAL_INPUT_SENSOR_g,INPUT_PULLUP);
                                
                                  attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR_e), onPulse_e, RISING);
                                  attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR_w), onPulse_w, RISING);
                                  attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR_g), onPulse_g, RISING);
                                  lastSend_e=millis();
                                  lastSend_w=millis();
                                  lastSend_g=millis();
                                }
                                
                                void presentation() {
                                  // Send the sketch version information to the gateway and Controller
                                  sendSketchInfo("Meterkast Marcel", "1.0");
                                
                                  // Register this device as power sensor
                                  present(CHILD_ID_e, S_POWER);
                                  present(CHILD_ID_w, S_WATER);
                                  present(CHILD_ID_g, S_GAS);
                                }
                                
                                void loop()     
                                { 
                                  unsigned long now = millis();
                                  // Only send values at a maximum frequency or woken up from sleep
                                  bool sendTime = now - lastSend_e > SEND_FREQUENCY;
                                  if (pcReceived_e && (SLEEP_MODE || sendTime)) {
                                    // New watt value has been calculated  
                                    if (!SLEEP_MODE && watt != oldWatt) {
                                      // Check that we dont get unresonable large watt value. 
                                      // could hapen when long wraps or false interrupt triggered
                                      if (watt<((unsigned long)MAX_WATT_e)) {
                                        send(wattMsg.set(watt));  // Send watt value to gw 
                                      }  
                                      Serial.print("Watt:");
                                      Serial.println(watt);
                                      oldWatt = watt;
                                    }
                                
                                    // Pulse count has changed
                                    if (pulseCount_e != oldPulseCount_e) {
                                      send(pcMsg.set(pulseCount_e));  // Send pulse count value to gw 
                                      double kwh = ((double)pulseCount_e/((double)PULSE_FACTOR_e));     
                                      oldPulseCount_e = pulseCount_e;
                                      if (kwh != oldKwh) {
                                        send(kwhMsg.set(kwh, 4));  // Send kwh value to gw 
                                        oldKwh = kwh;
                                      }
                                    }    
                                    lastSend_e = now;
                                  } else if (sendTime && !pcReceived_e) {
                                    // No count received. Try requesting it again
                                    request(CHILD_ID_e, V_VAR1);
                                    lastSend_e=now;
                                  }
                                
                                    unsigned long currentTime = millis();
                                
                                    // Only send values at a maximum frequency or woken up from sleep
                                  if (SLEEP_MODE || (currentTime - lastSend_w > SEND_FREQUENCY))
                                  {
                                    lastSend_w=currentTime;
                                
                                    if (!pcReceived_w) {
                                      //Last Pulsecount not yet received from controller, request it again
                                      request(CHILD_ID_w, V_VAR2);
                                      return;
                                    }
                                
                                    if (!SLEEP_MODE && flow_w != oldflow_w) {
                                      oldflow_w = flow_w;
                                
                                      Serial.print("l/min:");
                                      Serial.println(flow_w);
                                
                                      // Check that we dont get unresonable large flow value. 
                                      // could hapen when long wraps or false interrupt triggered
                                      if (flow_w<((unsigned long)MAX_FLOW_w)) {
                                        send(waterflowMsg.set(flow_w, 2));                   // Send flow value to gw
                                      }  
                                    }
                                
                                    // No Pulse count received in 2min 
                                    if(currentTime - lastPulse_w > 120000){
                                      flow_w = 0;
                                    } 
                                
                                    // Pulse count has changed
                                    if ((pulseCount_w != oldPulseCount_w)||(!SLEEP_MODE)) {
                                      oldPulseCount_w = pulseCount_w;
                                
                                      Serial.print("pulsecount_w:");
                                      Serial.println(pulseCount_w);
                                
                                      send(waterlastCounterMsg.set(pulseCount_w));                  // Send  pulsecount value to gw in VAR1
                                
                                      double volume_w = ((double)pulseCount_w/((double)PULSE_FACTOR_w));     
                                      if ((volume_w != oldvolume_w)||(!SLEEP_MODE)) {
                                        oldvolume_w = volume_w;
                                
                                        Serial.print("volume_w:");
                                        Serial.println(volume_w, 3);
                                
                                        send(watervolumeMsg.set(volume_w, 3));               // Send volume value to gw
                                      } 
                                    }
                                  }
                                
                                    // Only send values at a maximum frequency or woken up from sleep
                                  if (SLEEP_MODE || (currentTime - lastSend_g > SEND_FREQUENCY))
                                  {
                                    lastSend_g=currentTime;
                                
                                    if (!pcReceived_g) {
                                      //Last Pulsecount not yet received from controller, request it again
                                      request(CHILD_ID_g, V_VAR3);
                                      return;
                                    }
                                
                                    if (!SLEEP_MODE && flow_g != oldflow_g) {
                                      oldflow_g = flow_g;
                                
                                      Serial.print("l/min:");
                                      Serial.println(flow_g);
                                
                                      // Check that we dont get unresonable large flow value. 
                                      // could hapen when long wraps or false interrupt triggered
                                      if (flow_g<((unsigned long)MAX_FLOW_g)) {
                                        send(gasflowMsg.set(flow_g, 2));                   // Send flow value to gw
                                      }  
                                    }
                                
                                    // No Pulse count received in 2min 
                                    if(currentTime - lastPulse_g > 120000){
                                      flow_g = 0;
                                    } 
                                
                                    // Pulse count has changed
                                    if ((pulseCount_g != oldPulseCount_g)||(!SLEEP_MODE)) {
                                      oldPulseCount_g = pulseCount_g;
                                
                                      Serial.print("pulsecount_g:");
                                      Serial.println(pulseCount_g);
                                
                                      send(gaslastCounterMsg.set(pulseCount_g));                  // Send  pulsecount value to gw in VAR1
                                
                                      double volume_g = ((double)pulseCount_g/((double)PULSE_FACTOR_g));     
                                      if ((volume_g != oldvolume_g)||(!SLEEP_MODE)) {
                                        oldvolume_g = volume_g;
                                
                                        Serial.print("volume_g:");
                                        Serial.println(volume_g, 3);
                                
                                        send(gasvolumeMsg.set(volume_g, 3));               // Send volume value to gw
                                      } 
                                    }
                                  }
                                  
                                  
                                  if (SLEEP_MODE) {
                                    sleep(SEND_FREQUENCY);
                                  }
                                }
                                
                                void receive(const MyMessage &message) {
                                  if (message.type==V_VAR1) {  
                                    pulseCount_e = oldPulseCount_e = message.getLong();
                                    Serial.print("Received last pulse count from gw_e:");
                                    Serial.println(pulseCount_e);
                                    pcReceived_e = true;
                                  }
                                  if (message.type==V_VAR2) {
                                    unsigned long gwPulseCount_w=message.getULong();
                                    pulseCount_w += gwPulseCount_w;
                                    flow_w=oldflow_w=0;
                                    Serial.print("Received last pulse count from gw_w:");
                                    Serial.println(pulseCount_w);
                                    pcReceived_w = true;
                                  }
                                  if (message.type==V_VAR3) {
                                    unsigned long gwPulseCount_g=message.getULong();
                                    pulseCount_g += gwPulseCount_g;
                                    flow_g=oldflow_g=0;
                                    Serial.print("Received last pulse count from gw_g:");
                                    Serial.println(pulseCount_g);
                                    pcReceived_g = true;
                                  }
                                  
                                }
                                
                                void onPulse_e()     
                                { 
                                  if (!SLEEP_MODE) {
                                    unsigned long newBlink_e = micros();  
                                    unsigned long interval_e = newBlink_e-lastBlink_e;
                                    if (interval_e<10000L) { // Sometimes we get interrupt on RISING
                                      return;
                                    }
                                    watt = (3600000000.0 /interval_e) / ppwh;
                                    lastBlink_e = newBlink_e;
                                  } 
                                  pulseCount_e++;
                                }
                                
                                void onPulse_w()     
                                {
                                  if (!SLEEP_MODE)
                                  {
                                    unsigned long newBlink_w = micros();   
                                    unsigned long interval_w = newBlink_w-lastBlink_w;
                                
                                    if (interval_w!=0)
                                    {
                                      lastPulse_w = millis();
                                      if (interval_w<500000L) {
                                        // Sometimes we get interrupt on RISING,  500000 = 0.5sek debounce ( max 120 l/min)
                                        return;   
                                      }
                                      flow_w = (60000000.0 /interval_w) / pplw;
                                    }
                                    lastBlink_w = newBlink_w;
                                  }
                                  pulseCount_w++; 
                                }
                                
                                void onPulse_g()     
                                {
                                  if (!SLEEP_MODE)
                                  {
                                    unsigned long newBlink_g = micros();   
                                    unsigned long interval_g = newBlink_g-lastBlink_g;
                                
                                    if (interval_g!=0)
                                    {
                                      lastPulse_g = millis();
                                      if (interval_g<500000L) {
                                        // Sometimes we get interrupt on RISING,  500000 = 0.5sek debounce ( max 120 l/min)
                                        return;   
                                      }
                                      flow_g = (60000000.0 /interval_g) / pplg;
                                    }
                                    lastBlink_g = newBlink_g;
                                  }
                                  pulseCount_g++; 
                                }
                                

                                I still got one issue; my led on the meter does not give enough light to have a n interrupt. does anybody have a suggestion how to get the interrupt?

                                mfalkviddM Offline
                                mfalkviddM Offline
                                mfalkvidd
                                Mod
                                wrote on last edited by mfalkvidd
                                #15

                                @htca what are you using to detect the light? You mentioned a LDR in the first post. If that's what you are using, here are a few options:

                                1. More light. See if you can get the ldr closer to the led and more directly pointing towards it. You might be able to focus the light by using a lens in front of the LDR.
                                2. adjust the value of the pullup. (Don't use the built-in, add an external with a higher value instead - which value depends on your ldr. Measure the max and min resistance (led is off + led is on) and calculate what size the pullup should be)
                                3. get a ldr with different resistance
                                1 Reply Last reply
                                0
                                • htcaH Offline
                                  htcaH Offline
                                  htca
                                  wrote on last edited by
                                  #16

                                  I use this one:
                                  alt text

                                  I used earlier which I made myself, but on a raspberry pi. Reading out analogue, passed it through a ADC and fed it to the pi.

                                  Now use the one above and linked it to the mega. Adjusting the resistance by the pot-meter will get me always on or always off.

                                  mfalkviddM 1 Reply Last reply
                                  0
                                  • htcaH htca

                                    I use this one:
                                    alt text

                                    I used earlier which I made myself, but on a raspberry pi. Reading out analogue, passed it through a ADC and fed it to the pi.

                                    Now use the one above and linked it to the mega. Adjusting the resistance by the pot-meter will get me always on or always off.

                                    mfalkviddM Offline
                                    mfalkviddM Offline
                                    mfalkvidd
                                    Mod
                                    wrote on last edited by
                                    #17

                                    @htca how dark is the room? Can you prevent the ambient light from hitting the led, by using non-transparent tape or something? If that is possible, adjusting the potentiometer should be easier.

                                    1 Reply Last reply
                                    0
                                    • htcaH Offline
                                      htcaH Offline
                                      htca
                                      wrote on last edited by
                                      #18

                                      I will give it a try. I ordered also the LDR variants of these.
                                      M.

                                      htcaH 1 Reply Last reply
                                      0
                                      • htcaH htca

                                        I will give it a try. I ordered also the LDR variants of these.
                                        M.

                                        htcaH Offline
                                        htcaH Offline
                                        htca
                                        wrote on last edited by
                                        #19

                                        I finally built my set-up with the LDR (were lying in my working room for months...). Conclusion: it works!

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


                                        15

                                        Online

                                        11.7k

                                        Users

                                        11.2k

                                        Topics

                                        113.1k

                                        Posts


                                        Copyright 2025 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