no way to compare when less than two revisions
Differences
This shows you the differences between two versions of the page.
— | cybiko:wattusagemeter [2009/11/27 17:54] (current) – created - external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ======Electricity Usage Monitor====== | ||
+ | We all know that excessive power use is costly - both in terms of the adverse effect on the environment and also the high prices that we pay for our utility bills. It is quite awkward to keep looking at the electricity meter, usually tucked away in a dark cupboard, to find out how much power has been used. Also, it is hard to be disciplined and write down the dates/times of readings taken and convert this to cash spent. | ||
+ | |||
+ | So it seemed a good idea to have the Cybiko help keep tabs on how much electricity is being used in my home. Fortunately, | ||
+ | |||
+ | {{ cybiko: | ||
+ | |||
+ | The idea is to have a small external circuit count the pulses of light from the LED. | ||
+ | |||
+ | Importantly, | ||
+ | |||
+ | This info will then be sent, wirelessly, to another Cybiko, running [[RFTerm]]. This means that we now have a mobile unit that can be viewed easily. A neat feature would be the ability to specify a given power usage rate that, when exceeded, would sound an alarm on the RF Terminal Cybiko. This would be especially handy when living in a house where kids/ | ||
+ | |||
+ | Ideally, the solution could also feed an internet connected PC. This would then allow publishing of the info to the internet. The [[http:// | ||
+ | |||
+ | Standalone meters can be purchased from from [[http:// | ||
+ | |||
+ | A great way of adding MSN alerts to this system would be via the excellent [[http:// | ||
+ | |||
+ | |||
+ | =====Sensor Hardware===== | ||
+ | Update at 14th Oct - tried a little pulse counter circuit using a TIL81 phototransistor and a resistor. This worked well when illuminated with a LED. However, when tested on an actual meter, it didn't catch the pulses of light. The light source in the meter is rather dimmer than a standard LED. A more sensitive circuit is needed... | ||
+ | |||
+ | ^ Diagram (click image to zoom) ^ Description ^ | ||
+ | | {{cybiko: | ||
+ | | {{cybiko: | ||
+ | |||
+ | |||
+ | =====Interesting Product===== | ||
+ | |||
+ | http:// | ||
+ | |||
+ | http:// | ||
+ | |||
+ | http:// | ||
+ | |||
+ | =====AVR Firmware===== | ||
+ | Update at 28th Oct - now using an LDR ... this works very nicely. Next thing is to hook up an AVR chip to do the counting of the pulses. | ||
+ | |||
+ | The PC executable will be called, periodically, | ||
+ | When called, the .exe will send a '?' | ||
+ | |||
+ | Idea, flash a LED on the AVR board to show that pulse detection is working. | ||
+ | |||
+ | Now, if [[SerialRelay]] was able to selectively route to a given Cybiko, we could also send some ' | ||
+ | |||
+ | Update at 7th November - Brett knocked out some AVR code to count the pulses & send out the count over RS232 when a '?' | ||
+ | <code qbasic> | ||
+ | ' | ||
+ | '* Pulse counter | ||
+ | '* uP: AT90S2313 | ||
+ | '* Language: | ||
+ | ' | ||
+ | $regfile = " | ||
+ | $crystal = 4000000 | ||
+ | $baud = 9600 | ||
+ | |||
+ | ' Configure these for the specific implementation. | ||
+ | Config Pind.4 = Input , Pind.5 = Output | ||
+ | Led Alias Pind.5 | ||
+ | Sensor Alias Pind.4 | ||
+ | |||
+ | ' serial Rx complete interrupt | ||
+ | On Urxc Readrs232 | ||
+ | Enable Interrupts | ||
+ | Enable Urxc | ||
+ | |||
+ | Dim Count As Long | ||
+ | |||
+ | Count = 0 | ||
+ | |||
+ | ' Loop forever | ||
+ | Do | ||
+ | Bitwait Sensor , Reset ' | ||
+ | Reset Led ' Turn the LED off | ||
+ | Count = Count + 1 | ||
+ | Bitwait Sensor , Set ' | ||
+ | Set Led ' Turn the LED on. | ||
+ | Loop | ||
+ | |||
+ | Readrs232: | ||
+ | If Udr = 63 Then ' | ||
+ | Print Count | ||
+ | Count = 0 | ||
+ | End If | ||
+ | Return | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | =====PC Software===== | ||
+ | Here is a config file from MRTG. | ||
+ | Note that MRTG is configured here to call an external .exe (getdata.exe) to gather the data to be plotted. | ||
+ | < | ||
+ | WorkDir: C:\mrtg | ||
+ | RunAsDaemon: | ||
+ | |||
+ | Target[hostAdisk]: | ||
+ | Title[hostAdisk]: | ||
+ | MaxBytes[hostAdisk]: | ||
+ | PageTop[hostAdisk]: | ||
+ | Suppress[hostAdisk]: | ||
+ | LegendO[hostAdisk]: | ||
+ | Legend1[hostAdisk]: | ||
+ | Legend2[hostAdisk]: | ||
+ | YLegend[hostAdisk]: | ||
+ | ShortLegend[hostAdisk]: | ||
+ | Options[hostAdisk]: | ||
+ | </ | ||
+ | |||
+ | |||
+ | <note classic> | ||
+ | Code shown below is not finished yet. | ||
+ | </ | ||
+ | <code delphi> | ||
+ | unit Unit1; | ||
+ | |||
+ | { | ||
+ | DK 13 Oct 2005 | ||
+ | Designed to be called by MRTG | ||
+ | The idea goes like this ... | ||
+ | an AVR micro is running beside the electricity meter, counting pulses on the LED | ||
+ | |||
+ | every 5 mins, MRTG calls this application. | ||
+ | This app sends a '?' | ||
+ | This is serialrelayed to the cybiko connected to the AVR board. | ||
+ | The AVR receives the '?' | ||
+ | pulses since the last query. The count is then reset. | ||
+ | |||
+ | This app receives the pulse count string and passes it back to MRTG. | ||
+ | We probably want a timeout between sending the ? and waiting for a result back ... | ||
+ | just in case we never get one. | ||
+ | |||
+ | Code not finished yet! | ||
+ | } | ||
+ | |||
+ | interface | ||
+ | |||
+ | uses | ||
+ | Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, | ||
+ | Dialogs, StdCtrls, OoMisc, AdPort; | ||
+ | |||
+ | type | ||
+ | TForm1 = class(TForm) | ||
+ | cp1: TApdComPort; | ||
+ | procedure FormCreate(Sender: | ||
+ | procedure cp1TriggerData(CP: | ||
+ | private | ||
+ | { Private declarations } | ||
+ | public | ||
+ | { Public declarations } | ||
+ | end; | ||
+ | |||
+ | var | ||
+ | Form1: TForm1; | ||
+ | myVal : string; | ||
+ | implementation | ||
+ | |||
+ | {$R *.dfm} | ||
+ | |||
+ | |||
+ | procedure TForm1.FormCreate(Sender: | ||
+ | |||
+ | begin | ||
+ | cp1.AddDataTrigger(':', | ||
+ | cp1.PutChar('?' | ||
+ | sleep(100); | ||
+ | allocConsole; | ||
+ | writeln(' | ||
+ | writeln(myVal); | ||
+ | writeln; | ||
+ | writeln; | ||
+ | freeConsole; | ||
+ | Application.Terminate; | ||
+ | end; | ||
+ | |||
+ | procedure TForm1.cp1TriggerData(CP: | ||
+ | const | ||
+ | LF: Char = chr(10); | ||
+ | var | ||
+ | ch : char; | ||
+ | begin | ||
+ | myVal := ''; | ||
+ | repeat | ||
+ | ch := cp1.GetChar; | ||
+ | if ch <> LF then myVal := myVal + ch; | ||
+ | until ch = LF; | ||
+ | end; | ||
+ | |||
+ | end. | ||
+ | </ |