Introduction: ESP32/ESP8266 Weather Forecaster/Predictor

Picture of ESP32/ESP8266 Weather Forecaster/Predictor

Using an ESP32 or ESP8266 we can forecast weather by reading air pressure from a sensor such as the BOSCH BMP085/180 or BME280.

Then by monitoring the changes in air pressure and categorising the changes thus:

  •  Rising quickly
  •  Rising
  •  Rising slowly
  •  Steady
  •  Falling slowly
  •  Falling
  •  Falling quickly

And applying the changes to a set of rules this enables the weather to be forecast based on air pressure at your location (adjusted from sea level with a offset) and then by monitoring changes over time, in this case 3 and 1 hours leading to a prediction with a good level of certainty.

Step 1: Hardware Either an ESP32 or ESP8266

Picture of Hardware Either an ESP32 or ESP8266

The project uses an ESP32 or ESP8266 processor and the I2C bus to communicate with an OLED display of 1.3” or 0.96” size together with a BOSCH BMP180 or BME280 air pressure sensor.

The choices are the processor an ESP32 or ESP8266, then a suitable sensor either a BOSCH BMP180 or BME280 and then a display either a 1.3" OLED with SH22016 controller or alternatively a 0.96" OLED with a SSD1306 controller.

Step 2: BMP180 Sensor Type

Picture of BMP180 Sensor Type

This provided pressure and temperature, although in this project temperature is not used.

Step 3: BME280 Sensor Type

Picture of BME280 Sensor Type

This sensor provides pressure, temperature and humidity, which if mounted at an outside location enables even more advanced forecasting to be achieved rather than using pressure alone,. For example, air temperature nearly always falls just before it rains, so this parameter can help improve forecast prediction, albeit in the short-term.

Step 4: Wiring It Together Using the I2C Bus

Picture of Wiring It Together Using the I2C Bus

Use the following diagram to wire up the controller, sensor and OLED display. Most sensors use a +5v supply, so beware if using the 3.3v types as they will require an additional 3.3v regulator or a take off from the 3.3v available on most ESP32/ESP8266 development boards. IF your using a 3.3v system then make sure your OLED display will operate at that voltage and wire the sensors to by-pass the usual 3.3v regulator fitted on-board. You can obtain the Bosch sensors designed for 3.3v.

Connect the ESP32 or ESP8266 to the OLED and BMP/BME Sensors using the I2C bus connections. For example if you decide to use GPIO-5 for the I2C SDA function and GPIO-4 for the I2C SCL function then the source code statement that initiates the I2C bus support would be:

Wire.begin(5,4); // wire.begin(sda,scl)

Generally you can use any two pins to provide the I2C bus function, but be aware that other pins are often used for other functions, so be careful not to create a pin usage conflict.

Step 5: Software Set-Up

The source code needs to be adjusted depending on the hardware configuration. The BOSCH sensors require:

Device Driver Library Required

BMP085 or BMP180 Adafruit_BMP085

BME280 Adafruit_BME280

Both Adafruit libraries do-not provide support for the Bosch devices but are easily modified to enable support and compilation. See later.

The displays require the correct driver support, the most common screen driver device is the SSD1306 for the 0.96” OLED display or SH1106 for the 1.3” OLED variant.

The code works equally well on an ESP8266 but the time source requires some modification, see the ESP8266 source code version for the differences.


Adafruit sensor BME280 has an I2C address that has been set at 0x77 and if you are using an Adafruit device then no modification of the device library address is required.

However, if you have one of the many third-party devices these nearly always use the address 0x76 and require the following changes to the library file:

BME280 Modify the address in the library file: Adafruit_BME280.h to read thus:

#define BME280_ADDRESS (0x76)

Generally the BMP085 third-party devices use the address 0x77 as does the Adafruit variety.

In addition to device address changes the files Adafruit_BMP085.cpp and Adafruit_BME280.cpp need to be modified to remove a default Wire.begin() statement so that the ESP32 can have the required pins defined.

For the Adafruit_BMP085 library, edit the file Adafruit_BMP085.CPP and comment out the wire.begin statement:

