Weatherstations are a popular build for DIY-ers and with the ESP8266 WiFi capabilities that has become very easy.
Here I will present a simple weatherstation (DHT sensor BMP sensor for temperature, humidity and atmospheric pressure) that can be battery fed or mains fed.
It will send the info by MQTT and in order to save batteries, go to sleep most of the time.
Components needed are:
- A wemos mini D1
- A DHT11 or DHT22
- A BMP280
- A 100k resistor for the battery
- A small switch or jumper
- A LithiumIon charger module
Just a word for the wise… the Wemos D1 is not the best option to battery feed, as it has some peripheral components (such as the CH340 chip) that draw current. A better choice would be the bare ESP8266, but it is not for everybody to solder that.
The application has OTA. Using OTA together with deep sleep is always a bit of a tricky situation as you cannot do OTA when the ESP8266 is in deep sleep.
basically there are 3 solutions for that:
- Include a pause in which you can do OTA. Problem with that is that you would need some indication of when that pause starts (e.g. once the MQTT messages have come in). Another problem is that that pause in which the processor is not in deep sleep, it wil consume more energy.
- Make the deepsleep dependent on the state of a pin. With a jumper or Switch you could make one pin high or low and thus allow deepsleep or not.
- By having the software check on a seperate website whether or not there is an update for the software and then download that software. Obviously that requires some more organization and if the Wemos will do that check whenever it awakes, it will do that say every 15 minutes for something that may never happen.
Considering the above, Option 2 seemed the best, so I added a small switch to tell the software whether or not to go into deepsleep.
The program once loaded (get it here) has several tabs in the IDE.
The main program “esp8266_weatherstation” is quite straightforward, it sets up all the usual parameters, variables and the sensors.
It reads the sensors and sends these via MQTT to a broker.
Once that is done, it goes into deepsleep, depending on two parameters:
- the “FORCE_DEEPSLEEP” variable: if present there will be a 15 min deepsleep. If not set, the deepsleep will be determined by the battery voltage.
- the state of the ‘SLEEPPIN (D6): if LOW there will be deepsleep, if HIGH, there will be no deepsleep
[Edit: DeepSleep can be made more effective See the series “Very Deep sleep and energy saving” that starts here.]
If there is no deepsleep, a pause of 30 secs is added to avoid the MQTT messages being send in a frenzy.
You may be puzzled by the following code section:
float h = dht.readHumidity(); float t = dht.readTemperature(); delay(2000); float h = dht.readHumidity(); float t = dht.readTemperature();
The reason for this is the response time of the DHT22. If you start a reading, the results you get are from a reading that was started 2 secs before. Usually that is not an issue, but if you put the processor to sleep for 15 minutes, that first reading will give you 15 min old values. If that is not a problem, by all means remove the delay and second reading. It will not make a difference on your battery life as your DHT22 is not put to sleep.
technically ofcourse it is possible to feed the DHT22 from one of the I/O pins and switch it off when not needed, but the DHT22 also needs a warm-up time of about 2 secs, so you would need to take that into account. No doubt that warm up time could be catered for with the delay(2000) command mentioned above.
The “OTA” section sets up the OTA function. As explained before, OTA and DEEPSLEEP is a bit of an uneasy combination. In order to use OTA, tou would need to put the switch on D6 in the right position (HIGH) and either reset the WEMOS or wait till the next wake up. Mind you that when DEEPSLEEPing the OTA port can disappear, but it should come back once the processor is out of DEEPSLEEP.
the “config.h” file defines some variables
the “webconnect” file connects to WiFi. If for some reason that connection cannot be made after 10 times trying, the processor is going back to sleep for 30 more seconds and then tries again.
The libaries used are quite standard, with the exception of the PubSubClient library. This is not the well known PubSubclient library from Nick O’Leary, but a fork made by Ian Tester. The reason for using that one is that it is easier to send variables in the MQTT payload.
The DHT library is the DHT sensor Library from Adafruit. If you prefer another DHT library (there are many) you will probably only need to make minor changes.
The BMP280 library is also from Adafruit.
The DHT22 is the more accurate sibling of the DHT11, but both have a tendency of failure. generally the DHT22 needs a pull up resistor, but one can also use the internal pullup of the I/O pin for that.
There are two specification where the DHT11 is better than the DHT22. That’s the sampling rate which for the DHT11 is 1Hz or one reading every second, while the DHT22 sampling rate is 0,5Hz or one reading every two seconds and also the DHT11 has smaller body size.
If you are using this sensor outside, you can protect it against dirt and creepy crawlies by covering it with a single layer of teflon tape. Supposedly this is fully permeable for humidity.
The DHT sensors do not have eternal life. they give up working alltogether (and usually permanently) when the humidity is 100%
|Voltage||3-5 Volt||3-5 Volt|
|Temperature range||0 t/m 50 ºC||-40 t/m 80 ºC|
|Temperature accuracy||±2 ºC||±0,5 ºC|
|Humidity range||20-80% RH||20-95% RH|
|Humidity accuracy||±5% RH||±2-5% RH|
The BMP280 is the successor of the BMP085, BMP 180 and BMP183
Ofcourse it is possible to use one of the above predecessors, but these older sensors are generally more expensive than the BMP280.
The BMP280 can measure barometric pressure with ±1 hPa absolute accuraccy, and temperature with ±1.0°C accuracy. It can be controlled both by SPI and I2C.
Do not mix it up with the BME280. That sensor can also read humidity, but it is slightly more expensive.
The BME280 ofcourse would be a perfect chip to go to if you want to avoid the DHT22 sensor. It can read temperature, humidity and barometric pressure. I just didnt have it lying around, thus couldnt try.
If you are no fan of the DHT11/22 consider the I2C HTU21D, or theSi7021 (replaced by the HTU21D).
If you are only interested in say temperature and not in humidity, the BPM280 is the best choice and you can omit the DHT22. If you only want temperature, the DS18B20 is probably the best choice.
It is hard to give recommendations for what battery to use. I am using the battery shield to which I connect a LiPo battery. That makes it all very simple but it is not the most efficient way of using the energy from a battery as the battery shield first boosts it up to 5 Volt after which the Wemos makes 3V3 Volt from it.
Another easy way is to use a Lipo battery with a lowdrop 3V3 regulator and a cheap charging module (pictured top). You could combine the charging module with a small solar cell (with a 5-6 Volt max output). The 100k resistor in the circuit sketch should go directly to the V+batt, to monitor the battery voltage. The choice for the 100k resistor is explained here. If for power efficiency you decide to use a bare ESP8266 instead, one has the opportunity to increase the resistors of the voltage divider to come to a smaller current through these resistors