Yet Another Weather Station (Y.A.W.S.)

5.2K2516

Intro: Yet Another Weather Station (Y.A.W.S.)

This project is my take on the ever popular Weather Station. Mine is based on an ESP8266, a .96” OLED display and a BME280 environmental sensor array. Weather Stations seem to be a very popular project. Mine differentiates itself from the others by using a BME280 sensor array instead of the popular DHT22 temperature and humidity sensor. The BME280 has a temperature, humidity and air pressure sensor. It also uses the I2C interface. The .96” OLED display used is also I2C. It can be purchased as either I2C or SPI or both. I went with the I2C version to simplify the wiring. With both the OLED display and the BME280 using I2C and 3.3V it was very easy to make a ‘Y’ cable to connect both devices to the ESP8266. While developing this project I came across multiple weather station projects on the Internet that use the ESP8266, the same OLED display and the BME280. So this is not an original idea, but it is an original implementation.

The BME280 provides inside environment data. Outside weather information is obtained from OpenWeatherMap.org. You will need to signup with OpenWeatherMap.org to get a key to access the weather data. They offer a free service, which is what I used. See the step How to get an OpenWeatherMap Key for instructions on how to obtain a key.

An NTP time server is used to get the time of day and day-of-the-week.

The weather, time and environment data are displayed on the OLED display. Each piece of information has it’s own formatted screen. The screens are displayed for five seconds before switching to another. OpenWeatherMap.org is accessed every fifteen minutes to refresh the weather information. The BME280 is read about every fifty-five seconds. The font used on each screen is automatically adjusted to show all the information in the largest possible font.

The ESP8266 is also setup to be a web server. All of the weather information can be accessed using a browser from your phone, tablet of computer. One of the screens that is displayed shows the IP address of the web server.

The ESP8266 comes in a variety of shapes and sizes. I choose a GEEKCREIT DoIt ESP12E Dev Kit V2. This one is fully compatible with the NodeMCU ‘standard’ for ESP8266 standalone modules. It has an integrated 3.3V regulator, a CH340 as the USB-to-Serial bridge and the NodeMCU auto-reset circuit. You are free to use any ESP8266-12 module that you have. Just be aware that you may have to add a 3.3V regulator or other circuits to program it. I also built one using a Witty Cloud ESP8266. It allowed me to pack everything into a 1.5 inch cube. The lower USB bridge board is disconnected after programming. I added a right angle header pin to the 3.3V hole on the Witty board. The harness was made with two four pin shells, one two pin shell and two one pin shells.

In the photo above, the board that the ESP8266 module is plugged into is a circuit board that I developed as a breakout board for the ESP8266 and ESP32. It will accept the NodeMCU compatible, narrow body ESP8266 boards, The Witty Cloud ESP8266 board or an ESP32 board from GEEKCREIT. All of the available GPIO pins are broken out to headers for easy access. I have found that most development boards never have enough power and ground pins. Every time you want to attach something you need at least a ground pin and most times a pin to power the device. Each row of GPIO pins is accompanied by 3.3V power pin and a ground pin. I use the same layout that First Robotics uses, power in the middle. I like this layout because if you plug something in backwards you do not release the magic smoke. The board has a couple of extras, an IR sensor, a pushbutton switch and a tri-color LED. Jumpers can be used to connect to any of these features. If you are interested in one of these ESPxx breakout boards then contact me.

STEP 1: What You Will Need:

1 – BME280 I2C Temperature, Humidity and Pressure sensor board

I bought mine on Ebay from China for around $1.25 with free shipping. Also available from Adafruit or Sparkfun

1 - .96”, 128x64, I2C OLED display using SSD1306 driver

I bought mine on Ebay from China for around $4.00. Mine is white. You can find blue and white with an area of yellow on top. Some are sold as SPI and I2C. You may have to move some resistors to select I2C operation. The important part is that it uses the SD1306 driver chip. Also available from Adafruit.

1 – NodeMCU ESP8266-12 with CH340

You can use any ESP8266-12 module that you want. I prefer the ones with the CH340 USB-to-Serial bridge. There was a rash of fake FTDI and SI bridge chips a few years ago so I no longer trust anything other than the CH340.

2 – DuPont 4 pin, 0.1inch (2.54mm) pitch shells

2 – DuPont 2 pin, 0.1inch (2.54mm) pitch shells

