Battery powered weather station with ESP8266 and BME280

I used to use web services such as OpenWeatherMap to monitor outside temperature in openHAB. I found out that sometimes they’re not very accurate and naturally they fail when the internet is down. So I decided to measure the temperature myself. After some searching, I decided to settle with battery powered ESP8266 wireless solution. The advantages are the following:

  • no wires;
  • low cost;
  • easy programming via familiar Arduino IDE;
  • long battery operation with deep sleep mode.

I’ve chosen ESP-01 module mostly due to its popularity and low cost. However, to reduce power consumption it requires two hardware modifications: removing power LED (which is always on otherwise) and soldering pin #8 of ESP8266 chip to RST pin of the module. The latter is especially tricky—the chip pins are very tiny—so if you’re not comfortable you should probably choose ESP-03 module instead.

To measure temperature I use BME280 environmental sensors which also provide humidity and pressure readings. I prefer them over DHT-22 which are less accurate, very slow and generally less reliable. You can get BME280s in neat ready to use modules.

To program ESP-01 I used UART module I already had which supports 3.3V, but I’d highly recommend a specialized one. To enter programming mode, you need to connect GPIO0 to GND and CH_PD pin to VCC, and this module has a special switch for that. This makes debugging via serial connection much easier.

I need the setup to operate in cold temperatures (down to -20°C), so I chose 3×AA Ni-MH rechargeable batteries which are ubiquitous and behave better in such environment than Li-ion, for example. Three batteries connected in series give more than 4V fully charged which is above 3–3.6V datasheet range but seem to work nevertheless.

To summarize, you’ll need the following:

  • ESP-01 (or ESP-03, see above) module;
  • BME280 sensor module;
  • 3.3V USB UART;
  • 3×AA Ni-MH batteries with holder;
  • soldering iron, wires (breadboard, jump wires, etc.—optional);
  • PC with USB port and Arduino IDE.

On the software side, I used existing openHAB installation. To communicate with ESP-01 it needs running MQTT broker and corresponding addon. Fortunately, broker installation is simple:

wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key
sudo apt-key add mosquitto-repo.gpg.key
cd /etc/apt/sources.list.d/
sudo wget http://repo.mosquitto.org/debian/mosquitto-wheezy.list
sudo apt-get install mosquitto

sudo systemctl enable mosquitto
sudo systemctl start mosquitto

openHAB addon can (probably) be installed via Paper UI, but I used legacy config:

sudo nano /etc/openhab2/services/addons.cfg

sudo rm /var/lib/openhab2/config/org/openhab/mqtt.config
sudo nano /etc/openhab2/services/mqtt.cfg

I found that the best way to debug Mosquitto is to run it in terminal:

sudo systemctl stop mosquitto
sudo mosquitto -p 1883 -v

I did the wiring and debugging in following steps:

  1. Connected ESP-01 to UART and check if it works. I used WiFiScan example for that.
  2. I started with a great sketch by Marcel Akkerman but replaced BME280 code with dummy random values. Don’t forget to create config.h file with your parameters!
  3. When I got that running, I enabled BME280 code and connected the sensor. I was pleasantly surprised when it worked and started sending data.
  4. Then I soldered deep sleep pins and brutally destroyed power LED on ESP-01 and added ESP.deepSleep(10*1000*1000) call to the sketch which sends it to sleep for just 10 seconds. For debugging purposes, I disabled BME280 readout again and was removing GND wire from CH_PD pin of ESP as soon as the sketch was 100% uploaded. This way I could see the serial output.
  5. When I was happy with results, I increased the interval to 900 seconds, disabled serial output and enabled BME280 again.

As the last step, I used RX (GPIO3) pin on ESP-01 to power BME280 sensor. That prevents it from draining battery when the deep sleep is active.

Here’s the final wiring scheme:

AA battery powered ESP-01 with BME280 and deep sleep - scheme

And here’s the sketch for ESP-01:

The configuration file:

openHAB

Unfortunately, MQTT operates with strings and to draw plots and create conditions in openHAB we need numbers. So I created a set of hacky rules to convert values on each change:

The first test with some old used batteries showed that the setup worked down to at least 2.3V.

UPD Nov’18: So far with a set of few years old 2000 mAh AA NiMH batteries the setup works for 2 months+ in summer and ~1 month in winter.

