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
htcaH

htca

@htca
About
Posts
10
Topics
1
Shares
0
Groups
0
Followers
0
Following
0

Posts

Recent Best Controversial

  • combining pulse counters
    htcaH htca

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

    Development

  • combining pulse counters
    htcaH htca

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

    Development

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

    Development

  • combining pulse counters
    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?

    Development

  • combining pulse counters
    htcaH htca

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

    Development

  • combining pulse counters
    htcaH htca

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

    Development

  • combining pulse counters
    htcaH htca

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

    Development

  • combining pulse counters
    htcaH htca

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

    Development

  • combining pulse counters
    htcaH htca

    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++;
    }```
    Development

  • combining pulse counters
    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++;
    }
    
    Development
  • Login

  • Don't have an account? Register

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