Weather Station using an mBed microcontroller and a Windows CE Device

Dependencies:   TextLCD mbed HMC6352

Files at this revision

API Documentation at this revision

Comitter:
mafischl
Date:
Thu Dec 15 13:38:51 2011 +0000
Commit message:

Changed in this revision

GPS.cpp Show annotated file Show diff for this revision Revisions of this file
GPS.h Show annotated file Show diff for this revision Revisions of this file
HMC6352.lib Show annotated file Show diff for this revision Revisions of this file
MODSERIAL.lib Show annotated file Show diff for this revision Revisions of this file
TextLCD.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 75e6a2e50519 GPS.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GPS.cpp	Thu Dec 15 13:38:51 2011 +0000
@@ -0,0 +1,170 @@
+/* mbed EM-406 GPS Module Library
+ * Copyright (c) 2008-2010, sford
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "GPS.h"
+
+
+GPS::GPS(PinName tx, PinName rx) : _gps(tx, rx) {
+    _gps.baud(4800);
+    longitude = 0.0;
+    latitude = 0.0;
+}
+
+int GPS::sample() {
+    float time2, time, date;
+    float latitude2, longitude2, speed, course, magneticVar;
+    char ns, ew, ns2, ew2, mgEW, mode, status;
+    
+
+    //return 1; //testing by Jigar
+    while (1) {
+        getline();
+        //printf("\n\rentered the GPS.sample while loop \n\r %s\n\r", msg);
+        
+        
+        // Check if it is a GPGGA msg (matches both locked and non-locked msg)
+        // $GPGGA,000116.031,,,,,0,00,,,M,0.0,M,,0000*52
+        /*
+        eg3. $GPGGA,hhmmss.ss,llll.ll,a,yyyyy.yy,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx*hh
+                        1       2     3  4       5 6  7  8   9  10 11 12 13  14   15
+            1    = UTC of Position
+            2    = Latitude
+            3    = N or S
+            4    = Longitude
+            5    = E or W
+            6    = GPS quality indicator (0=invalid; 1=GPS fix; 2=Diff. GPS fix)
+            7    = Number of satellites in use [not those in view]
+            8    = Horizontal dilution of position
+            9    = Antenna altitude above/below mean sea level (geoid)
+            10   = Meters  (Antenna height unit)
+            11   = Geoidal separation (Diff. between WGS-84 earth ellipsoid and
+                   mean sea level.  -=geoid is below WGS-84 ellipsoid)
+            12   = Meters  (Units of geoidal separation)
+            13   = Age in seconds since last update from diff. reference station
+            14   = Diff. reference station ID#
+            15   = Checksum
+
+        */
+       // if (sscanf(msg, "GPGGA,%f,%f,%c,%f,%c,%*d,%*d, %*f,%*f,%*f,%*f,%*f,%*f,%d ", &time, &latitude, &ns, &longitude, &ew, &lock,  &numSat, &horDil, &altitude) >= 1) {
+        if(sscanf(msg, "GPGGA,%f,%f,%c,%f,%c,%d,%d,%f,%f", &time2, &latitude, &ns, &longitude, &ew, &lock, &numSat, &horDil, &altitude) >= 1) { 
+
+            if (!lock) {
+                longitude = 0.0;
+                latitude = 0.0;
+                return 0;
+            } else {
+                if (ns == 'S') {
+                    latitude  *= -1.0;
+                }
+                if (ew == 'W') {
+                    longitude *= -1.0;
+                }
+                float degrees = trunc(latitude / 100.0f);
+                float minutes = latitude - (degrees * 100.0f);
+                latitude = degrees + minutes / 60.0f;
+                degrees = trunc(longitude / 100.0f ); //degrees = trunc(longitude / 100.0f * 0.01f);
+                minutes = longitude - (degrees * 100.0f);
+                longitude = degrees + minutes / 60.0f;
+                return 1;
+            }
+        }  
+        
+        // Check if it is a GPRMC msg (matches both locked and non-locked msg)
+        /*
+        $GPRMC,hhmmss.ss,a,llll.ll,N,llll.ll,E,x.x,x.x,ddmmyy,x.x,E,A*hh
+                   1     2    3    4    5    6  7   8    9    10 11 12 13
+            1    = UTC of Position
+            2    = Status
+            3    = Latitude
+            4    = N or S
+            5    = Longitude
+            6    = E or W
+            7    = Speed Over Ground (knots)
+            8    = Course Over Ground (degrees)
+            9    = Date (ddmmyy)
+            10   = Magnetic Variation (degrees)
+            11   = E or W (for magnetic variation)
+            12   = Mode (A = Autonomous, D = DGPS, E = DR)
+            13   = Checksum
+
+        */
+        // $GPRMC,161229.487,A,3723.2475,N,12158.3416,W,0.13,309.62,120598, ,*10
+        if(sscanf(msg, "GPRMC,%f,%c,%f,%c,%f,%c,%f,%f,%f,%f,%c,%c", &time, &status, &latitude2, &ns2, &longitude2, &ew2, &speed, &course, &date, &magneticVar, &mgEW, &mode) >= 1) { 
+        
+        // CONVERT TO STRING AND FORMAT TIME AND DATE
+        
+        GPStime = time;
+        GPSdate = date;
+  
+        }
+        
+        
+    }
+}
+
+float GPS::trunc(float v) {
+    if (v < 0.0) {
+        v*= -1.0;
+        v = floor(v);
+        v*=-1.0;
+    } else {
+        v = floor(v);
+    }
+    return v;
+}
+
+void GPS::getline() {
+    
+    while (_gps.getc() != '$');   // wait for the start of a line
+    // printf("entered the getline loop\n\r");
+    for (int i=0; i<256; i++) {
+        msg[i] = _gps.getc();
+        if (msg[i] == '\r') {
+            msg[i] = 0;
+            return;
+        }
+    }
+    error("Overflowed message limit");
+}
+
+/*
+$GPRMC,000115.039,V,,,,,,,291006,,*2C
+$GPGGA,000116.031,,,,,0,00,,,M,0.0,M,,0000*52
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPGSV,3,1,12,20,00,000,,10,00,000,,31,00,000,,27,00,000,*7C
+$GPGSV,3,2,12,19,00,000,,07,00,000,,04,00,000,,24,00,000,*76
+$GPGSV,3,3,12,16,00,000,,28,00,000,,26,00,000,,29,00,000,*78
+$GPRMC,000116.031,V,,,,,,,291006,,*27
+$GPGGA,000117.035,,,,,0,00,,,M,0.0,M,,0000*57
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,000117.035,V,,,,,,,291006,,*22
+$GPGGA,000118.039,,,,,0,00,,,M,0.0,M,,0000*54
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,000118.039,V,,,,,,,291006,,*21
+$GPGGA,000119.035,,,,,0,00,,,M,0.0,M,,0000*59
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,000119.035,V,,,,,,,291006,,*2C
+$GPGGA,000120.037,,,,,0,00,,,M,0.0,M,,0000*51
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,000120.037,V,,,,,,,291006,,*24
+
+*/
\ No newline at end of file
diff -r 000000000000 -r 75e6a2e50519 GPS.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GPS.h	Thu Dec 15 13:38:51 2011 +0000
@@ -0,0 +1,75 @@
+/* mbed EM-406 GPS Module Library
+ * Copyright (c) 2008-2010, sford
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "mbed.h"
+
+#ifndef MBED_GPS_H
+#define MBED_GPS_H
+
+/**  A GPS interface for reading from a Globalsat EM-406 GPS Module */
+class GPS {
+public:
+
+    /** Create the GPS interface, connected to the specified serial port
+     */    
+    GPS(PinName tx, PinName rx);
+    
+    /** Sample the incoming GPS data, returning whether there is a lock
+     * 
+     * @return 1 if there was a lock when the sample was taken (and therefore .longitude and .latitude are valid), else 0
+     */
+    int sample();
+    
+    /** The longitude (call sample() to set) */
+    float longitude;
+
+    /** The latitude (call sample() to set) */
+    float latitude;
+    
+    /** Create a value for gps lock/unlocked */
+    int lock;
+    
+    /** Altitude of Sensor from Sea Level */
+    float altitude;
+    
+    /** Number of Satillites */
+    int numSat;
+    
+    /** Horizontal Dilution */
+    float horDil;
+    
+    /** Time */
+    float GPStime;
+    
+    /** Date */
+    int GPSdate;     
+    
+private:
+    float trunc(float v);
+    void getline();
+    
+    Serial _gps;
+    char msg[256];
+
+};
+
+#endif
diff -r 000000000000 -r 75e6a2e50519 HMC6352.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HMC6352.lib	Thu Dec 15 13:38:51 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/aberk/code/HMC6352/#83c0cb554099
diff -r 000000000000 -r 75e6a2e50519 MODSERIAL.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MODSERIAL.lib	Thu Dec 15 13:38:51 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/AjK/code/MODSERIAL/#af2af4c61c2f
diff -r 000000000000 -r 75e6a2e50519 TextLCD.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TextLCD.lib	Thu Dec 15 13:38:51 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/benyun/code/TextLCD/#7dd9751172e1
diff -r 000000000000 -r 75e6a2e50519 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Dec 15 13:38:51 2011 +0000
@@ -0,0 +1,788 @@
+#include "mbed.h"
+#include "GPS.h"
+#include "MODSERIAL.h"
+#include "TextLCD.h"
+#include "HMC6352.h"
+#define MESSAGE_BUFFER_SIZE 2048
+#define REVID 0x00    //ASIC Revision Number
+#define OPSTATUS 0x04   //Operation Status
+#define STATUS 0x07     //ASIC Status
+#define START 0x0A      //Constant Readings
+#define PRESSURE 0x1F   //Pressure 3 MSB
+#define PRESSURE_LSB 0x20 //Pressure 16 LSB
+#define TEMP 0x21       //16 bit temp
+
+
+extern "C" void mbed_reset();                   // Allows for software resets
+
+MODSERIAL serialIO(p28,p27);                    // RS-232 to PC (tx, rx)
+GPS gps(p13,p14);                               // RS-232 to GPS (tx, rx)
+TextLCD lcd(p23, p21, p22, p11, p12, p8);       // rs, e, d4-d7
+HMC6352 compass(p9, p10);                       // I2C (sda, scl)
+SPI spi(p5, p6, p7);                            // mosi, miso, sclk
+DigitalOut cs(p25);                             // chip select
+DigitalOut drdy(p26);                           // DRDY pin
+AnalogIn humidity(p17);                         // Humidity Analog from Phidgets
+AnalogIn temperature2(p20);                     // Temperature Analog from Phidgets
+AnalogIn light(p15);                            // Light Analog Sensor
+InterruptIn windSpeed(p18);                     // Anemometer for Wind Speed
+AnalogIn windDirection(p19);                    // Wind Direction
+InterruptIn rainGauge(p16);                     // Rain Gauge Click
+DigitalOut wdtLED(LED4);                        // WatchDog Indicator
+DigitalOut heartBeat(LED1);                     // Heartbeat
+DigitalOut led2(LED2);                          // Test for message process
+char messageBufferIncoming[MESSAGE_BUFFER_SIZE];
+char messageBufferOutgoing[MESSAGE_BUFFER_SIZE];
+LocalFileSystem local("local");
+Timer t;
+int timeCount;
+int state;
+int error;
+int progressBarCount = 0;
+int pressureDirection = 0;
+int rainLevel = 0;                              // Rain Level (3 = heavy rain, 2 = moderate rain, 1 = light rain, 0 = no rain)
+int rainInterval = 780;                         // Start at high count, as soon as the rain gauge clicks once, the level is based on the the rain interval.
+int rainCount = 0;
+int speedCount = 0;
+int lightLevel = 0;                             // light level (3 = sunny, 2 = partly cloudy, 1 = mostly cloudy, 0 = night)
+float lightCount = 0.0;
+float lightValue;
+int lightTimeCount = 1;
+bool GPSlock = 0;
+float prevLatitude = 0.0;
+float prevLongitude = 0.0;
+float prevPressure = 0.0;
+float getHumidity;
+float w_direction = 0.0;
+float wSpeed = 0.0;
+float getTemperature = 0.0;
+float rainAmount = 0.0;
+float temp_in;
+unsigned long pressure_lsb;
+unsigned long pressure_msb;
+unsigned long temp_pressure;
+unsigned long pressure;
+char forecastOutput[14];                        // Forecast Output String
+char outputString[161];                         // Output string for getWeather()
+
+
+// WATCHDOG FUNCTION
+
+class Watchdog {
+public:
+// Load timeout value in watchdog timer and enable
+    void kick(float s) {
+        LPC_WDT->WDCLKSEL = 0x1;                // Set CLK src to PCLK
+        uint32_t clk = SystemCoreClock / 16;    // WD has a fixed /4 prescaler, PCLK default is /4
+        LPC_WDT->WDTC = s * (float)clk;
+        LPC_WDT->WDMOD = 0x3;                   // Enabled and Reset
+        kick();
+    }
+// "kick" or "feed" the dog - reset the watchdog timer
+// by writing this required bit pattern
+    void kick() {
+        LPC_WDT->WDFEED = 0xAA;
+        LPC_WDT->WDFEED = 0x55;
+    }
+};
+
+Watchdog wdt;
+
+const float tbl_windvane[16][2] = {
+    {0.0, 33000}, {22.5, 6570}, {45.0, 8200}, {67.5, 891},
+    {90.0, 1000}, {112.5, 688}, {135.0, 2200}, {157.5, 1410},
+    {180.0, 3900}, {202.5, 3140}, {225.0, 16000}, {247.5, 14120},
+    {270.0, 120000}, {292.5, 42120}, {315.0, 64900}, {337.5, 21880}
+};
+
+char read_register(char register_name) {
+    register_name <<=2;
+    register_name &= 0xFC;
+    cs=0; //Select SPI device
+    spi.write(register_name); //Send register location
+    char register_value=spi.write(0x00);
+    cs=1;
+    return register_value;
+}
+
+
+void write_register(char register_name, char register_value) {
+    register_name <<= 2;
+    register_name |= 0x02; //le estamos diciendo que escriba
+    cs=0; //Select SPI device
+    spi.write(register_name); //Send register location
+    spi.write(register_value); //Send value to record into register
+    cs=1;
+}
+
+float read_register16(char register_name) {
+    register_name <<= 2;
+    register_name &= 0xFC; //Read command
+    cs=0; //Select SPI Device
+    spi.write(register_name); //Write byte to device
+    int in_byte1 = spi.write(0x00);
+    int in_byte2 = spi.write(0x00);
+    cs=1;
+    float in_word= (in_byte1<<=8) | (in_byte2);
+    return(in_word);
+}
+
+void w_rain() {
+    rainCount++;
+    if (rainInterval < 129) {
+        rainLevel = 3;  // heavy rain
+    } else if ((rainInterval >= 130) && (rainInterval < 390)) {
+        rainLevel = 2;  // moderate rain
+    } else if ((rainInterval >= 391) && (rainInterval < 780)) {
+        rainLevel = 1;  // light rain
+    } else {
+        rainLevel = 0;  // no rain
+    }
+    rainInterval = 0;
+}
+
+void w_speed() {
+    speedCount++;
+}
+
+float wdirection() {
+    int i;
+    float v;
+
+    v = windDirection * 3.3f; // V
+    v = v / ((3.3f - v) / 10000.0f); // ohm
+    for (i = 0; i < 16; i ++) {
+        if (v > tbl_windvane[i][1] * 0.9 && v < tbl_windvane[i][1] * 1.1) {
+            return tbl_windvane[i][0];
+        }
+    }
+    return 0;
+}
+
+
+void messageReceive(MODSERIAL_IRQ_INFO *q) {
+    MODSERIAL *sys = q->serial;
+    sys->move(messageBufferIncoming, MESSAGE_BUFFER_SIZE);
+
+
+
+// Routines for Received Commands
+
+    //Testing Routines
+    if (!strncmp(messageBufferIncoming, "LED2:1", sizeof("LED2:1")-1)) led2 = 1;                 // For testing
+    else if (!strncmp(messageBufferIncoming, "LED2:0", sizeof("LED2:0")-1)) led2 = 0;            // For testing
+    else if (!strncmp(messageBufferIncoming, "LED2:2", sizeof("LED2:2")-1)) led2 = !led2;        // For testing
+
+    // Reset mBed microcontroller
+    else if (!strncmp(messageBufferIncoming, "reset", sizeof("reset")-1)) mbed_reset();          // Force Reset of mBed microcontroller
+
+    // Set State of mbed microcontroller
+    else if (!strncmp(messageBufferIncoming, "setState(Active)", sizeof("setState(Active)")-1)) {
+        state = 1;                                                                               // Set State of Program
+        serialIO.printf("State set to: Active\r\n");
+    } else if (!strncmp(messageBufferIncoming, "setState(Paused)", sizeof("setState(Paused)")-1)) {
+        state = 0;                                                                               // Set State of Program
+        serialIO.printf("State set to: Paused\r\n");
+    }
+
+    // Status of mbed microcontroller
+    else if (!strncmp(messageBufferIncoming, "getStatus()", sizeof("getStatus()")-1)) {
+        if (state == 0) serialIO.printf("Paused\r\n");
+        if (state == 1) serialIO.printf("Active\r\n");
+        // Extra Messages
+    }
+
+    // Error Messages
+    else if (!strncmp(messageBufferIncoming, "getErrorMsg()", sizeof("getErrorMsg()")-1)) {
+        if (error == 0) serialIO.printf("No Errors\r\n");
+        // Extra Messages
+    }
+
+    // GPS Location
+    else if (!strncmp(messageBufferIncoming, "getLocation()", sizeof("getLocation()")-1)) {
+        // Get Location
+        if (state == 1) {
+            if ((gps.lock)&&(GPSlock)) {
+                serialIO.printf("Location = %.3f, %.3f\r\n", gps.latitude, gps.longitude);
+            } else {
+                serialIO.printf("Location = Not Locked\r\n");
+            }
+        } else {
+            serialIO.printf("Information is currently unavailable, please try again later\r\n");
+        }
+    }
+
+    // GPS Altitude
+    else if (!strncmp(messageBufferIncoming, "getAltitude()", sizeof("getAltitude()")-1)) {
+        // Get Altitude
+        if (state == 1) {
+            if ((gps.lock)&&(GPSlock)) {
+                serialIO.printf("Altitude = %.3f meters (MSL)\r\n", gps.altitude);
+            } else {
+                serialIO.printf("Altitude = Not Locked\r\n");
+            }
+        } else {
+            serialIO.printf("Information is currently unavailable, please try again later\r\n");
+        }
+    }
+
+    // GPS Date
+    else if (!strncmp(messageBufferIncoming, "getGPSDate()", sizeof("getGPSDate()")-1)) {
+        // Get Date
+        if (state == 1) {
+            if ((gps.lock)&&(GPSlock)) {
+                serialIO.printf("Date = %f\r\n", gps.GPSdate);
+            } else {
+                serialIO.printf("Date = Not Locked\r\n");
+            }
+        } else {
+            serialIO.printf("Information is currently unavailable, please try again later\r\n");
+        }
+    }
+
+    // GPS Time
+    else if (!strncmp(messageBufferIncoming, "getGPSTime()", sizeof("getGPSTime()")-1)) {
+        // Get Time
+        if (state == 1) {
+            if ((gps.lock)&&(GPSlock)) {
+                serialIO.printf("Time = %.3f\r\n", gps.GPStime);
+            } else {
+                serialIO.printf("Time = Not Locked\r\n");
+            }
+        } else {
+            serialIO.printf("Information is currently unavailable, please try again later\r\n");
+        }
+    }
+
+    // GPS Lock
+    else if (!strncmp(messageBufferIncoming, "getGPSLock()", sizeof("getGPSLock()")-1)) {
+        // Get Lock
+        if (state == 1) {
+            if ((gps.lock)&&(GPSlock)) {
+                serialIO.printf("Locked\r\n");
+            } else {
+                serialIO.printf("Not Locked\r\n");
+            }
+        } else {
+            serialIO.printf("Information is currently unavailable, please try again later\r\n");
+        }
+    }
+
+    // GPS Direction
+    else if (!strncmp(messageBufferIncoming, "getDirection()", sizeof("getDirection()")-1)) {
+        // Get Direction
+        if (state == 1) {
+            serialIO.printf("Direction = %.2f degrees\r\n", (compass.sample() / 10.0));
+        } else {
+            serialIO.printf("Information is currently unavailable, please try again later\r\n");
+        }
+    }
+
+    // Temperature
+    else if (!strncmp(messageBufferIncoming, "getTemperature()", sizeof("getTemperature()")-1)) {
+        if (state == 1) {
+            // Get Temperature
+            drdy = 1;
+            wait(0.1);
+            temp_in = read_register16(TEMP);
+            wait(0.1);
+            drdy = 0;
+            wait(0.1);
+            temp_in = (temp_in*3.3)/5;  // Calibration offset
+            temp_in = ((temp_in*9) / 100) + 32;     // Convert to fahrenheit
+            serialIO.printf("Temperature = %.2f degrees F\r\n", temp_in);
+        } else {
+            serialIO.printf("Information is currently unavailable, please try again later\r\n");
+        }
+    }
+
+    // Humidity
+    else if (!strncmp(messageBufferIncoming, "getHumidity()", sizeof("getHumidity()")-1)) {
+        if (state == 1) {
+            // Get Humidity
+            getHumidity = humidity;
+            getHumidity = getHumidity*38.12f;
+            serialIO.printf("Humidity = %.2f%%\r\n", getHumidity);
+        } else {
+            serialIO.printf("Information is currently unavailable, please try again later\r\n");
+        }
+    }
+
+    // Pressure
+    else if (!strncmp(messageBufferIncoming, "getPressure()", sizeof("getPressure()")-1)) {
+        // Get Pressure
+        if (state == 1) {
+            drdy = 1;
+            wait(0.1);
+            pressure_msb = read_register(PRESSURE);
+            pressure_msb &= 0x07;
+            pressure_lsb = read_register16(PRESSURE_LSB);
+            wait(0.1);
+            drdy = 0;
+            wait(0.1);
+            pressure = ((pressure_msb<<16)| pressure_lsb);
+            if (pressure != prevPressure) {
+                if (prevPressure < pressure - 2000) {
+                    pressureDirection = 1;                      // Pressure is increasing
+                    prevPressure = pressure;
+                    pressure /= 4;      // Convert to pascals
+                    pressure /= 3376.85f;  // Convert from pascals to inches of mercury (60 deg F)
+                    serialIO.printf("Pressure = %.2u, increasing\r\n", pressure);
+                } else if (prevPressure > pressure + 2000) {
+                    pressureDirection = -1;                     // Pressure is decreasing
+                    prevPressure = pressure;
+                    pressure /= 4;      // Convert to pascals
+                    pressure /= 3376.85f;  // Convert from pascals to inches of mercury (60 deg F)
+                    serialIO.printf("Pressure = %.2u, decreasing\r\n", pressure);
+                } else {
+                    pressureDirection = 0;                 // Pressure is relatively unchanged
+                    pressure /= 4;      // Convert to pascals
+                    pressure /= 3376.85f;  // Convert from pascals to inches of mercury (60 deg F)
+                    serialIO.printf("Pressure = %.2u, no change\r\n", pressure);
+                }
+            }
+        } else {
+            serialIO.printf("Information is currently unavailable, please try again later\r\n");
+        }
+    }
+
+    // Light
+    else if (!strncmp(messageBufferIncoming, "getLight()", sizeof("getLight()")-1)) {
+        if (state == 1) {
+            // Get Light
+            serialIO.printf("Light = %.2f\r\n", lightValue);
+        } else {
+            serialIO.printf("Information is currently unavailable, please try again later\r\n");
+        }
+    }
+
+    // Light Level
+    else if (!strncmp(messageBufferIncoming, "getLightLevel()", sizeof("getLightLevel()")-1)) {
+        // Get Light Level
+        if (state == 1) {
+            switch (lightLevel) {
+                case 0:
+                    serialIO.printf("It is Dark Outside.\r\n");
+                    break;
+                case 1:
+                    serialIO.printf("It is Mostly Cloudy.\r\n");
+                    break;
+                case 2:
+                    serialIO.printf("It is Partly Cloudy.\r\n");
+                    break;
+                case 3:
+                    serialIO.printf("It is Mostly Sunny.\r\n");
+                    break;
+                default:
+                    serialIO.printf("Unknown.\r\n");
+            }
+        } else {
+            serialIO.printf("Information is currently unavailable, please try again later\r\n");
+        }
+    }
+
+    // Wind Direction
+    else if (!strncmp(messageBufferIncoming, "getWindDirection()", sizeof("getWindDirection()")-1)) {
+        // Get Wind Direction
+        if (state == 1) {
+            w_direction = wdirection();
+            w_direction = w_direction + (compass.sample() / 10.0);  // Offset that the unit is no aligned by using compass
+            if (w_direction > 360) w_direction = w_direction - 360;
+            // Convert to cardinal direction
+            if (w_direction < 22.5) serialIO.printf("Wind Direction = N\r\n");
+            else if ((w_direction >= 22.5) && (w_direction < 67.5)) serialIO.printf("Wind Direction = NE\r\n");
+            else if ((w_direction >= 67.5) && (w_direction < 112.5)) serialIO.printf("Wind Direction = E\r\n");
+            else if ((w_direction >= 112.5) && (w_direction < 157.5)) serialIO.printf("Wind Direction = SE\r\n");
+            else if ((w_direction >= 157.5) && (w_direction < 202.5)) serialIO.printf("Wind Direction = S\r\n");
+            else if ((w_direction >= 202.5) && (w_direction < 247.5)) serialIO.printf("Wind Direction = SW\r\n");
+            else if ((w_direction >= 247.5) && (w_direction < 292.5)) serialIO.printf("Wind Direction = W\r\n");
+            else if ((w_direction >= 292.5) && (w_direction < 337.5)) serialIO.printf("Wind Direction = NW\r\n");
+            else serialIO.printf("Wind Direction = N\r\n");
+
+        } else {
+            serialIO.printf("Information is currently unavailable, please try again later\r\n");
+        }
+    }
+
+    // Wind Speed
+    else if (!strncmp(messageBufferIncoming, "getWindSpeed()", sizeof("getWindSpeed()")-1)) {
+        // Get Wind Speed
+        if (state == 1) {
+            serialIO.printf("Wind Speed = %.2f mph\r\n", (wSpeed));
+        } else {
+            serialIO.printf("Information is currently unavailable, please try again later\r\n");
+        }
+    }
+
+    // Wind
+    else if (!strncmp(messageBufferIncoming, "getWind()", sizeof("getWind()")-1)) {
+        // Get Wind Direction
+        if (state == 1) {
+            if (wSpeed < 1) {
+                serialIO.printf("There is no wind.\r\n");
+            } else if ((wSpeed >= 1) && (wSpeed < 5)) {
+                serialIO.printf("There are only calm winds.\r\n");
+            } else {
+                w_direction = wdirection();
+                w_direction = w_direction + (compass.sample() / 10.0);  // Offset that the unit is no aligned by using compass
+                if (w_direction > 360) w_direction = w_direction - 360;
+                // Convert to cardinal direction
+                if (w_direction < 22.5) serialIO.printf("Wind traveling N at %.2f mph\r\n", wSpeed);
+                else if ((w_direction >= 22.5) && (w_direction < 67.5)) serialIO.printf("Wind traveling NE at %.2f mph\r\n", wSpeed);
+                else if ((w_direction >= 67.5) && (w_direction < 112.5)) serialIO.printf("Wind traveling E at %.2f mph\r\n", wSpeed);
+                else if ((w_direction >= 112.5) && (w_direction < 157.5)) serialIO.printf("Wind traveling SE at %.2f mph\r\n", wSpeed);
+                else if ((w_direction >= 157.5) && (w_direction < 202.5)) serialIO.printf("Wind traveling S at %.2f mph\r\n", wSpeed);
+                else if ((w_direction >= 202.5) && (w_direction < 247.5)) serialIO.printf("Wind traveling SW at %.2f mph\r\n", wSpeed);
+                else if ((w_direction >= 247.5) && (w_direction < 292.5)) serialIO.printf("Wind traveling W at %.2f mph\r\n", wSpeed);
+                else if ((w_direction >= 292.5) && (w_direction < 337.5)) serialIO.printf("Wind traveling NW at %.2f mph\r\n", wSpeed);
+                else serialIO.printf("Wind traveling N at %.2f mph\r\n", wSpeed);
+            }
+        } else {
+            serialIO.printf("Information is currently unavailable, please try again later\r\n");
+        }
+    }
+
+    // Rain Amount
+    else if (!strncmp(messageBufferIncoming, "getRainAmount()", sizeof("getRainAmount()")-1)) {
+        // Get Rain Amount
+        if (state == 1) {
+            rainAmount = rainCount * 0.011f;
+            serialIO.printf("Rain Amount = %f inches today\r\n", (rainAmount));
+        } else {
+            serialIO.printf("Information is currently unavailable, please try again later\r\n");
+        }
+    }
+
+    // Current Weather Command
+    else if (!strncmp(messageBufferIncoming, "getWeather()", sizeof("getWeather()")-1)) {
+        // Message Sample: Current Condition is (forecast) at (temperature) degrees (wind condition). Pressure is (pressure) and humidity is (humidity). Observed at (location).
+        if (state == 1) {
+            //Predict conditions based on data collected from rain gauge and light sensor.
+            if (rainLevel == 3) {
+                if (temp_in >= 37.0) {                              // Heavy Rain
+                    strcpy(forecastOutput, "heavy rain at ");
+                } else if ((temp_in < 37.0) && (temp_in > 32.0)) {  // Heavy Mix
+                    strcpy(forecastOutput, "heavy rain/snow at ");
+                } else if (temp_in <= 32.0) {                       // Heavy Snow
+                    strcpy(forecastOutput, "heavy snow at ");
+                }
+            } else if (rainLevel == 2) {
+                if (temp_in >= 37.0) {                              // Moderate Rain
+                    strcpy(forecastOutput, "rain showers at ");
+                } else if ((temp_in < 37.0) && (temp_in > 32.0)) {  // Moderate Mix
+                    strcpy(forecastOutput, "rain/snow showers at ");
+                } else if (temp_in <= 32.0) {                       // Moderate Snow
+                    strcpy(forecastOutput, "snow showers at ");
+                }
+            } else if (rainLevel == 1) {
+                if (temp_in >= 37.0) {                              // Light Rain
+                    strcpy(forecastOutput, "light rain at ");
+                } else if ((temp_in < 37.0) && (temp_in > 32.0)) {  // Light Mix
+                    strcpy(forecastOutput, "light rain/snow at ");
+                } else if (temp_in <= 32.0) {                       // Light Snow
+                    strcpy(forecastOutput, "snow flurries at ");
+                }
+            } else if (rainLevel == 0) {                            // No Precipitation
+                if (lightLevel == 0) {                              // Dark Skies (Nighttime)
+                    strcpy(forecastOutput, "night skies at ");
+                } else if (lightLevel == 1) {                       // Mostly Cloudly
+                    strcpy(forecastOutput, "mostly cloudy at ");
+                } else if (lightLevel == 2) {                       // Partly Cloudy
+                    strcpy(forecastOutput, "partly cloudy at ");
+                } else {                                            // Mostly Sunny
+                    strcpy(forecastOutput, "mostly sunny at ");
+                }
+            }
+
+
+            // Temperature
+            drdy = 1;
+            wait(0.1);
+            temp_in = read_register16(TEMP);
+            wait(0.1);
+            drdy = 0;
+            wait(0.1);
+            temp_in = (temp_in*3.3)/5;  // Calibration offset
+            temp_in = ((temp_in*9) / 100) + 32;     // Convert to fahrenheit
+
+            // Pressure
+            drdy = 1;
+            wait(0.1);
+            pressure_msb = read_register(PRESSURE);
+            pressure_msb &= 0x07;
+            pressure_lsb = read_register16(PRESSURE_LSB);
+            wait(0.1);
+            drdy = 0;
+            wait(0.1);
+            pressure = ((pressure_msb<<16)| pressure_lsb);
+            pressure /= 4;
+            pressure /=3376.85f;
+
+            // Humidity
+            getHumidity = humidity;
+            getHumidity = getHumidity*38.12f;
+
+            // Determine Wind Condition
+
+            if (wSpeed < 1) {                                      // No Wind
+                serialIO.printf("Current Condition is %s%d degrees. Pressure is %.2u and humidity is %.2f. Observed at %.3f, %.3f\r\n", forecastOutput, (int)temp_in, pressure, getHumidity, gps.latitude, gps.longitude);
+            } else if ((wSpeed >= 1) && (wSpeed < 5)) {              // Calm Winds
+                serialIO.printf("Current Condition is %s%d degrees with calm winds. Pressure is %.2u and humidity is %.2f. Observed at %.3f, %.3f\r\n", forecastOutput, (int)temp_in, pressure, getHumidity, gps.latitude, gps.longitude);
+            } else {
+                if (w_direction < 22.5) serialIO.printf("Current Condition is %s%d degrees with wind traveling N at %d mph. Pressure is %.2u and humidity is %.2f. Observed at %.3f, %.3f\r\n", forecastOutput, (int)temp_in, (int)wSpeed, pressure, getHumidity, gps.latitude, gps.longitude);
+                else if ((w_direction >= 22.5) && (w_direction < 67.5)) serialIO.printf("Current Condition is %s%d degrees with wind traveling NE at %d mph. Pressure is %.2u and humidity is %.2f. Observed at %.3f, %.3f\r\n", forecastOutput, (int)temp_in, (int)wSpeed, pressure, getHumidity, gps.latitude, gps.longitude);
+                else if ((w_direction >= 67.5) && (w_direction < 112.5)) serialIO.printf("Current Condition is %s%d degrees with wind traveling E at %d mph. Pressure is %.2u and humidity is %.2f. Observed at %.3f, %.3f\r\n", forecastOutput, (int)temp_in, (int)wSpeed, pressure, getHumidity, gps.latitude, gps.longitude);
+                else if ((w_direction >= 112.5) && (w_direction < 157.5)) serialIO.printf("Current Condition is %s%d degrees with wind traveling SE at %d mph. Pressure is %.2u and humidity is %.2f. Observed at %.3f, %.3f\r\n", forecastOutput, (int)temp_in, (int)wSpeed, pressure, getHumidity, gps.latitude, gps.longitude);
+                else if ((w_direction >= 157.5) && (w_direction < 202.5)) serialIO.printf("Current Condition is %s%d degrees with wind traveling S at %d mph. Pressure is %.2u and humidity is %.2f. Observed at %.3f, %.3f\r\n", forecastOutput, (int)temp_in, (int)wSpeed, pressure, getHumidity, gps.latitude, gps.longitude);
+                else if ((w_direction >= 202.5) && (w_direction < 247.5)) serialIO.printf("Current Condition is %s%d degrees with wind traveling SW at %d mph. Pressure is %.2u and humidity is %.2f. Observed at %.3f, %.3f\r\n", forecastOutput, (int)temp_in, (int)wSpeed, pressure, getHumidity, gps.latitude, gps.longitude);
+                else if ((w_direction >= 247.5) && (w_direction < 292.5)) serialIO.printf("Current Condition is %s%d degrees with wind traveling W at %d mph. Pressure is %.2u and humidity is %.2f. Observed at %.3f, %.3f\r\n", forecastOutput, (int)temp_in, (int)wSpeed, pressure, getHumidity, gps.latitude, gps.longitude);
+                else if ((w_direction >= 292.5) && (w_direction < 337.5)) serialIO.printf("Current Condition is %s%d degrees with wind traveling NW at %d mph. Pressure is %.2u and humidity is %.2f. Observed at %.3f, %.3f\r\n", forecastOutput, (int)temp_in, (int)wSpeed, pressure, getHumidity, gps.latitude, gps.longitude);
+                else serialIO.printf("Current Condition is %s%d degrees with wind traveling N at %d mph. Pressure is %.2u and humidity is %.2f. Observed at %.3f, %.3f\r\n", forecastOutput, (int)temp_in, (int)wSpeed, pressure, getHumidity, gps.latitude, gps.longitude);
+            }
+
+        } else {
+            serialIO.printf("Information is currently unavailable, please try again later\r\n");
+        }
+    }
+
+    // Easter Eggs
+
+    // Hi
+    else if (!strncmp(messageBufferIncoming, "Hi", sizeof("Hi")-1)) {
+        serialIO.printf("Hello foolish person.\r\n");
+    }
+    // Do a barrel roll.
+    else if (!strncmp(messageBufferIncoming, "Do a barrel roll.", sizeof("Do a barrel roll.")-1)) {
+        serialIO.printf("Why don't you do a barrel roll?\r\n");
+    }
+    // Who created you?
+    else if (!strncmp(messageBufferIncoming, "Who created you?", sizeof("Who created you?")-1)) {
+        serialIO.printf("I was created by George P. Burdell.\r\n");
+    }
+    // Who are you?
+    else if (!strncmp(messageBufferIncoming, "Who are you?", sizeof("Who are you?")-1)) {
+        serialIO.printf("I am the Van Leer Weather Monitoring Station. I am truely a one-of-a-kind piece of technology.\r\n");
+    }
+    // Ping
+    else if (!strncmp(messageBufferIncoming, "Ping", sizeof("Ping")-1)) {
+        serialIO.printf("I am not a submarine.\r\n");
+    }
+    // Find Chuck Norris
+    else if (!strncmp(messageBufferIncoming, "Find Chuck Norris.", sizeof("Find Chuck Norris.")-1)) {
+        serialIO.printf("I am sorry but I cannot find Chuck Norris because I know that Chuck Norris cannot be found. Chuck Norris finds you.\r\n");
+    }
+    // Tell Me A Joke.
+    else if (!strncmp(messageBufferIncoming, "Tell me a joke.", sizeof("Tell me a joke.")-1)) {
+        serialIO.printf("Humans.\r\n");
+    }
+    // I need help !
+    else if (!strncmp(messageBufferIncoming, "I need help!.", sizeof("I need help!")-1)) {
+        serialIO.printf("I cannot help you, but you can get help from the one they call Ewout.\r\n");
+    }
+
+    // Invalid Command
+    else serialIO.printf("I am sorry but I do not understand your message. Please try again.\r\n");
+
+    serialIO.rxBufferFlush();                            //Flush the Buffer
+    return;
+}
+
+
+int main() {
+
+    if ((LPC_WDT->WDMOD >> 2) & 1)
+        wdtLED = 1;
+    else wdtLED = 0;
+
+    // 30 second timeout on watchdog timer hardware
+    wdt.kick(10.0);
+
+    serialIO.baud(9600);
+    serialIO.format(8, Serial::None, 1);
+    serialIO.attach(&messageReceive, MODSERIAL::RxAutoDetect);      //Attaches Interrupts
+    serialIO.autoDetectChar('\n');                                  //Set Detection to Line Feed
+
+    lcd.locate(0,0);
+    lcd.printf("Acquiring signal");
+    lcd.locate(0,1);
+    lcd.printf("from satellite..");
+
+    cs=1;
+    spi.frequency(500000);  // the fastest of the sensor
+    spi.format(8, 0);       // Use 8 bits of data
+    wait(0.5);
+
+    write_register(0x06,0x01);
+    wait(0.5);
+
+    write_register(0x03,0x0A);
+    wait(0.5);
+
+
+    wait(1.0);
+
+    //Continuous mode, periodic set/reset, 20Hz measurement rate.
+    compass.setOpMode(HMC6352_CONTINUOUS, 1, 20);
+
+    windSpeed.rise(&w_speed);
+    rainGauge.rise(&w_rain);
+
+    t.start();      // Heartbeat sensor time
+    state = 1;      // Sets state to active
+
+    serialIO.printf("systemReady\r\n");     // Send System Ready Message
+
+
+    while (1) {
+
+
+        timeCount = t.read();
+
+        if (timeCount > 0) {
+            if (state == 1) {
+                // Detect a unusual reading from the GPS Antenna. If consecutive readings are not roughly the same, then it should be assumed that the GPS does not have a confident reading and to signal that it does not have a lock.
+                if ((((gps.latitude - prevLatitude > 5.0)||(gps.latitude - prevLatitude < -5.0))&&((gps.longitude - prevLongitude > 5.0)||(gps.longitude - prevLongitude < -5.0)))||(gps.numSat < 2)) {
+                    GPSlock = 0;
+                    //  lcd.cls();
+                    //  lcd.locate(0,0);
+                    //  lcd.printf("GPS NOT LOCKED");
+                } else {
+                    GPSlock = 1;
+                    //  lcd.cls();
+                    //  lcd.locate(0,0);
+                    //  lcd.printf("GPS LOCKED");
+                }
+
+                if (gps.latitude != prevLatitude) prevLatitude = gps.latitude;
+                if (gps.longitude != prevLongitude) prevLongitude = gps.longitude;
+
+                if (gps.sample()&&(gps.lock)&&(GPSlock)) {
+                    lcd.cls();
+                    lcd.locate(0,0);
+                    lcd.printf("LAT: %f", gps.latitude);
+                    lcd.locate(0,1);
+                    lcd.printf("LON: %f", gps.longitude);
+                    progressBarCount = 0;
+                } else {
+                    lcd.cls();
+                    lcd.locate(0,0);
+                    if (progressBarCount > 19) {
+                        progressBarCount = 0;
+                    }
+                    if (progressBarCount < 3) lcd.printf("Acquiring Signal");
+                    else if (progressBarCount < 6) lcd.printf("from satellite  ");
+                    else if (progressBarCount < 8) lcd.printf("Are you inside? ");
+                    else if (progressBarCount < 10) lcd.printf("Any skyscrapers?");
+                    else if (progressBarCount < 13) lcd.printf("Acquiring Signal");
+                    else if (progressBarCount < 16) lcd.printf("from satellite  ");
+                    else if (progressBarCount < 18) lcd.printf("Clouds overhead?");
+                    else lcd.printf("Lost satellite? ");
+                    lcd.locate(0,1);
+                    switch (progressBarCount) {
+                        case 0:
+                            lcd.printf("                ");
+                            break;
+                        case 1:
+                            lcd.printf(">               ");
+                            break;
+                        case 2:
+                            lcd.printf(">>              ");
+                            break;
+                        case 3:
+                            lcd.printf("<>>             ");
+                            break;
+                        case 4:
+                            lcd.printf("<<>>            ");
+                            break;
+                        case 5:
+                            lcd.printf(" <<>>           ");
+                            break;
+                        case 6:
+                            lcd.printf("  <<>>          ");
+                            break;
+                        case 7:
+                            lcd.printf("   <<>>         ");
+                            break;
+                        case 8:
+                            lcd.printf("    <<>>        ");
+                            break;
+                        case 9:
+                            lcd.printf("     <<>>       ");
+                            break;
+                        case 10:
+                            lcd.printf("      <<>>      ");
+                            break;
+                        case 11:
+                            lcd.printf("       <<>>     ");
+                            break;
+                        case 12:
+                            lcd.printf("        <<>>    ");
+                            break;
+                        case 13:
+                            lcd.printf("         <<>>   ");
+                            break;
+                        case 14:
+                            lcd.printf("          <<>>  ");
+                            break;
+                        case 15:
+                            lcd.printf("           <<>> ");
+                            break;
+                        case 16:
+                            lcd.printf("            <<>>");
+                            break;
+                        case 17:
+                            lcd.printf("             <<>");
+                            break;
+                        case 18:
+                            lcd.printf("              <<");
+                            break;
+                        case 19:
+                            lcd.printf("               <");
+                            break;
+                    }
+                    progressBarCount++;
+
+                }
+                // Calculate the Wind Speed
+                wSpeed = speedCount * 1.492f;
+                speedCount = 0;
+
+                // Create a rolling average over 10 minutes to determine light and rain level
+                lightValue = light;
+                if (lightTimeCount < 600) {
+                    lightCount = (((lightCount*lightTimeCount)+lightValue)/(lightTimeCount+1));
+
+                    lightTimeCount++;
+                } else {
+                    lightCount = (((lightCount*599)+lightValue)/600);
+                }
+                if (lightCount >= 0.7) {
+                    lightLevel = 3;
+                } else if ((lightCount >= 0.5) && (lightCount < 0.7)) {
+                    lightLevel = 2;
+                } else if ((lightCount >= 0.3) && (lightCount < 0.5)) {
+                    lightLevel = 1;
+                } else {
+                    lightLevel = 0;
+                }
+
+                // Increase Rain Interval
+                rainInterval++;
+
+            } else {
+                lcd.cls();
+                lcd.locate(0,0);
+                lcd.printf("PAUSED");
+            }
+
+            heartBeat = !heartBeat;
+            t.stop();
+            t.reset();
+            t.start();
+        }
+
+        wait(0.05);
+        wdt.kick();
+    }
+    return 0;
+}
\ No newline at end of file
diff -r 000000000000 -r 75e6a2e50519 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu Dec 15 13:38:51 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/63bcd7ba4912