Building your own DIY weather monitoring station is not a herculean task. You can design one for your home or office using minimum hardware pieces at a nominal cost.  We have designed a tutorial for you to help you monitor the weather using Raspberry Pi Pico. There are actually two ways of doing so and we have explained them both: 

  1. Using temperature, pressure and a Humidity sensor to collect the data and then display it on a screen. 
  2. Grab the weather forecast from the internet and display it on a screen of your choice. 

Before we delve into the topic, let us first understand what a RaspberryPi Pico is (also referred to as RPI Pico). Refer the following article for the same. You can connect your Pico to the internet using an ESP32 board. They are inexpensive and provide an AT interface over UART.  

METHOD ONEUsing temperature, pressure and Humidity sensor to collect the data and then display it on a screen
METHOD TWOGrab the weather forecast from the internet and display it on a screen of your choice

METHOD ONE: What will you need?

Hardware Required Raspberry Pi Pico
Micro Sd card. We would suggest 8Gb or higher
16×2 1602 LCD Display
DHT11 Temperature and Humidity Sensor
BM180 Pressure sensor module
Male to Male, Female to Female and Male to Female jumper wires
Breadboard
Monitor, HDMI cable
Power bank (this is optional)
Software RequiredThingSpeak
Python

Some of us might be aware of Raspberry Pi’s. They are Single-Board Computers that runs Linux. RPI Pico is a microcontroller, similar to Arduino boards, but different from the regular Raspberry Pi. So, it does not run any OS but can be programmed to run a Simple Executable like stand-alone C/Python. 

It also differs from a regular Pi in terms of price and functionality. Unlike the other RPI boards, Pico does not use a Broadcom CPU and its circuitry is minimal.

You can refer the following video for better understanding.

Difference between RPI Pico and 4B

FunctionsRaspberry Pi PicoRaspberry Pi 4B
Release date2021 Jan 212019 Jan 24
Product descriptionIt is not a full computer, rather a micro-controller; its working is similar to that of an Arduino nanoThis fourth edition of raspberry pi has a memory card slot and several other functionalities.
RAM264 KB1GB, 2GB, 4GB LPDDR4
Ethernet absentpresent
Cameraabsentpresent
Weight0.10582 oz (3 gm)1.62 oz (46 g)
GPIO26 pins40 pins
WiFiAbsentPresent

STEP 1: Set up the visualisation part of the project on ThingSpeak

Building a weather station is a fairly light-weight project and therefore does not require expensive components. We will measure the environmental conditions and show the present humidity, temperature and pressure parameters will be displayed on the LCD screen. You can view this data from any part of the world as it will be displayed on ThingSpeak in the form of graphs. This is a great tool as it lets us monitor and visualize the data as well as control the system through the internet. 

Once you create an account on ThingSpeak, click on “New channel”. Here, you can define the fields, for example, Humidity, pressure and temperature. In order to read or write data to the selected channel, you need permission. Further this is provided in the form of a 16 digit API key that enables the user to read a private channel and write back to it. This API key is found under the ‘API keys’ tab in Channels. After you copy the key, select ‘Data Import/Export’ and copy the Update Channel Feed GET Request URL. Now paste this URL in your Python code. 

URL = 'https://api.thingspeak.com/update?api_key=%s' % key
finalURL = URL +"&field1=%s&field2=%s"%(humi, temp)+"&field3=%s" %(pressure)

You need to install Python IDE and packages before you dive into the working of the project. For this you will require a laptop or desktop. To learn how to install the IDE on host laptop/ desktop please refer to the article : Easy setup and program raspberry pi.

STEP 2: Connect your pico with LCD and other hardwares

STEP 3:

After you configure your Raspberry Pi, install Adafruit Python DHT Sensor Library onto the Pi. Use the following commands to do so:

sudo apt-get install git-core
sudo apt-get update
git clone https://github.com/adafruit/Adafruit_Python_DHT.git
cd Adafruit_Python_DHT
sudo apt-get install build-essential python-dev
sudo python setup.py install

DHT11 fetches data through single wire serial communication. Therefore, we use Adafruit DHT11 library for interfacing DHT11 with Raspberry Pi.

To enable Raspberry Pi I2C, navigate to the RPI Software Configuration tool and enter the following commands:

sudo raspi-config

After that, select ‘Advanced Options’, then ‘I2C’ and ‘Enable’. 

Before we start programming the sensors to collect data, we first need to make sure that all the libraries are installed, variables initialized and pins of LCD and DHT11 are defined. 

PIN OUT DIAGRAM FOR RPI PICO

