two energy meter



  • I installed my first Energy meter today and it seems to work.

    Would it be possible to have two(2) energy meter connected to one arduino?

    Can the Arduino miss one pulse if they both pluse at same time?

    I have one Energy meter for my whole house and a seperate meter for my heating system, I want to exclude the heating system to see how much energy we use for the house only.


  • Mod

    @flopp it should be possible. But having two in one would increase the complexity, which will make programming and troubleshooting harder. Build a combined node if you like the challenge and learning, build two separate nodes if you want to keep things simple.

    Here is one which handles up to 12 meters: https://forum.mysensors.org/topic/1978/power-usage-sensor-multi-channel-local-display



  • @mfalkvidd

    Thanks.

    Wow 12 counts!!!

    I will go for 2 MCU's then I can lay down in the sofa rest of the day instead 😄



  • I couldn't just lay down in the sofa so I started to test and now I got a code that seems to work. I have tested it for a few days and it seems to count correct.

    I made some changes so it will send data every minute and it will send Watt-value even if it is the same value since last time.

    I am using VAR2 for second energy meter since I don't know how to config Incomingmessage and seperate VAR1 from different Child_IDs.

    I change corrupted interrupts from 10000L to 40000L otherwise it reported interrupts twice.

    /**
     * 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
     * Use this sensor to measure kWh and Watt of your house meter
     * You need to set the correct pulsefactor of your meter (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
     */
    
    #include <SPI.h>
    #include <MySensor.h>  
    unsigned long SEND_FREQUENCY = 60000; // Minimum time between send (in milliseconds). We don't want to spam the gateway.
    #define SLEEP_MODE false        // Watt-value can only be reported when sleep mode is false.
    
    //sensor 1
    #define DIGITAL_INPUT_SENSOR_1 2 // The digital input you attached your light sensor.  (Only 2 and 3 generates interrupt!)
    #define PULSE_FACTOR_1 1000       // Number of blinks per KWH of your meeter
    #define MAX_WATT_1 10000          // Max watt value to report. This filters outliers.
    #define INTERRUPT_1 DIGITAL_INPUT_SENSOR_1-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
    #define CHILD_ID_1 1              // Id of the sensor child
    
    //sensor 2
    #define DIGITAL_INPUT_SENSOR_2 3 // The digital input you attached your light sensor.  (Only 2 and 3 generates interrupt!)
    #define PULSE_FACTOR_2 10000       // Number of blinks per KWH of your meeter
    #define MAX_WATT_2 10000          // Max watt value to report. This filters outliers.
    #define INTERRUPT_2 DIGITAL_INPUT_SENSOR_2-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
    #define CHILD_ID_2 2              // Id of the sensor child
    
    MySensor gw;
    
    //sensor 1
    double ppwh_1 = ((double)PULSE_FACTOR_1)/1000; // Pulses per watt hour
    boolean pcReceived_1 = false;
    volatile unsigned long pulseCount_1 = 0;   
    volatile unsigned long lastBlink_1 = 0;
    volatile unsigned long watt_1 = 0;
    unsigned long oldPulseCount_1 = 0;   
    unsigned long oldWatt_1 = 0;
    double oldKwh_1;
    unsigned long lastSend_1;
    
    //sensor 2
    double ppwh_2 = ((double)PULSE_FACTOR_2)/1000; // Pulses per watt hour
    boolean pcReceived_2 = false;
    volatile unsigned long pulseCount_2 = 0;   
    volatile unsigned long lastBlink_2 = 0;
    volatile unsigned long watt_2 = 0;
    unsigned long oldPulseCount_2 = 0;   
    unsigned long oldWatt_2 = 0;
    double oldKwh_2;
    unsigned long lastSend_2;
    
    //sensor 1
    MyMessage wattMsg_1(CHILD_ID_1,V_WATT);
    MyMessage kwhMsg_1(CHILD_ID_1,V_KWH);
    MyMessage pcMsg_1(CHILD_ID_1,V_VAR1);
    
    //sensor 2
    MyMessage wattMsg_2(CHILD_ID_2,V_WATT);
    MyMessage kwhMsg_2(CHILD_ID_2,V_KWH);
    MyMessage pcMsg_2(CHILD_ID_2,V_VAR2);
    
    
    void setup()  
    {  
      gw.begin(incomingMessage);
    
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("Energy Double", "1.0");
    
      // Register this device as power sensor
      //sensor 1
      gw.present(CHILD_ID_1, S_POWER);
      //sensor 2
      gw.present(CHILD_ID_2, S_POWER);
    
      //Send new VAR to Gateway
      //gw.send(pcMsg_1.set(xxxxxxxxx));  // Send pulse count value to gw 
      //gw.send(pcMsg_2.set(1895931000));  // Send pulse count value to gw 
      
      // Fetch last known pulse count value from gw
      //sensor 1
      gw.request(CHILD_ID_1, V_VAR1);
      //sensor 2
      gw.request(CHILD_ID_2, V_VAR2);
    
      //sensor 1
      attachInterrupt(INTERRUPT_1, onPulse_1, RISING);
      //sensor 2
      attachInterrupt(INTERRUPT_2, onPulse_2, RISING);
      
      lastSend_1=millis();
      lastSend_2=millis();
    }
    
    
    void loop()     
    { 
      gw.process();
    
      //sensor 1
      unsigned long now_1 = millis();
      // Only send values at a maximum frequency or woken up from sleep
      bool sendTime_1 = now_1 - lastSend_1 > SEND_FREQUENCY;
      if (pcReceived_1 && (SLEEP_MODE || sendTime_1)) {
        // New watt value has been calculated  
        //if (!SLEEP_MODE && watt_1 != oldWatt_1) {
          // Check that we dont get unresonable large watt value. 
          // could hapen when long wraps or false interrupt triggered
          if (watt_1<((unsigned long)MAX_WATT_1)) {
            gw.send(wattMsg_1.set(watt_1));  // Send watt value to gw 
          }  
          Serial.print("Watt_1:");
          Serial.println(watt_1);
          oldWatt_1 = watt_1;
        //}    
      
        // Pulse cout has changed
        if (pulseCount_1 != oldPulseCount_1) {
          gw.send(pcMsg_1.set(pulseCount_1));  // Send pulse count value to gw 
          double kwh_1 = ((double)pulseCount_1/((double)PULSE_FACTOR_1));     
          oldPulseCount_1 = pulseCount_1;
          //if (kwh_1 != oldKwh_1) {
            gw.send(kwhMsg_1.set(kwh_1, 4));  // Send kwh value to gw 
            oldKwh_1 = kwh_1;
          //}
        }    
        lastSend_1 = now_1;
      } else if (sendTime_1 && !pcReceived_1) {
        // No count received. Try requesting it again
        gw.request(CHILD_ID_1, V_VAR1);
        lastSend_1=now_1;
      }
    
        //sensor 2
      unsigned long now_2 = millis();
      // Only send values at a maximum frequency or woken up from sleep
      bool sendTime_2 = now_2 - lastSend_2 > SEND_FREQUENCY;
      if (pcReceived_2 && (SLEEP_MODE || sendTime_2)) {
        // New watt value has been calculated  
        //if (!SLEEP_MODE && watt_2 != oldWatt_2) {
          // Check that we dont get unresonable large watt value. 
          // could hapen when long wraps or false interrupt triggered
          if (watt_2<((unsigned long)MAX_WATT_2)) {
            gw.send(wattMsg_2.set(watt_2));  // Send watt value to gw 
          }  
          Serial.print("Watt_2:");
          Serial.println(watt_2);
          oldWatt_2 = watt_2;
        //}    
      
        // Pulse cout has changed
        if (pulseCount_2 != oldPulseCount_2) {
          gw.send(pcMsg_2.set(pulseCount_2));  // Send pulse count value to gw 
          double kwh_2 = ((double)pulseCount_2/((double)PULSE_FACTOR_2));     
          oldPulseCount_2 = pulseCount_2;
          //if (kwh_2 != oldKwh_2) {
            gw.send(kwhMsg_2.set(kwh_2, 4));  // Send kwh value to gw 
            oldKwh_2 = kwh_2;
          //}
        }    
        lastSend_2 = now_2;
      } else if (sendTime_2 && !pcReceived_2) {
        // No count received. Try requesting it again
        gw.request(CHILD_ID_2, V_VAR2);
        lastSend_2=now_2;
      }
      
      if (SLEEP_MODE) {
        gw.sleep(SEND_FREQUENCY);
      }
    }
    
    void incomingMessage(const MyMessage &message) {
      if (message.type==V_VAR1) {  
        pulseCount_1 = oldPulseCount_1 = message.getLong();
        Serial.print("Received_1 last pulse count from gw:");
        Serial.println(pulseCount_1);
        pcReceived_1 = true;
      }
      if (message.type==V_VAR2) {  
        pulseCount_2 = oldPulseCount_2 = message.getLong();
        Serial.print("Received_2 last pulse count from gw:");
        Serial.println(pulseCount_2);
        pcReceived_2 = true;
      }
    }
    
    void onPulse_1()     
    { 
      if (!SLEEP_MODE) {
        unsigned long newBlink_1 = micros();  
        unsigned long interval_1 = newBlink_1-lastBlink_1;
        if (interval_1<40000L) { // Sometimes we get interrupt on RISING
          return;
        }
        watt_1 = (3600000000.0 /interval_1) / ppwh_1;
        lastBlink_1 = newBlink_1;
      } 
      //Serial.println(pulseCount_1);
      pulseCount_1++;
      //Serial.println(pulseCount_1);
    }
    
    void onPulse_2()     
    { 
      if (!SLEEP_MODE) {
        unsigned long newBlink_2 = micros();  
        unsigned long interval_2 = newBlink_2-lastBlink_2;
        if (interval_2<40000L) { // Sometimes we get interrupt on RISING
          return;
        }
        watt_2 = (3600000000.0 /interval_2) / ppwh_2;
        lastBlink_2 = newBlink_2;
      } 
      //Serial.println(pulseCount_2);
        pulseCount_2++;
      //Serial.println(pulseCount_2);
    }
    
    

Log in to reply
 

Suggested Topics

62
Online

11.4k
Users

11.1k
Topics

112.7k
Posts