InqWeather – v5 now with weather prediction

InqWeather is a simple web based weather station. It is part of an ongoing project used to teach Introductory Arduino, IoT and Web based programming techniques at our local public library and community college. Now InqWeather includes Zambretti weather predictions. Version 5 is now available as an example when you download the InqPortal library in your Arduino IDE Library Manager.

Hardware

InqWeather hardware is very simple:

  • 1 ESP8266 based NodeMCU or WeMos
  • 1 Breadboard
  • 1 BMP180 Temperature/Pressure sensor breakout, using I2C
  • 1 AHT10 Temperature/Humidity sensor breakout, using I2C
  • 4 Jumper wires
InqWeather Wiring

We take advantage of I2C being a multi-targeted serial communications bus. In other words, we can use just 4 wires to service both sensors. Note how the BMP180 and AHT10 board’s pins VIN, GND, SCL and SDA are on the same breadboard rows.

  • Red wire – NodeMCU 3V pin to sensors’ VIN
  • Black wire – NodeMCU G pin to sensors’ GND
  • Yellow wire – NodeMCU D1 pin to sensors’ SCL
  • Orange wire – NodeMCU D2 pin to sensors’ SDA

Server-Side Sketch

The new version (5.0) has grown some. The main source code sketch is still about 200 lines, fully commented. Only about thirty of these lines are to create the web server. The rest of the Sketch is standard handling of the sensors and project specific calculations. Some of the features of the code include:

  1. The InqPortal web server to expose the client UI, supply client-server communications and greatly reduce coding necessary to interact with the InqWeather. You’ll note there is no code doing explicit sends and receives. It is all being handled transparently so the developer can focus solely on the project at hand… a weather station!
  2. Demonstrates a persisted, published variable – altitude = This is a factor used to convert air pressure at your location to equivalent sea-level pressure. Weather services show this sea-level adjusted value even if they are in Denver.
  3. Published read-only variables to disseminate current temperature, humidity and pressure. We wanted to have a more dynamic interface during testing and demonstration, so these variable are updated every second. These are not really needed for normal use and might actually be a bother in normal use.
  4. Published read-only variables to disseminate a minute-by-minute temperature, humidity and pressure. These are an accumulated one minute average of all the 1 second readings. These are the ones that should be used as a weather station.
  5. Using a circular buffer to store 3 hours worth of pressure readings. These are used as one of the major inputs for the Zambretti weather prediction algorithm (discussed later in the topic).
  6. There is now a second file Zambretti.h that contains all the logic to handle the weather prediction calculations.

The following file is just an excerpt of the InqWeather Sketch. It shows just the setup() routine. These lines are the sum total of all coding necessary to create a web server and publish fifteen different variables from your Sketch to the clients. Some will be read-only at the client while others can be modified. There is no explicit coding required to communicate with the browser clients in either direction. The rest of the code is your project specific code including global variables, reading sensors and making calculations. The full source code is provided as one of the examples included when you download the InqPortal library in your Arduino IDE Library Manager.

