Introduction
In this post, we will see how to make a weather Forecast Station, which will display the weather of any location using a Nodemcu flashed with MicroPython.We will read a JSON file containing weather data from https://www.metaweather.com/ and display relevant information on an OLED display.
Here’s is a demo of the final Results:
Note:There is some flickering on OLED screen when recording .This is not visible to the human eye.
CODE:
The entire code for this project is available at this Github Repository:https://github.com/htgdokania/Weather_station
Hardware requirement:
- NodeMCU Esp8266 module
- OLED display module.
Structure/WorkFlow:
- Step1: Setup Nodemcu with MicroPython image
- Step2: Download and setup Pycharm for flashing our Micropython code in Nodemcu
- Step3: Hardware Connections
- Step4: Let’s Begin Coding
Step1: Setup Nodemcu with MicroPython image
- First ,Download MicroPython image file from:http://micropython.org/download/esp8266/
- Now We will Flash Micro Python image using esptool which requires python.
- So First Download and install Python3 from here.(We will need python3 in later section as well).
Note:Make sure to check Add Python3 to path to use within Cmd (Command Promt) from any location.
- Next, click on custom installation.
- Browse the custom location on the next screen.
- Finally, Click on install.
- Now, open Cmd:
- And Download The esptool using pip command:
pip install esptool
- Now we will erase any previous flash on our NodeMCU. For this connect Nodemcu to PC using a USB cable and determine its Port Address from Device Manager. (In my case it is COM3)
- Using esptool.py you can erase the flash with the command:[ Replace COM3 with your port address ]
esptool.py --port COM3 erase_flash
- Next we will flash the MicroPython firmware downloaded in the above step:
- Browse to the location (in my case Downloads folder)containing the firmware (.bin file).
- Open Cmd and type:
esptool.py --port COM3 --baud 460800 write_flash --flash_size=detect -fm dio 0 esp8266-20191220-v1.12.bin
You might need to change the “port” setting to something else relevant to your PC. You may also need to reduce the baud rate if you get errors when flashing (eg down to 115200). The filename of the firmware should also match the file that you have.
With this you have successfully flashed MicroPython on NodeMCU:
Now Download and install Putty from Here: https://www.putty.org/
Next open it and set the
- Serial Line to your PORT address(COM3)
- Speed to 115200
- Save it by giving a name under Saved Sessions and click on save[To avoid typing again and again in next sessions.]
- Finally, Click on Open.
- If all the above steps are Successfully executed ,the following screen appears:
This will ensure a successful Flashing of Micropython .
Step2: Download and setup Pycharm for flashing our code in Nodemcu
- First Download and install pycharm community version[its free to use] from here.
- Select a theme of your choice:
- Finally start using PyCharm.
- Click on Create New Project.
- Set Your Desired Location and folder name and click on create:
- create a new python file with name main.py.
Note:NodeMCU looks for main.py after it has completed booting.This is why we name our python file as main.py
- Next GoTo File> Settings and search for Plugin and within that search Micropython and install it.Click Apply
- Next, Goto Languages & frameworks> Micropython
- and check Enable Micropython support.
- Set Device type as Esp8266 and
- Device Path as its Port address. (in my case COM3).
- Save and Exit from settings.
- Next click on add Configuration at upper right side
- Click on “+” button.
- Select Micropython
- Set path as the current Project folder. Finally click on ok.
- Finally Click on install Requirements to complete setting up.(Make sure your are connected to internet)
With this we are ready to flash any python code to our Nodemcu Module.
Step3: Hardware Connections
OLED display uses the I2C protocol to communicate with the NodeMCU. It uses a Data pin(SDA) and a clock(SCL) input along with Power (Vcc)and Gnd pins.
We can use any of the 2 GPIO pins to Connect our display to the NodeMCU.[ Here we use GPIO 4(D2),GPIO5(D1) ]
Connections:
Step4: Let’s Begin Coding
Part 1: Using the Oled Display :
Once This is done Type the below code to print “Hello” in the Oled Display:
- First import the libraries
- Specify the SDA,SCl pins using machine.I2C()
- Create a display object
- Fill the whole screen with (0)black[Reset the screen]
- Print the text
- Finally, show(). #important step
# Import Required
import machine
import ssd1306
#Specifiy Desired Pins For SDA and SCL respectively
i2c = machine.I2C(-1, machine.Pin(5), machine.Pin(4))
#Creation of Display Object using SSD1306 Library and binding it to I2C bus
# 128 is X direction pixels and 32 is y direction pixels
display = ssd1306.SSD1306_I2C(128, 64, i2c)
# Fill the Display with 0's (All black)
display.fill(0)
# Set a pixel in the origin 0,0 position.
display.text("Hello", 0, 0)
#Display the above on to display
display.show() #Very Important step
- Click on the Run Button to flash the code on Nodemcu.
- This will upload the code and display the text instantly on the OLED screen.
- Here’s the output in my setup:
Part 2: Getting the Weather info from the server in json format and using it to display:
In order to display weather forecast on our OLED diplay first we need to get the current data from any weather forecast website
For this purpose we choose https://www.metaweather.com/. This is because of the following reason:
- Next ,search for a location whose weather forecast we need to display. I will search “Kolkata”
- Next, we need the JSON file. We can get this by modifying the above URL a little. Just add /api/location as shown.
- The required new URL is thus:https://www.metaweather.com/api/location/2295386/ for Kolkata.
Now Let’s Code to read and use this JSON file in NodeMCU.
- First We import all the Required Libraries:
#import network and socket libraries to connect with wifi and receive data from the server.
import network
import socket
#For Parsing Json data and Getting a response from URLs
import urequests
import utime
# Libraries to communicate with the OLED Display
import machine
import ssd1306
- Next, define Pins for OLED display and define object “display”
#Specifiy Desired Pins For CLK and DATA respectively
i2c = machine.I2C(-1, machine.Pin(5), machine.Pin(4))
# 128 is X direction pixels and 32 is y direction pixels
display = ssd1306.SSD1306_I2C(128, 64, i2c)
- Next Define a function to connect to your local wifi network ,so th.at it can access the internet:
- We first connect in station Mode (STA) and display connected on successful connection.
def connect_Wifi():
# Fill the Display with 0's
display.fill(0)
display.text('connecting....', 0, 0)
display.show()
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print('connecting to network')
wlan.connect('Your_Wifi_SSID', 'Your_wifi_password') # Replace with your wifi credentials
while not wlan.isconnected():
pass
display.text('Connected', 0, 20) # Print connected once connected
display.show()
utime.sleep_ms(1000)
Next, we need a function get_data() to:
- create an HTTP request to get the response from the URL we got in the above step.
- Get the JSON file and store it in data.
- Return data.
def get_data():
response = urequests.get("https://www.metaweather.com/api/location/2295386/")
data = response.json()
return data
This is how the json file looks like: We will make use of the Highlighted text in our code below.
{ "consolidated_weather": [ {"id":4994698903027712, "weather_state_name":"Heavy Rain", "weather_state_abbr":"hr", "wind_direction_compass":"SE", "created":"2020-06-09T12:51:55.892202Z", "applicable_date":"2020-06-09", "min_temp":28.785, "max_temp":35.290000000000006, "the_temp":34.45, "wind_speed":3.890296212107956, "wind_direction":131.23911983387265, "air_pressure":1001.0, "humidity":71, "visibility":10.931783385031416, "predictability":77} {………} ……… ], "title":"Kolkata", "location_type":"City", "woeid":2295386, "latt_long":"22.549940,88.371582", "timezone":"Asia/Kolkata" }
- Now, we define another function that takes the above data we get from the get_data() function and print the required information on the Oled Display.
- Also, we get a lot of information for “each day”. We consider only those “KEYS” whose value we require to display.
- The following JSON file contains the forecast information for the next 6 days. So we print each day’s information in a loop :
def print_climate_data(data):
for i in range(6): # 6 for next 6 days forecast. If you want only today's forecast change it to 1.
# Fill the Display with 0's
# This will reset the screen and avoid overwriting
display.fill(0)
place = data["title"]
#Get Todays Data First
weather = data["consolidated_weather"][i]
date_today = weather["applicable_date"]
weather_today = weather["weather_state_name"]
temperature = weather["the_temp"]
Humidity = weather["humidity"]
#print on OLED Display
display.text(place,0,0)
display.text(date_today,0,15)
display.text(weather_today,0,30)
display.text(str(temperature),0,45) # we need convert temperature to string in order to display.
# Display the above on to display
display.show()
utime.sleep_ms(2000) # give a 2 sec delay inbetween two days.
- Finally we call the above functions. and display in a infinite loop
connect_Wifi() # FIRST CONNECT TO LOCAL WIFI NETWORK
while 1:
data=get_data() # GET WEATHER DATA IN JSON FORMAT
print_climate_data(data) # USING THE ABOVE DATA PRINT INFO ON OLED Display
With this, our coding part is Done!!
- Flash the code to Nodemcu just like we did in previous part
That’s all !!.
Just wait for a few seconds to connect and you will see the forecast data on your OLED screen.