12 – DuPont female crimps for 22-28 awg wire

I get mine on Ebay. You can also use Molex or any brand that you prefer. Crimped pins or IDC The choice is yours. Be careful that you buy the correct pins for your shells. They are not mix and match. You can also just solder the wires to the boards and eliminate the connectors. If you use the crimped pins, you will need a crimper. Do not try to crimp with a pair of pliers. It does not work.

1 – 5V, 1A minimum wall power pack.

These are cheap and available on Ebay. Get one with a micro USB connector or whatever mates with your ESP8266 board.

You will also need eight pieces of 22-28 awg wire to connect everything together. Or you can just wire it all to a piece of perf board. It is up to you.

I have included a picture of what was used to build the Weather Station using a Witty Cloud ESP8266. One picture details where to add a right angle header pin to pickup 3.3V. One of the two pin shells is replaced by two one pin shells. Ground and 3.3V wires are stuffed into the one pin shells.

Follow this link to get the source code files from the GitHub repository; ESP8266-Weather-Station. The zip folder or cloned folder will have a WeatherStation folder that contains WeatherStation.ino and BME280.h. These are the source code files. There are several pdf files as well. The pdf files have much the same information as this instructable.

STEP 2: Tools:

After trying many brands of crimpers, I found that the Japanese Engineer PA-21 or PA-09 works best for the DuPont male and female crimps. It is available on Ebay or Amazon. Either will work for the DuPont pins. The PA-09 will also do the pins for the JST connectors commonly used on LiPo batteries. Here is a link to a video on how to use the Engineer crimpers with DuPont crimps; How to use PA-21 Crimpers

Instructables recently had a great tutorial on using the Weierli Tools SN-28B crimpers with DuPont pins and shells. You can view it here; Make a Good Dupont Pin-Crimp EVERY TIME!

STEP 3: Make the Harness:

The wiring harness is the key to this project. It is a basic four wire ‘Y’ cable. Above is a picture of the harness I made. The OLED display and the BME280 sensor array have the same pinout. This means that the two four pin shells are identical after inserting the crimped wires. I made my harness with the double crimped wires going into the two two pin shells that attach to the ESP8266 board. You could instead, chose to stuff the double crimped wires into one of the four pin shells, making it like a daisy chain connection. Either will work.

  1. Cut all your wires to length. I like to use different colors for each wire; red for 3.3V, black for ground, yellow for SCL and green for SDA.
  2. Strip one end of each wire about 0.1 inch.
  3. Twist the strands together and add a female crimp.
  4. Once all the wires have a crimp on one end, strip all the wires about 0.2 inch.
  5. Twist the strands of two wires of the same color together.
  6. Once twisted, trim to about 0.1 inch and add a female crimp.
  7. When all the wire pairs are crimped it is time to insert the crimped ends into the shells.
  8. The two four pin shells are stuffed, from left to right, with red, black, yellow, green or 3.3V, Gnd, SCL, SDA.
  9. One of the two pin shells get the red and black wires.
  10. The other two pin shell gets the yellow and green wires.

STEP 4: Tip:

I found that when I use 28 awg wire with the crimp pins that they tend to fall off. What I do to prevent this is to strip the end of the wire twice as long as normal. Twist the exposed wires together. Then fold the twisted wire over to double the thickness. Now when I crimp it the wire is thick enough to hold tightly.

STEP 5: Connect It All Together:

  1. Plug the four pin shells into the OLED display and the BME280 boards.
  2. Align the red wire with the Vcc and 3V3 pins.
  3. Plug the two pin red/black shell on to a pair of 3V3 (3.3V) and GND pins on the ESP8266 board. There are three places on the board where 3V3 and GND pins are adjecent. Avoid the Vin (5V) and GND pins as these will release the magic smoke from your OLED and BME280 boards. Ensure that the red wire is connected to the 3V3 pin.
  4. Plug the yellow/green two pin shell on to D1 and D2 on the ESP8266 board. The yellow wire (SCL) should be on D1.

Double check your connections. If everything looks good then you are ready to power up the ESP8266 board.

STEP 6: How to Get an OpenWeatherMap Key

You will need an API key to access the OpenWeatherMap.org website to obtain current weather information. The next few steps detail how to signup with OpenWeatherMap.org and get an API key.

Follow this link to OpenWeatherMap.org.

