Weather Station with Arduino Tutorial

Updated 29 April 2022

This Weather Station with Arduino was designed for the South Australia Catholic Education STEM Weather Station Challenge. We were lucky enough to be asked to build one of the basic kits provided to schools across South Australia for entry into this challenge! Anyone can build this weather station though, and we will walk you through step by step!

We will be building the minimum viable product for this challenge, but there is so much more that you can do with this weather station! Measure wind speed, rainfall, dust particles in the air, UV light, and so much more! This project is meant to be a launching pad to experiment and develop on your own weather station!

The basic weather station measures the temperature and humidity over time and saves all that data to an SD card for easy analysis!

Collect the Parts

The parts required to build this project are:

There is a lot more room to add more to this project! Here are some recommended parts if you are looking to add some elements to your weather station!


Wiring it up

There are a few different components in this project. We found that the best way to assemble it is to first put the ProtoShield on top of the Arduino, and then stick the mini breadboard to the top of the ProtoShield, then wire up the different parts one at a time. We will break down the wiring of the different parts separately for clarity.

Connect the DHT22

This is the temperature sensor and humidity sensor of the weather station. The pins on it aren’t marked, see the below photo for the pinout.

DHT22 pinout

We will first plug the DHT22 into the mini breadboard. Make sure that you orient the sensor the correct way in the breadboard. For a refresher on how breadboards work, check out our How To Use Breadboards Tutorial.

If you're unsure, just make it line up like is shown in the diagram. Remember, the breadboard will be in the center of the ProtoBoard, we have it to the side in this picture so its easier to see where the wires go.

DHT22 connection schematic

Connect the power and ground to the 5V and GND rails on the ProtoShield. The data line on the DHT22 will connect to Digital Pin 2 on the shield.

Connect the RTC

The Real Time Clock keeps accurate time. The Arduino cannot keep precise time on its own and would quickly be reporting incorrect times with your readings.

This diagram shows just the RTC and Arduino:

RTC connection DS1307

Connect the 5V and GND to the respective rails on the ProtoShield, connect the SDA pin to Analog pin 4, SCL to Analog Pin 5.

Connect the SD Card Module

This is how we will store all the readings for later use.

Weather station wiring diagram just SD card module

Connect the SD Card Module as shown:

  • Arduino 13 > SCK
  • Arduino 12 > MISO
  • Arduino 11 > MOSI
  • Arduino 4 > SDCS
  • Arduino 5V > 5V
  • Arduino GND > GND

All Together

Here is everything shown hooked up at the same time:

Weather Station Wiring Diagram Full

Insert your SD card into the SD card Module and we are ready for the next step!


Setup the IDE

Now its time to load some code onto the newly built weather station! We will be programming with the Arduino IDE (see our Arduino IDE Tutorial). For this code to work we will need to install a few libraries. Here is a full explanation of how to add libraries to Arduino.

The libraries that we need to install are the DHT library, RTC library, and Adafruit Unified Sensor library. Using the ‘manage libraries’ option in the IDE search for “DHT” to find the DHT sensor library shown below, then select install.

DHT22 Library Install Screenshot

Search for “RTClib” to find the below library for the real-time clock.

RTClib library install screenshot

Search for “Adafruit Unified Sensor” to find the final required library. For us, this was all the way at the bottom of the list.

Adafruit Unified Sensor Library Screenshot


The Code

Here is the code that we will be using for the weather station. We’ll take a look at the whole thing, then break it down into parts and explain how it all works.

/*CESA Weather Station 2019 */

//include relevant libraries for the Arduino, sensor and Real time clock (RTC)
#include "DHT.h"
#include "DHT_U.h"
#include "SD.h"
#include "Wire.h"
#include "RTClib.h" 


//define DHT pin
#define DHTPIN 2        //  pin the sensor is connected to on arduino (can be any number from 2 - 13)
#define DHTTYPE DHT22   // DHT22 is the type of temperature sensor we are using  

File myFile;

// initialize DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN, DHTTYPE);
RTC_DS1307 RTC;


void setup () {   // setup function runs once

  Serial.begin(9600); //opens serial connection, sets the data rate to 9600 bps (bitspersecond) and waits for the port to open
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");
  

  // creates a new data file if one does not already exist
  if (not SD.exists("DATA.txt")) {
    myFile = SD.open("DATA.txt", FILE_WRITE);
    myFile.print("DATE, TIME, TEMP *C, HUMIDITY");
    myFile.println();
    myFile.close();
  }
  
  //initializing the DHT and RTC
  dht.begin();
  Wire.begin();
  RTC.begin();

  // Check to see if the RTC is keeping time.  
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // Sets the RTC to the time that this sketch was compiled 
    RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
}


void loop () {
  DateTime now = RTC.now(); //query the RTC for the current time

  //read and store the temperature and humidity
  float t = dht.readTemperature();
  float h = dht.readHumidity();

  if  (isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  //writes the current date, time, temperature, hummidity to SD card
  myFile = SD.open("DATA.txt", FILE_WRITE);  
  myFile.print(now.day(), DEC);  
  myFile.print('/');
  myFile.print(now.month(), DEC);
  myFile.print('/');
  myFile.print(now.year(), DEC);
  myFile.print(',');
  myFile.print(' ');
  myFile.print(now.hour(), DEC);
  myFile.print(':');
  //inserts a 0 before minutes from 1-9 so that the time displays correctly, ie 12:05 instead of 12:5
  if (now.minute()<10) {
    myFile.print('0');
    myFile.print(now.minute(), DEC);
  }
  else {
    myFile.print(now.minute(), DEC);
  }
  myFile.print(',');
  myFile.print(' ');
  myFile.print(t);
  myFile.print(',');
  myFile.print(' ');
  myFile.print(h);
  myFile.println();
  myFile.close();

  //writes the current date, time, temperature, hummidity to the serial monitor 
  Serial.print(now.day(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.year(), DEC);
  Serial.print(',');
  Serial.print(' ');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  //inserts a 0 before minutes from 1-9 so that the time displays correctly, ie 12:05 instead of 12:5 
  if (now.minute()<10) {
    Serial.print('0');
    Serial.print(now.minute(), DEC);
  }
  else {
    Serial.print(now.minute(), DEC);
  }
  Serial.print(',');
  Serial.print(' ');
  Serial.print("Temp: ");
  Serial.print(t);
  Serial.print(" *C");
  Serial.print(',');
  Serial.print(' ');
  Serial.print("Hum: ");
  Serial.print(h);
  Serial.println();

  delay(10000); //wait time until the device reads the temperature again
}

In this first section of code we include the libraries that we are using, and tell the program what sensors we are using.

//include relevant libraries for the Arduino, sensor and Real time clock (RTC)
#include "DHT.h"
#include "DHT_U.h"
#include "SD.h"
#include "Wire.h"
#include "RTClib.h" 


//define DHT pin
#define DHTPIN 2        //  pin the sensor is connected to on arduino (can be any number from 2 - 13)
#define DHTTYPE DHT22   // DHT22 is the type of temperature sensor we are using  

File myFile;

// initialize DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN, DHTTYPE);
RTC_DS1307 RTC;

The setup part of the code runs once each time the Arduino is powered on. Here we open our serial port, initialize the SD card, DHT22, and RTC. There are a couple of unique parts to this section of code.

First of all, we create a new data file if none exists. We want to store all our data in a text file on the SD card so we can easily read it later. In this section, we check to see if there is already a file on the SD card. If there is already a file then any readings are added to the file. If there is not a file then a new file is created with a header that labels the values. This makes it really easy to read the data later on, but more on that later.

We also check to see that the RTC is running. If it's not yet running then we set the time on the RTC to whenever the code was compiled. This only works the first time that the code is loaded. The RTC will stay running for about 5 years on a single battery (wow!).

void setup () {   // setup function runs once

  Serial.begin(9600); //opens serial connection, sets the data rate to 9600 bps (bitspersecond) and waits for the port to open
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");
  

  // creates a new data file if one does not already exist
  if (not SD.exists("DATA.txt")) {
    myFile = SD.open("DATA.txt", FILE_WRITE);
    myFile.print("DATE, TIME, TEMP *C, HUMIDITY");
    myFile.println();
    myFile.close();
  }
  
  //initializing the DHT and RTC
  dht.begin();
  Wire.begin();
  RTC.begin();

  // Check to see if the RTC is keeping time.  
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // Sets the RTC to the time that this sketch was compiled 
    RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
}

The next part of the code is the main loop. This part of the code runs continuously whenever the Arduino is powered. We read the RTC, the temperature and humidity and save them as variables to be used later.

We then open the file on the SD card and “print” our recorded data to it once every 10 seconds. It’s important to “close” the file at the end of each writing. This is what saves the file!

We then print the same data to the serial monitor. This allows you to see what is being recorded on your computer in real time. We added labels in here so it is easier to read.

At the very end of the loop, we have a delay. This pauses the program for a bit so we don’t have constant readings. An Arduino runs very fast and can take many readings every second. This slows the program down to save data and to make the data more meaningful. The temperature does not change every minute, let alone every second, there is no need to take superfast measurements.

void loop () {
  DateTime now = RTC.now(); //query the RTC for the current time

  //read and store the temperature and humidity
  float t = dht.readTemperature();
  float h = dht.readHumidity();

  if  (isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  //writes the current date, time, temperature, hummidity to SD card
  myFile = SD.open("DATA.txt", FILE_WRITE);  
  myFile.print(now.day(), DEC);  
  myFile.print('/');
  myFile.print(now.month(), DEC);
  myFile.print('/');
  myFile.print(now.year(), DEC);
  myFile.print(',');
  myFile.print(' ');
  myFile.print(now.hour(), DEC);
  myFile.print(':');
  //inserts a 0 before minutes from 1-9 so that the time displays correctly, ie 12:05 instead of 12:5
  if (now.minute()<10) {
    myFile.print('0');
    myFile.print(now.minute(), DEC);
  }
  else {
    myFile.print(now.minute(), DEC);
  }
  myFile.print(',');
  myFile.print(' ');
  myFile.print(t);
  myFile.print(',');
  myFile.print(' ');
  myFile.print(h);
  myFile.println();
  myFile.close();

  //writes the current date, time, temperature, hummidity to the serial monitor 
  Serial.print(now.day(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.year(), DEC);
  Serial.print(',');
  Serial.print(' ');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  //inserts a 0 before minutes from 1-9 so that the time displays correctly, ie 12:05 instead of 12:5 
  if (now.minute()<10) {
    Serial.print('0');
    Serial.print(now.minute(), DEC);
  }
  else {
    Serial.print(now.minute(), DEC);
  }
  Serial.print(',');
  Serial.print(' ');
  Serial.print("Temp: ");
  Serial.print(t);
  Serial.print(" *C");
  Serial.print(',');
  Serial.print(' ');
  Serial.print("Hum: ");
  Serial.print(h);
  Serial.println();

  delay(10000); //wait time until the device reads the temperature again
}

Once this loads you can upload the weather station code again, and your RTC should be reporting the correct time!

Working with Data

This program will take readings and save them to a file called DATA.txt whenever it is plugged in. The file is created with a header labelling the values separated by commas, and all the values are separated by commas. This makes it really easy to import into an excel spreadsheet! Just change the file name from “DATA.txt” to “DATA.csv” and open it and your computer will recognise it and open it in Excel properly formatted and everything!


Make a Housing

In order for the weather station to take readings, it needs to be out in the elements! We obviously need to keep it dry somehow though, so that’s where this 3D printed housing comes in handy. If you don’t have access to a 3D printer, a plastic or Tupperware container with vents cut in the sides will work just fine. Just make sure that air can flow freely through the housing but water cannot enter. This 3D printed example is not waterproof, so don’t put it outside somewhere where it can get rained on. It will keep all the electrical bits safe and a little protected though!

3D Print of Weather Station in Cura

When 3d printing, remember to use supports and have the wire opening point up.

3D Print of Weather Station in Printer

Final Housing


Going Further

Don’t stop there, add more to your weather station and contribute more data to your findings! To learn more about Arduino and how to use it. Check out our Arduino Online Workshop. For more information about 3D printing, check out our 3D Printing Online Workshop! If you run into any problems, have a question, or just want to say hi make a post on our Maker Forum!

Attachment - Weather_Station_V2_body.stl

Have a question? Ask the Author of this guide today!

Please enter minimum 20 characters

Your comment will be posted (automatically) on our Support Forum which is publicly accessible. Don't enter private information, such as your phone number.

Expect a quick reply during business hours, many of us check-in over the weekend as well.

Comments


Loading...
Feedback

Please continue if you would like to leave feedback for any of these topics:

  • Website features/issues
  • Content errors/improvements
  • Missing products/categories
  • Product assignments to categories
  • Search results relevance

For all other inquiries (orders status, stock levels, etc), please contact our support team for quick assistance.

Note: click continue and a draft email will be opened to edit. If you don't have an email client on your device, then send a message via the chat icon on the bottom left of our website.

Makers love reviews as much as you do, please follow this link to review the products you have purchased.