ESP32 Weather Forecaster


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

By monitoring the changes in air pressure and categorising the changes thus:

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

Enables the weather to be forecast using a set of rules 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.


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 BME280 or BMP180 air pressure sensor. The choices are, but not limited to:


 CPU    Pressure Sensor    Display
ESP32 OR  BMP180 OR 1.3″ OLED SH1106 Device Driver
ESP8266    BME280   0.96″ OLED SSD1306 Device Driver 


The source 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 libraries do-not provide ESP32 support for the Bosch devices but are easily modified to enable support and compilation.

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 for the differences.


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(SDA,SCL) or Wire.begin(5,4);

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


The 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) {
  if (mode > BMP085_ULTRAHIGHRES) mode = BMP085_ULTRAHIGHRES;
  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 is currently provided 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 BST and DST is active

configTime(0, 0, “”);                // UK GMT and DST is not active


There are five screens displayed thus:

1 2 3 4 5
3-Hr Summary 3-Hr Forecast Text 24-Hr Pressure trend  1-Hr Summary 1-Hr Forecast Text

Detailed screen summary:

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 either 1 or 3 hours.
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.

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 –