Click on API near the middle of the top of the web page.

STEP 7: How to Get an OpenWeatherMap Key, Subscribe

On the left side, under Current weather data, click the Subscribe button.

STEP 8: How to Get an OpenWeatherMap Key, Get API Key

Click on Get APIkey and Start in the Free column.

STEP 9: How to Get an OpenWeatherMap Key, Signup

Click on the Signup button under How to get API key (APPID).

STEP 10: How to Get an OpenWeatherMap Key, Create Account

Fill in all the fields. When finished, check the I agree to the Terms of Service and Privacy Policy checkbox. Then click on the Create Account button.

Check your email for a message from OpenWeatherMap.org. The email will have your API key. You will need to copy the API key into the source code for the Weather Station in order to obtain the current weather.

The OpenWeatherMap.org free service has some limitations. Foremost is that you cannot access it more often than once every ten minutes. This should not be a problem because the weather does not change that rapidly. The other limitations have to do with what information is available. Any of the paid subscriptions will provide more detailed weather information.

STEP 11: Setup the Arduino IDE:

Program development was done using the Arduino IDE Version 1.8.0. You can download the latest Arduino IDE here; Arduino IDE. The Arduino web site has excellent directions on how to install and use the IDE. Support for the ESP8266 can be installed in the Arduino IDE by following the instructions given by this link: ESP8266 Addon to Arduino. On the web page, click the “Clone or Download” button and select “Download Zip”. The ReadMe.md file has directions on how to add the ESP8266 support to the Arduino IDE. It is a plain text file that you can open with any text editor.

ESP8266 boards come in all sizes, shapes and use different USB-to-Serial bridge chips. I prefer the boards that use the CH340 bridge chip. A few years ago FTDI, SI and others got tired of cheap clones claiming to be their parts. The chip makers changed thier driver code to only work with their own genuine parts. This resulted in a lot of frustration as people discovered that the USB-to-Serial bridges no longer worked. Now a days I just stick to the CH340 based USB-to-Serial bridges to avoid buying boards that may or may not work. In any case you will need to find and install the correct driver for the bridge chip used on your board. This is a link to the official site for the CH340 drivers; CH341SER_EXE.

The ESP8266 does not have dedicated I2C hardware. All I2C drivers for the ESP8266 are based on bit-banging. One of the better ESP8266 I2C libraries is the brzo_I2C library. It was written in assembly language for the ESP8266 to make it as fast as possible. The OLED display library I am using uses the brzo_I2C library. I added code to access the BME280 sensor array using the brzo_I2C library.

You can get the OLED library here: ESP8288-OLED-SSD1306 Library.

You can get the brzo_I2C library here: Brzo_I2C Library.

Both libraries will need to be installed in your Arduino IDE. The Arduino website has directions on how to install zip libraries into the IDE here: How to Install Zip Libraries.

Tip: After installing the ESP8266 boards package and the libraries, close the Arduino IDE and re-open it. This will ensure that the ESP8266 boards and libraries will show up in the IDE.

STEP 12: Select Your Board:

Open the Arduino IDE. If you have not done so yet, install the ESP8266 addon, brzo_i2c library and the OLED driver library.

Click on "Tools" on the top menu bar. Scroll down the drop down menu to where it says "Board:". Slide over to the "Board Manager" drop down menu and scroll down to; "NodeMCU 1.0 (ESP-12E Module)". Click on it to select it. Leave all of the other setting at their default value.

STEP 13: Select the Serial Port:

Click on "Tools" on the top menu bar. Scroll down the drop down menu to where it says "Port". Select the port that is appropriate for your computer. If your port does not show up, either your board is not plugged in or you have not loaded the driver for your bridge chip or your board was not plugged in when you opened the Arduino IDE. Simple fix is to close the Arduino IDE, plug in your board, load any missing drivers then re-open the Arduino IDE.

STEP 14: WeatherStation.ino

You can either use the Download buttons above or follow this link to GitHub to obtain the source code; ESP8266-Weather-Station.

The files WeatherStation.ino and BME280.h need to be in the same folder. The folder name has to match the name of the .ino file (without the .ino extension). This is an Arduino requirement.

STEP 15: Edit WeatherStation.ino

