Making a simple weather web server using ESP8266 and BME280

Since its launch in 2014, ESP8266 has revolutionized the IoT space by offering an extremely cost-effective and programmable WiFi-enabled microcontroller to hobbyists and professionals, thereby opening the doors to all kinds of everyday objects and sensors to the internet. In addition, with it’s built-in WiFi capability, the ESP8266 can also serve as a standalone web server on a local network, and can respond to the http GET commands received from an internet browser. This project illustrates how to construct a simple standalone weather web server utilizing NodeMCU development board for ESP8266 and Bosch’s BME280 environmental sensor chip. On receiving the web requests, the ESP8266 responds back by returning back an HTML webpage containing the ambient temperature, humidity and pressure measurements. With the help of refresh meta tags, the webpage automatically reloads every 15 seconds to get the latest environmental sensor data.

Weather web server using ESP8266 and BME280 environmental sensor

Weather web server using ESP8266 and BME280 environmental sensor

Hardware

This project requires minimal hardware components. You will need an ESP8266 development board, like NodeMCU that I am using here, a BME280 sensor module, a breadboard with some jumper wires, and a USB cable for programming the NodeMCU board.

BME280 is a fully integrated environmental unit from Bosch that combines sensors for pressure, humidity, and temperature in a tiny 8-pin metal-lid LGA package of size 2.5 x 2.5 x 0.93 mm³. Because of its compact size, ease of use (BME280 supports standard I2C and SPI interfaces), and availability of supporting open-source Arduino libraries, BME280 is very popular among weather enthusiasts. In this project, the I2C data (SDA) and clock (SCL) pins of the BME sensor module are connected to the NodeMCU pins D3 and D4, respectively.

setupserver

Weather web server setup on breadboard

Weather web server hardware setup on breadboard

Software

The ESP8266 firmware for this project is developed using Arduino IDE. You need to install the ESP8266 core to enable the Arduino IDE for ESP8266 programming. Instructions can be found in the ESP8266 core github page or here too. You will also need the following Adafruit libraries for reading data from the BME280 sensor.

Adafruit unified sensor library

Adafruit BME280 library

