Simple web weather display
Moderators: adafruit_support_bill, adafruit

Simple web weather display

by Desert_Rat on Sun Mar 18, 2012 4:14 am

Simple current weather display utilizing an Arduino Ethernet (Arduino with Ethernet built-in) and the Adafruit RGBLCD Shield.

I live and work in a windowsless shack in the middle of a desert in the Middle East. Opening the door in the middle of a sandstorm is not advisable.
So I built a little LCD display that tells me the current weather conditions outside since I have no windows to look out of.
All those U.S. DoD budget cuts didn't leave us with enough taxpayer money to pay for windows. :-)
In other words, prison cells have better natural lighting.

And since I'm a lazy, lazy man I'd prefer to just be able to look at something to get the data I need and not have to go banging around on a web browser or installing a full-blown $$$ weather station.
Arduinos are perfect devices for lazy, cheap people such as myself.

Every two minutes it pulls down an RSS feed, parses it for current Heat Index, Wind DIrection, Wind Speed, Surface Visibility, and Current Conditions.
It then abbreviates and displays that data on an Adafruit 16x2 RGBLCD shield, however just about any LCD can be used with some minor code changes.

Eventually this will be connecting via an Xbee-style WiFly module, but for now it works fine on the Arduino Ethernet or Ethernet Shield.

I chose RSSWEATHER.COM because it has ICAO airport weather data. That means just about any airport on the planet, including small local airfields to get really local weather data...it's tracking stations that not even Weather Underground or Google's hidden weather API track.
In the "GET http://69.5.27.250/icao/KQWM/rss.php HTTP/1.0" string around line 88 in the code below, just substitute your own 4-digit airport code in place of KQWM.

Forgive the messy, unoptimized code - I'm not a programmer and have never written code before, but I've read a lot of it.
I also have zero formal training or education in electronics or anything past high school, really. I've just been working with computers and strange technical stuff since I was 7 years old.
That this works at all is actually pretty amazing in itself, well to me at least.
Eventually hoping to utilize some of the shield's buttons to change up the display to show more data.

Here's the code:

Code: Select all | TOGGLE FULL SIZE
#include <SPI.h>
#include <Ethernet.h>
#include <TextFinder.h>
#include <Wire.h>
#include <SoftwareSerial.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>

//Setting up colors for the backlight..some unused for now
#define RED 0x1
#define YELLOW 0x3
#define GREEN 0x2
#define TEAL 0x6
#define BLUE 0x4
#define VIOLET 0x5
#define WHITE 0x7

//setup Serial LCD data pin
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0xE3, 0x0F };
//byte ip[] = { 192,168,1,177 };  // remarked here just in case a DHCP server plays funny with Arduino's DHCP code - I'm looking at you, every Microsoft DHCP Server!

char serverName[] = "69.5.27.250";  //char serverName[] = "www.rssweather.com";

// Initialize the Ethernet client library
EthernetClient client;
//Setup TextFinder
TextFinder  finder( client );
//setup character strings, or "straings" if you're from south like me
char cond[40];
char winddir[25];
char pubdate[40];


void setup() {
  // start serial comms for debugging
  Serial.begin(9600);
  lcd.begin(16,2);  //This is originally setup for a 16x2 RGB reverse backlight display from adafruit.com, with minor mods it will work for any simple LCD line display
  lcd.setBacklight(WHITE);  //the backlight at night is big and WHITE....deep in the heart of Kuwait!
  lcd.clear();
  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    lcd.print("no IP from DHCP!");
    lcd.print("Check network!");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
}