Pin diagram of RPI Pico

To include required libraries, import the following:

import sys
import RPi.GPIO as GPIO
import os
import Adafruit_DHT
import urllib2
import smbus
import time
from ctypes import c_short
 
#Register Address
regCall   = 0xAA

The entire code is given below. But, we have explained small pieces of the code to help you understand it better. We strongly encourage you to tinker with the code and make adjustments as per your requirement. 

Create a separate function – def main()- for sending data to the server and using the LCD as a display. A continuous while loop will be executed. 

def main():
    
    print 'System Ready...'
    URL = 'https://api.thingspeak.com/update?api_key=%s' % key
    print "Wait...."
    while True:
            (humi, temp)= readDHT()
            (pressure) =readBmp180()
           
            lcdcmd(0x01)
            lcdstring("Humi#Temp#P(hPa)")
            lcdstring(humi+'%'+"  %sC  %s" %(temp, pressure))
            finalURL = URL +"&field1=%s&field2=%s"%(humi, temp)+"&field3=%s" %(pressure) 
            print finalURL
            s=urllib2.urlopen(finalURL);
            print  humi+ " " + temp + " " + pressure
            s.close()
            time.sleep(10)

Use the def lcd_init() function to initialize the LCD and send commands to it. The function def lcddata(ch) sends data to the lcd and the def lcdstrings(Str) function sends data string to the LCD. 

def readDHT():  # reads DHT11 sensor
    humi, temp = Adafruit_DHT.read_retry(Adafruit_DHT.DHT11, DHTpin)
    return (str(int(humi)), str(int(temp)))

The def readBmp180() function reads the pressure from the BM180 sensor.

def readBmp180(addr=deviceAdd):    
  value = bus.read_i2c_block_data(addr, regCall, 22)  # Read calibration data
 
  # Convert byte data to word values
  AC1 = convert1(value, 0)
  AC2 = convert1(value, 2)
  AC3 = convert1(value, 4)
  AC4 = convert2(value, 6)
  ..... .......
  ........ ......
The entire code :
import sys
import RPi.GPIO as GPIO
import os
import Adafruit_DHT
import urllib2
import smbus
import time
from ctypes import c_short
#Register Address
regCall   = 0xAA
regMean   = 0xF4
regMSB    = 0xF6
regLSB    = 0xF7
regPres   = 0x34
regTemp   = 0x2e
DEBUG = 1
sample = 2
deviceAdd =0x77
humi=""
temp=""
#bus = smbus.SMBus(0)  #for Pi1 uses 0
I2cbus = smbus.SMBus(1) # for Pi2 uses 1
DHTpin = 17
key="30BCDSRQ52AOI3UA"       # Enter your Write API key from ThingSpeak
GPIO.setmode(GPIO.BCM)
# Define GPIO to LCD mapping
LCD_RS = 18
LCD_EN  = 23
LCD_D4 = 24
LCD_D5 = 16
LCD_D6 = 20
LCD_D7 = 21
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)     
GPIO.setup(LCD_E, GPIO.OUT)  
GPIO.setup(LCD_RS, GPIO.OUT) 
GPIO.setup(LCD_D4, GPIO.OUT) 
GPIO.setup(LCD_D5, GPIO.OUT) 
GPIO.setup(LCD_D6, GPIO.OUT) 
GPIO.setup(LCD_D7, GPIO.OUT) 
def convert1(data, i):   # signed 16-bit value
  return c_short((data[i]<< 8) + data[i + 1]).value
 
def convert2(data, i):   # unsigned 16-bit value
  return (data[i]<< 8) + data[i+1] 
   
