I wanted to have a home weather station for quite some time and one that everyone in the family could easily check on for temperature and humidity. In addition to monitor the outside conditions I wanted to monitor specific rooms in the house as well and my garage workshop. That would let us know when it is a good time to air out the house or run the dehumidifier (it rains a lot here during the winter). What I created is an ESP-Now based sensor system that reports to a local web-server that anyone can check from their computer or phone. For the phone I wrote as simple Android app to make that even easier.
Step 1: Design Details
I wanted to have various sensor stations I could place in different locations and have them report back to one main station (or hub) that would save the information. After trying various ideas, I decided to use Espressif's ESP-Now protocol, since it allowed for rapid communication directly between devices. You can read a bit about ESP-Now here and this GitHub repo was a great part of my inspiration.
The first picture shows the layout of the system. Each sensor reports its measurements to a gateway device which forwards the data to the main server by hard wired serial connection. The reason for this is that the ESP-Now protocol cannot be active at the same time as the WIFI connection. For a user to access the web page, the WIFI would have to be on at all times and that then makes it impossible to use the ESP-Now communications on the same device. While the gateway device must be an Espressif based device (capable of ESP-Now), the main server could be any device capable of running a web page.
Some sensor stations would run off batteries (or solar charged batteries) and others would simply have mains power. However, I wanted all to use as little power as possible and that is where the "deepsleep" feature available to ESP8266 and ESP32 devices is extremely helpful. The sensor stations would periodically wake up, take measurements and send them to the gateway device and go back to sleep for some preprogrammed period of time. Their wake period of only about 300ms every 5 minutes (in my case) reduces their power consumption significantly.
Step 2: Sensors
There are various sensors to chose from for measuring environmental parameters. I decided to stick with I2C communications capable sensors only, as it allowed rapid measurements and would work on any of the devices I had. Rather than working with ICs directly, I searched for ready to use modules that had the same pin-outs to simplify my designs. I started with only wanting to measure temperature and humidity and therefore chose a SI7021 based module. Later I wanted a sensor that could measure pressure as well and decided to try the BME280 based sensor modules. For some locations I even wanted to monitor the light levels and the BH1750 module was ideal for this as a separate sensor module. I bought my sensor modules off ebay and these are the modules I received:
- BME280 (GY-BMP/E280), measures temperature, humidity and pressure
- SI7021 (GY-21), measures temperature and humidity
- BH1750 (GY-302), measures light
There are two styles of the GY-BMP/E280 PCB modules to be found. Both share the same pin out for pins 1 to 4. One module has two additional pins, CSB and SDO. Those two pins are pre-connected on the 4-pin version of the module. The level of the SDO pin determines the I2C address (Ground = default of 0x76, VCC = 0x77). The CSB pin must be connected to VCC to select the I2C interface. I prefer the 4 pin module, since it is ready to use as is for my purpose.
In general, these modules are very convenient to use as they already have pull-up resistors installed for the communications lines and all run on 3.3V so are compatible with ESP8266 based boards. Note, that the pins on these sensor ICs are generally not 5V tolerant, so interfacing them directly with something like an Arduino Uno may damage them permanently.
Step 3: Sensor Stations
As mentioned, the sensor stations would all be Espressif devices using the ESP-Now communications protocol. From previous projects and experimentation, I had several different devices available to me to conduct my initial tests and incorporate them into the final design. I had the following devices on hand:
- two ESP-01 modules
- two Wemos D1 mini development boards
- one Lolin ESP8266 development boards
- one ESP12E serial WIFI kit board
- one GOOUUU ESP32 board (a 38 pin development board)
I also had a Wemos D1 R2 development board, but there were issues with it that did not allow it to wake up from deep sleep and as a gate way device it would crash and not properly restart. I repaired it later on and it became part of the Garage Door opener project. In order for "deepsleep" to work, the RST pin of the ESP8266 must be connected to the GPIO16 pin, so the sleep timer can wake up the device. Ideally this connection should be made with a Schottky diode (cathode to GPIO16) so that the manual reset through the USB-TLL connection during programming still works. However, a low value (300-ish Ohm) resistor or even direct wire connection can still be successful.
ESP-01 modules do not allow for easy access to the GPIO16 pin and one must solder directly to the IC. This is not a simple task and I would not recommend this for everyone. The ESP12E serial WIFI kit board was a bit of a novelty item and required quite a few changes for it to be useful for my purpose. The easiest boards to use were the Wemos D1 mini type boards and the Lolin board. ESP32 devices do not require any modifications for deepsleep to work. Andreas Spiess has a nice Instructable on this.
Step 4: ESP-01 Sensor Station
On all sensor stations the sensor modules are mounted vertically to reduce the amount of dust that can collect on them. Not all are in enclosures and I may not mount them in enclosures. The reason for this is that the devices may warm up and affect the temperature and humidity readings in not sufficiently ventilated.
ESP-01 boards are very compact and have few digital IO pins to work with, but it is enough for the I2C interface. The boards do however require a tricky modification to allow "deepsleep" to work. In the photo shown, a wire was soldered from the corner pin (GPIO16) to the RST pin on the header. The wire I used is 0.1mm diameter insulated "repair" wire. The insulation coating melts away upon heating, so it can be soldered to repair traces, etc in PCBs and still not worry about creating shorts where the wire contacts other components. Its size makes it difficult to work with and I soldered this wire in place under a (hobbyist/stamp collectors’ style) microscope. Keep in mind that the header on the right side has a 0.1" (2.54mm) pin spacing. Installing a Schottky diode here would not be easy at all, so I decided to just try the wire alone and both units have been running for over a month without any issues.
The modules were installed on two prototype boards I created. One (#1) is a programmer board that also allows I2C modules to be installed and tested, while the other (#2) is a development/test board for I2C devices. For the first board I soldered together an old USB male connector and a small PCB to power the unit directly from a USB wall adapter. The other unit has a regular DC jack modified to fit into the screw terminal header and is powered via a wall adapter as well.
The schematic shows how they are connected and how the programmer works. I do not have any other ESP-01 modules, so I haven't had any immediate need for the programmer. In the future I will likely make a PCB for them. Both of these boards have the SI7021 sensor module installed as I was not as interested in pressure measurements on those locations.
Step 5: ESP 12E Serial WIFI Kit Sensor Station
The ESP12E Serial WIFI Kit board was not intended for development as much as it was for showcasing what could be done with this device. I bought it long ago to learn a bit about ESP8266 programming and finally decided to give it some new use. I removed all the LEDs that were installed for demonstrations and added a USB programming header as well as a I2C header suitable for the modules I use. It had a CdS photo resistor connected to its analog input pin and I decided to leave it there. This particular unit was going to monitor my garage workshop and the photo-sensor it had was sufficient to let me know if the lights had been accidentally left on. For the light measurement I normalized the readings to give me a percent output and anything over “5” at night meant the lights were left on or a door to the house was not properly closed. The RST and GPIO16 pins are clearly labeled on the PCB and the Schottky diode connecting them was installed on the underside of the PCB. It is powered through a USB-serial board that is directly plugged into a USB wall charger. I have extras of these USB-serial boards and don't need this one right now.
I did not make a schematic for this board and generally do not recommend buying one to use for this purpose. The Wemos D1 Mini boards are much more suitable and will be discussed next. Although, if you do have one of these and need some advice, I'd be happy to help.
Step 6: D1 Mini Sensor Stations
The Wemos D1 Mini type of ESP8266 development boards are my preferred ones to use and if I had to do it over, I would just use these. They have a large number of accessible IO pins, can be directly programmed via the Arduino IDE and are still fairly compact. The D0 pin is GPIO16 on these boards and connecting a Schottky diode is rather easy to do. The schematic shows how I have these boards wired up and both of them use the BME2808 sensor module.
One of the two boards is used to monitor the outside weather and runs from a solar power battery. A 165mm x 135mm (6V, 3.5W) solar panel is connected to a TP4056 Li-ion battery charging module (see the Solar Powered Battery Sensor Station Setup Diagram). This particular charging module (03962A) features a battery protection circuit which is necessary if the battery (pack) does not contain one. The Li-ion battery was recycled from an old laptop battery pack and it still can hold sufficient charge to run the D1 Mini board, especially with deep sleep enabled. The board was placed in a plastic enclosure to keep it somewhat safe from the elements. However, in order for the interior to be exposed to the outside temperature and humidity, two 25mm diameter holes were drilled on opposite sides and covered (from the inside) with black landscape cloth. The cloth is designed to allow moisture to penetrate and therefor the humidity can be measured. At one end of the enclosure a small hole was drill and a clear plastic window installed. This is where the BH1750 light sensor module was placed. The entire unit is placed outdoors in the shade (not direct sun) with the light sensor point out into the open. It has been running from the solar powered battery for almost 4 weeks in our rainy/cloudy winter weather here.
Step 7: Gateway and Webserver
A Lolin NodeMCU V3 (ESP8266) board was used for the ESP-Now Gateway device and an ESP32 (GOOUUU board) was used for the Webserver. Almost any ESP8266 or even ESP32 board could have served as the gateway device, this was simply the board I had "left over" after I used all the other boards I had.
I used the ESP32 board since I need a board with a bit more computing power to collect the data, sort it, save it to storage and run the web server. In the future it may also have its own sensor and a local (OLED) display. For storage an SD card was used with a customized adapter. I used a common microSD to SD card adapter and soldered a 7 pin male (0.1" pitch) header to the plated contacts. I followed the advice from this GitHub to make the connections.
The prototyping setup (with Dupont wires) does not include a sensor module, but the finalized PCB that I designed does allow for one as well as a small OLED display. Details on how I designed that PCB are part of a different Instructable.
Step 8: Software
ESP8266 (ESP-NOW) Devices
The software for all devices was written using the Arduino IDE (v1.87). Each sensor station runs essentially the identical code. They only differ by which pins are used for the I2C communications and which sensor module they are connected to. Most importantly they send the identical measurement data packet to the ESP-Now Gateway station, regardless whether they have the same sensor. What this means is that some sensor stations will fill in dummy values for the pressure and light level measurements if they do not have sensors to provide real values. The code for each station and the gateway was adapted from Anthony Elder's examples on this GitHub.
The gateway device code used SoftwareSerial to communicate with the web server, since ESP8266 has only one fully functioning hardware UART. Running at maximum baud rate of 9600 it seems quite reliable and is more than sufficient for sending these relatively small data packets. The gateway device is also programmed with a private MAC address. The reason for this is so if it needs replacing, then the sensor stations do not all have to be re-programmed with the new recipient MAC address.
ESP32 (Web Server)
Each sensor station sends its data packet to the gateway device which forwards it to the web server. Along with the data packet the sensor station MAC address is also sent to identify each station. The web server has a "look-up" table to determine the location of each sensor and sorts the data accordingly. The time interval between measurements was set to 5 min plus a random factor to avoid having sensors "collide" with one another when sending to the gate way device.
The home WIFI router was set to allot a fixed IP address to the web server when it connects to the WIFI. For mine it was 192.168.1.111. Typing that address in any browser will connect to the weather station web server as long as the user is within WIFI range of (and connect to) the home network. When user connects to the web page, the web server responds with a table of the measurements, and includes the time of the last measurement of each sensor. This way if a sensor station becomes non-responsive, one can see that from the table if a reading is more than 5-6 min old.
The data is saved in individual text files on an SD card and they can also be downloaded from the web page as well. It can be imported into Excel or any other application for plotting data
To make it easier to view the local weather information on a smartphone, I created a relatively Android App using Android Studio. It is available on my GitHub page here. It uses the webview class to load the web page from the server and as such as limited functionality. It is not capable of downloading the data files and I had no need for those on my phone anyway.
Step 9: Results
Finally, here are some results for from my home weather station. The data was downloaded on a laptop and plotted in Matlab. I attached my Matlab scripts and you can also run them in GNU Octave. The outdoor sensor has been running on its solar charged battery for almost 4 weeks and we have rarely any sun at this time of the year. So far everything is working well and everyone in the family can look up the weather themselves rather than asking me now!