Today, I am going to show you how I designed a very efficient WiFi button that can be used
as a trigger to control different devices using home assistant. As an example, I will
integrate it with nodeRED and then use it to control a smart LED bulb that I set up
in a previous video. Towards the end, I will share with you a trick that you can use to
conserve battery even longer.
Here are the requirements for this project. I want this to be very simple so that you
can easily build one yourself. I would also like to have the wireless node last for at
least six months on a single charge and ideally a year. This sounds like a tricky combination,
but as you will see, it isn’t that difficult to achieve, well, at least if my calculations
are correct.
Let us assume that we want to run this module using two, standard AA batteries. They have
a capacity of around 2500 mA¬¬h. Let us assume 100% efficiency to keep things simple
and let us calculate the amount of current we can consume to run the node for 6 months
continuously. 6 months is about 180 days and that equates to 4320 hours. If we divide the
battery capacity by this number, we end up with 0.578 milliamps or 578 microamps. What
this means is that if we want our node to be ON continuously for 6 months, then it cannot
consume more than 578 microamps. This is a very low current budget and if we take a look
at the datasheet for the ESP8266, then you will see that it has an average current consumption
of 80 milliamps which is about 138 times higher than what we need. Not only that, it can consume
more than double the current at its peak when transmitting data. This makes one thing clear,
we cannot keep the ESP8266 ON continuously as we will run out of battery within a day.
Thankfully, the chip supports different sleep modes that consume much less current as seen
here. I’ve used these numbers to quickly calculate the run time from AA batteries.
And as you can see, we need to spend a lot of time in deep sleep in order to last at
least 6 months. The figures here are ideal values and in reality, the node will last
for much less time.
If you have been following along with the home automation videos, then you might have
already guessed that my first approach would be to use a wemos d1 mini board along with
ESPHome. And that is exactly what I tried initially but I ended up with a few concerns
that I am going to talk about next.
The first thing I wanted to do was test the current consumption during idle mode. To do
this, I created a test node that simply connects to my WiFi network. As usual the ESPHome flasher
tool was used to upload the binary file to the board and if you are not familiar with
this process then please check out the previous videos in the home automation playlist. I
then used a multimeter to measure the current as that’s what I had with me. The 5V output
from the breakout board first passes through the multimeter before reaching the wemos d1
mini. This way, I could quickly obtain the current consumption which was about 68 milliamps.
At this rate, it would run for just about 1 and a half day as seen here.
ESPHome has this deep sleep component that can be used to conserve energy and that’s
what I decided to test next. The component allows you to specify the run time or ON duration
and then for how long you want the node to sleep for. This cycle will repeat continuously
and that’s easy enough to do. In order for this to work you need to connect GPIO16 or
pin D0 to the RST pin as the wake-up signal is sent using pin D0. I decided to configure
the node to run for 10 seconds and then sleep for 20 seconds. Once this was uploaded to
the board, I used a jumper wire to connect pins D0 and RST which allows the board to
successfully wake up from deep sleep.
What I observed was that it takes about 18 seconds to cycle through even though I’ve
set it to run for only 10 seconds. And I know this because of the current consumption values
which are about 74 milliamps on average when active and 140 microamps when in deep sleep.
The deep sleep value is much higher compared to what is specified in the datasheet and
that is because we have an additional voltage regulator, USB to serial converter, LED and
a few passives. You could remove these components but it then gets more complicated and as you
will see, we don’t need to do that.
At a very basic level what we have is a button connected to the d1 mini and every time we
press it, we want to send a message to home assistant. Let us assume that we press it
once every hour and let us use this to calculate the run time. One hour has 3600 seconds, and
out of these, we will be spending 18 seconds in the active mode and the remaining 3582
in the deep sleep mode. The average current consumption will then be 0.51mAh and this
gives us a run time of about 204 days. At this point I was like, yes it can be done
with ESPHome, but there was one big concern that I will talk about next.
We’ve set the board to run for only 10 seconds and as we have seen it is active for about
18. This is because it first waits to connect to the WiFi network before running for 10
seconds and then going to sleep. This is great if you want to monitor a sensor value for
some time and then go to sleep but it’s not exactly suitable for this project. We
do not need the board to wake up periodically as that is simply going to waste more energy.
There’s also a critical issue here in that if it does not connect to the WiFi network
for any reason, then it will continuously stay active in order to try and connect to
it and this will drain the battery.
In order to have more control over the tasks and take care of these issues, you can use
the on_boot automation and tell it exactly what you want it to do. This is suitable for
what I wanted to do but it then ends up getting a bit complicated as you need to consider
things like priorities and so on. And I thought to myself that instead of doing all of this,
it would make more sense to use standard Arduino code along with MQTT which will not only give
me more control over everything but it will also keep things simple. MQTT is a protocol
that allows you to communicate efficiently and I have explained this in detail in a previous
video so please watch that if you do not exactly know how it works.
The next step was to write some code to get this working but I first decided to measure
the idle current when it only connects to the WiFi network. That was done by using this
simple sketch shown here. All the board is doing is connecting to the WiFi network and
nothing more. After uploading it to the board, the current worked out to about 74 milliamps
which is in the similar range to the previous values. I then decided to measure the deep
sleep current consumption and the sketch was simply connecting to the network and then
going to sleep. A sleep time of 0 causes the board to sleep indefinitely. This also meant
that I did not need to connect pin D0 to RST as there would not be any wake-up signal being
sent. By doing this I could see that it took about 7 seconds to connect to the WiFi network
and that the deep sleep current was still about 140 microamps like before. With this,
I managed to save about 2 seconds for each activation. Pressing the reset switch would
cause the board to repeat this cycle and this was perfect for my needs. All that was left
to do now was to send the actual MQTT message every time the board powers up. For this,
I used the pubsubclient library and once again we have covered this in a previous video.
The sketch first tries to connect to the WiFi network and if it cannot do so within 20 seconds,
then it goes back to sleep. If it has managed to connect to the network then it tries to
connect to the MQTT broker that is running within home assistant. Once the connection
is successful, it sends a message to a particular topic. It is important to make sure that the
message has been sent and that is why the node waits for the client to disconnect before
disconnecting the WiFi network. Once all of this is done, it goes to sleep. As you can
see, I’ve received the message within home assistant. The node takes about 7 seconds
to complete this and in an ideal world with the node being triggered 24 times a day we
get a run time of about 372 days or just over a year.
We have made a lot of progress but there is one more thing that we can do to extend the
battery life further. Instead of keeping the node in deep sleep, we can use a simple external
circuit to disconnect it completely. This will reduce the power consumption further.
The first thing that came to mind was using a P-channel MOSFET which switches ON when
its gate voltage is lower than its source voltage. This means that if we add a pull
up resistor like this, then it will keep the MOSFET OFF. By connecting a switch to the
gate, we can switch ON the MOSFET when the switch is pressed and if we connect the output
to the d1 mini then it will switch ON as well. This is great progress so far but the d1 mini
will only be ON when the MOSFET is ON and this happens only when we press the switch.
However, it takes about 7 seconds to connect and send the MQTT message which means that
we need to keep pressing the switch for this long. An easy way to fix this issue is by
connecting a GPIO pin to the MOSFET gate and we can pull this pin LOW as soon as the d1
mini switches ON. Here’s what the final circuit looks like and you can use any other
suitable logic level P channel MOSFET like the NDP6020P. I only have the DMG3415U with
me so that is what I decided to use.
This is what the final sketch looks like. I have defined the MOSFET pin as D1 and I
have set it to LOW as soon as the board powers up. This should keep the MOSFET ON until the
board goes back to sleep. Here I have the final circuit and I had to get a little creative
with the MOSFET. Right now, the current is 3 microamps which is leakage current and as
soon as I press the switch, the d1 mini will connect to the network and send a message
before going back to sleep. Once again, the message is received as shown on screen.
The switch is now going to consume on average 74mA for 7 seconds when it is active and it
will then consume 3 microamps when inactive. If we run the numbers again then in an ideal
world, it would last for about 2 years. To be realistic, I am not going to switch the
lights ON and OFF 24 times a day. It will probably be 2-3 times but let’s recalculate
the values for 5 times a day. This works out to about 8.65 years in an ideal world which
is a long way from the initial run time of a day if kept it in the active state continuously.
What this also means is that I can reduce the battery capacity and since I have these
tiny 240mAh batteries with me, I decided to use them instead. These particular ones have
a built-in protection circuit which meant that I did not need to use a protection board
like the TP4056 during normal use. Using these smaller batteries will give me an ideal run
time of 303 days or 10 months which is a decent trade-off given the size. I can always recharge
them after that. Do let me know if I have made any error in my calculations and if I
have made a mistake then I will pin a comment with the correct values. Either way here’s
what the final circuit looks like and I decided to connect the battery directly to the 5V
input pin as the onboard regulator will take care of the voltage regulation for us.
It was now time for the enclosure and I found this one on Thingiverse which appeared to
be suitable. It was a bit tall so I scaled it down to 85% on the Z axis and printed it
to give me this. I decided to use this switch which was good enough for the job since there
was enough space to fit everything inside. I mounted the switch on the proto board to
give me this circuit and I also wrapped everything up with some Kapton tape to prevent any short
circuits later. This build would not be complete without some hot glue, so I added some to
keep the switch in place and prevent it from sliding around. Finally, it was time to assemble
everything together which was easy enough to do. This is what the final outcome looks
like. You could obviously design something a bit better but I’ll keep that for later.
The last part was integrating it with nodeRED and if you are not familiar with it, then
please watch these two previous videos where I show you how to get started with nodeRED
and also integrate a smart LED bulb with home assistant. There have been several updates
to the home assistant user interface and here are some of the things I have noted. The name
Hass.io has been replaced by supervisor. When you navigate to the add-on store, you need
to use this button here to add more repositories. Within a particular add-on, you now have the
tabs at the top and previously you had to scroll down to access these sections. The
biggest change that I like is perhaps the integration view where in you can quickly
see the different devices that are connected, the entities and so on. This makes it very
easy to get their IDs for instance.
Anyway, creating the nodeRED flow was very simple. All I had to do was use an MQTT in
node and the first thing I had to do was configure the MQTT broker. You will need to use the
details that are specific to your setup which is just the IP address of the broker, the
username and password. If you have followed my previous videos, then the broker IP address
is the same as your Raspberry PI. Once that was done, I simply had to specify the topic
to listen to. I could then use a switch node to check the output value and then give me
an output when the appropriate payload was received. We are only sending one value from
the board so this node is not really needed but you might want to send multiple values
in the future in which case you know how to use them in nodeRED. I then connected the
output from this switch node to a call service node and I had to specify the domain, action,
entity ID like so. I used the toggle action here as I want the light to switch ON when
I press the switch and I want it to switch OFF when I press it again. All I had to do
now was deploy the flow and test the setup. When I press the switch, a message will get
sent to home assistant and nodeRED will then use this to trigger the bulb as indicated
by the messages below the nodes. Pressing the switch again will repeat the cycle but
this time, nodeRED will switch it OFF instead.
And that is how I created a WiFi switch like this that can be used for automations. I plan
on using this as a master power switch for my workstation. By using a SonOff switch I
can control everything using a single button that can be conveniently located. I hope you
found this video useful, don’t forget to like and subscribe if you haven’t already.
Thanks for watching and I will see you in the next one.