Click on "File" on the top menu bar. Click on "Open". In the File Open dialog box find the WeatherStation folder and select it. You should see two tabs, one for WeatherStation and one for BME280.h. If you do not have both tabs then you opened the wrong folder or you did not download both files or you did not save them in the correct folder. Try again.

You will need to edit the WeatherStation.ino file to add the SSID and password for your WiFi network. look around line 62 for the following;

// put the SSID and password for your WiFi network here
const char* ssid = "yourssid";
const char* password = "password";

Replace "yourssid" with the SSID of your WiFi network.

Replace "password" with the passkey for your WiFi network.

You will also need to add your OpenWeatherMap key and the zip code where you live. Look around line 66 for the following;

// put your OpenWeatherMap.com Key and the zip code here
const char* owmkey = "yourkey";
const char* owmzip = "yourzip,country";

Replace "yourkey" with the key obtained from OpenWeatherMap.org.

Replace "yourzip,country" with your zip code and country. Your zip code should be followed by a comma and your country ("10001, us").

Next you have to set your timezone and enable/disable daylight savings time (DST). Look around line 85 for the following;

// Raw time returned is in seconds since 1970. To adjust for timezones subtract
// the number of seconds difference for your timezone. Negative value will
// subtract time, positive value will add time
#define TZ_EASTERN  -18000    // number of seconds in five hours
#define TZ_CENTRAL  -14400    // number of seconds in four hours
#define TZ_MOUTAIN  -10800    // number of seconds in three hours
#define TZ_PACIFIC  -7200     // number of seconds in two hours
// Adjust time for your timezone by changing TZ_EASTERN to one of the other values.
#define TIMEZONE    TZ_EASTERN    // change this to your timezone

There is a group of #define statements that define the time offset for various time zones. If your time zone is there then replace "TZ_EASTERN" in the "TIMEZONE" definition. If your time zone is not listed then you will need to create one. The NTP server gives time as Greenwich Mean Time. You have to either add or subtract some number of hours (in seconds) to arrive at your local time. Just copy one of the "#define TZ_XXX" statements then change the name and the number of seconds. Then change "TZ_EASTERN" to your new timezone.

You also have to decide to use Daylight Savings time or not. To disable DST, replace the "1" with a "0" in the following line;

#define DST         1             // set to 0 to disable daylight savings time 

When enabled, DST will automatically advance or retard the time by one hour when appropriate.

STEP 16: Upload the Code to Your ESP8266

Click on the circular right facing arrow icon that is just below "Edit" in the top menu bar. This will compile the code and upload it to your board. If everything compiles and uploads properly, after a few seconds, the OLED display should light up and the the connecting message should appear.

STEP 17: How to View the Weather Data Website

The picture above shows the web page served by the Weather Station. You can access it using your PC, phone or tablet. Simply open a browser and type in the IP address of the Weather Station as the URL. The IP address of the Weather Station is displayed on one of the screens of the Weather Station. Click Refresh Page to update the information.

STEP 18: Congratulations, You Are Done

That is it. You should now have a working Weather Station. Your next step might be to design and make a case to house your Weather Station. Or maybe you want to add a few more screens to show wind chill, dew point, sunrise or sunset times or a graph of barometric pressure changes or predict the weather using barometric pressure. Have fun and enjoy.

13 Comments

My compile keeps failing at the statement
brzo_i2c_start_transaction(BMEADRS, 100);
because it says BMEADRS is not defined in scope.
I did a search and didn't find it declared anywhere in the program, and nowhere in the libraries.
I'm also have the same trouble with BME280_DIG_T1_LSB_REG