void loop()
{

    if (client.connect(serverName, 80)) {
    client.println("GET http://69.5.27.250/icao/KQWM/rss.php HTTP/1.0"); // rssweather.com RSS feed for Camp Udairi, Kuwait
    client.println();
    lcd.print("Updating data...");
    delay(1000);  //1 second ot display the LCD message above
  }
  else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
    lcd.print("connect failed");
    lcd.print(serverName);
  }

  if (client.connected()) {
        int gusts = 0; //this zeroes out gusts until check is done below - if gusts = 0 then no gust data is printed to LCD
        lcd.clear();  //clears LCD
       
        //Here is where we use the TextFinder library to pull data from the RSSWEATHER page we pulled down at the start of the loop 
        finder.find("pubDate");  //Date last METAR/WX report was published on the server
        finder.getString(">","<",pubdate,(40));
        finder.find("alt=");  //Now find the Current Conditions
        finder.getString("\"","\"",cond,(40));
        finder.find("\"windspeed\"");  //Now find the Windspeed
        int windspd = ((finder.getValue() / 1.6));  //windspeed is given in KMs so I'm converting it to MPH
        finder.find("\"winddir\"");  //Wind Direction
        finder.getString("\">"," ",winddir,(40));
       
  if ((finder.findUntil("\"gusts\"", "\n\r")) == (true)){  //scan the incoming client data for the "gusts" field and return true if found
        gusts = (finder.getValue());}
       
        finder.find("\"heatindex\"");  //find Heat Index
        int temperature = ((finder.getValue() * 9 / 5) + 32);  //Heat Index is given in Celsius so I'm converting it to Fahrenheit
        finder.find("\"visibility\"");  //find surface visibility - useful for desert conditions when sand and dust are blowing...do I really want to get on that chopper?
        int visibility = ((finder.getValue() / 1.6));  //Visibility at surface is given in KMs so I'm converting it to miles
               
        //print this to serial in CSV format - useful for those using an Xbee to transmit to a an Arduino-controlled remote display device
        Serial.print(temperature);//Heat Index, converted to F
        Serial.print(",");
        Serial.print(cond); //Current Conditions
        Serial.print(",");
        Serial.print(winddir);
        Serial.print(",");
        Serial.print(windspd);
        Serial.print(",");
        Serial.print(gusts);
        Serial.print(",");
        Serial.print(visibility);
        Serial.println("M");
        Serial.println(pubdate); //date of last published report on the web server
       
        //Now time to print it all to the serial, starting with the first line on a 16x2 LCD display
        lcd.setCursor(0,0);
        lcd.print(temperature);//Heat Index converted to F
   lcd.print("F ");
        lcd.print(winddir);  //Wind direction
        lcd.print(windspd);  //Wind speed
       
        //this next bit checks if there is gust data and if so appends it to the windspeed data with /GUSTS so that "N12" becomes "N12/24"
  if (gusts != 0){
        lcd.print("/");
        lcd.print(gusts);
    }
        lcd.print(" ");
        lcd.print("V");
        lcd.print(visibility);  //Visibility at surface so one knows if to "Run! Get to the chopper!" or not
        lcd.print("M");  //this indicates "Miles"
        //Now for the second line on the LCD display
        lcd.setCursor(0,1);
        //Since we're actually capturing a JPEG's ALT description string, we want to re-write the longer strings so that they fit in 16 characters or look better...needs optimization
  if (strcmp(cond, "blowing widespread dust")  == 0)
        lcd.print("Blowing Dust");
        else
  if (strcmp(cond, "heavy duststorm")  == 0)
        lcd.print("Heavy Dust Storm");
        else
  if (strcmp(cond, "duststorm")  == 0)
        lcd.print("Dust Storm");  //Making it look pretty, oh so pretty...
        else
        lcd.print(cond);
     
      //now let's change the backlight color to reflect weather conditions...man, I really need to optimize this
  if (strcmp(cond, "blowing widespread dust")  == 0)
     lcd.setBacklight(YELLOW);
      else
  if (strcmp(cond, "widespread dust")  == 0)
     lcd.setBacklight(YELLOW);
      else
  if (strcmp(cond, "heavy duststorm")  == 0)
     lcd.setBacklight(YELLOW);
      else
  if (strcmp(cond, "duststorm")  == 0)
     lcd.setBacklight(YELLOW);  //Because after spending many years in the desert, it really is yellow during a sand/dust storm
      else
  if (temperature >= 90) 
     lcd.setBacklight(RED);  //If the Heat Index is 90 or above, switch to RED backlight
      else
  if (temperature >=80)
     lcd.setBacklight(GREEN); //If the Heat Index is in the 80s, switch backlight to green
        else
  if (temperature >=70)
     lcd.setBacklight(BLUE);  //if the Heat Index is 70 or below, switch backlight to BLUE - in the desert this is COLD!
 
  //Here at the end is where we stop the client, flush the data, wait two minutes, flush the serial data, and then it starts all over again
  client.stop();
  client.flush();
  delay(120000);  //wait about 2 minutes before next update
  Serial.flush();
   }

}
Attachments
Data_Gathering_Base_Station_RGB_LCD_final.zip
for Arduino 1.0
(3.7 KiB) Downloaded 191 times
---------------------------------------------------------------------------------
I went from living in a van down by the river to a shack in the desert.
Meh, at least it's an upgrade.
User avatar
Desert_Rat
 
Posts: 5
Joined: Sun Mar 18, 2012 4:04 am

Re: Simple web weather display

by dananddna on Sun Jul 22, 2012 6:54 am

Desert_Rat, That is a great project! I don't know why no one else chimed in, i've only posted once on this forum but its not the greatest crowd apparently.

Your Lab/Home sounds awesome! I imagine the environment aids in inspiring some rather mad scientific experiments.

I had the idea of making a project like this for awhile myself. I too have the Ethernet Uno rather than the shield. I've actually used the FTDI cable far more times then I've used the MCU, which has led to drafting up a few of my own MAX232 & FTDI breakout adapters.

I made my own shields for the LCD and for the nokia B&W GLCD. I could upload pictures but I doubt there's enough interest.

I'm going to have a whack at your code using my setup with a plane 20x4 LCD. Feel free to reply or to PM me for details later, I don't check this forum often but I'll have it email me upon reply.

Best Wishes,
-eschatologicalengineer-

I just wanted to thank you kindly for posting your code and your project. I''m a disabled basement dweller & I too have educate outside of the educational system. I'm very thankful for certain (certain...) online communities that offer a creative learning environment. Keep up the great work!
dananddna
 
Posts: 3
Joined: Wed Jan 04, 2012 2:53 pm

Re: Simple web weather display

by funinalaska on Mon Oct 14, 2013 5:30 pm

This seems to be one part of a project I am beginning to plan.
I live in an area where the weather is poorly reported and even worse at forecasting.
The only way I have to get actual local observations is via METAR data from the airport about a mile away.
I can get the forecast on WUnderground, But I have no idea how to strip out the bits I need.
I have not yet looked into how to use that data.
I am still in the process of gathering all the necessities I will need to purchase to do this.
My goal is to have a scrolling LED marquee to display:
Current indoor temp (TMP module)
Current outdoor temp (thermistor good to -67F that will be run through the wall I have it mounted on)
Airport observations of Current Temp, Day High, Day Low, Wind and Humidity (Arduino Ethernet Shield)
I am going to need loads of help on the code for this as I am not very good at programming.
I am going to place the order for the things I need here in the next week.
If anyone would like to work with me on this project please get in touch with me.
I am learning.... Slowly.
Thanks in advance for anyone's help.
funinalaska
 
Posts: 18
Joined: Mon Sep 16, 2013 11:33 am