boolean Adafruit_BMP085::begin(uint8_t mode) {


oversampling = mode;

//Wire.begin(); //***************** Comment out

For the Adafruit_BME280 library, edit the file Adafruit_BME280.CPP and comment out the wire.begin statement:

bool Adafruit_BME280::begin(uint8_t addr) {

_i2caddr = addr; // init I2C or SPI sensor interface

if (_cs == -1) { // I2C

//Wire.begin(); //***************** Comment out


The source code time statement currently provided is for UK time and Daylight Saving Time is enabled, this requires a time configuration statement thus:

configTime(1*3600, 3600, ""); // +1hour (1*60*60=3600=+1hour) ahead for DST in the UK

The format of the ‘configtime’ statement is thus:

configTime(timezone, daylightoffset, primary_timeserver_address, secondary_timeserver_address);

therefore examples are:

configTime(1*3600, 3600, ""); // UK and DST is active

configTime(0, 0, ""); // UK and DST is not active

Step 8: 3-Hr Forecast Screen

Picture of 3-Hr Forecast Screen

The top line displays a real time clock that is updated every second together with the current Day of week and date.

An icon is displayed that corresponds to the forecast, in this example ‘Mostly Sunny’.

The second line displays the current air pressure in hPA. If you wish to convert to “ (inches) change the display of air pressure using a simple units conversion constant and change text from hPA to inches or “

The third line displays the change in air pressure over the time period being displayed for this screen 3 hours.

Step 9: 3-Hr Forecast Text Screen

Picture of 3-Hr Forecast Text Screen

This display provides the forecast text that corresponds to the weather icon in the previous screen.

When the forecast screen is the 3-hour or 1hr Segment and the forecast is either ‘No Change’ or ‘Clear Spells’ and depending on the average 1 or 3-hours of previous weather conditions preceding this forecast, the forecast test can have a suffix added thus:

  • expect sun
  • mainly cloudy
  • expect rain

‘No change’ is assumed to be a continuation of the previous weather patterns, which the program averages for the given period; either 1 or 3-hours.

Step 10: Pressure Trend Screen

Picture of Pressure Trend Screen

This display provides a
graph of pressure change over the last 24-Hrs. The reference is time-0 or the first column which will always be display as zero regardless of any historical value. It provides a useful visual indication of how pressure is changing over time.

Pressure is displayed at the following time periods in historical hours -24, -18, -12, -6, -3, -2, -1, 0:

  • 0 now or since the last update
  • -1 pressure 1-hour ago
  • -2 pressure 2-hours ago
  • -3 pressure 3-hours ago
  • -6 pressure 6-hours ago
  • -12 pressure 12-hours ago
  • -18 pressure 18-hours ago
  • -24 pressure 24-hours ago

The display on the far-left indicates the currency of the data in hours, so a display of 3 would mean the data is current up to the 3-hour column. The Y-axis is in hPA + or -

Step 11: Source Code and Youtube Video

These are the source files for the ESP32/ESP8266 variant together with a YouTube video and User Guide.

The files can also be downloaded from GitHub here: Weather Forecaster Source Code and other files


Bill_P (author)2017-08-27

Okay, thanks. I'll study the code some more.

Bill_P (author)2017-08-26

I just built this in the last couple of days and I can't figure out how "weather_extra_text" is displayed. I see where is it set, but where is it used? I'm using the ESP8266 version.
Thanks for the Instructable.

DavidB394 (author)Bill_P2017-08-26

see my other explanation, but the extra text is added at e.g. Line 319 with the expression 'test?true:false' which calls either the 1hr or 3hr average checker as required. Frame 2 display is the 3hr forecast and frame 5 the 1hr variant so called with range=true for one and false for the other.

g6ejd (author)Bill_P2017-08-26

It only gets displayed (Extra-Text) if the conditions move to No Change and the preceding average value is say 'Sunny' then the prediction is more of the same so 'No Change, Expect Sun' or if the preceding weather was rain and No Change is forecasted, then the same thing happens (No Change, Expect Rain) it checks the average weather before the forecast change then adds whatever it was , most likely Rain so the extra-text is added for 'Expect Rain'. or if no significant weather precedes the 'No Change' forecast then most likely 'Cloudy Conditions' will follow. The forecast is saved for every hour to make the average based on a simple + / - number scale, so Sunny is say +3, Cloudy +2 and Rain -2 and so-on. The average if predominantly negative, is then mostly likely for rain or storms. Hope this helps.

Swansong (author)2017-08-16

That's a neat setup :)

g6ejd (author)Swansong2017-08-16

My aim was not use any of the many weather data sources like Weather Underground as many people don't like to get an account, so using pressure trends is the next best solution and it's quite accurate. I've been running my setup for over 6-weeks now and the correlation with real weather is high, I would say >80%, but I have not been recording to be sure. Glad you like it.