Navigation

    • Register
    • Login
    • OpenHardware.io
    • Categories
    • Recent
    • Tags
    • Popular
    1. Home
    2. htca
    3. Posts
    • Profile
    • Following
    • Followers
    • Topics
    • Posts
    • Best
    • Groups

    Posts made by htca

    • RE: combining pulse counters

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

      posted in Development
      htca
      htca
    • RE: combining pulse counters

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

      posted in Development
      htca
      htca
    • RE: combining pulse counters

      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.

      posted in Development
      htca
      htca
    • RE: combining pulse counters

      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?

      posted in Development
      htca
      htca
    • RE: combining pulse counters

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

      posted in Development
      htca
      htca
    • RE: combining pulse counters

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

      posted in Development
      htca
      htca
    • RE: combining pulse counters

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

      posted in Development
      htca
      htca
    • RE: combining pulse counters

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

      posted in Development
      htca
      htca
    • RE: combining pulse counters

      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++;
      }```
      posted in Development
      htca
      htca
    • combining pulse counters

      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++;
      }
      
      posted in Development
      htca
      htca