Code for a Portable Weather Station built on a PCB.
Dependencies: BMP180 N5110 PowerControl mbed
Diff: main.cpp
- Revision:
- 12:1d4b5465ecc1
- Parent:
- 11:dc05458980b6
- Child:
- 14:054e6faf0ca8
--- a/main.cpp Mon May 04 00:22:20 2015 +0000 +++ b/main.cpp Mon May 04 02:21:24 2015 +0000 @@ -14,9 +14,10 @@ @brief -- Adjusting the unit the pressure is displayed in: millibars(mb), Pascals(Pa) and Atmospheres (atm). @brief -- Displaying a brief splash screen to show changes in the unit display settings. @author Volkan Esendag (SID:200795870) -@date 11 March 2015 (created) / 3 May 2015(last modified) +@date 11 March 2015 (created) / 4 May 2015(last modified) */ + #include "mbed.h" #include "N5110.h" #include "BMP180.h" @@ -45,7 +46,12 @@ //once struct has been declared, define a pointer type with it. typedef const struct RecState RecS; -//RecS object to determine states for logging intervals. Array size 10. +/** +@namespace recInterval +@brief Structed RecS object type that holds information on different logging interval settings for a given state. +@brief Has an array size of 10 to accomodate 10 different logging settings. +*/ + RecS recInterval[10] = { {0,600.0}, //state 0, 10 minutes {1,1200.0}, //state 1, 20 minutes @@ -59,7 +65,12 @@ {9,43200.0} //state 9, 12 hours }; -//Use the same struct again to create another object, this time for reading display intervals. Array size 6. +/** +@namespace dispInterval +@brief Another RecS pointer type object that holds information on device readings update intervals. +@brief Has an array size of 6 to accomodate 6 different display interval settings. +*/ + RecS dispInterval [6] = { {0,1.0}, //state 0, 1 second. Default state. {1,2.0}, //state 1, 2 seconds @@ -69,7 +80,7 @@ {5,0.5}, //state 5, 500 milliseconds }; -/**Struct to set the temperature threshold after which point the device gives off a warning.*/ +/*!<Struct to set the temperature threshold after which point the device gives off a warning.*/ struct TempThreshold { int tempState; float thresTemp; @@ -78,7 +89,13 @@ //define the TempTyp pointer type using the TempThreshold struct. typedef const struct TempThreshold TempTyp; -//using this type create an object which contains an array of threshold states. Array size 5. +/** +@namespace tempThres +@brief Structed TempTyp pointer type object to hold information on threshold temperature settings for the device. +@brief Should the temperature reading exceed a set value, visual and audible feedback is generated. +@brief Has 5 different settings to accomodate 5 threshold temperature settings. +*/ + TempTyp tempThres[5] = { {0,30.0}, //state 0, 30'C {1,40.0}, //state 1, 40'C @@ -87,7 +104,13 @@ {4,70.0} //state 4, 70'C }; -//do the same for minimum temperature display value. +/** +@namespace lowerTemp +@brief Structed TempTyp pointer type object to hold information on lower end temperature settings for the device. +@brief This is instead used for the Temperature Plotter Menu to set a bottom floor for the plot space. +@brief Has 5 different settings to accomodate 5 minimum display temperature settings. +*/ + TempTyp lowerTemp[5] = { {0,-10.0}, //state 0, -10'C {1,-5.0}, //state 1, -5'C @@ -96,17 +119,39 @@ {4,20.0} //state 4, 20'C }; +/** +An array of characters to represent temperature unit settings (C - Degrees Celsius F - Degrees Fahrenheit K - Kelvins R - Degrees Rankine). +*/ + char tempUnit [4] = {'C','F','K','R'}; //character that stores temperature unit type. +/** +An array of characters to represent pressure unit settings (M - millibars P - Pascals A - Atmospheres) +*/ + char pressUnit[3] = {'M','P','A'}; //character that stores pressure units. M - millibars P - Pascals A - atmospheres +/** +An array of characters to represent unit settings (m - metres f - feet y - yards) for altitude. +*/ + char AltUnit[3] = {'m','f','y'}; //character that stores altitude units. m - metres f - feet y - yards +/** +An array of characters to represent the column chart and the dot graph mode of the Temperature Plotter. +*/ + char tempGraphMode [2] = {'c','d'}; //column chart, dot graph +/** +An array of characters to represent the column chart and the dot graph mode of the Pressure Plotter. +*/ char pressGraphMode [2] = {'c','d'}; //column chart, dot graph -//float could work as well, but it is better to use double as pow(double x,double y) may not accept *arrays* with float pointer type! +/** +An array of PNought values to be used to calibrate the device for different weather fronts for altitude compensation. +float could work as well, but it is better to use double as pow(double x,double y) may not accept *arrays* with float pointer type! +*/ double PNought [13] = {983.25,988.25,993.25,998.25,1003.25,1008.25,PNought_DEFAULT,1018.25,1023.25,1028.25,1033.25,1038.25,1043.25}; @@ -203,33 +248,33 @@ void printReadings(); // declare function to print readings here, which is then defined after the main() function. void clearCells(); //declare function to clear all cells should there be a need for it. Even though lcd.clear() also does the job this can be handy in case of failure. -float temp = 0.0; //declare the temp variable for temperature universally so that it can be shared across functions to represent temperature. -float press = 0.0; //do the same for pressure using press. -float altitude = 0.0; //and altitude using, well, altitude :P +float temp = 0.0; /*!< declare the temp variable for temperature universally so that it can be shared across functions to represent temperature. */ +float press = 0.0; /*!< do the same for pressure using press. */ +float altitude = 0.0; /*!< and altitude using, well, altitude :P */ -int i = 0; //represents the column number (horizontal pixel number) of the display. -int j = 0; //represents the row number of the display. +int i = 0; /*!< represents the column number (horizontal pixel number) of the display. */ +int j = 0; /*!< represents the row number of the display. */ -int dispSetting = 0; //set display setting to default. -int recSetting = 3; //set log setting to default. -int tempSetting = 2; //set temperature threshold to default. +int dispSetting = 0; /*!< set display setting to default. */ +int recSetting = 3; /*!< set log setting to default. */ +int tempSetting = 2; /*!< set temperature threshold to default. */ -int tempUnitSetting = 0; //set temperature unit setting to default. -int pressUnitSetting = 0; //set pressure unit setting to default. -int altUnitSetting = 0; //and do the same for altitude. -int tempGraphSetting = 1; //set the default to be dot chart. -int pressGraphSetting = 1; //set the default to be dot chart. -int PNoughtSetting = 6; //set the default PNought to be PNought_DEFAULT. -int subMenuId = 0; //int used to store sub-menu number. For instance pressing the menu button once and then Button One gives Sub-Menu 1. +int tempUnitSetting = 0; /*!< set temperature unit setting to default. */ +int pressUnitSetting = 0; /*!< set pressure unit setting to default. */ +int altUnitSetting = 0; /*!< and do the same for altitude. */ +int tempGraphSetting = 1; /*!< set the default to be dot chart. */ +int pressGraphSetting = 1; /*!< set the default to be dot chart. */ +int PNoughtSetting = 6; /*!< set the default PNought to be PNought_DEFAULT. */ +int subMenuId = 0; /*!< int used to store sub-menu number. For instance pressing the menu button once and then Button One gives Sub-Menu 1. */ -int logCounter = 0; //*int pointer used to store second count for logging. Initialised to 0. -int lowerTempSetting = 2; //set lower temperature display to default. +int logCounter = 0; /*!< int pointer used to store second count for logging. Initialised to 0.*/ +int lowerTempSetting = 2; /*!< set lower temperature display to default.*/ N5110 lcd(p7,p8,p9,p10,p11,p13,p21); //VCC,SCE,RST,DC,MOSI,SCLK,BACKLIGHT ///////////The following pieces of code are to configure real-time clock for the data logger.************* -char rxString[16]; // buffer to store received string. Each character is a byte long - hence the char pointer type. +char rxString[16]; /*!< buffer to store received string. Each character is a byte long - hence the char pointer type. */ int setTimeFlag = 0; /*!< set time flag set in serial ISR */ @@ -249,6 +294,11 @@ set_time(time); } +/** +Interrupt Service Routine performed by Serial Interrupts - by using a serial terminal program such as CoolTerm. +Sets time flag in order to set and overwrite the current time onto the mbed. This only needs to be done once. +*/ + void serialISR() { // when a serial interrupt occurs, read rx string into buffer. Holds 16 characters. gets implies fetching a string from serial port. @@ -275,6 +325,13 @@ LocalFileSystem local("local"); // create local filesystem +/** +Pretty self-explanatory: Using the local file system created, overwrites the mbed's Flash Memory and saves data on it. +@param data - placeholder for temperature data to be overwritten. +@param dataTwo - placeholder for pressure data to be overwritten. +@param dataThree - placeholder for time string to be stored - hence has an array size of 30 and a data type of char. +*/ + void writeDataToFile(float data, float dataTwo, char dataThree[30]) { time_t seconds = time(NULL); // get current time @@ -293,6 +350,11 @@ int buttonOneFlag = 0; /*!< Button One flag set in ISR */ int buttonOneAltFlag = 0; /*!< Button One Alternate flag set in ISR */ +/** +Interrupt Service Routine to toggle buttonOneFlag/buttonOneAltFlag when not in a settings main menu and when in one respectively. +No parameters to be entered by, or values to be returned to, the user. +*/ + void buttonOnePressed() { if(menuButtonFlag > 0) { //if menu button has been pressed and main menu entered @@ -306,6 +368,11 @@ int buttonTwoFlag = 0; /*!< Button Two flag set in ISR */ int buttonTwoAltFlag = 0; /*!< Button Two Alternate flag set in ISR */ +/** +Interrupt Service Routine to toggle buttonTwoFlag/buttonTwoAltFlag. +No parameters to be entered by, or values to be returned to, the user. +*/ + void buttonTwoPressed() { if(menuButtonFlag > 0) { @@ -319,6 +386,11 @@ int buttonThreeFlag = 0; /*!< Button Three flag set in ISR */ int buttonThreeAltFlag = 0; /*!< Button Three Alternate flag set in ISR */ +/** +Interrupt Service Routine to toggle buttonThreeFlag/buttonThreeAltFlag. +No parameters to be entered by, or values to be returned to, the user. +*/ + void buttonThreePressed() { if(menuButtonFlag > 0) { @@ -328,6 +400,11 @@ buttonThreeFlag = !buttonThreeFlag; } +/** +Interrupt Service Routine to increment menuButtonFlag when Menu Button is pressed to navigate to settings menus. +No parameters to be entered by, or values to be returned to, the user. +*/ + void menuButtonPressed() { if(buttonOneAltFlag == 0 && buttonTwoAltFlag == 0 && buttonThreeAltFlag == 0 || buttonOneFlag || buttonTwoFlag){ //if no flag is set and therefore no menu accessed (except buttonOneFlag and buttonTwoFlag which are set in the measurement menu) @@ -373,6 +450,10 @@ logTimerFlag = 1; } +/** +Displays the initial splash screen when the Weather Station is turned on from rest. +*/ + void displayInitSplash() //!display splash screen { lcd.printString("Welcome to",15,1); @@ -382,6 +463,10 @@ lcd.printString("Esendag",20,5); } +/** +Displays the first settings main menu. +*/ + void displayMenuOne(){ //!settings main menu 1! lcd.printString("Settings Menu",0,0); lcd.printString("One",0,1); @@ -391,7 +476,11 @@ lcd.refresh(); } -void displayMenuTwo(){ //!settings main menu 2! +/** +Displays the second settings main menu. +*/ + +void displayMenuTwo(){ lcd.printString("Settings Menu",0,0); lcd.printString("Two",0,1); lcd.printString("Use menuButton",0,2); @@ -400,7 +489,11 @@ lcd.refresh(); } -void displayMenuThree(){ //!settings main menu 3! +/** +Displays the third settings main menu. +*/ + +void displayMenuThree(){ lcd.printString("Settings Menu",0,0); lcd.printString("Three",0,1); lcd.printString("Use menuButton",0,2); @@ -409,6 +502,11 @@ lcd.refresh(); } +/** +Displays the Temperature Unit Display Sub-Menu. In this menu one can determine whether the temperature will be displayed... +...in degrees Celsius(default), degrees Fahrenheit, Kelvins or degrees Rankine. +*/ + void displayTempUnit(){ //!temperature unit display sub-menu lcd.printString("Use Button 2",0,0); lcd.printString("To decrease",0,1); @@ -423,6 +521,11 @@ lcd.refresh(); //needs to refresh to write the string buffers to the display } +/** +Displays the Pressure Unit Display Sub-Menu. In this menu one can determine whether the pressure will be displayed... +...in millibars(default), Pascals or Atmospheres. +*/ + void displayPressUnit(){ //!pressure unit display sub menu lcd.printString("Use Button 1",0,0); lcd.printString("To decrease",0,1); @@ -437,6 +540,11 @@ lcd.refresh(); } +/** +Displays the Log Interval Menu for the Weather Station. In this menu one can determine how often the device will log... +...or more correctly the number of counters it takes for the device to log data on and reset the counter. +*/ + void displayLogMenu(){ //!displays the log interval change sub-menu. lcd.printString("Use Button 1",0,0); lcd.printString("To decrease",0,1); @@ -458,7 +566,12 @@ lcd.refresh(); } -void displayDispMenu(){ //>!displays the display interval change sub-menu. +/** +Displays the Display Interval Sub-Menu. Intervals of a few seconds or 500 ms. +In other words, determines how often the device will update temperature/pressure/altitude readings. +*/ + +void displayDispMenu(){ lcd.printString("Use Button 2",0,0); lcd.printString("To decrease",0,1); lcd.printString("Time Setting;",0,2); @@ -478,6 +591,11 @@ lcd.refresh(); } +/** +Displays the Threshold Temperature Change menu. Above this threshold temperature set here a visual and audible alert will be generated. +This threshold temperature also determines the maximum value for the temperature graph menu. +*/ + void displayThresholdTemp(){ //!displays the threshold temperature change sub-menu. lcd.printString("Use Button 1",0,0); lcd.printString("To decrease",0,1); @@ -492,6 +610,10 @@ lcd.refresh(); } +/** +Displays the Altitude Change Sub-Menu for the Weather Station. Determines whether altitude data will be displayed in metres, feet or yards. +*/ + void displayAltitudeUnit(){ //!displays the altitude unit change sub-menu. lcd.printString("Use Button 1",0,0); lcd.printString("To decrease",0,1); @@ -506,6 +628,12 @@ lcd.refresh(); } +/** +Displays the Temperature Graph Sub-Menu for the Weather Station. This Sub-Menu determines whether the temperature value will be displayed as a... +...column chart or a dot chart (just a mark at where the pressure would be located for a given point in time). +Also displays (and used to change) the lower end value for the temperature graph. +*/ + void displayTempMode(){ //!temperature graph display mode lcd.printString("Graph mode",0,0); lcd.printString("for Temp.",0,1); @@ -521,7 +649,12 @@ lcd.refresh(); } -void displayPressMode(){ //!pressure graph display mode +/** +Displays the Pressure Graph Sub-Menu for the Weather Station. This Sub-Menu determines whether the pressure value will be displayed as a column chart or... +...a dot chart (just a mark at where the pressure would be located for a given point in time) +*/ + +void displayPressMode(){ lcd.printString("Graph mode",0,0); lcd.printString("for Press.",0,1); lcd.printString("c: column ch",0,2); @@ -534,7 +667,12 @@ lcd.refresh(); } -void displayPNoughtMenu(){ //!a menu to alter the PNought value to compensate for calculated altitude given a certain weather front. +/** +Displays the PNought value setting sub-menu. PNought indicates pressure at sea level and changing it allows to compensate for altitude... +...at a certain weather front. +*/ + +void displayPNoughtMenu(){ lcd.printString("Alter P0 val",0,0); lcd.printString("to compensate",0,1); lcd.printString("for altitude",0,2); @@ -542,12 +680,15 @@ lcd.printString("CurrentValue:",0,4); char bufferSt[14]; //buffer to store string - sprintf(bufferSt,"%2f",PNought[PNoughtSetting]); + sprintf(bufferSt,"%.2f",PNought[PNoughtSetting]); //.2f works just as well for doubles as floats as doubles are essentially high-precision floats! lcd.printString(bufferSt,0,5); lcd.refresh(); } +/** +Displays the "measurement title" which is just a collection of shapes to make the measurements menu look nicer... +*/ void displayMeasurementTitle(){ // origin x,y,width,height,type lcd.drawRect(0,0,83,6,0); // transparent, just outline @@ -583,7 +724,14 @@ */ lcd.drawLine(77,0,83,6,1); lcd.drawLine(77,6,83,0,1); -} +} + +/** +Prints current time on the screen whenever the measurements menu is updated. Time is first converted into strings to be held in buffers. +@param hourBuffer +@param dateBuffer +Displays time and date on two different lines. +*/ void printCurrentTime(char hourBuffer[14], char dateBuffer[14]){ @@ -612,7 +760,7 @@ buttonThree.rise(&buttonThreePressed); - serial.attach(&serialISR); // attach serial ISR + serial.attach(&serialISR); // attach serial ISR, which is to be used to set time. char buffer[30]; // buffer used to store time string for logging. char bufferTwo[14]; //buffer used to store time string for hour/minute/second display. @@ -684,7 +832,7 @@ dispTimerFlag = 0; //set flag to 0 and wait for it to be set again measurement = bmp180.readValues(); temp = measurement.temperature; - int tempHeight = (temp/(tempThres[tempSetting].thresTemp + lowerTemp[lowerTempSetting].thresTemp))*40; //Set graph vertical point by dividing current temperature by (threshold temperature plus lower temperature). Which is the height of the sample space. + int tempHeight = (temp/(tempThres[tempSetting].thresTemp + lowerTemp[lowerTempSetting].thresTemp))*40; //Set graph vertical point by dividing current temperature by (threshold temperature plus lower temperature). Which is the height of the plot space. if(tempGraphSetting == 0){ //column chart selected // x0,y0,x1,y1,type 0-white,1-black,2-dotted lcd.drawLine(i,47,i,(47-tempHeight),1); @@ -694,7 +842,7 @@ } i++; if(i > 83){ //if the 84th pixel has been exceeded - i = 18; //set i back to 12. + i = 18; //set i back to 18. lcd.clear(); lcd.printString("Temp Graph",0,0); //string, column #, row # sprintf(tempBuffer,"%.0f",tempThres[tempSetting].thresTemp); @@ -719,7 +867,7 @@ dispTimerFlag = 0; //set flag to 0 and wait for it to be set again measurement = bmp180.readValues(); press = measurement.pressure; //1 atm is 1013.25 mb. 1519.875 mb equals 1.5 atm. - int pressHeight = (press/(1519.875))*40; //Set graph vertical point by dividing current pressure by the sample space height. Then multiply by 40 as it is the number of pixels for the sample space. + int pressHeight = (press/(1519.875))*40; //Set graph vertical point by dividing current pressure by the plot space height. Then multiply by 40 as it is the number of pixels for the plot space. if(pressGraphSetting == 0){ //column chart selected // x0,y0,x1,y1,type 0-white,1-black,2-dotted lcd.drawLine(i,47,i,(47-pressHeight),1); @@ -729,7 +877,7 @@ } i++; if(i > 83){ //if the 84th pixel has been exceeded - i = 18; //set i back to 12. + i = 18; //set i back to 18. lcd.clear(); lcd.printString("Temp Graph",0,0); //string, column #, row # lcd.printString("1.5",0,1); //display max. pressure value (set for atm) for graph. Keep in mind each string is 6 pixels wide and 8 pixels tall. @@ -1160,6 +1308,10 @@ } //close unit setting 2 } +/** +Function to "kill" all cells after looping through i-j coordinates. Used as a back-up to lcd.clear() should that fail. +Void type, so it returns no values. +*/ void clearCells() { //loop through cells, and clear them @@ -1169,4 +1321,4 @@ } } lcd.refresh(); //must refresh to write buffer to display -} \ No newline at end of file +}