Weather Station using an mBed microcontroller and a Windows CE Device

Dependencies:   TextLCD mbed HMC6352

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "GPS.h"
00003 #include "MODSERIAL.h"
00004 #include "TextLCD.h"
00005 #include "HMC6352.h"
00006 #define MESSAGE_BUFFER_SIZE 2048
00007 #define REVID 0x00    //ASIC Revision Number
00008 #define OPSTATUS 0x04   //Operation Status
00009 #define STATUS 0x07     //ASIC Status
00010 #define START 0x0A      //Constant Readings
00011 #define PRESSURE 0x1F   //Pressure 3 MSB
00012 #define PRESSURE_LSB 0x20 //Pressure 16 LSB
00013 #define TEMP 0x21       //16 bit temp
00014 
00015 
00016 extern "C" void mbed_reset();                   // Allows for software resets
00017 
00018 MODSERIAL serialIO(p28,p27);                    // RS-232 to PC (tx, rx)
00019 GPS gps(p13,p14);                               // RS-232 to GPS (tx, rx)
00020 TextLCD lcd(p23, p21, p22, p11, p12, p8);       // rs, e, d4-d7
00021 HMC6352 compass(p9, p10);                       // I2C (sda, scl)
00022 SPI spi(p5, p6, p7);                            // mosi, miso, sclk
00023 DigitalOut cs(p25);                             // chip select
00024 DigitalOut drdy(p26);                           // DRDY pin
00025 AnalogIn humidity(p17);                         // Humidity Analog from Phidgets
00026 AnalogIn temperature2(p20);                     // Temperature Analog from Phidgets
00027 AnalogIn light(p15);                            // Light Analog Sensor
00028 InterruptIn windSpeed(p18);                     // Anemometer for Wind Speed
00029 AnalogIn windDirection(p19);                    // Wind Direction
00030 InterruptIn rainGauge(p16);                     // Rain Gauge Click
00031 DigitalOut wdtLED(LED4);                        // WatchDog Indicator
00032 DigitalOut heartBeat(LED1);                     // Heartbeat
00033 DigitalOut led2(LED2);                          // Test for message process
00034 char messageBufferIncoming[MESSAGE_BUFFER_SIZE];
00035 char messageBufferOutgoing[MESSAGE_BUFFER_SIZE];
00036 LocalFileSystem local("local");
00037 Timer t;
00038 int timeCount;
00039 int state;
00040 int error;
00041 int progressBarCount = 0;
00042 int pressureDirection = 0;
00043 int rainLevel = 0;                              // Rain Level (3 = heavy rain, 2 = moderate rain, 1 = light rain, 0 = no rain)
00044 int rainInterval = 780;                         // Start at high count, as soon as the rain gauge clicks once, the level is based on the the rain interval.
00045 int rainCount = 0;
00046 int speedCount = 0;
00047 int lightLevel = 0;                             // light level (3 = sunny, 2 = partly cloudy, 1 = mostly cloudy, 0 = night)
00048 float lightCount = 0.0;
00049 float lightValue;
00050 int lightTimeCount = 1;
00051 bool GPSlock = 0;
00052 float prevLatitude = 0.0;
00053 float prevLongitude = 0.0;
00054 float prevPressure = 0.0;
00055 float getHumidity;
00056 float w_direction = 0.0;
00057 float wSpeed = 0.0;
00058 float getTemperature = 0.0;
00059 float rainAmount = 0.0;
00060 float temp_in;
00061 unsigned long pressure_lsb;
00062 unsigned long pressure_msb;
00063 unsigned long temp_pressure;
00064 unsigned long pressure;
00065 char forecastOutput[14];                        // Forecast Output String
00066 char outputString[161];                         // Output string for getWeather()
00067 
00068 
00069 // WATCHDOG FUNCTION
00070 
00071 class Watchdog {
00072 public:
00073 // Load timeout value in watchdog timer and enable
00074     void kick(float s) {
00075         LPC_WDT->WDCLKSEL = 0x1;                // Set CLK src to PCLK
00076         uint32_t clk = SystemCoreClock / 16;    // WD has a fixed /4 prescaler, PCLK default is /4
00077         LPC_WDT->WDTC = s * (float)clk;
00078         LPC_WDT->WDMOD = 0x3;                   // Enabled and Reset
00079         kick();
00080     }
00081 // "kick" or "feed" the dog - reset the watchdog timer
00082 // by writing this required bit pattern
00083     void kick() {
00084         LPC_WDT->WDFEED = 0xAA;
00085         LPC_WDT->WDFEED = 0x55;
00086     }
00087 };
00088 
00089 Watchdog wdt;
00090 
00091 const float tbl_windvane[16][2] = {
00092     {0.0, 33000}, {22.5, 6570}, {45.0, 8200}, {67.5, 891},
00093     {90.0, 1000}, {112.5, 688}, {135.0, 2200}, {157.5, 1410},
00094     {180.0, 3900}, {202.5, 3140}, {225.0, 16000}, {247.5, 14120},
00095     {270.0, 120000}, {292.5, 42120}, {315.0, 64900}, {337.5, 21880}
00096 };
00097 
00098 char read_register(char register_name) {
00099     register_name <<=2;
00100     register_name &= 0xFC;
00101     cs=0; //Select SPI device
00102     spi.write(register_name); //Send register location
00103     char register_value=spi.write(0x00);
00104     cs=1;
00105     return register_value;
00106 }
00107 
00108 
00109 void write_register(char register_name, char register_value) {
00110     register_name <<= 2;
00111     register_name |= 0x02; //le estamos diciendo que escriba
00112     cs=0; //Select SPI device
00113     spi.write(register_name); //Send register location
00114     spi.write(register_value); //Send value to record into register
00115     cs=1;
00116 }
00117 
00118 float read_register16(char register_name) {
00119     register_name <<= 2;
00120     register_name &= 0xFC; //Read command
00121     cs=0; //Select SPI Device
00122     spi.write(register_name); //Write byte to device
00123     int in_byte1 = spi.write(0x00);
00124     int in_byte2 = spi.write(0x00);
00125     cs=1;
00126     float in_word= (in_byte1<<=8) | (in_byte2);
00127     return(in_word);
00128 }
00129 
00130 void w_rain() {
00131     rainCount++;
00132     if (rainInterval < 129) {
00133         rainLevel = 3;  // heavy rain
00134     } else if ((rainInterval >= 130) && (rainInterval < 390)) {
00135         rainLevel = 2;  // moderate rain
00136     } else if ((rainInterval >= 391) && (rainInterval < 780)) {
00137         rainLevel = 1;  // light rain
00138     } else {
00139         rainLevel = 0;  // no rain
00140     }
00141     rainInterval = 0;
00142 }
00143 
00144 void w_speed() {
00145     speedCount++;
00146 }
00147 
00148 float wdirection() {
00149     int i;
00150     float v;
00151 
00152     v = windDirection * 3.3f; // V
00153     v = v / ((3.3f - v) / 10000.0f); // ohm
00154     for (i = 0; i < 16; i ++) {
00155         if (v > tbl_windvane[i][1] * 0.9 && v < tbl_windvane[i][1] * 1.1) {
00156             return tbl_windvane[i][0];
00157         }
00158     }
00159     return 0;
00160 }
00161 
00162 
00163 void messageReceive(MODSERIAL_IRQ_INFO *q) {
00164     MODSERIAL *sys = q->serial;
00165     sys->move(messageBufferIncoming, MESSAGE_BUFFER_SIZE);
00166 
00167 
00168 
00169 // Routines for Received Commands
00170 
00171     //Testing Routines
00172     if (!strncmp(messageBufferIncoming, "LED2:1", sizeof("LED2:1")-1)) led2 = 1;                 // For testing
00173     else if (!strncmp(messageBufferIncoming, "LED2:0", sizeof("LED2:0")-1)) led2 = 0;            // For testing
00174     else if (!strncmp(messageBufferIncoming, "LED2:2", sizeof("LED2:2")-1)) led2 = !led2;        // For testing
00175 
00176     // Reset mBed microcontroller
00177     else if (!strncmp(messageBufferIncoming, "reset", sizeof("reset")-1)) mbed_reset();          // Force Reset of mBed microcontroller
00178 
00179     // Set State of mbed microcontroller
00180     else if (!strncmp(messageBufferIncoming, "setState(Active)", sizeof("setState(Active)")-1)) {
00181         state = 1;                                                                               // Set State of Program
00182         serialIO.printf("State set to: Active\r\n");
00183     } else if (!strncmp(messageBufferIncoming, "setState(Paused)", sizeof("setState(Paused)")-1)) {
00184         state = 0;                                                                               // Set State of Program
00185         serialIO.printf("State set to: Paused\r\n");
00186     }
00187 
00188     // Status of mbed microcontroller
00189     else if (!strncmp(messageBufferIncoming, "getStatus()", sizeof("getStatus()")-1)) {
00190         if (state == 0) serialIO.printf("Paused\r\n");
00191         if (state == 1) serialIO.printf("Active\r\n");
00192         // Extra Messages
00193     }
00194 
00195     // Error Messages
00196     else if (!strncmp(messageBufferIncoming, "getErrorMsg()", sizeof("getErrorMsg()")-1)) {
00197         if (error == 0) serialIO.printf("No Errors\r\n");
00198         // Extra Messages
00199     }
00200 
00201     // GPS Location
00202     else if (!strncmp(messageBufferIncoming, "getLocation()", sizeof("getLocation()")-1)) {
00203         // Get Location
00204         if (state == 1) {
00205             if ((gps.lock)&&(GPSlock)) {
00206                 serialIO.printf("Location = %.3f, %.3f\r\n", gps.latitude, gps.longitude);
00207             } else {
00208                 serialIO.printf("Location = Not Locked\r\n");
00209             }
00210         } else {
00211             serialIO.printf("Information is currently unavailable, please try again later\r\n");
00212         }
00213     }
00214 
00215     // GPS Altitude
00216     else if (!strncmp(messageBufferIncoming, "getAltitude()", sizeof("getAltitude()")-1)) {
00217         // Get Altitude
00218         if (state == 1) {
00219             if ((gps.lock)&&(GPSlock)) {
00220                 serialIO.printf("Altitude = %.3f meters (MSL)\r\n", gps.altitude);
00221             } else {
00222                 serialIO.printf("Altitude = Not Locked\r\n");
00223             }
00224         } else {
00225             serialIO.printf("Information is currently unavailable, please try again later\r\n");
00226         }
00227     }
00228 
00229     // GPS Date
00230     else if (!strncmp(messageBufferIncoming, "getGPSDate()", sizeof("getGPSDate()")-1)) {
00231         // Get Date
00232         if (state == 1) {
00233             if ((gps.lock)&&(GPSlock)) {
00234                 serialIO.printf("Date = %f\r\n", gps.GPSdate);
00235             } else {
00236                 serialIO.printf("Date = Not Locked\r\n");
00237             }
00238         } else {
00239             serialIO.printf("Information is currently unavailable, please try again later\r\n");
00240         }
00241     }
00242 
00243     // GPS Time
00244     else if (!strncmp(messageBufferIncoming, "getGPSTime()", sizeof("getGPSTime()")-1)) {
00245         // Get Time
00246         if (state == 1) {
00247             if ((gps.lock)&&(GPSlock)) {
00248                 serialIO.printf("Time = %.3f\r\n", gps.GPStime);
00249             } else {
00250                 serialIO.printf("Time = Not Locked\r\n");
00251             }
00252         } else {
00253             serialIO.printf("Information is currently unavailable, please try again later\r\n");
00254         }
00255     }
00256 
00257     // GPS Lock
00258     else if (!strncmp(messageBufferIncoming, "getGPSLock()", sizeof("getGPSLock()")-1)) {
00259         // Get Lock
00260         if (state == 1) {
00261             if ((gps.lock)&&(GPSlock)) {
00262                 serialIO.printf("Locked\r\n");
00263             } else {
00264                 serialIO.printf("Not Locked\r\n");
00265             }
00266         } else {
00267             serialIO.printf("Information is currently unavailable, please try again later\r\n");
00268         }
00269     }
00270 
00271     // GPS Direction
00272     else if (!strncmp(messageBufferIncoming, "getDirection()", sizeof("getDirection()")-1)) {
00273         // Get Direction
00274         if (state == 1) {
00275             serialIO.printf("Direction = %.2f degrees\r\n", (compass.sample() / 10.0));
00276         } else {
00277             serialIO.printf("Information is currently unavailable, please try again later\r\n");
00278         }
00279     }
00280 
00281     // Temperature
00282     else if (!strncmp(messageBufferIncoming, "getTemperature()", sizeof("getTemperature()")-1)) {
00283         if (state == 1) {
00284             // Get Temperature
00285             drdy = 1;
00286             wait(0.1);
00287             temp_in = read_register16(TEMP);
00288             wait(0.1);
00289             drdy = 0;
00290             wait(0.1);
00291             temp_in = (temp_in*3.3)/5;  // Calibration offset
00292             temp_in = ((temp_in*9) / 100) + 32;     // Convert to fahrenheit
00293             serialIO.printf("Temperature = %.2f degrees F\r\n", temp_in);
00294         } else {
00295             serialIO.printf("Information is currently unavailable, please try again later\r\n");
00296         }
00297     }
00298 
00299     // Humidity
00300     else if (!strncmp(messageBufferIncoming, "getHumidity()", sizeof("getHumidity()")-1)) {
00301         if (state == 1) {
00302             // Get Humidity
00303             getHumidity = humidity;
00304             getHumidity = getHumidity*38.12f;
00305             serialIO.printf("Humidity = %.2f%%\r\n", getHumidity);
00306         } else {
00307             serialIO.printf("Information is currently unavailable, please try again later\r\n");
00308         }
00309     }
00310 
00311     // Pressure
00312     else if (!strncmp(messageBufferIncoming, "getPressure()", sizeof("getPressure()")-1)) {
00313         // Get Pressure
00314         if (state == 1) {
00315             drdy = 1;
00316             wait(0.1);
00317             pressure_msb = read_register(PRESSURE);
00318             pressure_msb &= 0x07;
00319             pressure_lsb = read_register16(PRESSURE_LSB);
00320             wait(0.1);
00321             drdy = 0;
00322             wait(0.1);
00323             pressure = ((pressure_msb<<16)| pressure_lsb);
00324             if (pressure != prevPressure) {
00325                 if (prevPressure < pressure - 2000) {
00326                     pressureDirection = 1;                      // Pressure is increasing
00327                     prevPressure = pressure;
00328                     pressure /= 4;      // Convert to pascals
00329                     pressure /= 3376.85f;  // Convert from pascals to inches of mercury (60 deg F)
00330                     serialIO.printf("Pressure = %.2u, increasing\r\n", pressure);
00331                 } else if (prevPressure > pressure + 2000) {
00332                     pressureDirection = -1;                     // Pressure is decreasing
00333                     prevPressure = pressure;
00334                     pressure /= 4;      // Convert to pascals
00335                     pressure /= 3376.85f;  // Convert from pascals to inches of mercury (60 deg F)
00336                     serialIO.printf("Pressure = %.2u, decreasing\r\n", pressure);
00337                 } else {
00338                     pressureDirection = 0;                 // Pressure is relatively unchanged
00339                     pressure /= 4;      // Convert to pascals
00340                     pressure /= 3376.85f;  // Convert from pascals to inches of mercury (60 deg F)
00341                     serialIO.printf("Pressure = %.2u, no change\r\n", pressure);
00342                 }
00343             }
00344         } else {
00345             serialIO.printf("Information is currently unavailable, please try again later\r\n");
00346         }
00347     }
00348 
00349     // Light
00350     else if (!strncmp(messageBufferIncoming, "getLight()", sizeof("getLight()")-1)) {
00351         if (state == 1) {
00352             // Get Light
00353             serialIO.printf("Light = %.2f\r\n", lightValue);
00354         } else {
00355             serialIO.printf("Information is currently unavailable, please try again later\r\n");
00356         }
00357     }
00358 
00359     // Light Level
00360     else if (!strncmp(messageBufferIncoming, "getLightLevel()", sizeof("getLightLevel()")-1)) {
00361         // Get Light Level
00362         if (state == 1) {
00363             switch (lightLevel) {
00364                 case 0:
00365                     serialIO.printf("It is Dark Outside.\r\n");
00366                     break;
00367                 case 1:
00368                     serialIO.printf("It is Mostly Cloudy.\r\n");
00369                     break;
00370                 case 2:
00371                     serialIO.printf("It is Partly Cloudy.\r\n");
00372                     break;
00373                 case 3:
00374                     serialIO.printf("It is Mostly Sunny.\r\n");
00375                     break;
00376                 default:
00377                     serialIO.printf("Unknown.\r\n");
00378             }
00379         } else {
00380             serialIO.printf("Information is currently unavailable, please try again later\r\n");
00381         }
00382     }
00383 
00384     // Wind Direction
00385     else if (!strncmp(messageBufferIncoming, "getWindDirection()", sizeof("getWindDirection()")-1)) {
00386         // Get Wind Direction
00387         if (state == 1) {
00388             w_direction = wdirection();
00389             w_direction = w_direction + (compass.sample() / 10.0);  // Offset that the unit is no aligned by using compass
00390             if (w_direction > 360) w_direction = w_direction - 360;
00391             // Convert to cardinal direction
00392             if (w_direction < 22.5) serialIO.printf("Wind Direction = N\r\n");
00393             else if ((w_direction >= 22.5) && (w_direction < 67.5)) serialIO.printf("Wind Direction = NE\r\n");
00394             else if ((w_direction >= 67.5) && (w_direction < 112.5)) serialIO.printf("Wind Direction = E\r\n");
00395             else if ((w_direction >= 112.5) && (w_direction < 157.5)) serialIO.printf("Wind Direction = SE\r\n");
00396             else if ((w_direction >= 157.5) && (w_direction < 202.5)) serialIO.printf("Wind Direction = S\r\n");
00397             else if ((w_direction >= 202.5) && (w_direction < 247.5)) serialIO.printf("Wind Direction = SW\r\n");
00398             else if ((w_direction >= 247.5) && (w_direction < 292.5)) serialIO.printf("Wind Direction = W\r\n");
00399             else if ((w_direction >= 292.5) && (w_direction < 337.5)) serialIO.printf("Wind Direction = NW\r\n");
00400             else serialIO.printf("Wind Direction = N\r\n");
00401 
00402         } else {
00403             serialIO.printf("Information is currently unavailable, please try again later\r\n");
00404         }
00405     }
00406 
00407     // Wind Speed
00408     else if (!strncmp(messageBufferIncoming, "getWindSpeed()", sizeof("getWindSpeed()")-1)) {
00409         // Get Wind Speed
00410         if (state == 1) {
00411             serialIO.printf("Wind Speed = %.2f mph\r\n", (wSpeed));
00412         } else {
00413             serialIO.printf("Information is currently unavailable, please try again later\r\n");
00414         }
00415     }
00416 
00417     // Wind
00418     else if (!strncmp(messageBufferIncoming, "getWind()", sizeof("getWind()")-1)) {
00419         // Get Wind Direction
00420         if (state == 1) {
00421             if (wSpeed < 1) {
00422                 serialIO.printf("There is no wind.\r\n");
00423             } else if ((wSpeed >= 1) && (wSpeed < 5)) {
00424                 serialIO.printf("There are only calm winds.\r\n");
00425             } else {
00426                 w_direction = wdirection();
00427                 w_direction = w_direction + (compass.sample() / 10.0);  // Offset that the unit is no aligned by using compass
00428                 if (w_direction > 360) w_direction = w_direction - 360;
00429                 // Convert to cardinal direction
00430                 if (w_direction < 22.5) serialIO.printf("Wind traveling N at %.2f mph\r\n", wSpeed);
00431                 else if ((w_direction >= 22.5) && (w_direction < 67.5)) serialIO.printf("Wind traveling NE at %.2f mph\r\n", wSpeed);
00432                 else if ((w_direction >= 67.5) && (w_direction < 112.5)) serialIO.printf("Wind traveling E at %.2f mph\r\n", wSpeed);
00433                 else if ((w_direction >= 112.5) && (w_direction < 157.5)) serialIO.printf("Wind traveling SE at %.2f mph\r\n", wSpeed);
00434                 else if ((w_direction >= 157.5) && (w_direction < 202.5)) serialIO.printf("Wind traveling S at %.2f mph\r\n", wSpeed);
00435                 else if ((w_direction >= 202.5) && (w_direction < 247.5)) serialIO.printf("Wind traveling SW at %.2f mph\r\n", wSpeed);
00436                 else if ((w_direction >= 247.5) && (w_direction < 292.5)) serialIO.printf("Wind traveling W at %.2f mph\r\n", wSpeed);
00437                 else if ((w_direction >= 292.5) && (w_direction < 337.5)) serialIO.printf("Wind traveling NW at %.2f mph\r\n", wSpeed);
00438                 else serialIO.printf("Wind traveling N at %.2f mph\r\n", wSpeed);
00439             }
00440         } else {
00441             serialIO.printf("Information is currently unavailable, please try again later\r\n");
00442         }
00443     }
00444 
00445     // Rain Amount
00446     else if (!strncmp(messageBufferIncoming, "getRainAmount()", sizeof("getRainAmount()")-1)) {
00447         // Get Rain Amount
00448         if (state == 1) {
00449             rainAmount = rainCount * 0.011f;
00450             serialIO.printf("Rain Amount = %f inches today\r\n", (rainAmount));
00451         } else {
00452             serialIO.printf("Information is currently unavailable, please try again later\r\n");
00453         }
00454     }
00455 
00456     // Current Weather Command
00457     else if (!strncmp(messageBufferIncoming, "getWeather()", sizeof("getWeather()")-1)) {
00458         // Message Sample: Current Condition is (forecast) at (temperature) degrees (wind condition). Pressure is (pressure) and humidity is (humidity). Observed at (location).
00459         if (state == 1) {
00460             //Predict conditions based on data collected from rain gauge and light sensor.
00461             if (rainLevel == 3) {
00462                 if (temp_in >= 37.0) {                              // Heavy Rain
00463                     strcpy(forecastOutput, "heavy rain at ");
00464                 } else if ((temp_in < 37.0) && (temp_in > 32.0)) {  // Heavy Mix
00465                     strcpy(forecastOutput, "heavy rain/snow at ");
00466                 } else if (temp_in <= 32.0) {                       // Heavy Snow
00467                     strcpy(forecastOutput, "heavy snow at ");
00468                 }
00469             } else if (rainLevel == 2) {
00470                 if (temp_in >= 37.0) {                              // Moderate Rain
00471                     strcpy(forecastOutput, "rain showers at ");
00472                 } else if ((temp_in < 37.0) && (temp_in > 32.0)) {  // Moderate Mix
00473                     strcpy(forecastOutput, "rain/snow showers at ");
00474                 } else if (temp_in <= 32.0) {                       // Moderate Snow
00475                     strcpy(forecastOutput, "snow showers at ");
00476                 }
00477             } else if (rainLevel == 1) {
00478                 if (temp_in >= 37.0) {                              // Light Rain
00479                     strcpy(forecastOutput, "light rain at ");
00480                 } else if ((temp_in < 37.0) && (temp_in > 32.0)) {  // Light Mix
00481                     strcpy(forecastOutput, "light rain/snow at ");
00482                 } else if (temp_in <= 32.0) {                       // Light Snow
00483                     strcpy(forecastOutput, "snow flurries at ");
00484                 }
00485             } else if (rainLevel == 0) {                            // No Precipitation
00486                 if (lightLevel == 0) {                              // Dark Skies (Nighttime)
00487                     strcpy(forecastOutput, "night skies at ");
00488                 } else if (lightLevel == 1) {                       // Mostly Cloudly
00489                     strcpy(forecastOutput, "mostly cloudy at ");
00490                 } else if (lightLevel == 2) {                       // Partly Cloudy
00491                     strcpy(forecastOutput, "partly cloudy at ");
00492                 } else {                                            // Mostly Sunny
00493                     strcpy(forecastOutput, "mostly sunny at ");
00494                 }
00495             }
00496 
00497 
00498             // Temperature
00499             drdy = 1;
00500             wait(0.1);
00501             temp_in = read_register16(TEMP);
00502             wait(0.1);
00503             drdy = 0;
00504             wait(0.1);
00505             temp_in = (temp_in*3.3)/5;  // Calibration offset
00506             temp_in = ((temp_in*9) / 100) + 32;     // Convert to fahrenheit
00507 
00508             // Pressure
00509             drdy = 1;
00510             wait(0.1);
00511             pressure_msb = read_register(PRESSURE);
00512             pressure_msb &= 0x07;
00513             pressure_lsb = read_register16(PRESSURE_LSB);
00514             wait(0.1);
00515             drdy = 0;
00516             wait(0.1);
00517             pressure = ((pressure_msb<<16)| pressure_lsb);
00518             pressure /= 4;
00519             pressure /=3376.85f;
00520 
00521             // Humidity
00522             getHumidity = humidity;
00523             getHumidity = getHumidity*38.12f;
00524 
00525             // Determine Wind Condition
00526 
00527             if (wSpeed < 1) {                                      // No Wind
00528                 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);
00529             } else if ((wSpeed >= 1) && (wSpeed < 5)) {              // Calm Winds
00530                 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);
00531             } else {
00532                 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);
00533                 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);
00534                 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);
00535                 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);
00536                 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);
00537                 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);
00538                 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);
00539                 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);
00540                 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);
00541             }
00542 
00543         } else {
00544             serialIO.printf("Information is currently unavailable, please try again later\r\n");
00545         }
00546     }
00547 
00548     // Easter Eggs
00549 
00550     // Hi
00551     else if (!strncmp(messageBufferIncoming, "Hi", sizeof("Hi")-1)) {
00552         serialIO.printf("Hello foolish person.\r\n");
00553     }
00554     // Do a barrel roll.
00555     else if (!strncmp(messageBufferIncoming, "Do a barrel roll.", sizeof("Do a barrel roll.")-1)) {
00556         serialIO.printf("Why don't you do a barrel roll?\r\n");
00557     }
00558     // Who created you?
00559     else if (!strncmp(messageBufferIncoming, "Who created you?", sizeof("Who created you?")-1)) {
00560         serialIO.printf("I was created by George P. Burdell.\r\n");
00561     }
00562     // Who are you?
00563     else if (!strncmp(messageBufferIncoming, "Who are you?", sizeof("Who are you?")-1)) {
00564         serialIO.printf("I am the Van Leer Weather Monitoring Station. I am truely a one-of-a-kind piece of technology.\r\n");
00565     }
00566     // Ping
00567     else if (!strncmp(messageBufferIncoming, "Ping", sizeof("Ping")-1)) {
00568         serialIO.printf("I am not a submarine.\r\n");
00569     }
00570     // Find Chuck Norris
00571     else if (!strncmp(messageBufferIncoming, "Find Chuck Norris.", sizeof("Find Chuck Norris.")-1)) {
00572         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");
00573     }
00574     // Tell Me A Joke.
00575     else if (!strncmp(messageBufferIncoming, "Tell me a joke.", sizeof("Tell me a joke.")-1)) {
00576         serialIO.printf("Humans.\r\n");
00577     }
00578     // I need help !
00579     else if (!strncmp(messageBufferIncoming, "I need help!.", sizeof("I need help!")-1)) {
00580         serialIO.printf("I cannot help you, but you can get help from the one they call Ewout.\r\n");
00581     }
00582 
00583     // Invalid Command
00584     else serialIO.printf("I am sorry but I do not understand your message. Please try again.\r\n");
00585 
00586     serialIO.rxBufferFlush();                            //Flush the Buffer
00587     return;
00588 }
00589 
00590 
00591 int main() {
00592 
00593     if ((LPC_WDT->WDMOD >> 2) & 1)
00594         wdtLED = 1;
00595     else wdtLED = 0;
00596 
00597     // 30 second timeout on watchdog timer hardware
00598     wdt.kick(10.0);
00599 
00600     serialIO.baud(9600);
00601     serialIO.format(8, Serial::None, 1);
00602     serialIO.attach(&messageReceive, MODSERIAL::RxAutoDetect);      //Attaches Interrupts
00603     serialIO.autoDetectChar('\n');                                  //Set Detection to Line Feed
00604 
00605     lcd.locate(0,0);
00606     lcd.printf("Acquiring signal");
00607     lcd.locate(0,1);
00608     lcd.printf("from satellite..");
00609 
00610     cs=1;
00611     spi.frequency(500000);  // the fastest of the sensor
00612     spi.format(8, 0);       // Use 8 bits of data
00613     wait(0.5);
00614 
00615     write_register(0x06,0x01);
00616     wait(0.5);
00617 
00618     write_register(0x03,0x0A);
00619     wait(0.5);
00620 
00621 
00622     wait(1.0);
00623 
00624     //Continuous mode, periodic set/reset, 20Hz measurement rate.
00625     compass.setOpMode(HMC6352_CONTINUOUS, 1, 20);
00626 
00627     windSpeed.rise(&w_speed);
00628     rainGauge.rise(&w_rain);
00629 
00630     t.start();      // Heartbeat sensor time
00631     state = 1;      // Sets state to active
00632 
00633     serialIO.printf("systemReady\r\n");     // Send System Ready Message
00634 
00635 
00636     while (1) {
00637 
00638 
00639         timeCount = t.read();
00640 
00641         if (timeCount > 0) {
00642             if (state == 1) {
00643                 // 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.
00644                 if ((((gps.latitude - prevLatitude > 5.0)||(gps.latitude - prevLatitude < -5.0))&&((gps.longitude - prevLongitude > 5.0)||(gps.longitude - prevLongitude < -5.0)))||(gps.numSat < 2)) {
00645                     GPSlock = 0;
00646                     //  lcd.cls();
00647                     //  lcd.locate(0,0);
00648                     //  lcd.printf("GPS NOT LOCKED");
00649                 } else {
00650                     GPSlock = 1;
00651                     //  lcd.cls();
00652                     //  lcd.locate(0,0);
00653                     //  lcd.printf("GPS LOCKED");
00654                 }
00655 
00656                 if (gps.latitude != prevLatitude) prevLatitude = gps.latitude;
00657                 if (gps.longitude != prevLongitude) prevLongitude = gps.longitude;
00658 
00659                 if (gps.sample()&&(gps.lock)&&(GPSlock)) {
00660                     lcd.cls();
00661                     lcd.locate(0,0);
00662                     lcd.printf("LAT: %f", gps.latitude);
00663                     lcd.locate(0,1);
00664                     lcd.printf("LON: %f", gps.longitude);
00665                     progressBarCount = 0;
00666                 } else {
00667                     lcd.cls();
00668                     lcd.locate(0,0);
00669                     if (progressBarCount > 19) {
00670                         progressBarCount = 0;
00671                     }
00672                     if (progressBarCount < 3) lcd.printf("Acquiring Signal");
00673                     else if (progressBarCount < 6) lcd.printf("from satellite  ");
00674                     else if (progressBarCount < 8) lcd.printf("Are you inside? ");
00675                     else if (progressBarCount < 10) lcd.printf("Any skyscrapers?");
00676                     else if (progressBarCount < 13) lcd.printf("Acquiring Signal");
00677                     else if (progressBarCount < 16) lcd.printf("from satellite  ");
00678                     else if (progressBarCount < 18) lcd.printf("Clouds overhead?");
00679                     else lcd.printf("Lost satellite? ");
00680                     lcd.locate(0,1);
00681                     switch (progressBarCount) {
00682                         case 0:
00683                             lcd.printf("                ");
00684                             break;
00685                         case 1:
00686                             lcd.printf(">               ");
00687                             break;
00688                         case 2:
00689                             lcd.printf(">>              ");
00690                             break;
00691                         case 3:
00692                             lcd.printf("<>>             ");
00693                             break;
00694                         case 4:
00695                             lcd.printf("<<>>            ");
00696                             break;
00697                         case 5:
00698                             lcd.printf(" <<>>           ");
00699                             break;
00700                         case 6:
00701                             lcd.printf("  <<>>          ");
00702                             break;
00703                         case 7:
00704                             lcd.printf("   <<>>         ");
00705                             break;
00706                         case 8:
00707                             lcd.printf("    <<>>        ");
00708                             break;
00709                         case 9:
00710                             lcd.printf("     <<>>       ");
00711                             break;
00712                         case 10:
00713                             lcd.printf("      <<>>      ");
00714                             break;
00715                         case 11:
00716                             lcd.printf("       <<>>     ");
00717                             break;
00718                         case 12:
00719                             lcd.printf("        <<>>    ");
00720                             break;
00721                         case 13:
00722                             lcd.printf("         <<>>   ");
00723                             break;
00724                         case 14:
00725                             lcd.printf("          <<>>  ");
00726                             break;
00727                         case 15:
00728                             lcd.printf("           <<>> ");
00729                             break;
00730                         case 16:
00731                             lcd.printf("            <<>>");
00732                             break;
00733                         case 17:
00734                             lcd.printf("             <<>");
00735                             break;
00736                         case 18:
00737                             lcd.printf("              <<");
00738                             break;
00739                         case 19:
00740                             lcd.printf("               <");
00741                             break;
00742                     }
00743                     progressBarCount++;
00744 
00745                 }
00746                 // Calculate the Wind Speed
00747                 wSpeed = speedCount * 1.492f;
00748                 speedCount = 0;
00749 
00750                 // Create a rolling average over 10 minutes to determine light and rain level
00751                 lightValue = light;
00752                 if (lightTimeCount < 600) {
00753                     lightCount = (((lightCount*lightTimeCount)+lightValue)/(lightTimeCount+1));
00754 
00755                     lightTimeCount++;
00756                 } else {
00757                     lightCount = (((lightCount*599)+lightValue)/600);
00758                 }
00759                 if (lightCount >= 0.7) {
00760                     lightLevel = 3;
00761                 } else if ((lightCount >= 0.5) && (lightCount < 0.7)) {
00762                     lightLevel = 2;
00763                 } else if ((lightCount >= 0.3) && (lightCount < 0.5)) {
00764                     lightLevel = 1;
00765                 } else {
00766                     lightLevel = 0;
00767                 }
00768 
00769                 // Increase Rain Interval
00770                 rainInterval++;
00771 
00772             } else {
00773                 lcd.cls();
00774                 lcd.locate(0,0);
00775                 lcd.printf("PAUSED");
00776             }
00777 
00778             heartBeat = !heartBeat;
00779             t.stop();
00780             t.reset();
00781             t.start();
00782         }
00783 
00784         wait(0.05);
00785         wdt.kick();
00786     }
00787     return 0;
00788 }