Watz: Electricity meter pulse counter on a Core

Over the last few days I have been working on a simple little project to monitor my energy usage at home. A project I have called watz: https://github.com/scottsweb/watz

watz is a WiFi smart meter / pulse counter. It mounts to the LED on your electricity meter and measures the number of pulses in a given time period. This is used to generate real time power information. This data is periodically pushed to the Particle cloud and can be subscribed to via server-sent events.

My meter is based in a cupboard outside the house so powering the project is tricky. I have tried to optimise the code for power efficiency - pushing data every 15 minutes with WiFi off most of the time. I have a small solar panel and battery but I feel these are still only going to give a few days at the current rate (it is winter and there is very little sun at the moment).

What I may try and do is up the interval for data collection but send the data in batches every 6 hours or so. Any tips would be appreciated.

To log the data I am using the hosted emoncms service. I relay the data via Node-RED on a Raspberry Pi using the Particle and emoncms nodes.

Here it is:

3 Likes

Thank you for sharing this project.

As I’m fairly new to programming, it helped me do what I have been trying off and on to do with my Cores for over a year. I did not manage to get your code to run on my Core, so I have modified it to work without flashee. My meter is located indoors with a power outlet nearby, so I had no use for the power saving solutions that you have implemented.

I’m publishing the data every minute, relaying the data via Node-RED to emoncms running on my NAS.

// Puls counter for energy-meter based on https://github.com/scottsweb/watz 
SYSTEM_MODE(AUTOMATIC);
// pins
int intled = D7;
int sensor = D0;

// general vars
char json[64];

// pulse vars
void pulseInt(void);		    // function for interrupt
float pulseCount = 0;  		    // counts power pulses on sensor


void setup() {
    Particle.connect();
	// set led as output
	pinMode(intled, OUTPUT);
	// set sensor as input
	pinMode(sensor, INPUT);
	// attach interrupt to LED pin, when RISING
	attachInterrupt(sensor, pulseInt, RISING);
}

void loop() 
{
	// publish once every 1 minutes
	if (Time.second() == 30) 
		{
		noInterrupts();   // Disables interrupts while publishing data
		float avgInterval = 60 / pulseCount;
		float kw = 3600 / (avgInterval * 1000);
		sprintf(json,"{\"kw\": %.3f, \"count\": %.0f}", kw, pulseCount);
		Particle.publish("watz", json, 60, PRIVATE);
		pulseCount = 0;
		delay(1500);  // delay more than 1000ms so that the data on second 30 is only published one time
		interrupts(); // Re-enables interrupts when data is published
		}
}
void pulseInt() {
	// visually indicate the blink has been detected on internal LED D7
	digitalWrite(intled, HIGH);
	delay(100);   
	digitalWrite(intled, LOW);
	// increment pulse count
	pulseCount++;
}
1 Like

Great stuff! glad you found the code and project useful. :smile: