The Arduino is now connected to a photoreceiver that I got at Ax-Man for $0.95, picking up IR pulses every watt-hour of usage!
Since Google Powermeter still has no open API, I am uploading data to pachube.com – but they have an iGoogle plugin so Google doesn’t have to feel too bad (Hi Mike!). I’m sure they’ll carry on without me for now. It’s working pretty well but it’s all duct tape, chewing gum and baling twine, and you may notice a flat spot on the screenshot; the photoreceiver doesn’t work when the sun shines on the meter during the day. Not sure how to fix that even with various shading I put over it. Still, kind of interesting. I’m updating pachube every 20s. They have a pretty cool API where you can generate all sorts of type of graphs, besides the ugly pink ones:
Russell ordered some current transformers [amzn] to play with, which at least won’t be exposed to the elements; I may get a 2nd Arduino for that experimentation because I’d like this logging to keep going if I can. So far there is strong-ish incentive to run around turning off lights to make the graph go down, but I suppose that will wear off…
Arduino code follows; it ain’t pretty but it works. It listens on the serial port for a “p” (power) and sends the avg power over all the pulses since the last query. Right now my mac is running crummy perl to poke the arduino board and upload the data to pachube with curl.
As I said, chewing gum and duct tape…
//
// Use interrupt to detect change on IR phototransistor
//
// So we know what's up, light up the built-in LED
//
// PIN DEFINITIONS
int led_pin = 12; // Display LED pin
int int0_pin = 2; // Interrupt 0 on pin 2, input
// Delays
int bounce_delay_ms = 100; // pulse is 10ms wide
int blink_delay_ms = 100; // LED on time; delays loop()
unsigned long counter = 0; // Nr of pulses seen
unsigned long first_pulse_time = 0;
unsigned long last_pulse_time = 0;
// These are modified in the interrupt
volatile int pulse_seen = 0; // Pulse was seen in interrupt
static unsigned long ms_per_hour = 3600000UL; // ms per hour for power calcs
void setup()
{
pinMode(led_pin, OUTPUT);
// We want internal pullup enabled:
pinMode(int0_pin, INPUT);
// digitalWrite(int0_pin, HIGH); // Turns on pullup resistors
// And set up the interrupt.
// RISING: -pin- goes from low to high
// When IR detected, Axman detector emits 5V
attachInterrupt(0, blink, RISING);
// initialize serial communication:
Serial.begin(9600);
}
void loop()
{
static unsigned long avg_watts; // average watt draw since startup
unsigned long delta; // Time since last interrupt
int incoming_byte;
// Query exists on serial port; service it.
if (Serial.available() > 0) {
incoming_byte = Serial.read();
Serial.flush();
switch (incoming_byte) {
case 'c':
// Just print the count since last query
Serial.println(counter);
counter = 0;
break;
case 'p':
// print the avg watt draw since last query
delta = last_pulse_time - first_pulse_time;
if (delta && counter) {
avg_watts = (counter - 1) * ms_per_hour / delta;
counter = 0;
}
Serial.println(avg_watts);
break;
default:
break;
}
}
// IR pulse interrupt happened
if (pulse_seen == 1) {
counter++;
last_pulse_time = millis();
if (counter == 1 || first_pulse_time == 0) // we were reset
first_pulse_time = last_pulse_time;
// Blinky-blink
digitalWrite(led_pin, HIGH);
delay(blink_delay_ms);
digitalWrite(led_pin, LOW);
// Reset until next one.
pulse_seen = 0;
}
}
// Interrupt handler
// Whenever we get an IR state change our LED should change too.
//
// We get here for RISING; so when IR turns on.
//
void blink()
{
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
// If interrupts come faster than bounce_delay_ms, assume it's a bounce and ignore
//
// Note, millis() wraps every 50 days, be sure we cope...
//
if (interrupt_time - last_interrupt_time > bounce_delay_ms)
pulse_seen = 1; // loop() sees pulse == 1 and takes action
last_interrupt_time = interrupt_time;
}



Hello Eric,
This is great. Thank you for sharing this. When I found this post yesterday, I ran out the Radio Shack to pick up a photo-transistor, as I had all the other hardware and didn’t want to wait for my monthly parts order.
I’ve never fiddled, with IR sensors before and was surprised to see how sensitive it was to just about any light source I exposed it to. In the near future I plan to order an assortment of infrared sensitive components to see if I can enhance things.
Do you have any tips or techniques for how to attach / mount an IR sensor to an electric utilities “smart meter”? The smart meters my utility deployed have the IR emitter diode on the (round) face of the meter at the 12 o’clock position, just above the LCD readout.
Best regards,
Steve
Hey Steve, sorry for the late reply. I really rigged mine in a crazy way, with zip-ties, foam, pipe-end caps, and a rubber roof membrane to build a shade/hood. Without that, sunlight made it fail during the day. Maybe some putty to stick it to the face, but I dunno.
Some utilities may get antsy if they see stuff stuck to their meter though, just a fair warning. If your meter is “smart” enough maybe you can read it with something more sophisticated?
Hi, thanks for the code works very well, Herbert