The I2C address for BME280 is hardcoded in the Adafruit_BME280.h file (look for the line #define BME280_ADDRESS  0x77) inside the Adafruit_BME280_Library folder. Adafruit’s BME sensor modules are hard-wired to use the I2C address of 0x77. But the BME280 can have a slightly different I2C address (0x76) if its external SDO pin is grounded. If you are using the sensor modules from other party, it is likely that it’s address would not match with the default value in the Adafruit library. For example, for most of the BME280 sensor modules available on eBay or Aliexpress, I have found their I2C address to be 0x76. So, if you didn’t get any response from the sensor using the default address set in the Adafruit_BME280.h file, you might need to change that to 0x76.

My complete code for this weather webserver project can be downloaded from the following link:

Download BME280_webserver_code

The code for a very basic HTML webpage with sensor output and auto refresh meta tag is included in the above ESP8266 firmware. Note that you need to edit the SSID name and password in the program to match with your WiFi network before uploading it to the NodeMCU board.

Output

After uploading the program to NodeMCU, when the ESP8266 restarts it prints out on the serial monitor the IP address it’s allocated in the local network. In order to access the ESP8266 web server, you need to open a web browser on any computer, tablet, or smartphone connected to the same WiFi network and type in the ESP8266 IP address in the URL field and hit enter. On receiving a client request, the ESP8266 serves a webpage containing the BME sensor readings, as shown below.

Standalone weather web server using ESP8266 and BME280

Standalone weather web server using ESP8266 and BME280

The HTML page is refreshed automatically every 15 second to get the latest sensor readings. The Dew Point is computed from temperature and humidity using the following approximation:

Source: Wikipedia

Source: Wikipedia

Weather web server broadcasting BME sensor readings

Weather web server broadcasting BME sensor readings

This is a very nice and handy way of monitoring the weather around us, as it allows to watch the environmental parameters on our tablets and smartphones that we are carrying all the time.

Smartphone

Weather data on smartphone

Acknowledgement

Thanks to Rui Santos from Random Nerd Tutorials for sharing his DS1820-based temperature web server code. I modified his code to incorporate the BME280 sensor readings, and also added auto-refresh Meta tag to reload the HTML page automatically in every 15 sec.

Related Posts

18 comments

  • That BME280 module looks EXACTLY like the module I bought from Amazon (enter B0118XCKTG in Amazon search). That module has a 3.3V LDO and a two MOSFET 5V/3.3V SCL SDA I2C level shifters on the back of the board. So how can it work by connecting the input power and I2C pins to 3.3V only? Or is your BME280 breakout board design different (no LDO and no level shifters)? I wish you would have included a picture of the back of the BME280 module so we would know what kind of module you are using; either that or a link to the actual module you used.

  • PLZ HELP

    i used invento bme280 sensor
    should i need to change progam for this sensor

  • Thanks for posting this. I have it up and running, but there seems to be an appreciable offset in the reported temperature. It is reporting higher than other sensors in the same room. I suspect self heating may be the culprit having seen a few posts around the internet that describe it.

    This link describes putting the thermometer into a “forced” mode where it only takes a reading when called for, rather than regularly multiple times a second.
    https://github.com/letscontrolit/ESPEasy/issues/164

    I look through the library you posted and see that it looks like it does indeed use forced mode… Could it be that we are polling the sensor too often even though we are in forced mode?

    Any other ideas regarding over temp readings or self heating?

    Thanks again!

  • This is what I get when trying to upload the code… But I guess it is not connecting properly…do you have an idea whats wrong?

    Archiving built core (caching) in: C:\Users\UJJVAL\AppData\Local\Temp\arduino_cache_108913\core\core_esp8266_esp8266_nodemcuv2_CpuFrequency_80,UploadSpeed_115200,FlashSize_4M3M_0a1d2cea65098425b769992f1079e102.a
    Sketch uses 237429 bytes (22%) of program storage space. Maximum is 1044464 bytes.
    Global variables use 32864 bytes (40%) of dynamic memory, leaving 49056 bytes for local variables. Maximum is 81920 bytes.
    Uploading 241584 bytes from C:\Users\UJJVAL\AppData\Local\Temp\arduino_build_112005/BME280_Webserver.ino.bin to flash at 0x00000000
    …………………………………………………………………….. [ 33% ]
    …………………………………………………………………….. [ 67% ]
    …………………………………………………………………. [ 100% ]

    • That looks normal. The sketch uploaded correctly if it says 100%.
      Open the serial port to see the IP address then type that into your browser.

  • Nice tutorial!!

    Got it working after changing the I2C adress, in the Adafruit_BME280B.h.

    But where do I chagnge F to C ?

    • I have tried the tutorial but not works, I get “Could not find a valid BME280 sensor, check wiring!” error. What have you changed in Adafruit_BME280B.h?

    • (chagnge F to C )
      h = bme.readHumidity();
      t = bme.readTemperature();
      //t = t*1.8+32.0;
      dp = t-0.36*(100.0-h);

      client.println(“°CHumidity = “);

      client.println(“°CPressure = “);

  • Hi again and thanks for the previous reply.

    Can you point me to an example or help me out with a new question?

    I would like to use your project but have the web server on the ESP8266 be a master for multiple projects as you built yours.

    Just to clarify, 4 or 5 projects just like you built but have them all report to and displayed on a single ESP8266 webserver page.

    Thanks

  • Just to be clear because I have never used an Arduino product.
    Do I need an Arduino controller or can the NodeMCU ESP8266 be programmed directly from the computer with the IDE software?

    If so, All I need is
    NodeMCU ESP8266
    BME820
    Breadboard with jumpers

    What type of connection do you use for power? Does the USB cable supply the power do run the device?

    Thanks
    Frank

    • Hi Frank,
      You are right. All you need is NoceMCU board, BME280 sensor module, and some jumpers for this project. It can be powered with a standard USB port or a cell phone charger.

  • Nice tutorial. well presented.
    Wondering why the client connects twice during the process. I’m not an HTML/Web hound so I don’t understand this.

    Client disconnected.
    New client
    GET / HTTP/1.1
    Host: 192.168.1.48
    Connection: keep-alive
    Cache-Control: max-age=0
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Referer: http://192.168.1.48/
    Accept-Encoding: gzip, deflate, sdch
    Accept-Language: en-US,en;q=0.8

    Client disconnected.
    New client
    GET /favicon.ico HTTP/1.1
    Host: 192.168.1.48
    Connection: keep-alive
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36
    Accept: */*
    Referer: http://192.168.1.48/
    Accept-Encoding: gzip, deflate, sdch
    Accept-Language: en-US,en;q=0.8

    Client disconnected.

    • The two connections are slightly different – the second connection by the client attempts to get the “favicon” for the web server. Of course this is unnecessary in such a simple embedded application, but your client (web browser) is unaware and makes the request anyway. It appears that the server code doesn’t differentiate between the two requests, so it will probably reply to both requests with the same response. If you wanted, you could modify the server code to ignore the favicon request – or make an appropriate reply to the favicon request 🙂

  • Nice tutorial! Can anyone make this sever available outside the home WiFi network?

Leave a Reply

Your email address will not be published. Required fields are marked *