void setup() 
{
    svr.onInterval(takeReading, READING_INTERVAL);  

    svr.publishRO("V", VERSION_INQ_WEATHER, sizeof(VERSION_INQ_WEATHER),
        "InqWeather Version");
    
    svr.heading("LS", "Settings");
    svr.publishRW("North", &config.zNorth, "Northern Hemisphere (bool)");
    svr.publishRW("Alt", &config.altitude, "Altitude adjustment", NULL,
        validateAltitudeFactor);
    svr.publishRW("Pmin", &config.zMinP, "Area Min Pressure (mbar)");
    svr.publishRW("Pmax", &config.zMaxP, "Area Max Pressure (mbar)");
    
    svr.heading("LH", "AHT10 Humidity Sensor");
    svr.publishRO("Th1", &temperatureAHT10Cur, "Current Temperature (°C)"); 
    svr.publishRO("H1", &humidityAHT10Cur, "Current Humidity (%H)");
    
    svr.heading("LP", "BMP180 Pressure Sensor");
    svr.publishRO("T1", &temperatureBMP180Cur, "Current Temperature (°C)");
    svr.publishRO("P1", &pressureBMP180Cur, "Current Pressure (mbar)");
    
    svr.heading("LA", "Minute Averages");
    svr.publishRO("Th", &temperatureAHT10Min, "Temperature (°C)"); 
    svr.publishRO("H", &humidityAHT10Min, "Humidity (%M)");
    svr.publishRO("Tp", &temperatureBMP180Min, "Temperature (°C)");
    svr.publishRO("P", &pressureBMP180Min, "Pressure (mbar)");
    
    svr.heading("LZ", "Calculations");
    svr.publishRO("D3P", &pressureDelta3Hour, "3 Hour Pressure Change (mbar)");
    svr.publishRO("Z", &zam, "Zambretti (0-25) = (A-Z)");

    svr.begin(DEFAULT_HOST_SSID, NULL, YOUR_SSID, YOUR_PW);

    pinMode(LED_BUILTIN, OUTPUT);
    
    if (bmp180.begin())
        Serial.printf("BMP180 init success\n");
    else
        Serial.printf("BMP180 init fail\n");
    
    if (aht10.begin())
        Serial.printf("AHT10 init success\n");
    else
        Serial.printf("AHT10 init fail\n");
}

Calibrating Your InqWeather for Altitude

Electronic weather stations as well as your local radio and TV weather news services display pressure as-if you were at sea-level. Although a pressure gauge in Denver will never see 30 in-Hg, it’ll commonly be converted to a sea-level basis. If you live above sea-level, you must perform these calibration steps to give accurate readings that compare to your local weather service values. The Zambretti algorithm is also dependent on this adjustment. InqWeather allows you to calibrate your station depending on your station’s altitude.

Calibrating InqWeather
  1. First, if you live at sea-level, you can skip calibration all-together. Leave this Altitude adjustment equal to 1. If you’re like me and live at some significant altitude, you’ll need to do this calibration step or your weather station won’t work.
  2. Otherwise, start by making sure that Altitude adjustment is equal to 1. This will make the calculation simple.
  3. Find your local weather pressure. This is the current barometric pressure at your location. It constantly changes relative to the weather conditions. “How do I do that?“, you might ask.
    • If you live near (say… less than 10 miles) from an airport, radio station or TV station, you can get the current pressure from their services.
    • Most people are unlikely to have one of those, so I found this website – Barometric Pressure that lets you plug in your location.
      1. First go to Google Maps and find you house. Right click on it and Maps will show you its exact latitude and longitude. ie – 35.yyyy, -83.xxxx
      2. Plug them into Barometric Pressure ie – https://barometricpressure.app/results?lat=35.yyyy&lng=-83.xxxx
      3. About midway down the page there is an option to set the values to Metric. InqWeather uses sensors that spit out data in metric units. The Zambretti algorithm also expects metric units. Thus, the InqWeather server works only in metric.
      4. Get the current reading reported by the Barometric Pressure website. On mine today, I found: 1005.54 mbar
  4. Find the InqWeather Pressure (mbar) under the Minute Averages heading. If you just booted it up, it’ll take 1 minute before the first average pressure is available. On mine today, it was 929.6898 mbar
  5. Get out your calculator and divide <station Pressure> / <InqWeather Pressure>. ie 1005.54 / 929.6898 = 1.08159
  6. This is the altitude adjustment ratio. Plug your value into InqWeather Attitude adjustment.
  7. There is a second constant Area Min Pressure(mbar) that is used for the Zambretti calculations. It is the minimum sea-level pressure you’re weather station has ever observed. If you live at a high altitude (like I do) OR the weather is bad while you did the calibration, this value may have been changed by the sensors. After you put in your Altitude adjustment, you’ll need to reset this to 950 or your predictions won’t make sense.
  8. You’ll see the Current Pressure bouncing around the adjusted pressure right away, but you’ll need to give the Average Pressure a minute or two before it too will report the adjusted pressure. It should now match fairly close to the barometricpressure.app website value.
  9. You are now calibrated. If in the future your InqWeather reboots, it will retain this value.