def readBmp180(addr=deviceAdd):    
  value = bus.read_i2c_block_data(addr, regCall, 22)  # Read calibration data
  # Convert byte data to word values
  AC1 = convert1(value, 0)
  AC2 = convert1(value, 2)
  AC3 = convert1(value, 4)
  AC4 = convert2(value, 6)
  AC5 = convert2(value, 8)
  AC6 = convert2(value, 10)
  B1  = convert1(value, 12)
  B2  = convert1(value, 14)
  MB  = convert1(value, 16)
  MC  = convert1(value, 18)
  MD  = convert1(value, 20)
    # Read temperature
  bus.write_byte_data(addr, regMean, regTemp)
  time.sleep(0.005)
  (msb, lsb) = bus.read_i2c_block_data(addr, regMSB, 2)
  P2 = (msb << 8) + lsb
 
  # Read pressure
  bus.write_byte_data(addr, regMean, regPres + (sample << 6))
  time.sleep(0.05)
  (msb, lsb, xsb) = bus.read_i2c_block_data(addr, regMSB, 3)
  P1 = ((msb << 16) + (lsb << 8) + xsb) >> (8 - sample)
   # Refine temperature
  X1 = ((P2 - AC6) * AC5) >> 15
  X2 = (MC << 11) / (X1 + MD)
  B5 = X1 + X2
  temperature = (B5 + 8) >> 4
 
  # Refine pressure
  B6  = B5 - 4000
  B62 = B6 * B6 >> 12
  X1  = (B2 * B62) >> 11
  X2  = AC2 * B6 >> 11
  X3  = X1 + X2
  B3  = (((AC1 * 4 + X3) << sample) + 2) >> 2
 
  X1 = AC3 * B6 >> 13
  X2 = (B1 * B62) >> 16
  X3 = ((X1 + X2) + 2) >> 2
  B4 = (AC4 * (X3 + 32768)) >> 15
  B7 = (P1 - B3) * (50000 >> sample)
 
  P = (B7 * 2) / B4
 
  X1 = (P >> 8) * (P >> 8)
  X1 = (X1 * 3038) >> 16
  X2 = (-7357 * P) >> 16
  pressure = P + ((X1 + X2 + 3791) >> 4)
  
  return (str(pressure/100.0))
def readDHT():
    humi, temp = Adafruit_DHT.read_retry(Adafruit_DHT.DHT11, DHTpin)
    return (str(int(humi)), str(int(temp)))
def lcd_init():
  lcdcmd(0x33) 
  lcdcmd(0x32) 
  lcdcmd(0x06)
  lcdcmd(0x0C) 
  lcdcmd(0x28) 
  lcdcmd(0x01) 
  time.sleep(0.0005)
 
def lcdcmd(ch): 
  GPIO.output(RS, 0)
  GPIO.output(D4, 0)
  GPIO.output(D5, 0)
  GPIO.output(D6, 0)
  GPIO.output(D7, 0)
  if ch&0x10==0x10:
    GPIO.output(D4, 1)
  if ch&0x20==0x20:
    GPIO.output(D5, 1)
  if ch&0x40==0x40:
    GPIO.output(D6, 1)
  if ch&0x80==0x80:
    GPIO.output(D7, 1)
  GPIO.output(EN, 1)
  time.sleep(0.0005)
  GPIO.output(EN, 0)
  # Low bits
  GPIO.output(D4, 0)
  GPIO.output(D5, 0)
  GPIO.output(D6, 0)
  GPIO.output(D7, 0)
  if ch&0x01==0x01:
    GPIO.output(LCD_D4, 1)
  if ch&0x02==0x02:
    GPIO.output(LCD_D5, 1)
  if ch&0x04==0x04:
    GPIO.output(LCD_D6, 1)
  if ch&0x08==0x08:
    GPIO.output(LCD_D7, 1)
  GPIO.output(EN, 1)
  time.sleep(0.0005)
  GPIO.output(EN, 0)
  
 def lcddata(ch): 
  GPIO.output(RS, 1)
  GPIO.output(D4, 0)
  GPIO.output(D5, 0)
  GPIO.output(D6, 0)
  GPIO.output(D7, 0)
  if ch&0x10==0x10:
    GPIO.output(D4, 1)
  if ch&0x20==0x20:
    GPIO.output(D5, 1)
  if ch&0x40==0x40:
    GPIO.output(D6, 1)
  if ch&0x80==0x80:
    GPIO.output(D7, 1)
  GPIO.output(EN, 1)
  time.sleep(0.0005)
  GPIO.output(EN, 0)
  # Low bits
  GPIO.output(D4, 0)
  GPIO.output(D5, 0)
  GPIO.output(D6, 0)
  GPIO.output(D7, 0)
  if ch&0x01==0x01:
    GPIO.output(LCD_D4, 1)
  if ch&0x02==0x02:
    GPIO.output(LCD_D5, 1)
  if ch&0x04==0x04:
    GPIO.output(LCD_D6, 1)
  if ch&0x08==0x08:
    GPIO.output(LCD_D7, 1)
  GPIO.output(EN, 1)
  time.sleep(0.0005)
  GPIO.output(EN, 0)
 
def lcdstring(Str):
  l=0;
  l=len(Str)
  for i in range(l):
    lcddata(ord(message[i]))
lcd_init()
 lcdcmd(0x01)
lcdstring("Circuit Digest")
lcdcmd(0xc0)
lcdstring("Welcomes you")
time.sleep(3) # 3 second delay
    
