The Arduino Weather Station / Thermostat

188,846

414

35

Introduction: The Arduino Weather Station / Thermostat

About: Professionally, I'm an IT Engineer (Executive Level) and Electronics Tech. I'm a Amateur Radio Operator (KK4HFJ). I lived off grid, with Solar (PV), Wind, and veggie oil fueled diesel generator power for 6 y...
UPDATE: https://www.instructables.com/id/Temperature-and-Humidity-on-a-Graphical-LCD/

UPDATE: Add dew point calculations


UPDATE: Wind Speed Monitoring

I've always been interested in monitoring my local weather, and noticed the difference between what weather.com and accuweather.com think my local weather is, and what I see out the window. I also wanted better control over my heating and A/C system. As a computer and electronics nut, I've been playing with the Arduino Microcontroller, and decided to to meld my interests. So here goes the documentation on my home built solar powered weather station (always being modified, and expanded) with HVAC Control.

Step 1: The Arduino

The first step was obtaining a Arduino board. We purchased ours from hacktronics.com. After working through the tutorials on their site, I felt confident that I understood the simple scripting and connection concepts, and moved forward.

Arduino is an open-source electronics prototyping platform based on flexible, easy-to-use hardware and software. It's intended for artists, designers, hobbyists, and anyone interested in creating interactive objects or environments. - http://arduino.cc/

The Arduino requires 5v to run, and we supply this with our Pico Solar PV / Lithium battery pack.

Step 2: The LCD Display

I needed the ability to display temperature, humidity, barometric pressure, and time/date, so I picked a 4 line white on blue LCD display from Hacktronics. I used their LCD tutorial to get it connected and display some sample text on the screen.

// character LCD example code
// www.hacktronics.com

// Connections:
// rs (LCD pin 4) to Arduino pin 12
// rw (LCD pin 5) to Arduino pin 11
// enable (LCD pin 6) to Arduino pin 10
// LCD pin 15 to Arduino pin 13
// LCD pins d4, d5, d6, d7 to Arduino pins 5, 4, 3, 2
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

int backLight = 13; // pin 13 will control the backlight

void setup()
{
pinMode(backLight, OUTPUT);
digitalWrite(backLight, HIGH); // turn backlight on. Replace 'HIGH' with 'LOW' to turn it off.
lcd.begin(16,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.clear(); // start with a blank screen
lcd.setCursor(0,0); // set cursor to column 0, row 0 (the first row)
lcd.print("Hello, World"); // change this text to whatever you like. keep it clean.
lcd.setCursor(0,1); // set cursor to column 0, row 1
lcd.print("hacktronics.com");

// if you have a 4 row LCD, uncomment these lines to write to the bottom rows
// and change the lcd.begin() statement above.
//lcd.setCursor(0,2); // set cursor to column 0, row 2
//lcd.print("Row 3");
//lcd.setCursor(0,3); // set cursor to column 0, row 3
//lcd.print("Row 4");
}

void loop()
{
}

See http://www.hacktronics.com/Tutorials/arduino-character-lcd-tutorial.html for actual code as instructables breaks our include statements.

Step 3: Temperature & Humidity

I purchased a SHT21 Temperature Humidity sensor from MisensO.com. This chip uses the I2C protocol for communicating. I found some sample code on the net that makes it talk to the Arduino, but it outputs to the serial port back to the pc. I modified the code to output to my LCD. I now have the Temperature and Humidity showing on the LCD display.

//Tested with SHT21 Breakout from Misenso
//SHT21 pin SDA to Arduino Analog pin 4
//SHT21 pin SCL to Arduino Analog pin 5
//SHT21 pin GND to Arduino GND
//SHT21 pin VCC to Arduion 3v (not 5v)

lcd.begin(20,4); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.clear(); // start with a blank screen
lcd.setCursor(0,0); // set cursor to column 0, row 0 (the first row)
lcd.print("Humidity: "); // change this text to whatever you like. keep it clean.
lcd.print(humidity.GetHumidity());
lcd.setCursor(0,1); // set cursor to column 0, row 1
lcd.print("Temp in C: ");
lcd.print(humidity.GetTemperatureC());
lcd.setCursor(0,2); // set cursor to column 0, row 2
lcd.print("Temp in F: ");
lcd.print(humidity.GetTemperatureF());

See http://arduinotronics.blogspot.com/2010/09/our-temperature-humidity-monitor-is.html for actual code as instructables breaks our include statements. You will need the LibHumidity.h library from Modern Devices for this project.

Step 4: HVAC Control

Now that I know what the temperature is, I need to control my A/C and heat based on what I want the temp to be. I installed a RGB LED as a placeholder for the relays I will be installing. If the system calls for heat, it turns the LED red. If it calls for cooling, it turns the LED Blue. If it's in our comfort range, it turns green.

if (humidity.GetTemperatureF() < 60)
{
digitalWrite(RedLEDPin, LOW); // sets the Red LED on
digitalWrite(BlueLEDPin, HIGH); // sets the Blue LED off
digitalWrite(GreenLEDPin, LOW); // sets the Green LED off

}
else if (humidity.GetTemperatureF() >= 75)
{
digitalWrite(BlueLEDPin, LOW); // sets the Blue LED on
digitalWrite(RedLEDPin, HIGH); // sets the Red LED off
digitalWrite(GreenLEDPin, HIGH); // sets the Green LED off
}
else
{
digitalWrite(GreenLEDPin, LOW); // sets the Green LED on
digitalWrite(BlueLEDPin, HIGH); // sets the Blue LED off
digitalWrite(RedLEDPin, HIGH); // sets the Red LED off

}

See http://arduinotronics.blogspot.com/2010/09/our-temperature-humidity-monitor-is.html for actual code as instructables breaks our include statements.

Step 5: Current Code With Wiring Instructions

The following is the code as it exists today. I am adding a second SHT21 for indoor/outdoor measuring (means hacking a second I2C channel, as the SHT21's all have the same address, and can't exist on one channel), and I'm still waiting for my real time clock chip and barometric pressure sensor to arrive from Sparkfun.com (they arrived yesterday, and I will work on this on the weekend - 9-29-10). I migrated the project over to my new Arduino Mega 2560 (58 I/O lines), and installed the new 0021 IDE. I will edit this instructable as the project evolves.

// Connections:
// LCD pin 1 to Arduino GND
// LCD pin 2 to Arduino 5v
// LCD pin 3 (Contrast) to GND
// rs (LCD pin 4) to Arduino pin 12
// rw (LCD pin 5) to Arduino pin 11
// enable (LCD pin 6) to Arduino pin 10
// LCD pin 15 to Arduino pin 13
// LCD pin 16 to Arduino GND
// LCD pins d4, d5, d6, d7 to Arduino pins 5, 4, 3, 2

//Tested with SHT21 Breakout from Misenso
//SHT21 pin SDA to Arduino Analog pin 4
//SHT21 pin SCL to Arduino Analog pin 5
//SHT21 pin GND to Arduino GND
//SHT21 pin VCC to Arduino 3v (not 5v)

//RGB LED
//Red Cathode to Arduino pin 9
//Blue Cathode to Arduino pin 8
//Green Cathode to Arduino pin 7
//Anode to 270 ohm resistor to 5V

#include #include
#include

LibHumidity humidity = LibHumidity(0);

LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

int backLight = 13; // pin 13 will control the backlight
int RedLEDPin = 9; // LED connected to digital pin 9
int BlueLEDPin = 8; // LED connected to digital pin 8
int GreenLEDPin = 7; // LED connected to digital pin 7

void setup()
{
pinMode(backLight, OUTPUT);
digitalWrite(backLight, HIGH); // turn backlight on. Replace 'HIGH' with 'LOW' to turn it off.

//I2C
pinMode(16, OUTPUT);
digitalWrite(16, LOW); //GND pin
pinMode(17, OUTPUT);
digitalWrite(17, HIGH); //VCC pin

//Furnace / AC Indicator
pinMode(RedLEDPin, OUTPUT); // sets the digital pin as output
pinMode(BlueLEDPin, OUTPUT); // sets the digital pin as output
pinMode(GreenLEDPin, OUTPUT); // sets the digital pin as output

}

void loop()
{
lcd.begin(20,4); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.clear(); // start with a blank screen
lcd.setCursor(0,0); // set cursor to column 0, row 0 (the first row)
lcd.print("Humidity: "); // change this text to whatever you like. keep it clean.
lcd.print(humidity.GetHumidity());
lcd.setCursor(0,1); // set cursor to column 0, row 1
lcd.print("Temp in C: ");
lcd.print(humidity.GetTemperatureC());
lcd.setCursor(0,2); // set cursor to column 0, row 2
lcd.print("Temp in F: ");
lcd.print(humidity.GetTemperatureF());
{
if (humidity.GetTemperatureF() < 60)
{
digitalWrite(RedLEDPin, LOW); // sets the Red LED on
digitalWrite(BlueLEDPin, HIGH); // sets the Blue LED off
digitalWrite(GreenLEDPin, LOW); // sets the Green LED off

}
else if (humidity.GetTemperatureF() >= 75)
{
digitalWrite(BlueLEDPin, LOW); // sets the Blue LED on
digitalWrite(RedLEDPin, HIGH); // sets the Red LED off
digitalWrite(GreenLEDPin, HIGH); // sets the Green LED off
}
else
{
digitalWrite(GreenLEDPin, LOW); // sets the Green LED on
digitalWrite(BlueLEDPin, HIGH); // sets the Blue LED off
digitalWrite(RedLEDPin, HIGH); // sets the Red LED off

}
}

delay (20000);
}

See http://arduinotronics.blogspot.com/2010/09/our-temperature-humidity-monitor-is.html for actual code as instructables breaks our include statements.

Step 6: Arduino Clock Module

We finished the Arduino Time & Date functions using the Sparkfun DS1307 I2C RTC module, a 2 line LCD, and the Arduino Duemilanove. There are four connections from the DS1307 to the Arduino:

//pin SDA to Arduino Analog pin 4
//pin SCL to Arduino Analog pin 5
//pin GND to Arduino GND
//pin VCC to Arduino 5v

To set the time, edit the following section in the code with the correct time and date,

// Change these values to what you want to set your clock to.
// You probably only want to set your clock once and then remove
// the setDateDs1307 call.
second = 0;
minute = 42;
hour = 9;
dayOfWeek = 1; //Sunday
dayOfMonth = 3;
month = 10; //October
year = 10;

and temporarily remove the // from the following line:

//setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);

Upload your code to the Arduino, then put the // back in the above line, and upload again.

The complete code and wiring are posted at http://arduinotronics.blogspot.com/2010/10/ds1307-real-time-clock-working.html

Share

    Recommendations

    • Tiny Home Contest

      Tiny Home Contest
    • Fix It! Contest

      Fix It! Contest
    • Metalworking Contest

      Metalworking Contest

    35 Discussions

    Good instructable, but, his is an old clock check out the newer more accurate DS3231 clock Easier to implement with the new 1604 4 line LCD module with the I2C backpack module it only requires 2 serial data wires as opposed to 7

    gr8 keep it up

    I was thinking about doing something like this, but with wind speed and rainfall as well. Thanks for the instructable! It'll probably help a lot when I finally get around to building mine.

    5 replies

    I'll eventually get those functions in there, probably by sniffing the wireless feed from a lacrosse weather station. easier than making a anemometer and rain gauge.

    I thought about making a anemometer and rain gauge, and I've even planned them out, but I don't want to take the time to actually make them. So instead, I just bought them from sparkfun: http://www.sparkfun.com/commerce/product_info.php?products_id=8942

    I'll post an instructable once they arrive at my house and I've programed my arduino!

    I know this was quite a while ago. But did you get that SparkFun weather kit? If so, what do you think of it?

    We did. It's up and flying. I didn't think it would hold up, as it appears fragile, but after a year or so, it's still going strong. Need to publish the code for that.

    Cool, nice to know. The "arms" that hold the anemometer and vane look kind of delicate to me.

    Couple of quick questions, is it impossible to use the Arduino to keep time.... (I was thinking of using pulseIn function at the start/end of the loop to keep time...)

    So if the RTC is essential can you just plug it into 5 consecutive Arduino pins instead of dealing with so much wiring?

    8 replies

    There exists an Arduino Time library http://playground.arduino.cc/Code/Time
    But this will not work if running on external power and not connected to the computer of course.

    When I just started with Arduino, I attempted to write a clock code https://docs.google.com/document/d/1nSeXLC3vC2sNe9...
    There was a decent amount of drift over a few hours, but it was still pretty cool. Again, I did this when I just started with Arduino/programming so it's definitely not the best thing around. You could probably find some better stuff if you just Googled, "Arduino clock" or something like that.This is something I found https://www.instructables.com/id/Make-an-accurate-A... Haven't looked at it much though.

    Secondly, in my code, I kept time using the millis() function. You would probably have better luck using interrupts.

    Good luck

    Thanks pal!

    I will definitely look at those links!!, Personally I am all about doing more with less, and this is up my alley!

    the rtc uses two datalines (a4 and a5) in addition to power and ground. you can't just plug the rtc into the arduino, as the pin connections will not line up.

    Hmm... I think you can, instead of GND you just digiWrite(pin LOW) and instead of 5V you digiWrite(Pin HIGH)... I know its not best practice but it does seem to work seamlessly

    Have a look at an example with an Ultrasonic sensor:

    https://www.youtube.com/watch?v=pdIUNHps-5s

    sda and scl are reversed on this module, so you can't. you'll need to find another module. do you really want to waste your analnog ports defining them as power and ground?

    Good point, I guess that depends on what the circuit needs, I really like what you built... especially that its self powered. I just bought some 1W panels + lipo batteries to see if I can build similar circuits.

    Hi! We launched a new project of weather map layer for OpenStreetMap http://openweathermap.org/. It public project that collects data from more than 20,000 meteorological and weather stations around the world. The more weather stations connect the more precise weather data we provide to people. All collected weather data are provided under CC-BY-SA 2.0.You can connect your weather station to the service http://openweathermap.org/connect

    I added the SSR's, directly addresses by an output pin. This allows control of ac devices, up to 660v and 150 amps, depending on the SSR, with an optically isolated 5v input.

    I also added the outdoor temp and humidity.