Energy Monitor Proof of Concept

igoogle-pachube

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! 

arduino-power

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:

power_history

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;
}

6 thoughts on “Energy Monitor Proof of Concept

  1. 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?

  2. Hi Eric – super late to the party here, so I hope you see this comment..
    Can I ask what brand of meter you have? I am having some success with detecting and doing the time/pulse math with IR LED pulses from a GE i210+ce meter; however, once in a while, I detect a burst of pulses which is super fast and can’t be related to my power usage (i.e. usage spikes from 3 kW to 180,000 kW … I don’t have anything that high power in my house :) ) I imagine that they are part of a communications protocol which a handheld diagnostic tool would understand, but I’m more interested in being able to predict *when* those bursts will happen so I can ignore them. Any ideas / similar issues in your project?
    Thanks!

    • Hi Dave!
      Well, it was an Itron meter; it’s since been replaced. You’re probably right about it being some other communication. Perhaps you should just ignore anything over the max capacity of your mains? :) Looking up the FCC ID sometimes yields interesting manuals, too, if you’re up for some sleuthing…

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.