# main() function
def main():
    
    print 'System Ready...'
    URL = 'https://api.thingspeak.com/update?api_key=%s' % key
    print "Wait...."
    while True:
            (humi, temp)= readDHT()
            (pressure) =readBmp180()
           
            lcdcmd(0x01)
            lcdstring("Humi#Temp#P(hPa)")
            lcdstring(humi+'%'+"  %sC  %s" %(temp, pressure))
            finalURL = URL +"&field1=%s&field2=%s"%(humi, temp)+"&field3=%s" %(pressure) 
            print finalURL
            s=urllib2.urlopen(finalURL);
            print  humi+ " " + temp + " " + pressure
            s.close()
            time.sleep(10)
            
     
if __name__=="__main__":
   main()

METHOD 2: Grab the weather forecast from the internet and display it on a screen of your choice.

To collect data on the weather forecast and conditions, visit Weather Underground or Hong Kong Observatory Open Data API. Similarly there are several other websites that provide you with an API key and allows you to extract the information collected. Some are free while other charge a small fee to avail this service. In order to receive the latest local weather forecast, click here.

Enable the I2C in pico and reboot it. We then need to install two python libraries- a) Adafruit’s CircuitPython and the library required for LCD1602. You can download the LCD1602 library (from Github) using the following command lines:

[email protected]:~/rpi-weather$ pip3 install –upgrade RPI.GPIO adafruit-blinka 

[email protected]:~/rpi-weather$ git clone https://github.com/dhylands/python_lcd.git
[email protected]:~/rpi-weather$ cp python_lcd/lcd/lcd_api.py .
[email protected]:~/rpi-weather$ cp python_lcd/lcd/circuitpython_i2c_lcd.py .

The urllib library imports data from the internet and the json library parses the formatted data. The request library allows HTTP requests to be sent to a web server. GET is the most frequently used HTTP method. So, when you enter a URL in a web browser like Chrome or Firefox, you send a GET request to a web server and it responds to the request by forwarding the HTML data to the browser. 

Parse your JSON data with python

Launch a code editor of your choice on the pi, copy the code we have provided and save it with a name of your choice, eg: pi-weather.py. 

from requests import get
url = 'https://data.weather.gov.hk/weatherAPI/opendata/weather.php?dataType=rhrread&lang=en'
data = get(url).json()
print(data)

When you run this file in the terminal, you will see the output in the form of a list.

from requests import get
url = 'https://data.weather.gov.hk/weatherAPI/opendata/weather.php?dataType=rhrread&lang=en'
 
data = get(url).json()

We will explain the code above for better understanding : The request library allows the client to send HTTP requests to the web server. The url in the code is the open data API and we will be drawing our information on the weather from here. 

Now, connect the LCD with pico and install the following libraries:

import board
import busio
from circuitpython_i2c_lcd import I2cLcd
from time import sleep

Then Initialize the LCD display. The value of GPIO pins entered here can be changes as per your requirement. 

i2c = busio.I2C(board.SCL, board.SDA)  
while i2c.try_lock():   #checks for the I2C access
    pass
DEFAULT_I2C_ADDR = 0x27   #defines address of character LCD display
lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, 2, 16)
lcd.backlight_on()

Now, we will extract information and display it on the LCD screen. 

temp_data = data['temperature']['data']
for entry in temp_data:
    lcd.clear()
    lcd.move_to(0, 0)
    lcd.putstr(entry['place'][:15])
    lcd.move_to(1, 0)
    lcd.putstr(entry['value'])
    sleep(2)

We have considered an example to help you understand the process better. We will be displaying the temperatures of different regions on the LCD screen. The entire code is as follows:

from requests import get
import board
import busio

from circuitpython_i2c_lcd import I2cLcd

from time import sleep

i2c = busio.I2C(board.SCL, board.SDA)

while i2c.try_lock():

    pass

DEFAULT_I2C_ADDR = 0x27

lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, 2, 16)

url = 'https://data.weather.gov.hk/weatherAPI/opendata/weather.php?dataType=rhrread&lang=en'
while True:
    data = get(url).json()

    temp_data = data['temperature']['data']

    for entry in temp_data:

        lcd.clear()

        lcd.move_to(0, 0)

        lcd.putstr(entry['place'][:15])

        lcd.move_to(0, 1)

        lcd.putstr(str(entry['value']))

        sleep(2)

This is a great project if you are new to the world of Internet of Things and want to get some hands-on experience without spending thousands of rupees. Raspberry pi has several functions that let you explore this domain even more and gain a deeper insight on complicated topics. 

For more Raspberry pi pico projects you can refer the video below:

0 0 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments