Showing posts with label Electronics. Show all posts
Showing posts with label Electronics. Show all posts

Monday, 30 October 2017

ESP8266 CurrentCost Wifi Gateway

I have two CurrentCost power monitors - a CC128 EnviR panel in the living room which monitors our entire electricity usage, and an old white first generation panel in the office which monitors the office's electricity usage.

The CurrentCost panels output real time data in XML format every 6 seconds through a TTL serial connection presented as an 8P8C connector on the bottom, and I used to have a WRT54GL wireless access point connected to that, which sent the data to the server.  The WRT54GL was retired some time ago, so I wanted another way of recording the power usage data.  The ESP8266 seemed like a good choice to provide a bridge to my wifi network and I've chosen to use an ESP-12F board.  I could build a small enough device on stripboard to sit in the cavity under the base of the panel and connect to the CurrentCost's TTL serial output.


The 8P8C connector also includes regulated and unregulated power connections, but the 3v PSU is only rated for 80mA which is nowhere near enough to power the ESP8266.  I didn't want to have a second PSU, so opted to use a single USB power supply to power everything.  I've used an LM1117T LDO regulator to drop the supply voltage down to 3.3v, and connected this to both the ESP8266 and the unregulated supply rail of the CurrentCost.  There's a schottky diode between the regulator and the CurrentCost - this isn't strictly necessary, but will protect against someone plugging the CurrentCost PSU in at the same time as the wifi bridge.

GPIO0 and GPIO2 are pulled up by 10KΩ resistors, GPIO15 is pulled down by a 10KΩ resistor - you can probably get away with omitting the resistors and connecting these directly to Vcc / 0v respectively, although using a resistor to pull up GPIO0 allows the ESP8266 to be programmed in circuit by temporarily pulling it down to 0v.

CH_PD and reset are pulled up all the time by tieing them to the Vcc rail.

The connections to the CurrentCost's 8P8C connector are:
  • Pin 1 - Vcc / unregulated power
  • Pin 4 - Ground / 0v
  • Pin 8 - TTL serial data
Component-side view on the left, flipped for a track-side view on the right
Since the ESP-12F has solder pads with a 2mm spacing and the stripboard has 0.1" hole spacing, the ESP has to stand off the stripboard a little.  I've taken the opportunity to use the space between the ESP-12F and the board for the pullup / pulldown resistors.  I've shown the ESP-12F as a translucent block on the stripboard layout above so you can see the components under it.

The power connector is a surface mount mini-USB socket - obviously that's incompatible with stripboard, so I have just tacked on a couple of wires to connect it to the circuit and soldered its mounting lugs down to the track-side.  I find it useful to hot-glue the wires onto the board for mechanical support to avoid breaking off the socket's pins.
Component-side view

Track-side view
Although the CurrentCost outputs XML, I'm not bothering to parse that in the ESP8266.  Helpfully, each XML sentence is terminated with a newline, so it's easy to use Serial.readStringUntil('\n') to grab the whole sentence and post it to the web server.  Data posted over HTTP needs to be URL encoded and there doesn't seem to be a standard library to do this, so I ended up writing a quick and dirty encoder.  A PHP script on the web server parses the XML and feeds the data into RRDTool, and I'm using Cacti to display graphs of the data.




I wanted my graphs to display a total number of kilowatt hours used.  Unfortunately Cacti doesn't have a generic function to do this.  It can do bandwidth summation for network usage (i.e. displaying a "total megabytes" on a "bytes per second" graph), which is almost what I need.  Using that on the "watts" data gives a total number of watt seconds (i.e. joules) used, but no way to divide this by 3600 to produce watt hours.  In the end I added a COMPUTE data source to the RRD file, which records watts divided by 3600, and Cacti can then use that to calculate the total watt hours of electricity consumed.  Since I'm abusing the bandwidth summation functions, this unfortunately adds a "B" (bytes) unit to the total displayed, but I can live with that.

The code, schematic and layout are available from my Subversion repository.  The circuit works for both the CurrentCost EnviR (also known as the CC128) and the first generation CurrentCost, although the baud rate needs to be changed in the code - the EnviR uses a rate of 57600bps whilst the first generation panel uses 2400bps.  I believe there are also second generation panels around that look similar to the first generation ones but run at 9600bps.


Sunday, 24 July 2016

Wifi doorbell project

We've got a wireless doorbell which is fairly unreliable.  Also, I can't hear it from my office, and the 433MHz transmitter built into the doorbell button doesn't have enough range for me to put a sounder in the office.  The unreliability problem could probably be fixed by just buying a new wireless doorbell, but that probably wouldn't help with the range problem.

The advent of the ESP8266 microcontrollers opened up a more interesting approach.  These are programmable microcontrollers with a built in wifi interface.  They are tiny and also only cost about a pound each.  So my plan was: build a new doorbell push from scratch, which talks to the wifi network.  The old doorbell has an electromechanical sounder, which I'm reusing by replacing the driver circuit.

Doorbell push

ESP-01 on stripboard
The first job was the doorbell push.  I'm using an ESP-01 module for this because it's tiny, and its running off a pair of AAA cells, which will provide a 3.0v supply when new.  In theory, I could use a buck-boost regulator to maintain a 3.3v supply to the ESP throughout the life of the batteries, but the quiescent current draw of the regulator would probably drain the battery fairly quickly since this circuit is going to spend most of its life asleep.  Although the ESP8266 is supposed to run on 3.3v, they are apparently ok down to around 2.3v, so I'm running it directly off the batteries with no regulator.  The ESP8266's wifi radio has some reasonably high power demands, so there's a 100µF capacitor across the supply rails to absorb any high current bursts which the batteries may not be up to supplying.

The theory of operation is as follows: the ESP-01 module will be put in deep sleep mode when idle.  The button is wired between the ESP's reset pin and ground, so when someone pushes the button to ring the bell, it pulls reset low and wakes the device from deep sleep.  The ESP-01 has an on board power LED which is always on and would drain the batteries quite quickly, so I've cut the track supplying power to that LED - the module now draws 20µA when in deep sleep mode, so I expect the batteries to last a while.  When the ESP resets, it immediately associates with the wifi network and makes two HTTP requests - one directly to the sounder (more on this later) and the other to my home server.  A php script on the server sends out "doorbell rang" instant messages to both myself and Mel via XMPP - this solves the problem of hearing the bell in the office, since the XMPP notification pops up on my workstation and phone.

Everything just fits!
The button I bought contains an LED ring which I'm using to give the person ringing the bell feedback - The ring lights up when the wifi connection has been established (including DHCP, etc.) and flashes after the HTTP requests have successfully completed.  There's a minor complication that the ESP-01 only makes 2 GPIO pins available, they both have to be pulled high when the ESP boots up, and in fact the ESP-01 module has integrated pullups for this reason.  So the LED is wired between the positive power rail and GPIO-0.  This results in inverted logic - to turn the LED on GPIO-0 has to be set low, to turn it off GPIO-0 has to be either high or in high impedance (input) mode.  Once the HTTP requests have completed and the LED has been flashed, the ESP goes back into deep sleep mode.

The web requests that the button makes include the current battery voltage, so I can figure out when to change the batteries.  Its now been in use for about 15 weeks and the reported battery voltage has fallen from about 3.182v to 3.053v, which I think is pretty reasonable.

The finished doorbell push On the door frame

Sounder

As mentioned, I'm re-purposing the old electromechanical sounder by replacing the old circuit board and driving the solenoid directly.  The old sounder was powered by 3 C cells.  Unlike the button, the sounder will need to remain connected to the wifi all the time, so batteries aren't really an option.  I've opted to using a USB power supply, and with no need for the batteries there's now a lot of space inside the sounder for my new circuit.

I'm using an ESP-12F in the sounder - it's a bit overkill really, but I wanted to have an output that didn't have to be pulled up on boot.  The mini-USB port is connected to an LM1117T-3.3 linear regulator to provide the 3.3v supply voltage.  The solenoid is driven by an RFD14N05L field effect transistor and I've included a fairly chunky capacitor to help with the high power requirements of the solenoid.  Of course there's also a reverse biassed diode in parallel with the solenoid to absorb the back-EMF (although no magic smoke was released before I bothered adding it).

The whole thing is soldered up onto stripboard and just pushed into the battery compartment of the sounder (having removed the battery contacts).

The sounder connects to the wifi network as soon as it is powered up and sits there waiting for an HTTP request.  Making a request to "/" returns a status page, requesting "/ring" causes it to fire the striker and make the classic "ding-dong".
The old electromechanical sounder with an ESP-12F installed

Problems to be aware of

Receiving a notification on your phone to say the doorbell is being rung when you're a few hundred miles away is infuriating because you know you're going to have to drive up to the postal depot to collect a parcel when you get home. :)

Source code

Source code for the project is available in Subversion:
https://subversion.nexusuk.org/projects/doorbell/