InqWeather calibrated for my altitude.

Client Side Applications

InqWeather has three different applications (web pages) for displaying results. This is in addition to the Admin application built-in to every InqPortal based Sketch. These three apps are mostly cosmetic and can be readily changed for cosmetics or functionality. Since these applications are just web content (html, css, javascript and images) you do not have to recompile the Sketch. Simply copy the client side files to your server. The following shows a list of files (web content) uploaded to the InqWeather/InqPortal server.

Client Side Application Files for Three Versions.

Version 1 – Plain Digital

Default Web Page (http://InqWeather or http://InqWeather/Index.html)

The Plain Digital web page is the default web page – meaning that it will be the one called if no html file is defined after the URL address line on your browser. This is a standard web server default that actually uses the index.html if it is available.

  • It displays two temperatures since both sensors supply a temperature. (one tiny next to the label) Normally, we might not show both on a weather application, but in our class, we want to demonstrate and discuss sensor variability.
  • The temperatures and pressures are modified from their metric units (°C and mbar) supplied by the server to (°F and in-Hg) here at the client. The index.js source code file makes the change. If you’re metric type of person, you can delete the obvious equations and you’ll get metric units. This is an important concept where we intercept raw data supplied by the server and change it based on the context of the client user. In this example one observer of the InqWeather server may prefer °C, while another °F. You could have a page for each or if you need a challenge, you can create an option to handle both based on URL parameter or say… a checkbox on the UI. Both can have their way and server does not have to bother with the details.

Version 2 – Analog

Analog Version (http://InqWeather/Analog.html)

In this version we wanted to demonstrate using an off-the-shelf JavaScript library. During class, we pulled it off the Internet on a whim and slapped it in after about ten minutes of reading the website’s documentation. Give a shout-out for MykhaIloStadnyk for his library.

Version 3 – Zambretti Prediction

Dynamic Background of Weather Prediction (http://InqWeather/changing.html)

The Zambretti algorithm, created in 1915, long before digital computers, takes atmospheric pressure and the change in the pressure over the last three hours to come up with one of 26 different weather predictions (A-Z). InqWeather uses a circular buffer holding the pressure readings over the past three hour. It uses these values to supply this important piece of information to the Zambretti algorithm. The InqWeather Sketch (the server) sends this value down to any clients whenever it changes. The client application (in this case the changing.html and changing.js files) takes this value, performs a look-up for the weather description and displays it. It also checks for an image with the same name (A.jpg, B.jpg… Z.jpg) and finds the closest available image to display as the background.

Programmatically, its main demonstration point is separation of concerns. The server supplies the Zambretti letter, but the client can display the results in different ways. All the descriptions can be changed from the original 1915 strings to something more relatable here in the 21st century or into any other language. Simply edit the values in the changing.js file and upload it to the InqWeather server. The backgrounds can also be changed (say… pictures out your front door of the weather conditions) by simply naming the picture to the desired condition. In the above example,  N.jpg and uploading it to the server. No code change is necessary. The client application will detect the available image and display it when appropriate.

100 Hour Test Results

During the first 100 hours of testing, the server was being monitored by the InqPortal Admin. It has the ability to configure the History meter to track important System performance metrics as well as any of your numeric outputs. In this case, we added the readings from all the sensors. Here we have 100 hours worth of data showing temperatures from both the AHT10 and BMP180 and the Humidity and Sea-level normalized Barometric pressure. It also tracks the three hour change in pressure.

100 Hour InqWeather Output

Futures

That’s it for now. InqWeather has been a great teaching / learning project. In the works for future versions are to add data logging code so we can track useful numbers like the minimum and maximum temperatures in the last month or last year. Let me know if you have any suggestions for future additions… especially if they can be used as a teaching moment for future students.