Lets Make Weather Station
This is sort of a tutorial that I put together to explain much as I can about the process of making a simple realtime weather station with Arduino and some web technologies. In this project, I will be attempting to get sensor data from a DHT11 temperature, Humidity sensor and displaying it in a nice web user interface.
For the back-end of the system, I will be using a Javascript web framework called Express. Sensor reading from the Arduino will be sent through a serial communication and with the help of javascript, I will be reading those serial communications and manipulating the data to emit to the frontend using socket.io. For an extra thing, I am also Integrating the MoosunMv API to display some extra weather information. MoosunMv API is an open API that is built on top of Maldives meteorology stations.
NOTE: All the weather information is coming from my own server. it won’t overload meteorology servers. Our servers get the weather information every 12hrs from the Maldives meteorology stations and store it our database :)
Web Technologies used
- Express
- Socket.io
- Vuejs
- Axios
Requirement:
- Arduino Uno
- DHT11 Sensor
- Breadboard
- 3 Jumper cables
- USB cable type A/B Standard USB 2.0 cable
Hardware wiring:
Wiring the hardware components to arduino. The wiring diagram is shown below:
Note: Sensor I am using has a built in resistor so one of the pin will be missing from my sensor.
Writing the Arduino codes with Arduino IDE:
1#include "DHT.h"
2
3//Sensor digital pin
4#define DHTPIN 8
5//Setting the sensor type
6#define DHTTYPE DHT11
7
8DHT dht(DHTPIN, DHTTYPE);
9
10void setup() {
11 //Starting the serial communication
12 Serial.begin(9600);
13 dht.begin();
14}
15
16void loop() {
17 //delay for 2 second before reading again
18 delay(2000);
19 //setting humidityfloat humidity = dht.readHumidity();
20 //setting temperaturefloat temperature = dht.readTemperature();
21
22 Serial.print(temperature);
23 //Output for splitting the string into two array during serial read.
24 Serial.print(",");
25 Serial.println(humidity);
26}
Arduino library I used to read data from the sensor is DHT-sensor-library by adafruit. DHT Library.
Reading Serial data and sending to front-end:
After sending the sensor data through serial. I am using a javascript library called Serial Port to read the serial data sent by the Arduino and splitting the data string into two variable. Data is split from where the comma starts.
emitting the date to the front-end is done like so:
1var today = new Date();
2var date = today.getDate() + "-" + (today.getMonth() + 1) + "-" + today.getFullYear();
3weekday = [
4 "Sunday", "Monday", "Tuesday", "Wednesday", "Thurday", "Friday", "Saturday"
5];
6var day = weekday[today.getDay()];
7var secondDay = weekday[today.getDay() + 1];
8var thirdDay = weekday[today.getDay() + 2];
9var fourthDay = weekday[today.getDay() + 3];
So far what I have done is to get all the information I need to send to the front end using a WebSocket connection. Now I am going to use a javascript library called socket.io to send the data from the backend to the front-end in realtime.
Code for this part is shown below:
1io.sockets.emit('data', {
2 humidity: humidity,
3 temperature: temperature,
4 date: date,
5 day: day,
6 secondDay: secondDay,
7 thirdDay: thirdDay,
8 fourthDay: fourthDay
9});
Now, pretty much that’s all the things required to do in the backend. Not the most complicated thing in the world. The next day is sent to the frontend for a demonstration only. The temperature data on it is completely static. MOVING ON!!..
Let’s recall a bit. I am sending the sensor data from the Arduino to a serial port. In my case its COM5. Javascript Serial Port library than reads the serial data from the serial port and split the data according to where the split key is set. In this case, I am using a comma to separate the string into two variables. I am also setting some date and information about the data to sent out to the front-end. At last, I am emitting the data through a WebSocket using socket.io. In the front-end, socket.io is gonna listen to the port the data is coming from and I am using VUEJS to bind the data that is being received by socket.io to display them in the HTML.
Connecting Everything together:
Front-end javascript code is shown below:
1feather.replace()
2
3var socket = io.connect('http://127.0.0.1:4000/');
4var temperature = new Vue({
5 el: '#app',
6 data: {
7 ApiUrl: 'http://moosunmv.jinas.me/v1/latest',
8 temperature: '',
9 humidity: '',
10 date: '',
11 day: '',
12 wind: '',
13 secondDay: '',
14 thirdDay: '',
15 fourthDay: ''
16 },
17 methods: {
18 getWeather(){
19 var vm = this;
20 axios.get(this.ApiUrl)
21 .then(function (response) {
22 vm.wind = response.data.wind;
23 console.log(vm.wind);
24 })
25 }
26 },
27 mounted: function () {
28 socket.on('data', function (data) {
29 this.temperature = data.temperature;
30 console.log(this.temperature);
31 this.humidity = data.humidity;
32 console.log(this.humidity);
33 this.date = data.date;
34 this.day = data.day;
35 this.secondDay = data.secondDay;
36 this.thirdDay = data.thirdDay;
37 this.fourthDay = data.fourthDay;
38 }.bind(this));
39
40 this.getWeather();
41
42 }
43
44});
Data set by VUEJS is then bind to inside the HTML file. I am using a javascript library called axios to get the weather information from MoosunMv API.
It is done like so:
1<div class="info-side">
2 <div class="today-info-container">
3 <div class="today-info">
4 <div class="precipitation">
5 <span class="title">PRECIPITATION</span>
6 <span class="value">0 %</span>
7 <div class="clear"></div>
8 </div>
9 <div class="humidity">
10 <span class="title">HUMIDITY</span>
11 <span class="value">{{humidity}} %</span>
12 <div class="clear"></div>
13 </div>
14 <div class="wind">
15 <span class="title">WIND</span>
16 <span class="value">{{wind}}</span>
17 <div class="clear">
18
19 </div>
20 </div>
21 </div>
22 </div>
Demo
Note: Html, Css template used in this project is taken from codepen. Shout out to Colin Espinas.
That’s pretty much it for this project. You can find all the codes of this project down below: