Introduction: Arduino Wireless Weather Station

Picture of Arduino Wireless Weather Station

In this Instructable I am going to show you how to build a Wireless Weather Station with a big 3.2" Color TFT display using Arduino. Building a Wireless Weather Station is a great learning experience. When you finish building this project you will have a better understanding of how wireless communucations work, how sensors work, and how powerful the Arduino platform can be. With this project as a base and the experience gained, you will be able to easily build more complex projects in the future.

A Weather station is a device that collects data related to the weather and enviroment using many different sensors. We can measure many things like:

  • Temperature
  • Humidity
  • Wind
  • Barometric Pressure
  • UV index
  • Rain

In the Weather Station that we are going to build we are going to measure Temperature and Humidity in two locations and display the current date and time. Building a weather station is extremely easy. But can a maker build a unit with a color TFT display and features that match those of a commercial unit? The answer is YES! With the power of open source software and hardware, one can build this impressive weather station easily!

The project consists of two parts, the transmitter and the receiver.

The transmitter measures the temperatutre and the humidity and send the data wirelessly to the receiver.

The receiver, measures the temperatutre and the humidity, receives the data from the remote sensor and displays everyting in big color tft display.

Let's build this project!

Step 1: Get All the Parts

Picture of Get All the Parts

The parts needed in order to build this project are the following:

Arduino Due: http://bit.ly/ArduinoDUE

Arduino Mega: http://bit.ly/ArduinoMega

Arduino Nano: http://bit.ly/CheapArduinoNano

3.2" TFT display: http://bit.ly/32COLORTFT

DHT22: http://bit.ly/DHT_22

NRF24L01: http://bit.ly/NRF24L01B

DS3231 RTC: http://bit.ly/Ds3231

Breadboard: http://bit.ly/SmallBreadboard

Wires: http://bit.ly/Wires3InOne

Header Pins: http://bit.ly/HeaderPinsB

Xiaomi Powerbank: http://bit.ly/XiaomiPowerbank2

The cost of the project is around 40$. You can reduce the cost of the project by 5$ if you use the Arduino Mega instead of the Arduino Due. I choose to use the Arduino Due for the receiver because it is very fast and it has a lot of memory. This is going to be very useful in the future as we add more and more features to the project.

Step 2: Temperature and Humidity Sensor - DHT22

Picture of Temperature and Humidity Sensor - DHT22

The DHT22 is a very popular Temperature and Humidity sensor. It is cheap, easy to use and the specification claims good precision and accuracy.

The DHT sensors are made of two parts, a capacitive humidity sensor and a thermistor. There is also a chip inside that does some analog to digital conversion and outputs a digital signal with the temperature and humidity. The digital signal is fairly easy to read using any microcontroller.

Characteristics of the DHT22

  • Low cost
  • 3 to 5V power and I/O
  • 2.5mA max current use during conversion
  • 0-100% humidity readings with 2-5% accuracy
  • -40 to 125°C temperature readings ±0.5°C accuracy
  • Slow

The connection with Arduino is extremelly easy. We connect the sensor pin with the + sign to the 5V or the 3.3V output of the Arduino. We connect the sensor pin with the - sign to GROUND. Lastly we connect the OUT pin to any digital pin of the Arduino.

In order to use the DHT22 sensor with Arduino we have to use the DHT library.

https://github.com/adafruit/DHT-sensor-library

Step 3: The DS3231 Real Time Clock Module

Picture of The DS3231 Real Time Clock Module

The DS3231 real time clock module is as its name suggest a Real Time Clock. Using its battery it can keep time for years since it has minimal power consumption.

The DS3231 is a low-cost, extremely accurate I2C real-time clock (RTC) with an integrated temperature compensated crystal oscillator (TCXO) and crystal. The device incorporates a battery input, and maintains accurate timekeeping when main power to the device is interrupted. The integration of the crystal resonator enhances the long-term accuracy of the device as well as reduces the piece-part count in a manufacturing line.
The RTC maintains seconds, minutes, hours, day, date, month, and year information. The date at the end of the month is automatically adjusted for months with fewer than 31 days, including corrections for leap year. The clock operates in either the 24-hour or 12-hour format with an AM/PM indicator. Two programmable time-of-day alarms and a programmable square-wave output are provided. Address and data are transferred serially through an I2C bidirectional bus.

The cost of the module is extremely low, it costs around 2$ including the battery! We are going to use it in order to keep time in our Weather Station Project.

Step 4: NRF24L01+: Wireless Modules

Picture of NRF24L01+: Wireless Modules

The NRF24L01 module is a low cost bi-directional transceiver module. The cost of it is less than 3$! It operates at the 2.4GHz band and it can achieve at a data rate of 2Mbits! Impressive isn’t it? It uses the SPI interface in order to communicate with Arduino, so it is very easy to use with it. We have to connect 7 of the 8 pins of the module in order to make it work with Arduino.

Unfortunately we can’t plug the module in the breadboard so we are going to use male to female wires in order to connect the module to Arduino. Pin number 1 of the module is GND. You have to connect it to Arduino Ground. The next pin is Vcc. You have to connect it to the 3.3V output of the Arduino Uno. Be careful! Do not connect it to 5V or you will destroy your module! The third pin is named CE and you can connect it to any digital pin you like. In this example I am going to connect it to digital pin 7. Pin 4 is CS and you can connect to any digital pin as well. I am going to connect to digital pin 8. The next pin is SCK which goes to digital pin 13 of the Arduino Uno. The next pin is MOSI which goes to digital pin 11 and the last pin in MISO which goes to digital pin 12. That’s it!

In order to be easy to use the module with Arduino we have to use the following library:

https://github.com/TMRh20/RF24

If you haven't used the NRF24L01+ modules so far, please check the attached video in order to see how to use it by building a simple project. It will help you understand the way it works.

Step 5: Building the Trasmitter

Picture of Building the Trasmitter

Let’s first build the transmitter. It is very simple.

For the transmitter we use:

  • An Arduino Nano
  • A DHT22 sensor
  • A NRF24L01+ wireless module
  • A breadboard
  • Some wires

We connect the output pin of the sensor to digital pin 4 of the Arduino Nano. We connect the Ground and Vcc and we are ready. All we have to do now is to connect the NRF24L01 wireless module.

Please attach it using the pins that are shown in the third image. For more details, please watch the detailed video I have attached in the previous step.

That's it, your transmitter is ready. Let's now move on to the receiver.

Step 6: Building the Receiver

Picture of Building the Receiver

In order to build the receiver we need the following parts:

  • An Arduino Due or a Mega
  • A DS3231 Real Time Clock module
  • A DHT22 Temperature and Humidity Sensor
  • A NRF24L01+ Wireless module
  • A 3.2" Color TFT display
  • A breadboard
  • 7 header pins
  • Some wires

At first we bend 7 header pins and we place them at some of the Arduino Due pins. We need one to Ground and one to 3.3V. We need two at the I2C pins. We need the remaining 3 to digital pins from 6 to 8. We also have to solder three wires to the hardware SPI pins of the Arduino Due pins. We need MOSI, MISO and SCK. Check the diagram carefully. We connect the wires to the header pins and we are ready to attach the display.

Connecting the DS3231
the VCC pin on Arduino’s 3.3V output

the GND pin to Arduino’s GND and

the SDA (Serial Data Line) pin to Arduino’s SDA pin and

the SCL (Serial Clock Line) pin to Arduino’s SCL pin

Connecting the DHT22 Sensor

the VCC pin on Arduino’s 3.3V output

the GND pin to Arduino’s GND and

the output pin to Arduino's digital pin 8

Connecting the NRF24L01 module

the GND pin to Arduino’s GND

the VCC pin to Arduino 3.3V

the 3rd pin to Arduino's digital pin 6

the 4th pin to Arduino's digital pin 7

the 5th pin to SCK pin that we have soldered

the 6th pin to MOSI pin that we have soldered

the 7th pin to MISO pin that we have soldered

Step 7: The Transmitter Code

Picture of The Transmitter Code

First of all, we have to download the RF24 library in order to make our life easier when we work with the NRF24L01 wireless modules. We also need the DHT library for the DHT22 sensor.

NRF24L01 Library: https://github.com/TMRh20/RF24

DHT22 Library: https://github.com/adafruit/DHT-sensor-library

Let’s first see the Transmitter code. It sends out a simple data structure which contains two floats, the temperature and the humidity.

In order to establish a communication link we have to create a “pipe” between the two modules. That pipe needs to have an address. Both modules have to write and read from the same pipe in order to communicate. That’s the first thing we define in our code, we set the pipe address to “0”. Next we define the channel at which we want to communicate with the other module. The NRF24L01 chip supports 126 different channels. Both modules need to use the same channel in order to communicate with each other. In this example I am using channel 115. Next, I define that I want to use the maximum transmitting power that the module offers. It uses more power but extends the range of the communication. Next we define the data rate of the transmission. I set it to 250Kbs which is the lowest possible data rate in order to achieve better range. The next step is to open the pipe in order to write to it later.

In the loop function, we read the temperature and humidity values from the sensor, we save that data to the data structrure and then we send the data structure by writing the data structure to the pipe. That's it. You can find the code attached in this intstuctable.

Step 8: The Receiver Code

Picture of The Receiver Code

Let’s now see the receiver code. We need 4 libraries.

First we have to download the library for the display from this link:

DISPLAY Library: https://github.com/Bodmer/TFT_HX8357_Due

After downloading the library you have to open the User_Setup.h file comment line 13 and uncomment line 14 because the display we have is using the HX8357C driver. Now we can continue with the 3 other libraries. We need one library for the Real Time clock, one for the DHT22 sensor and lastly one for the Wireless module.

NRF24L01: https://github.com/TMRh20/RF24

DHT22: https://github.com/adafruit/DHT-sensor-library

DS3231: https://github.com/SodaqMoja/Sodaq_DS3231

Let's take a look at the code.The first thing we have to do is to set the time to the real time clock module if it is not already set. In order to do it, enter the current date and time in then setRTCTime function uncomment the setRTCTime call of the function on line 54 and upload the program to Arduino. Now the time is set. But, then we have to comment setRTCTime call of the function again and upload the program to Arduino once more.

The code of the receiver works like this. In the setup function we initialize all the sensors and the modules and we print the User Interface. Then at the loop function we continuously check for new wireless data. If there is new data we save that data in variables and print them on the display. We read the temperature and the humidity once a minute and we only update the display if there is a change in the values. This way we reduce flickering of the display even more! I have also prepared a version of the code with the temperature displayed in degrees Fahrenheit. You can find both version of the code attached on this instructable.

Step 9: Testing the Project

Picture of Testing the Project

The last step to power up everything and see if everything is working as expected. If so, at the top of the display the current date and time is displayed. At the bottom of the display you can see the temperature and the humidity from both the remote and the local sensor.

If there is no data displayed for the remote sensor, move the transmitter closer, it be out of range. If the problem persists, check all the connections one more time, there must be something wrong there.

As you can see, this project is a great demonstration of what open source hardware and software is capable of. Within a few hours one can build such an impressive project! Of course, this is a just the beginning. We can add many more features to the project. I will soon add a button, so we can display graphs, and have different modes. We can also add more sensors, data logging, internet connection and so on. We are using the Arduino Due, so we have plenty of memory to implement many more things. I would love to hear your opinion on this project. How do you want to see it evolve? Please post your comments or ideas in the comments section below!

If you want more details, watch the YouTube Video in the introduction or visit mywebsite. Thanks for taking a look!

Comments

mildrid1 (author)2017-09-04

Hello and good evening

I am gonna have ago at this, My first project but ive hit a problem. The screen is sold out and ive got bored waiting for new stock. Is there another type of screen i could use instead of the one you listed in the parts section. Would i be able to add many sensors and make it gadget heaven as i also have Polaroid tablet doing nothing which i wouldnt mind making it to something awesome. Got to make this one yet.

I also see no message since beginning of the year?

Cheers mark w.

Mad6969 (author)2017-01-02

Hello,

I'm trying to build this weather station but I'm having trouble making the screen work.

It just stays black, powered, but black. I'm sure I'm just missing a tiny point, like a library or something. I've tried to upload an exemple sketch (the 3D Demo) and it doesn't work either.

The weather part works fine, I get the datas on the serial monitor.

Any idea?

Palant1r (author)2016-07-23

Hi Nick, am I missing something, if you bend a header pin inthe 3.3v of the due then the supply 3.3v pin for the display will not connect.

cheers

Steve B

educ8s (author)Palant1r2016-11-18

The display gets power from another pin don't worry, this pin is not used to power the display!

bennassi (author)educ8s2016-11-18

Did you removed that 2pin header from the display? (1 for 3v3 and the 2nd was for reset?).

Will continue this weekend. WhenI got it running, I plan to rebuild it into an web thermostate (maybe even try to intergrate the OpenTherm. protocol).

