Need help with pulse counter for power meter



  • Hello
    First I tried to use the sketch from MySensors, but it was a little bit to advanced for what i needed and also it didnt work to good with mqtt gateway (requested for variable 1 and got no answer).

    Anyhow I tried to make this more simple version which only sends current consumption (have not started on kwh yet, first want to get this working).

    I try this scetch and it boot up, but then it completly stalls after sending first kwh message. I get 1 V_WATT message, but nothing in the serial monitor.
    Any ideas?? I am very uncertain about the variable declarations, maybe I have done something strange there?

        #include <SPI.h>
        #include <MySensor.h>  
        
        #define CHILD_ID 1              // Id of the sensor child
        
        MySensor gw;
        
        long pulseCount = 0;   //Number of pulses, used to measure energy.
        unsigned long pulseTime,lastTime; //Used to measure power.
        unsigned long watt, elapsedkWh; //power and energy
        int ppwh = 1; //1000 pulses/kwh = 1 pulse per wh //Number of pulses per wh - found or set on the meter.
        
        MyMessage wattMsg(CHILD_ID,V_WATT);
        MyMessage kwhMsg(CHILD_ID,V_KWH);
        
        void setup()
        {
        
          gw.begin();
          Serial.begin(115200);
          
          // Send the sketch version information to the gateway and Controller
          gw.sendSketchInfo("Energy Meter", "1.0");
        
          // Register this device as power sensor
          gw.present(CHILD_ID, S_POWER);
        
        // KWH interrupt attached to IRQ 1  = pin3
          attachInterrupt(1, onPulse, RISING);
        }
        
        
        void loop()     
        { 
        }
          
        void onPulse()
        {
        
        //used to measure time between pulses.
          lastTime = pulseTime;
          pulseTime = micros();
        
        //pulseCounter
          pulseCount++;
        
        //Calculate power
          watt = (3600000000.0 / (pulseTime - lastTime))/ppwh;
          
          //Find kwh elapsed
          elapsedkWh = (1.0*pulseCount/(ppwh*1000)); //multiply by 1000 to pulses per wh to kwh convert wh to kwh
        
        //Print the values.
          Serial.print(watt);
          Serial.print(" ");
          Serial.println(elapsedkWh);
          
         //Send mqtt message 
          gw.send(wattMsg.set(watt));
          //gw.send(kwhMsg.set(elapsedkWh));
        }

  • Admin

    You cannot do the actual sending in the interrupt call.
    Just set some global variable and handle sending in loop(),



  • I tried using the "original" sensor sketch with Mqtt and Openhab and the sensor receives no answer to the request for a pulsecount startup value. Exactly as you describe.

    I found one way to bypass this problem. Maybe not the most elegant but it works. I used V_VAR2 to send the request for the startup value, picked this up with an item in Openhab and made a rule which did send back a startup pulsecount using V_VAR1 as the sensor sketch expects. Thus the change to the code is very small.

    Another way (the rude version) is to set the pulsecount to 0 in the sensor sketch and comment out the code part requesting the value when no count received i e this part

    else if (sendTime && !pcReceived) {
    // No count received. Try requesting it again
    gw.request(CHILD_ID, V_VAR1);
    }

    It is not nice but after a few hickups the sensor starts working :-)



  • @mbj said:

    V_VAR2

    Nice trick!
    I did that also and now everything seems to work!

    I am currently working with node-RED.
    Here a simple setup storing the pulsecount in a global variable (but is off course reset after reboot of the node-RED so store this in a database of choice)

    [{"id":"d0ff7866.2f0088","type":"mqtt-broker","broker":"192.168.1.201","port":"1883","clientid":"MQTT"},{"id":"dcd8de30.23272","type":"mqtt in","name":"MyMQTT/22/1/V_VAR2","topic":"MyMQTT/22/1/V_VAR2","broker":"d0ff7866.2f0088","x":119,"y":866,"z":"cda8f31c.32571","wires":[["cd8597d6.327a68"]]},{"id":"cd8597d6.327a68","type":"function","name":"","func":"msg.payload = context.global.pulsecount;\nif (context.global.pulsecount == null) {\nmsg.payload=0;} else {\nmsg.payload= context.global.pulsecount}\n\nreturn msg;","outputs":1,"x":342,"y":867,"z":"cda8f31c.32571","wires":[["fff8241c.0007d8","fe45e523.01ba18"]]},{"id":"fff8241c.0007d8","type":"mqtt out","name":"MyMQTT/22/1/V_VAR1","topic":"MyMQTT/22/1/V_VAR1","qos":"0","retain":"false","broker":"d0ff7866.2f0088","x":605,"y":871,"z":"cda8f31c.32571","wires":[]},{"id":"fe45e523.01ba18","type":"debug","name":"","active":true,"console":"false","complete":"false","x":552,"y":823,"z":"cda8f31c.32571","wires":[]},{"id":"c283bfb9.3d7c4","type":"mqtt in","name":"","topic":"MyMQTT/22/1/V_VAR1","broker":"d0ff7866.2f0088","x":104,"y":955,"z":"cda8f31c.32571","wires":[["4f883422.b077cc"]]},{"id":"4f883422.b077cc","type":"function","name":"","func":"context.global.pulsecount = context.global.pulsecount || new Object();\ncontext.global.pulsecount = msg.payload;\n\nreturn msg;","outputs":1,"x":282,"y":955,"z":"cda8f31c.32571","wires":[["10c4ee19.ef3b12"]]},{"id":"10c4ee19.ef3b12","type":"debug","name":"","active":true,"console":"false","complete":"false","x":424,"y":955,"z":"cda8f31c.32571","wires":[]}]


  • @mbj said:

    I found one way to bypass this problem. Maybe not the most elegant but it works. I used V_VAR2 to send the request for the startup value, picked this up with an item in Openhab and made a rule which did send back a startup pulsecount using V_VAR1 as the sensor sketch expects. Thus the change to the code is very small.

    I don't suppose you have a sketch you can share that works with OpenHAB and maybe some detail on the items and any rules you setup in OpenHAB?



  • @TommySharp My sketch is from a prior version of MySensors software and also much modified due to other sensors attached. It will not be of any help to you and right now I have no time to rewrite it to the current code base and libraries, sorry.

    But making the change the way I described is quite easy to implement if you take a look at the code and my brief description above. On the Openhab side there are heaps of ways to implement the change depending on what your intended function is. I have added functionality like setting the pulse counter manually in Openhab so also here the logic is quite complex and beyond what is useful as an example.
    But basic steps in my implementation are:

    • Define a new message of type V_VAR2 (I use it for sending a string, actually does not matter what it is as long as the receiving item matches the type sent. My definition is:

    MyMessage pcMsgStart(CHILD_ID,V_VAR2);

    • Disable original startup message:

    // gw.request(CHILD_ID,V_VAR1);

    • Send new startup message based on V_VAR2 (I just send it with a string):

    gw.send(pcMsgStart.set("START"));

    • Create a receiving item in Openhab, I use just a string Item:

    String node2_pulsecounter_start "Start för pulsecounter[%s]" (gEnergy) {mqtt="<[mysensor:MyMQTT/22/1/V_VAR2:state:default]"}

    • Create sending item in Openhab. I use this one:

    Number node2_pulsecounter_out "Count out [%.0f pulser]" (gEnergy) {mqtt=">[mysensor:MyMQTT/22/1/V_VAR1:state:*:default]"}

    • I also have a receiving item to get the actual pulse counter into Openhab once the sensor is running:

    Number node2_pulsecounter_in "Count in [%.0f pulser] " (gEnergy) {mqtt="<[mysensor:MyMQTT/22/1/V_VAR1:state:default]"}

    Then you just need to make rule for sending a pulse counter back to the sensor. Here is the rule:

    rule "Pulsecounter node 2 startvalue"
    when
    Item node2_pulsecounter_start received update
    then
    {
    postUpdate (node2_pulsecounter_out, pulsecounter)
    }
    end

    So when the sketch sends the start message Openhab senses an update of this V_VAR2 value and returns the requested pulse count ( which is set to 0 at startup or a previously incoming value at a restart or a setpoint value from elsewhere in the logic). But you can always use O to get going without any complications.

    I am basically interested in the energy consumption per 24 hours so I reset the counter at midnight. The absolute exact consumption is clearly stated on my energy bill so for follow-up the daily consumption is the most interesting one. Below you can see how I graph the values and I have successfully used these to spot problems. Our house is electrically heated so with a consumption of 15000 - 18000 KWh each year there are good reasons to keep an eye on it.

    0_1455133610226_Capture.JPG

    Hope you can follow the logic because unfortunately it does not make any sense to even try to explain the full set of rules which I use for this.

    It is also possible that I today could sniff the original gw.request message from the sketch and fix a reply from Openhab but this was the simplest functional solution I could think of at that time.



  • Thanks for the long reply!
    Over 100KwH in one day.... Pretty impressive!

    I'll have a good slow read of your reply and hopefully I can make some headway.



  • @TommySharp When it drops down under -20 to -25 C it is more than 100 KWh. So the pulse counter has a job to do :-)



  • @TommySharp Actually, if you plan to use any of the new MQTT gateways from the development branch there might be no need to change the Power Meter code.

    Reason is that the new format for the MQTT topic now includes the MySensors cmd-type field where requests will have a cmd-type of 2 and sensor value updates a cmd-type of 1 (the new format is MY_MQTT_PUBLISH_TOPIC_PREFIX/FROM-NODE-ID/SENSOR-ID/CMD-TYPE/ACK-FLAG/SUB-TYPE).

    It is still needed to define a "start-command-received" item in Openhab but that item can now be attached to the V_VAR1 type message which the power meter sends with the request method.

    With the new format things might look something like (I excluded all not needed info like text, formatting etc and changed the string item to a number):

    Number node2_pulsecounter_start {mqtt="<[mosquitto:mygateway-out/22/1/2/0/24:state:default]"}

    The inbound pulse count from the power meter will look like this using same message structure:
    Number node2_pulsecounter_in {mqtt="<[mosquitto:mygateway-out/22/1/1/0/24:state:default]"}

    The outbound pulse count from the controller to the power meter then looks like this:
    Number node2_pulsecounter_out {mqtt=">[mosquitto:mygateway-in/22/1/1/0/24:state:*:default]"}

    The rule will be the same.

    The new MQTT gateway from the development branch is a MQTT client and in these examples the publish topic starts with "mygateway-out" and the subscribe topic with "mygateway-in" and the broker is called "mosquitto".

    I have not tested this so no guarantees but it ought to work. When I update my power meter sketch I will try it.

    Have I confused you enough yet? :-)



  • @mbj I tested using the new version for MQTT but unfortunately Openhab will not recognize the empty message sent by gw.request(CHILD_ID, V_VAR1) . The error message is:

    2016-02-12 10:41:51.154 [WARN ] [.c.i.events.EventPublisherImpl] - given new state is NULL, couldn't post update for 'node2_pulsecounter_start'

    So I was wrong, Openhab will not recognize the message unless the sketch is modified to send something with a payload (which is easily done in many ways, not just the one mentioned above).

    If anybody knows a way to bind the gw.request type messages (with null payload) for Openhab MQTT it would be nice to know, please inform.



  • That's a shame...

    I've been building something from scratch this weekend to help me learn all about arduinos, WiFi, MQTT etc.... Its taking forever but as of now I have a WiFi based sensor that will send a MQTT message to OpenHAB every time there is a pulse on my power meter.

    This is a great result for me 😁

    Next step is to decide if I want to try calculate the watts and KwH in OpenHAB or on the sensor end.....



  • @TommySharp Very nice, hope you realize you have started on a long journey :-)
    But try to modify the original sketch, it works really well and will save you a lot of work.


Log in to reply
 

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.