Thanks,
You are missing the file; BME280.h. This file should be in the same directory as WeatherStation.ino. Go back and check your github download, the file should be there. If you cannot find it give me your email address and I will email it to you.
Hey Behr, thanks for the reply. Yes, BME280.h is there, and here is the version info:
* @file bme280.h
* @date 2020-03-28
* @version v3.5.0
But that didn't stop the problem. What I did instead was to look at how the var is being used in other similar programs (as an int8, if I remember correctly) and just declared an int8 BMEADRS local to the offending function. However, BMEADRS is not found in BME280.h or other versions of the BME280 driver package by authors other than Bosch.
BTW: Still have the same trouble with the register definition BME280_DIG_T1_LSB_REG
First, BMEADRS is not a var, it is a macro. Near the end of the BME280.h file is the line; #define BMEADRS 0x76 // I2C address of the BME280. Macrosare replaced by their defined value by the 'C' preproccessor. In other words, BMEADRS is replaced by 0x76 where ever it appears in the source code.
BME280_DIG_T1_LSB_REG is also a macro.
If the BME280.h file is in the same directory as the .ino file and the #include "BME280.h" directive is in the beginning of the .ino file then it should be added to the source code by the preprocessor.
What version of the Arduino IDE are you using ?
What OS are you using (Mac, Windows, linux) ?
I have the same code and cannot reproduce your issue. I am running Windows 10 and Arduino IDE version 1.8.12.
If you are still having an issue then copy the contents of the BME280,h file to the .ino file, near the top, into the area where other #defines are. Copy everything from the line; #include "stdint.h" to the line; #define BME280_CHIP_ID 0x60 // chip ID for BME280, inclusive. The rest is just comments and to prevent the file from being included more than once.
Hi,
I've got everything correct but it seems something is amiss.
this error keeps popping up on compile:
WeatherStation:995:18: error: 'D4' was not declared in this scope
digitalWrite(D4, LOW);

also, this error is showing up:
WeatherStation:760:33: error: 'brzo_i2c_read' was not declared in this scope

both files are in the same directory and as far as i can tell, all libraries are installed. A little help would be appreciated.
The first error message indicates that you did not declare what GPIO pin is used when 'D4' is the target. This error is most likely caused by using a different ESP8266 module than the one I called out. In the Arduino IDE, some ESP8266 modules have the GPIO defined similarly to how they are defined for the Arduino Uno board. Other ESP8266 modules use the actual GPIO pin number. To fix this problem add a "#define D4 xx" statement at the top of the file. xx should be the GPIO pin number that you want to use (for GPIO 5 then just use 5).

The second error appears to be because you do not have the Brzo I2C library installed. The documentation tells you where to get the library and how to install it. The Brzo library is used because the Arduino Wire library for I2c did not always work on all ESP8266 boards. Plus the Brzo library is faster.

A cracking Instructable. I made it - just got to print an enclosure. I adjusted a couple of lines in the sketch to read "Indoor" etc instead of "Inside" and I prefer Celsius as opposed to Fahrenheit. Also I had difficulties with the library for the display - a headache for very many diy projecteers I suspect, as there are dozens of libraries and dozens of manufacturers but little clue as to which goes with which but hey - it's all good fun once it works.

There are many display driver libraries for the OLED display. I used one that was specifically for the ESP8266/ESP32 and an SSD1306 based OLED display. There are some small ESP8266 boards that are about the same size as the OLED display. Look for a Witty ESP8266 or a WeMos D1. Banggood or AliExpress should have them. I found that the BME280s that I have were reading the temperature about five degrees Fahrenheit too high, so I adjusted for it in the code. Glad to hear that you made one. I recently figured out how to get forecasts from openweathermap.com. I added forecasting to my scrolling sign projects. If you are interested in adding forecasts let me know.

Thank you, yes I'd be interested in displaying the forecast too. I have linked my own weather station to WU so I may convert this to get from there in the future. Also it would be useful to be able to access ANY server network with or without inputting passwords etc, to get access for this weather display from anywhere without delving in to change the code each time I change location and internet logon server. I think this can be done with the ESP8266 in aggressive mode although I may have to get details from Hackster.io or somewhere else. Do you have details of how to do this?

Sorry, I do not know anything about an 'aggressive mode' in the ESP8266. I do not believe that you can do what you described. If you could, then the system would be extremely vulnerable to attack.

What you could try is to run the ESP8266 in station mode. That way it will be like a router with DHCP and allow you to log on to it to get the weather data. It would appear in the list of available WiFi networks. You could also try running in dual mode, station and AP (access point). Then it is part of your network and also its own network.

As far as forecasts go, I know how to do that with openweathermap. I do not know how to get forecasts from other weather services.

I hope this helps.

Thanks for the info - I was referring specifically to esp promiscuous and the wifi_send_pkt_freedom() capabilities of version 2 of the sdk sometimes referred to as "aggressive mode". The only other way to gather data from weather sites wherever you are is with the addition of a SIM900 module or similar - this however then makes the whole thing become bulky.

You did a great job on your first instructable! Good simple setup and great writeup :)

Thank you for your comments. You have brightened my day. Glad to hear that you liked my write up.