19 comments:

  1. Marco says:

    Hi,

    I try to use your sketch but I use a username an password to connect mqtt. Unfortunately I am not a programmer is there a line where I just can add password and username?

    Thank you & regards

    Marco

  2. Kim says:

    So I’m completely new to this!
    What should I do when I get:

    In function ‘void setup()’:
    sketch_aug14b:80: error: ‘WIFI_SSID’ was not declared in this scope
    WiFi.begin(WIFI_SSID, WIFI_PASS);
    ^
    sketch_aug14b:80: error: ‘WIFI_PASS’ was not declared in this scope
    WiFi.begin(WIFI_SSID, WIFI_PASS);
    ^
    sketch_aug14b:93: error: ‘MQTT_IP’ was not declared in this scope
    client.setServer(MQTT_IP, MQTT_PORT);
    ^
    sketch_aug14b:93: error: ‘MQTT_PORT’ was not declared in this scope
    client.setServer(MQTT_IP, MQTT_PORT);
    ^
    exit status 1
    ‘WIFI_SSID’ was not declared in this scope

  3. Adrian says:

    “I’ll update this post with long term testing results.”

    This.

    • glsk says:

      Fair point! So far with a set of few years old 2000 mAh AA NiMH batteries the setup works for 2 months+ in summer and ~1 month in winter.

  4. Leo Diaconu says:

    hi,
    Great project.
    Can you share some sketch with an web interface to change the network settings ?
    It is not practical to connect the device to pc every time you change your SSID or password.
    Thanks!

  5. neonew says:

    Thank you for this excellent article! Best tutorial I’ve found, including all youtube videos.
    Maybe you can add a photo of your final setup?

    • glsk says:

      Haha, no way, sorry. :) It’s just too ugly to show — basically it’s the scheme shown above stuffed in a plastic box with a hole for the sensor to react faster.

  6. Kimmo Hassinen says:

    Is there way to monitor battery levels somehow? Like putting alarm or something when 10% or less is battery left.

  7. InLeon says:

    Hi,
    thanks for your great project, what I’m exactly looking for.
    But I have a problem: I can read only the values from the esp out of the MQTT server, but not from the BME. These values shows always “nan” (not a number).
    When I connect the BME directly to VCC everything is fine, but not when powering it with GPIO3.
    I am using 3xEneloop (~3,9V). GPIO3 switches every 10 seconds between 3.7V and 3.5V, but never goes down to 0V as I expected.

    Do you have any idea?

    Best regards
    Ingo

    • glsk says:

      Now that I think of it, maybe powering off BME280 doesn’t make too much sense in the first place. The sensor itself consumes just 0.1 uA in sleep mode, that’s less than 0.1 mAh per month. I never did any long term tests myself, maybe you want to try?

      Anyway, a stupid question: are you sure ‘digitalWrite(3, LOW)’ is actually being called before going to sleep? In my sketch it’s executed only if DEBUG is not defined.

      • InLeon says:

        Hi glsk, yes, I do call ‘digitalWrite(3, LOW)’ because DEBUG is not defined. That’s strange, isn’t it?
        Regarding the powering of BME280, 0.1 uA is not very much. I think I have to use it in MODE_FORCED, so it goes to sleep mode after a read. I have no experience with it, but I will try and tell you about it.
        Ingo

  8. Iulian Gheorghiu says:

    Hi!
    I’m trying to achieve something similar to the above but using a ds18b20 temperature sensor instead, and I’m facing some issues powering the esp-01 :(. For some reason, it doesn’t power on 3 regular AA batteries (Duracell, not rechargeable) connected in series with a pull down regulator (AMS1117-3.3 3.3V) and 2 electrolytic capacitors (100uf, 10uf). Still, when I connect the entire setup on RPi it powers on perfectly fine. I even tried with 4 AA batteries and it powered on, but I don’t think this is the way to go since replacing 4 batteries is not cost-effective. The output voltage on those 3 AA is about 4.6V and the pull down regulator reduces it to a steady 3.24V. Connecting the ESP-01, reduces the voltage even more to about 2V.
    Am I missing a point here, should I have gone with rechargeable batteries instead?
    Thanks & really appreciate this tutorial! :thumbsup:

    • glsk says:

      That’s odd. My ESP-01 works just fine in ~2.5-4.2V range. According to the datasheet the maximum dropout voltage of AMS1117 is 1.3V, may this be the reason of your troubles (4.6 – 1.3 = 3.3)?

      BTW, are you sure this regulator won’t drain the battery too quickly? Since DS18B20 can go up to 5.5V I’d try powering your setup with 3 AAs directly. But better have a spare ESP-01 just in case. ;)

Your comment: