Weather Station using an mBed microcontroller and a Windows CE Device
Dependencies: TextLCD mbed HMC6352
Revision 0:75e6a2e50519, committed 2011-12-15
- Comitter:
- mafischl
- Date:
- Thu Dec 15 13:38:51 2011 +0000
- Commit message:
Changed in this revision
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