FLarne (author)Palant1r2016-08-09

You can take the 5V Supply for the DHT22

bennassi (author)FLarne2016-11-17

The NRF24L01 still needs the 3V3. RTC module can run on 5V.

Allmost ready to build it.

educ8s (author)bennassi2016-11-18

When ready, please post your experience!

Km t (author)2016-10-19

diagram ?

FLarne (author)2016-09-04

Does anyone know how i can write the temperature on the SD-Card (there is a card reade on the back of the display), or as an alternative , use an esp 01 to write the data on a server (via wifi)

VincentP27 (author)2016-07-18

Very nice project.

What would be the typical power consumption of the transmitter? Any chance to run it out of batteries?

educ8s (author)VincentP272016-08-23

The transmitter needs around 10mA of current. If we use a bare Arduino board we can have a transmitter running for almost a year on batteries.

FLarne (author)2016-08-10

Thanks for this nice Tutorial. I recommend using the low Power Mode for the remote nanos to extend the battery life time.

How many remote nanos can i receive with one NRF24L01?

educ8s (author)FLarne2016-08-23

Yes that's a good idea. If I am not mistaken we can set up to 6 different channels for each NRF module.

JoeW98 made it! (author)2016-07-30

I am still new to Arduino and new to learning code however. I believe there is a glitch somewhere in this code. First glitch I found was here.

float remoteHumidity = 0.0;

float remoteTemperature = 0.0;

String dateString;

String hours;

int minuteNow=0;

int minutePrevious=0;

struct package

{

float temperature ;

float humidity ;

};

float previousIndoorHumidity = 0;

float previousIndoorTemperature = 10;

float previousRemoteHumidity = 0.1;

float previousRemoteTemperature = 0.1;

float indoorHumidity = 0;

float indoorTemperature = 0;

typedef struct package Package;

Package data;

Now I do not have a graphic display I only a 20x4 LCD. I also only have 2 DHT11 Humidity and Temp sensors and I don't have a clock sensor but that did not matter I got it to work except inside temp won't work and I am thinking it is in the coding someplace.

I am using 2 nrf24l01, 2 DHT11, 1 arduino nano 1 arduino uno and 1 20x4 LCD below is the code and pic of what I is happening any help to get inside temp working would be great. Thanks

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

#include "DHT.h"

#include "RF24.h"

#define DHTPIN 8

#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

RF24 myRadio (9, 10);

byte addresses[][6] = {"0"};

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address to 27`

String dateString;

String hours;

int minuteNow=0;

int minutePrevious=0;

struct package

{

float temperature ;

float humidity ;

};

float indoorHumidity = 0.0;

float indoorTemperature = 0.0;

float previousIndoorHumidity = 0.1;

float previousIndoorTemperature = 0.1;

float remoteHumidity = 0.0;

float remoteTemperature = 0.0;

float previousRemoteHumidity = 0.1;

float previousRemoteTemperature = 0.1;

typedef struct package Package;

Package data;

void setup() {

Serial.begin(9600);

// Switch on the backlight

lcd.begin(20,4); // initialize the lcd

delay(100);

dht.begin();

delay(2000);

startWirelessCommunication();

printUI();

}

void loop() {

checkForWirelessData();

printIndoorTemperature();

printIndoorHumidity();

printRemoteTemperature();

printRemoteHumidity();

}

void startWirelessCommunication()

{

myRadio.begin();

myRadio.setChannel(90);

myRadio.setPALevel(RF24_PA_LOW);

myRadio.setDataRate( RF24_250KBPS ) ;

myRadio.openReadingPipe(1, addresses[0]);

myRadio.startListening();

delay(100);

}

void checkForWirelessData()

{

if ( myRadio.available())

{

while (myRadio.available())

{

myRadio.read( &data, sizeof(data) );

previousRemoteTemperature = remoteTemperature;

previousRemoteHumidity = remoteHumidity;

remoteTemperature = Celcius2Fahrenheit(data.temperature);

remoteHumidity = data.humidity;

}

Serial.print("\nPackage:");

Serial.print("\n");

Serial.println(data.temperature);

Serial.println(data.humidity);

}

}

void printUI()

{

lcd.home ();

lcd.print("Outside");

lcd.setCursor(12,0 );

lcd.print("Inside");

lcd.setCursor(5, 2 );

lcd.print("%");

lcd.setCursor(17, 2);

lcd.print("%");

lcd.setCursor(5, 1 );

lcd.print("F");

lcd.setCursor(17, 1 );

lcd.print("F");

}

void readSensor()

{

previousIndoorTemperature = indoorTemperature;

previousIndoorHumidity = indoorHumidity;

indoorHumidity = dht.readHumidity();

indoorTemperature = Celcius2Fahrenheit(dht.readTemperature());

Serial.println(indoorTemperature);

Serial.println(indoorHumidity);

}

void printIndoorTemperature()

{

String temperature;

if(indoorTemperature != previousIndoorTemperature)

{

if(indoorTemperature>=100)

{

temperature = String(indoorTemperature,0);

}else

{

temperature = String(indoorTemperature,1);

}

lcd.setCursor(12, 1 );

lcd.print(temperature);

previousIndoorTemperature = indoorTemperature;

}

}

void printRemoteHumidity()

{

String humidity;

if(remoteHumidity != previousRemoteHumidity)

{

if(remoteHumidity == 0.0 && remoteTemperature == 0.0) //We just booted up

{

humidity = "---";

}else

{

humidity = String(remoteHumidity,1);

}

lcd.setCursor(0, 2 );

lcd.print(humidity);

previousRemoteHumidity = remoteHumidity;

}

}

void printRemoteTemperature()

{

String temperature;

if(remoteTemperature != previousRemoteTemperature)

{

if(remoteHumidity == 0.0 && remoteTemperature == 0.0) //We just booted up

{

temperature = "---";

}else if(remoteTemperature>=100)

{

temperature = String(remoteTemperature,0);

}else

{

temperature = String(remoteTemperature,1);

}

lcd.setCursor(0, 1 );

lcd.print(temperature);

previousRemoteTemperature = remoteTemperature;

}

}

void printIndoorHumidity()

{

if(indoorHumidity != previousIndoorHumidity)

{

String humidity = String(indoorHumidity,1);

lcd.setCursor(12, 2 );

lcd.print(humidity);

previousIndoorHumidity = indoorHumidity;

}

}

float Celcius2Fahrenheit(float celsius)

{

return 1.8 * celsius + 32;

}

jerry.ericsson2 (author)2016-07-19

Good project, had it going togather nicely till my iron slipped when soldering the pins and melted the solder on my main chip of my old MEGA. SHES DEAD JIM!! Well I think she is, I spent the last hour and a half trying to clean the blob of solder that is connecting one entire side of the chip into one contact but everything I try seems to make things worse. Guess I don't really need this item anyhow, still have all the other parts to make other toys. Thanks anyhow.

nmsr1196 (author)2016-07-17

Also, which IDE version did you compile in?

nmsr1196 (author)2016-07-17

I tried to compile and received an error (see picture)

Also, would I use the same code for a Mega2560?

Very cool project.

Filbert11 (author)2016-07-14

Excellent - very comprehensive project !! Can you tell me - What is the range of the NRF24L01+ SI24R1 Wireless module ?

rch (author)Filbert112016-07-16

Theoretical range of the NRF24L01 is about 100 meters outdoors with no obstructions. This deminishes going indoors and with obstructions and other forms of interference.

Filbert11 (author)rch2016-07-16

Thanks !! Sounds great !!

mjmes (author)2016-07-14

Could you evolve this project to where I can check the data on my Android remotely via the internet?

Kindest Thanks!

BennyP5 (author)mjmes2016-07-14

Forgot to mention, I used the ATWINC1500 to get my station connected to the internet, and a NTP clock in favour of a RTC. Adafruit has good libraries for theor products that come with a bunch of example scetches.

BennyP5 (author)mjmes2016-07-14

Check out adafruit io. You can easily build a browser based UI, and its compatible with IFTTT. They have great tutorials at adafruit so stitching the projects together should not be a problem. Ill probably take the screen part of this project and add it to my almost finnished weatherstation.

About This Instructable

66,735views

761favorites

License:

Bio: I am Nick Koumaris from Sparta, Greece. I'm extremely passionate about electronics, making things and design. I love teaching what I know and sharing ... More »
More by educ8s:Arduino TEA5767 FM Radio ReceiverArduino Weather Station with a Nextion DisplayAdd Email Notifications to Any Robotic Vacuum Cleaning Robot
Add instructable to: