{"id":51065,"date":"2012-10-01T21:29:55","date_gmt":"2012-10-01T11:29:55","guid":{"rendered":"http:\/\/riscy.biz\/?p=51065"},"modified":"2024-11-06T18:02:25","modified_gmt":"2024-11-06T08:02:25","slug":"home-power-monitor","status":"publish","type":"post","link":"https:\/\/riscy.biz\/index.php\/2012\/10\/01\/home-power-monitor\/","title":{"rendered":"Home Power Monitor"},"content":{"rendered":"<p>I&#8217;ve wanted to do a home power monitoring project for some time. I was using a Clipsal Cent-a-meter a while ago to track power usage when I lived in Victoria but I didn&#8217;t have much luck with the newer model. It didn&#8217;t have a good range and seemed to lose connection between the base and sending unit. So I thought I would go DIY.<\/p>\n<p>I looked at lots of different systems including PIC microcontrollers but I decided to give the JeeNode and JeeLink combination a try. It seemed like a good choice for the following reasons:<\/p>\n<ul>\n<li>Arduino compatible<\/li>\n<li>Low power (3.3V)<\/li>\n<li>Integrated wireless<\/li>\n<li>Easy interfacing with a PC (JeeLink)<\/li>\n<li>Expandable<\/li>\n<\/ul>\n<p>In our house we have a smart meter which has a blinking red light for every Watt Hour of power used. So by measuring the length of the pulse you can have an indication of instantaneous power usage. This saves using clip on CTs which need to be installed by an electrician. The other advantage of using the smart meter is that this is the actual power usage I am being charged for. The only problem with this is that in Tasmania we have two different tariffs, one for normal usage and one for heating (cheaper). My system doesn&#8217;t take into account the tariffs and can only measure total usage. It also could not be used with electricity generation because the smart meter only blinks for imported power, if you are generating then the actual power usage will be higher than the imported.<\/p>\n<p>So I went to <a href=\"http:\/\/shop.moderndevice.com\">Modern Device<\/a> and ordered the following:<\/p>\n<ul>\n<li><a href=\"http:\/\/shop.moderndevice.com\/products\/jeenode-kit\">JeeNode v6 kit<\/a><\/li>\n<li><a href=\"http:\/\/shop.moderndevice.com\/products\/jeelink-module-fully-assembled\">JeeLink<\/a><\/li>\n<li><a href=\"http:\/\/shop.moderndevice.com\/products\/bub_ii\">USB BUB II<\/a><\/li>\n<\/ul>\n<p>The JeeNode will be used to monitor the blinking light, which will send data to the JeeLink (plugged into my HTPC running Ubuntu) and the USB BUB II is required for programming the JeeNode.<\/p>\n<p>I soldered the JeeNode and JeeLink up when they arrived on the coffee table while watching something mindless on TV. It had been a while since I had done proper soldering and with a good temperature controlled iron it was pretty easy. I should get some good quality solder though!<\/p>\n<p>I tested the JeeNode and JeeLink and they worked first time. Now to look for some code.<\/p>\n<p>I ended up using this code <a href=\"http:\/\/jeelabs.net\/projects\/cafe\/wiki\/Electricity_consumption_meter\">http:\/\/jeelabs.net\/projects\/cafe\/wiki\/Electricity_consumption_meter<\/a> I modified it to suit the 1Wh blinks and using a LDR.<\/p>\n<p>Here is my version of the transmitter code:<\/p>\n<pre style=\"padding-left: 30px;\">\/\/ Reading Comparator input\n\n#include &lt;Ports.h&gt;\n#include &lt;RF12.h&gt;\n#include \"kWh.h\"\n\nclass Port;\nPort inputPort(1);\nstatic unsigned long last;\n\nvoid setup() {\n\u00a0\u00a0\u00a0 inputPort.mode2(INPUT); \/\/ Set AIO mode as input\n\u00a0\u00a0\u00a0 inputPort.digiWrite2(1); \/\/ Activate pull-up resistor for AIO\n\u00a0 \n\u00a0\u00a0\u00a0 rf12_config();\n\u00a0\u00a0\u00a0 rf12_config(); \/\/ Apparently this is necessary\n\u00a0\u00a0\u00a0 rf12_easyInit(3); \/\/ Send value at most every 3 seconds\n\u00a0\u00a0\u00a0 last = millis();\n}\n\nvoid loop () {\n\u00a0\u00a0 \u00a0static boolean ledOn = false; \/\/ Variable to indicate LED status\n\u00a0\u00a0\u00a0 int data = inputPort.anaRead();\n\u00a0\u00a0\u00a0 rf12_easyPoll();\n\u00a0\u00a0\u00a0 if (!ledOn &amp;&amp; data &gt; 750) {\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/ After testing I found the switching point was 750\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ledOn = true;\n\u00a0\u00a0\u00a0 } else if (ledOn &amp;&amp; data &lt; 750) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ledOn = false;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ledBlink();\n\u00a0\u00a0\u00a0 }\n}\n\nvoid ledBlink() {\n\u00a0\u00a0\u00a0 static int nBlinks = 0;\n\u00a0\u00a0\u00a0 unsigned long time = millis();\n\u00a0\u00a0\u00a0 unsigned long interval = time - last;\n\n\u00a0\u00a0\u00a0 nBlinks++;\n\u00a0\u00a0\u00a0 if (interval &lt; 0) { \/\/ millis() overflow\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 last = time;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 nBlinks = 0;\n\u00a0\u00a0\u00a0 } else if (interval &gt; 1000) { \/\/ 1+ sec passed\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Blinks are 1000 per kWh, or 1 Wh each\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ One hour has 3.6M milliseconds\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 long watts = nBlinks * 1 * 3.6E6 \/ interval;\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 wattSend(watts);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 last = time;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 nBlinks = 0;\n\u00a0\u00a0\u00a0 }\n}\n\nstatic void wattSend(long watts) {\n\u00a0\u00a0\u00a0 Packet_t packet;\n\u00a0\u00a0\u00a0 packet.lang = LANG_ELECTRICITY;\n\u00a0\u00a0\u00a0 packet.mesg = MESG_ELEC_CURRENT;\n\u00a0\u00a0\u00a0 packet.data = watts;\n\u00a0\u00a0\u00a0 rf12_easySend(&amp;packet, sizeof packet);\n}<\/pre>\n<p>And here is my version of the JeeLink receiver code<\/p>\n<pre style=\"padding-left: 30px;\">#include &lt;Ports.h&gt;\n#include &lt;RF12.h&gt;\n#include \"kWh.h\"\n\nvoid setup() {\n\u00a0\u00a0\u00a0 Serial.begin(57600);\n\u00a0\u00a0\u00a0 rf12_config();\n\u00a0\u00a0\u00a0 rf12_config();\n}\n\nvoid loop() {\n\u00a0\u00a0\u00a0 if (rf12_recvDone() &amp;&amp; rf12_crc == 0 &amp;&amp; rf12_len == sizeof (Packet_t)) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Packet_t packet = *(Packet_t *) rf12_data;\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (packet.lang == LANG_ELECTRICITY) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (packet.mesg == MESG_ELEC_CURRENT) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 wattShow(packet.data);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\n\u00a0\u00a0\u00a0 } \n\u00a0\u00a0\u00a0 else {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 delay(10);\n\u00a0\u00a0\u00a0 }\n}\n\nstatic void wattShow(long watts) {\n\u00a0\u00a0\u00a0 Serial.print(\"Usage: \");\n\u00a0\u00a0\u00a0 Serial.print(watts);\n\u00a0\u00a0\u00a0 Serial.println(\" W\");\n}\n\n<\/pre>\n<p>I connected 4 AA NiMh batteries as the power supply to the JeeNode and sat it on top of the smart meter. The LDR is connected between the AI pin and ground of one of the ports.<\/p>\n<p><a href=\"http:\/\/riscy.biz\/?attachment_id=51067\" rel=\"attachment wp-att-51067\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-51067 size-medium\" title=\"_MG_2033\" src=\"https:\/\/i0.wp.com\/riscy.biz\/wp-content\/uploads\/2012\/10\/MG_2033.jpg?resize=300%2C199&#038;ssl=1\" alt=\"\" width=\"300\" height=\"199\" srcset=\"https:\/\/i0.wp.com\/riscy.biz\/wp-content\/uploads\/2012\/10\/MG_2033.jpg?resize=300%2C199&amp;ssl=1 300w, https:\/\/i0.wp.com\/riscy.biz\/wp-content\/uploads\/2012\/10\/MG_2033.jpg?resize=1024%2C681&amp;ssl=1 1024w, https:\/\/i0.wp.com\/riscy.biz\/wp-content\/uploads\/2012\/10\/MG_2033.jpg?w=1200&amp;ssl=1 1200w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Pretty isn&#8217;t it?<\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-51068\" src=\"https:\/\/i0.wp.com\/riscy.biz\/wp-content\/uploads\/2012\/10\/MG_2034.jpg?resize=300%2C199&#038;ssl=1\" alt=\"\" width=\"300\" height=\"199\" srcset=\"https:\/\/i0.wp.com\/riscy.biz\/wp-content\/uploads\/2012\/10\/MG_2034.jpg?resize=300%2C199&amp;ssl=1 300w, https:\/\/i0.wp.com\/riscy.biz\/wp-content\/uploads\/2012\/10\/MG_2034.jpg?resize=1024%2C681&amp;ssl=1 1024w, https:\/\/i0.wp.com\/riscy.biz\/wp-content\/uploads\/2012\/10\/MG_2034.jpg?w=1200&amp;ssl=1 1200w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-51066\" src=\"https:\/\/i0.wp.com\/riscy.biz\/wp-content\/uploads\/2012\/10\/MG_2032.jpg?resize=300%2C199&#038;ssl=1\" alt=\"\" width=\"300\" height=\"199\" srcset=\"https:\/\/i0.wp.com\/riscy.biz\/wp-content\/uploads\/2012\/10\/MG_2032.jpg?resize=300%2C199&amp;ssl=1 300w, https:\/\/i0.wp.com\/riscy.biz\/wp-content\/uploads\/2012\/10\/MG_2032.jpg?resize=1024%2C681&amp;ssl=1 1024w, https:\/\/i0.wp.com\/riscy.biz\/wp-content\/uploads\/2012\/10\/MG_2032.jpg?w=1200&amp;ssl=1 1200w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>The LDR is right next to the LED<\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-51069\" src=\"https:\/\/i0.wp.com\/riscy.biz\/wp-content\/uploads\/2012\/10\/MG_2035.jpg?resize=300%2C199&#038;ssl=1\" alt=\"\" width=\"300\" height=\"199\" srcset=\"https:\/\/i0.wp.com\/riscy.biz\/wp-content\/uploads\/2012\/10\/MG_2035.jpg?resize=300%2C199&amp;ssl=1 300w, https:\/\/i0.wp.com\/riscy.biz\/wp-content\/uploads\/2012\/10\/MG_2035.jpg?resize=1024%2C681&amp;ssl=1 1024w, https:\/\/i0.wp.com\/riscy.biz\/wp-content\/uploads\/2012\/10\/MG_2035.jpg?w=1200&amp;ssl=1 1200w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>The JeeLink is connected to my PC running Mythbuntu, which is my HTPC.<\/p>\n<p>Ubuntu is running Perl code to read the serial port and dump it to a file which timestamps the incoming data.<\/p>\n<pre style=\"padding-left: 30px;\">use strict;\nuse warnings;\nuse Device::SerialPort;\nuse POSIX qw\/strftime\/;\n\nmy $port = Device::SerialPort-&gt;new('\/dev\/ttyUSB0');\nmy $time = time;\n\nif( ! defined($port) ) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 die(\"Can't open \/dev\/ttyUSB0 $^E\\n\");\n}\n\nmy $outfd;\nopen ($outfd, \"&gt;&gt;\", \"log.txt\") or die \"Failed to open output file - $!n\";\n\nmy $output = select(STDOUT);\n$|++;\nselect($outfd);\n$|++;\nselect $output;\n\n$port-&gt;baudrate(57600);\n$port-&gt;parity('none');\n$port-&gt;databits(8);\n$port-&gt;stopbits(1);\n$port-&gt;write_settings();\n$port-&gt;are_match(\"\\n\");\n\nwhile(1) {\n\u00a0\u00a0\u00a0 my $char = $port-&gt;lookfor();\n\u00a0\u00a0\u00a0 if ($char) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $char =~ s\/\\xd\/\/g;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 my ($watts)= $char =~ \/(\\d+) W\/;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 print strftime('%d-%m-%Y %H:%M:%S',localtime);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 print \",$watts\\n\";\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 print $outfd strftime('%d-%b-%Y %H:%M:%S',localtime);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 print $outfd \",$watts\\n\";\n\u00a0\u00a0\u00a0 }\n}\n$port-&gt;close();\nexit(0);<\/pre>\n<p>It works and the next step is to make a nice graphing utility. I&#8217;ll post again when I have some pretty graphs. At the moment I&#8217;m just dumping all the data into Excel.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve wanted to do a home power monitoring project for some time. I was using a Clipsal Cent-a-meter a while ago to track power usage when I lived in Victoria but I didn&#8217;t have much luck with the newer model. &hellip; <a href=\"https:\/\/riscy.biz\/index.php\/2012\/10\/01\/home-power-monitor\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[63,1,62,7],"tags":[],"class_list":["post-51065","post","type-post","status-publish","format-standard","hentry","category-arduino","category-computers","category-jeenode","category-personal"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/riscy.biz\/index.php\/wp-json\/wp\/v2\/posts\/51065","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/riscy.biz\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/riscy.biz\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/riscy.biz\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/riscy.biz\/index.php\/wp-json\/wp\/v2\/comments?post=51065"}],"version-history":[{"count":1,"href":"https:\/\/riscy.biz\/index.php\/wp-json\/wp\/v2\/posts\/51065\/revisions"}],"predecessor-version":[{"id":51256,"href":"https:\/\/riscy.biz\/index.php\/wp-json\/wp\/v2\/posts\/51065\/revisions\/51256"}],"wp:attachment":[{"href":"https:\/\/riscy.biz\/index.php\/wp-json\/wp\/v2\/media?parent=51065"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/riscy.biz\/index.php\/wp-json\/wp\/v2\/categories?post=51065"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/riscy.biz\/index.php\/wp-json\/wp\/v2\/tags?post=51065"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}