Building a local weather station using Raspberry pi W and Arduino Nano || Serial communication over Bluetooth HC-05 module
So this DIY Weather Station involves a few different Hardware modules and a little bit of programming. The idea is, to display the weather status, temperature and humidity levels on a LCD Display that gets updated on a hourly basis. Our Raspberry pi W is going to host the programs and is responsible for sending the correct data from the internet to the Arduino Nano over a Serial communication. We'll make use of the bluetooth module to connect to the bluetooth capabilities of pi to send the data over to the display unit.
Things required :
- Raspberry Pi Zero W x 1
- Arduino Nano x 1
- LCD 1602 Display x 1
- I2C module x 1
- Bluetooth HC-05 module x 1
- Jumper wires for making connections
- 5V power source for both raspberry pi and arduino nano (we can power other modules from nano board)
Setup Arduino Nano
Our LCD Display Module can be connected to Arduino nano in two ways, with or without I2C module. Without it, we'll need to connect 8 pins to the Arduino which is tedious and time consuming, not to mention takes up more number of pins on the microcontroller, so we will opt for connecting it to the I2C module instead. This reduces our number of pins to 2(SDA and SCL) excluding the Vcc and GND pins.
Following this concise tutorial on setting up Arduino with a I2C connected LCD module and testing it to ensure the screens light up with proper message, we can also rotate the potentiometer to adjust to a proper contrast setting, we complete our display unit setup.
Our next device is the bluetooth HC-05 module. This module is very easy to setup, with 2 pins(exlcluding Vcc and GND). Just connecting the Tx pin to Rx pin on Arduino and Rx pin to Tx pin on Arduino, the module can be enabled for Serial communications over bluetooth with default setting of 9600 baud. Test can be perfomed using any serial bluetooth comms app on Play Store by sending data over serial to the arduino. There is this great guide to get it up and running with HC-05 and also troubleshoot along the way.
After completing the setup for both modules, let's write a basic program using Arduino IDE to flash our Nano with. The objective is to display whatever is being sent over the serial comms with a proper formatting to the display. Since there are two rows in the Display module, we can use a separator such as '~' that will split the serial data over two lines in the LCD. The code would look something like this :
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
void setup()
{
Serial.begin(9600);
lcd.init();
lcd.backlight();
lcd.print("Loading...");
}
void loop()
{
if (Serial.available()) {
delay(100);
lcd.clear();
while (Serial.available() > 0) {
char myChar = Serial.read();
if (myChar == '~') {
lcd.setCursor(0,1);
} else {
lcd.print(myChar);
}
}
}
}
Setup Raspberry Pi
If you haven't done so already, installing a Pi-based Linux OS that you can download from the official website(or any OS will suffice) is a pretty straight-forward process. Once it's up, let's begin by working on our program first.
- Head over to https://openweathermap.org/ and sign up for a basic account.
- Go to API Keys after verifying your account information. Copy the default Key and keep it somewhere safe. You need this to make the GET request for weather data.
- Google your local city latitude and longitudes to get the value for lat and long in the request.
- Using any programming language(I used python3), make a get request to the following URL : http://api.openweathermap.org/data/2.5/weather?appid=<API-KEY-HERE>&units=metric&lat=27.7654&long=85.3653
- With the requests library, you can simply call .json() and use it as a dict object. We can then extract required data from the response data(temperature, humidity, weather etc.) and build a string using str(). We've also used the separator '~' that our Arduino program is going to parse and split the data into two lines on the display. Let's pass our data to be passed to a print function. Our end program should look something like this :
import requests
url = "http://api.openweathermap.org/data/2.5/weather?id=1283240&appid=<API-KEY>&units=metric&lat=27.7654&long=85.3653"
payload = {}
headers= {}
response = requests.request("GET", url, headers=headers, data = payload)
data = response.json()
temp = str(data['main']['temp'])
weather = str(data['weather'][0]['main'])
humidity = str(data['main']['humidity'])
weatherDesc = str(data['weather'][0]['description'])
print("KTM "+temp+"C "+weather+"~"+humidity+"% "+weatherDesc)
- We save this python program as getWeatherData.py. Next, we open a new bash script start.datatransmit.sh and add in the following lines :
#!/bin/sh
sudo rfcomm bind rfcomm0 <Bluetooth Address Here>
sudo rfcomm watch rfcomm0 &
python /home/pi/github/sndpwrites/getWeatherData.py > /dev/rfcomm0
sudo rfcomm release rfcomm0
sudo killall rfcomm
rfcomm is a serial emulation application. The first line is going to bind the bluetooth address to a rf process rfcomm0. Use the bluetooth scan on your phone or other means to obtain the bluetooth address after powering the module on. The next line creates a communication channel and waits for any serial exchange. Then, we will use python to run our python script that we prepared and then redirect the output to /dev/rfcomm0. This will send our data over instantly over serial to the arduino, which is going to parse it and display accordingly. Next, we release the rfcomm0 process bind and kill any orphaned processes.
- After testing this to success, we can add this to our crontab which will fetch and display the weather data on repeated intervals, say every one hour.
- One more thing we can do is, run the script when pi starts up so that it can update the display when it restarts. Just add the script to /etc/rc.local before exit 0 and it should be good to go.
Possible enhancements would be to :
Display Time/Date
Display Weather across multiple geographic zones
Display Weather across multiple geographic zones
Push notifications?
E-mail alerts
Other useful info, etc..
I wanted to learn this. I will catch up with your blog now :)
ReplyDeleteThanks. If you enjoy reading please take time to share in Social Media as well. :)
DeleteI really like it whenever people come together and share thoughts. Great post, keep it up.
ReplyDeletelcd manufacturer
ReplyDeleteWonderful article, which you have shared about the service. Your article is very important and I really enjoyed reading it. Get for more information 5 inch lcd screen