Weather Station using an mBed microcontroller and a Windows CE Device

Dependencies:   TextLCD mbed HMC6352

Revision:
0:75e6a2e50519
--- /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