Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BMP180 ConfigFile N5110 PowerControl beep mbed
Revision 0:da2b8c7a1ec1, committed 2015-05-11
- Comitter:
- OHstin
- Date:
- Mon May 11 15:25:52 2015 +0000
- Commit message:
- Completed Weather Station
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BMP180.lib Mon May 11 15:25:52 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/spiridion/code/BMP180/#072073c79cfd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BatteryStatusScreen.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,152 @@
+/**
+@file BaterryStatusScreen.h
+
+
+*/
+
+#ifndef BATTERYSTATUSSCREEN_H
+#define BATTERYSTATUSSCREEN_H
+
+#include "ParameterController.h"
+#include "Inputs.h"
+#include "Sensors.h"
+
+/**
+
+@brief Displays the current battery voltage along with it's sentiment on the LCD screen \n
+@brief It consists of a parameter controller\n
+@brief battery voltage is shown in Volts\n
+@author Augustine Kizito K\n
+@date April 2015
+
+*/
+
+
+
+class BatteryStatusScreen : public ParameterController // inherit ParameterController Properties
+{
+
+public:
+ /**
+ This functions manages the execution of the battery status screen
+ @returns
+ -1 - Navigate to previous screen
+ */
+ int start();
+ /**
+ Creates an instance of the battery status screen
+
+ */
+ BatteryStatusScreen()
+ :ParameterController( "Voltage", // Parameter
+ "Volts") // Units
+ {} // initialises parameter controller
+
+private:
+
+ void setVoltageSentiment( float temperature); // get temperature sentiment
+ void voltageUpdate(); // update the voltage
+ float getCurrentVoltage(); // get the current voltage
+ void onBack(); // user pressed the back button
+ void onEnter(); // user pressed the enter button
+
+ bool changeScreen; // tracks if the user pressed a button that changes screen
+ int nextScreen; // tracks whether the user wants to go to
+ //the previous screen or next screen
+ Ticker voltTicker; // create ticker object
+
+
+};
+
+int BatteryStatusScreen::start()
+{
+
+ changeScreen = false;
+
+ float currentVoltage = getCurrentVoltage(); // get current temperature
+
+ backButton.mode(PullDown); // activate pullDown resistor
+ enterButton.mode(PullDown); // activate pullDown resistor
+
+ backButton.rise(this,&BatteryStatusScreen::onBack); // call onBack when the back button is pressed
+
+ debounce.start(); // start the debouncing timer
+
+ voltTicker.attach(this, &BatteryStatusScreen::voltageUpdate, 10); // update parameter every 10 seconds
+
+ // initialise the ParameterController appropriately
+ ParameterController::setValue(currentVoltage);
+ setVoltageSentiment(currentVoltage);
+
+ // Launch the Parameter Controller
+ ParameterController::showInfo();
+
+ while(changeScreen == false) { // shows the screen until the user presses the back button
+ // mbed goes to sleep to save power
+ Sleep();
+ }
+
+ // detach interrupts
+ backButton.rise(NULL);
+ voltTicker.detach();
+
+ return nextScreen;
+}
+
+void BatteryStatusScreen::voltageUpdate()
+{
+
+ float currentVoltage = getCurrentVoltage(); // get current voltage
+ // update the voltage sentiment
+ setVoltageSentiment(currentVoltage);
+
+ // initialise the ParameterController appropriately
+ ParameterController::setValue(currentVoltage);
+ ParameterController::updateInfo();
+
+}
+
+
+void BatteryStatusScreen::setVoltageSentiment(float batteryVoltage)
+{
+ if (batteryVoltage > 7.92) { // battery voltage is greater than 2.6V
+ // battery has three bars
+ ParameterController::setSentiment("Battery Full ");
+
+ } else if ( (batteryVoltage < 7.92 )&& (batteryVoltage > 6.5)) { // battery voltage is between 2.64V and 1.65V
+ // battery has two bars
+ ParameterController::setSentiment("Sufficient ");
+
+ } else if ((batteryVoltage < 6.5) && (batteryVoltage > 6)) { // battery voltage is between 1.65V and 0.66V
+ // battery has one bar
+ ParameterController::setSentiment("Battery Low ");
+ } else { // battery voltage is less than 0.66V
+ // empty battery
+ ParameterController::setSentiment("Change Battery");
+ }
+
+}
+
+float BatteryStatusScreen::getCurrentVoltage()
+{
+ float voltage = getVoltage(); // read voltage
+ return voltage;
+}
+
+void BatteryStatusScreen::onBack()
+{
+ if (debounceSuccess()) {
+ playSound(); // play sound from buzzer
+ nextScreen = -1;
+ changeScreen = true; // user wants to view a different screen
+ debounce.reset(); // reset the timer
+ }
+
+
+}
+
+
+
+
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BrightnessScreen.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,224 @@
+/**
+@file BrightnessScreen.h
+
+
+*/
+#ifndef BRIGHTNESSSCREEN_H
+#define BRIGHTNESSSCREEN_H
+
+#include "SettingController.h"
+#include "Inputs.h"
+
+
+/**
+
+@brief Shows the current brightness setting of the LCD backlight brightness\n
+@brief Consists of a Setting Controller\n
+@brief brightness can be set to 100%, 50%, 25%, or Off\n
+@brief the setting is persistent i.e saved onto onboard flash memory\n
+@author Augustine K Kizito\n
+@date April 2015
+
+*/
+
+
+
+class BrightnessScreen: public SettingController // inherit SettingController class
+{
+private:
+ bool changeScreen; // tracks if the user pressed a button that changes the screen
+ char *brightnessKey; // key to be used for the cfg file
+ char brightnessValue[BUFSIZ]; // buffer to store the brightness value retrieved from cfg file
+ int brightness; // the brightness stored as an int
+
+ void onScrollUp(); // user pressed the scroll up button
+ void onScrollDown(); // user pressed the scroll down button
+ void onEnter(); // user pressed the enter button
+ void onBack(); // user pressed the back button
+ void saveSetting(); // save a selected option as a setting
+ void adjustBrightness(); //adjust brightness according to the stored setting
+
+public:
+ /**
+ This function creates an instance of the brightness screen
+
+ */
+ BrightnessScreen()
+ :SettingController( "Brightness", // Title
+ "100%", // Option 1
+ "50%", // Option 2
+ "25%", // Option 3
+ "Off", // Option 4
+ 4) // Number of Options
+ {};
+ /**
+ This function manages the exectution of the brightness screen
+
+ @returns
+ -1 - navigate to previous screen
+ */
+ int start();
+
+};
+
+
+
+int BrightnessScreen::start()
+{
+
+ enterButton.mode(PullDown); // activate pull down resistor
+ upButton.mode(PullDown); // activate pull down resistor
+ downButton.mode(PullDown); // acivate pull down resistor
+ backButton.mode(PullDown); // activate pull down resistor
+
+ upButton.rise(this,&BrightnessScreen::onScrollUp); // call onScrollUp when the up button is pressed
+ downButton.rise(this,&BrightnessScreen::onScrollDown); // call onScrollDown when the down button is pressed
+ enterButton.rise(this,&BrightnessScreen::onEnter); // call onEnter when the enter button is pressed
+ backButton.rise(this, &BrightnessScreen::onBack);
+
+ brightnessKey = "brightness ";
+
+ // prepare the cfg file to be read
+ cfg.read("/local/bright.cfg");
+
+ // if key aand value exist, retrieve and store
+ if (cfg.getValue(brightnessKey, &brightnessValue[0], sizeof(brightnessValue))) { // if key aand value exist, retrieve and store
+
+ brightness = atoi(brightnessValue); // convert string to integer
+ currentBrightness = brightness;
+ // set the ListController setting appropriateley
+ if (brightness == 100) {
+ SettingController::setCurrentSetting(0);
+ } else if (brightness == 50) {
+ SettingController::setCurrentSetting(1);
+ } else if (brightness == 25) {
+ SettingController::setCurrentSetting(2);
+ } else {
+ SettingController::setCurrentSetting(3);
+ }
+ }
+
+ adjustBrightness(); // adjust brightness apprpriately
+ SettingController::showInfo(); //populate the settingController
+ changeScreen = false; // stay on this screen until further notice
+
+ while(!changeScreen) {
+ // mbed goes to sleep to save power
+ Sleep();
+ }
+
+ // detach all interrupts
+ enterButton.rise(NULL);
+ backButton.rise(NULL);
+
+ return -1; // go to the previous screen
+
+}
+
+void BrightnessScreen::onEnter()
+{
+ if (debounceSuccess()) { // debouncing successful
+ //sound the buzzer
+ playSound();
+ // save the selected option as the new setting
+ saveSetting();
+
+ //change the setting marker on the screen accordingly
+ SettingController::changeSetting();
+
+ //adjust the brigtness accordingly
+ adjustBrightness();
+
+
+ // reset the debounce timer
+ debounce.reset();
+ }
+
+}
+
+void BrightnessScreen::onBack()
+{
+
+ if (debounceSuccess()) { // debouncing successful
+ // sound the buzzer
+ playSound();
+ changeScreen = true; // user wants to change screen
+
+ // reset the debounce timer
+ debounce.reset();
+ }
+
+
+}
+
+void BrightnessScreen::onScrollDown()
+{
+ if (debounceSuccess()) { // debouncing successful
+
+ SettingController::scrollDown(); //scroll Up
+ // reset the timer
+ debounce.reset();
+ }
+
+}
+
+void BrightnessScreen::onScrollUp()
+{
+ if (debounceSuccess()) { // debouncing successful
+
+ SettingController::scrollUp(); //scroll Down
+ // reset the debounce timer
+ debounce.reset();
+ }
+
+}
+
+void BrightnessScreen::saveSetting()
+{
+ // retrieve the current option
+ int currentOption = SettingController::getCurrentOption();
+
+
+
+ if ( currentOption == 0) {
+ cfg.setValue(brightnessKey,"100"); //100%
+ } else if ( currentOption == 1) {
+ cfg.setValue(brightnessKey,"50"); //50%
+ } else if ( currentOption == 2) {
+ cfg.setValue(brightnessKey,"25"); //25%
+ } else if ( currentOption == 3) {
+ cfg.setValue(brightnessKey,"0"); //Off
+ } else {
+ // do nothing
+ }
+
+ // write data to the file
+ cfg.write("/local/bright.cfg");
+
+}
+
+void BrightnessScreen::adjustBrightness()
+{
+
+ // retireve currentSetting
+ int currentSetting = SettingController::getCurrentSetting();
+
+ if ( currentSetting == 0) { // 100%
+ currentBrightness = 100;
+ lcd.setBrightness(1.0);
+ } else if ( currentSetting == 1) { // 50%
+ currentBrightness = 50;
+ lcd.setBrightness(0.5);
+ } else if ( currentSetting == 2) { // 25%
+ currentBrightness = 25;
+ lcd.setBrightness(0.25);
+ } else if ( currentSetting == 3) { // Off
+ currentBrightness = 0;
+ lcd.setBrightness(0);
+ } else {
+ // do nothing
+ }
+
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ConfigFile.lib Mon May 11 15:25:52 2015 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/OHstin/code/ConfigFile/#c966b18d8d67
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CurrentPressureScreen.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,193 @@
+/**
+@file CurrentPressureScreen.h
+
+
+*/
+
+
+#ifndef CURRENTPRESSURESCREEN_H
+#define CURRENTPRESSURESCREEN_H
+
+#include "ParameterController.h"
+#include "Inputs.h"
+#include "Sensors.h"
+
+/**
+@brief Displays the current pressure along with it's sentiment on the LCD screen\n
+@brief It consists of a parameter controller\n
+@brief pressure is shown in mbars by default but can be toggled to kPscl\n
+@brief when the enter button is pressed \n
+@author Augustine Kizito K \n
+@date April 2015 \n
+
+*/
+
+
+class CurrentPressureScreen : public ParameterController // inherit ParameterController Properties
+{
+private:
+ void setPressureSentiment( float pressure); // get pressure sentiment
+ void pressureUpdate(); // update the pressure
+ float getCurrentPressure(); // get the current temperature
+ void changeUnits(); // change units form mbar to Pa
+ void onBack(); // user pressed the back button
+ void onEnter(); // user pressed the enter button
+
+ bool changeScreen; // tracks if the user pressed a button that changes screen
+ int nextScreen; // tracks whether the user wants to go to
+ //the previous screen or next screen
+ bool mbar; // tracks the current units of pressure
+ Ticker prsTicker; // create ticker object
+
+
+public:
+ /**
+ This function manages the execution of the current pressure screen
+
+ */
+ int start();
+ /**
+ Creates an instance of the Current Pressure Screen
+
+ returns
+ -1 - navigate to previous screen
+ */
+ CurrentPressureScreen()
+ :ParameterController( "Pressure", // Parameter
+ "mbars") // Units
+ {} // initialises parameter controller
+
+};
+
+int CurrentPressureScreen::start()
+{
+
+ changeScreen = false;
+ mbar = true; // units are in millibars
+
+ float currentPressure = getCurrentPressure(); // get current temperature
+
+ backButton.mode(PullDown); // activate pullDown resistor
+ enterButton.mode(PullDown); // activate pullDown resistor
+
+ backButton.rise(this,&CurrentPressureScreen::onBack); // call onBack when the back button is pressed
+ enterButton.rise(this,&CurrentPressureScreen::onEnter); // call onBack when the back button is pressed
+
+ debounce.start(); // start the debouncing timer
+
+ prsTicker.attach(this, &CurrentPressureScreen::pressureUpdate, 10); // update parameter every 30 seconds
+
+ // initialise the ParameterController appropriately
+ ParameterController::setValue(currentPressure);
+ setPressureSentiment(currentPressure);
+
+ // Launch the Parameter Controller
+ ParameterController::showInfo();
+
+ while(!changeScreen) { // shows the menu screen until the user presses the back button
+ // mbed goes to sleep to save power
+ Sleep();
+ }
+
+ // detach interrupts
+ backButton.rise(NULL);
+ enterButton.rise(NULL);
+ prsTicker.detach();
+
+ return nextScreen;
+}
+
+void CurrentPressureScreen::pressureUpdate()
+{
+
+ float currentPressure = getCurrentPressure(); // get current temperature
+ // update the pressure sentiment
+ setPressureSentiment(currentPressure);
+
+ if (!mbar) { // units are currently is Pascals
+ //convert to Pascal
+ currentPressure = (currentPressure*9/5)+32;
+ }
+
+ // initialise the ParameterController appropriately
+ ParameterController::setValue(currentPressure);
+ ParameterController::updateInfo();
+
+}
+
+
+void CurrentPressureScreen::setPressureSentiment(float pressure)
+{
+
+ if (pressure >= 1000 ) { // Sunny if temperatuure is 1000mb or higher
+ ParameterController::setSentiment("Sunny :-) ");
+ } else if ( pressure < 1000 && pressure >= 980 ) {
+ ParameterController::setSentiment("Sunny & Clouds"); // Sunny with clouds
+ } else if ( pressure < 980 && pressure >= 960 ) {
+ ParameterController::setSentiment("Cloudy "); // Cloudy
+ } else if ( pressure < 960 && pressure >= 940 ) {
+ ParameterController::setSentiment("Rainy "); // Rainy
+ } else if ( pressure < 940 && pressure >= 920 ) {
+ ParameterController::setSentiment("Stormy! "); // Stormy
+ } else {
+ ParameterController::setSentiment("Thunderstorm!!"); // Thunderstorm
+ }
+
+}
+
+float CurrentPressureScreen::getCurrentPressure()
+{
+ float pressure = getPressure(); // read temperature from BMP180 sensor
+ return pressure;
+}
+
+void CurrentPressureScreen::onBack()
+{
+ if (debounceSuccess()) { // debouncing was successful
+ playSound(); // play sound from buzzer
+ nextScreen = -1;
+ changeScreen = true; // user wants to view a different screen
+ debounce.reset(); // reset the timer
+ }
+
+
+}
+
+void CurrentPressureScreen::onEnter()
+{
+ if (debounceSuccess()) { // debouncing was successful
+ //sound the buzzer
+ playSound();
+ changeUnits(); // change the units
+ debounce.reset(); // reset the debounce timer
+ }
+
+}
+
+void CurrentPressureScreen::changeUnits()
+{
+ // toggle the units form Cel to Fahr and back
+ mbar = !mbar;
+
+ float currentPressure = getCurrentPressure(); // get current temperature
+ // update the pressure sentiment
+ setPressureSentiment(currentPressure);
+
+ if (mbar) { // units are in milibars
+ ParameterController::setUnit("mbars");
+ } else { // units are in Pascals
+ ParameterController::setUnit("kPscl");
+ //convert to kilo Pascals
+ currentPressure = currentPressure/10;
+
+ }
+
+ // update the ParameterController appropriately
+ ParameterController::setValue(currentPressure);
+ ParameterController::updateInfo();
+
+}
+
+
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CurrentTemperatureScreen.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,190 @@
+/**
+@file CurrentTemperatureScreen.h
+
+
+
+*/
+#ifndef CURRENTTEMPERATURESCREEN_H
+#define CURRENTTEMPERATURESCREEN_H
+
+#include "ParameterController.h"
+#include "Inputs.h"
+#include "Sensors.h"
+
+/**
+@brief Displays the current temperature along with it's sentiment on the LCD screen\n
+@brief It consists of a parameter controller\n
+@brief temperature is shown in deg cel by default but can be toggled to deg fahr\n
+@brief whent the enter button is pressed\n
+@author Augustine Kizito K\n
+@date April 2015
+*/
+
+
+
+
+class CurrentTemperatureScreen : public ParameterController // inherit ParameterController Properties
+{
+private:
+ void setTemperatureSentiment( float temperature); // get temperature sentiment
+ void temperatureUpdate(); // update the temperature
+ float getCurrentTemperature(); // get the current temperature
+ void changeUnits(); // change units form celsius to fahrenheit
+ void onBack(); // user pressed the back button
+ void onEnter(); // user pressed the enter button
+
+ bool changeScreen; // tracks if the user pressed a button that changes screen
+ int nextScreen; // tracks whether the user wants to go to
+ //the previous screen or next screen
+ bool celsius; // tracks the current units of temperature
+ Ticker tempTicker; // create ticker object
+
+
+public:
+ /**
+ This function manages the execution of the temperature screen
+
+ @ returns
+ -1 - navigate to previous screen
+ */
+ int start();
+ /**
+ This function creates an instance of the current temperature scren
+
+ */
+ CurrentTemperatureScreen()
+ :ParameterController( "Temperature", // Parameter
+ "Deg Cel") // Units
+ {} // initialises parameter controller
+
+};
+
+int CurrentTemperatureScreen::start()
+{
+
+ changeScreen = false;
+ celsius = true; // units are in celsius
+
+ float currentTemperature = getCurrentTemperature(); // get current temperature
+
+ backButton.mode(PullDown); // activate pullDown resistor
+ enterButton.mode(PullDown); // activate pullDown resistor
+
+ backButton.rise(this,&CurrentTemperatureScreen::onBack); // call onBack when the back button is pressed
+ enterButton.rise(this,&CurrentTemperatureScreen::onEnter); // call onBack when the back button is pressed
+
+ debounce.start(); // start the debouncing timer
+
+ tempTicker.attach(this, &CurrentTemperatureScreen::temperatureUpdate, 10); // update parameter every 30 seconds
+
+ // initialise the ParameterController appropriately
+ ParameterController::setValue(currentTemperature);
+ setTemperatureSentiment(currentTemperature);
+
+ // Launch the Parameter Controller
+ ParameterController::showInfo();
+
+ while(changeScreen == false) { // shows the screen until the user presses the back button
+ // mbed goes to sleep to save power
+ Sleep();
+ }
+
+ // detach interrupts
+ backButton.rise(NULL);
+ enterButton.rise(NULL);
+ tempTicker.detach();
+
+ return nextScreen;
+}
+
+void CurrentTemperatureScreen::temperatureUpdate()
+{
+
+ float currentTemperature = getCurrentTemperature(); // get current temperature
+ setTemperatureSentiment(currentTemperature); // update the temperature sentiment
+
+ if (!celsius) { // units are in celsius
+ //convert to fahrenheit
+ currentTemperature = (currentTemperature*9/5)+32;
+ }
+
+ // initialise the ParameterController appropriately
+ ParameterController::setValue(currentTemperature);
+ ParameterController::updateInfo();
+
+}
+
+
+void CurrentTemperatureScreen::setTemperatureSentiment(float temperature)
+{
+
+ if (temperature > 35) { // Blazing if temperature is greature than 35 Deg
+ ParameterController::setSentiment("Blazing ");
+ } else if ( temperature <= 35 && temperature > 25 ) {
+ ParameterController::setSentiment("Hot "); // Hot if temperature is between 35 and 25 Deg Cel
+ } else if ( temperature <= 25 && temperature > 20 ) {
+ ParameterController::setSentiment("Warm "); // Warm if temperature is between 25 and 20 Deg Cel
+ } else if ( temperature <= 20 && temperature > 15 ) {
+ ParameterController::setSentiment("Cool "); // Cool if temperature is between 20 and 15 Deg Cel
+ } else if ( temperature <= 15 && temperature >= 10 ) {
+ ParameterController::setSentiment("Cold "); // Cold if temperature is between 15 and 10 Deg Cel
+ } else {
+ ParameterController::setSentiment("Frigid "); // Frigid if temperature is less than 10
+ }
+
+}
+
+float CurrentTemperatureScreen::getCurrentTemperature()
+{
+ float temperature = getTemperature(); // read temperature from BMP180 sensor
+ return temperature;
+}
+
+void CurrentTemperatureScreen::onBack()
+{
+ if (debounceSuccess()) { // debugging successful
+ playSound(); // play sound from buzzer
+ nextScreen = -1;
+ changeScreen = true; // user wants to view a different screen
+ debounce.reset(); // reset the timer
+ }
+
+
+}
+
+void CurrentTemperatureScreen::onEnter()
+{
+ if (debounceSuccess()) { // debugging successful
+ playSound(); // sound the buzzer
+ changeUnits(); // change the units
+ debounce.reset(); // reset the timer
+ }
+
+}
+
+void CurrentTemperatureScreen::changeUnits()
+{
+ // toggle the units form Cel to Fahr and back
+ celsius = !celsius;
+
+ float currentTemperature = getCurrentTemperature(); // get current temperature
+ setTemperatureSentiment(currentTemperature);
+
+ if (celsius) { // Units are in celsius
+ ParameterController::setUnit("Deg Cel ");
+ } else { // Units are in Fahrenheit
+ ParameterController::setUnit("Deg Fahr");
+ //convert to fahrenheit
+ currentTemperature = (currentTemperature*9/5)+32;
+
+ }
+
+ // update the ParameterController appropriately
+ ParameterController::setValue(currentTemperature);
+ ParameterController::updateInfo();
+
+}
+
+
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/DataController.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,448 @@
+/**
+@file DataController.h
+@brief Manages the display of logged data on onto the LCD
+
+
+*/
+
+#ifndef DATACONTROLLER_H
+#define DATACONTROLLER_H
+
+#include "Outputs.h"
+#include "ConfigFile.h"
+
+/**
+@brief Manages the display of logged data on onto the LCD \n
+@brief consists of three different pages\n
+@brief Page 1 shows date, time and duration of the log\n
+@brief Page 2 shows the maximum, average and minimum values recorded\n
+@brief Page 3 shows a plot of logged data against time\n
+@author Augustine Kizito K\n
+@date April 2015
+
+*/
+
+class DataController
+{
+private:
+ char units[10]; // parameter of data temperature/pressure
+ char time[32]; // the time the log was taken
+ char date[32]; // the date the log was taken
+ char duration[10]; // the duration of the log
+ char average[10]; // average value
+ char maximum[10]; // maximum value
+ char minimum[10]; // minimum value
+ float dataArray[84]; // array that stores retrieved data
+ int dataAmount; // contains the number of retrieved data values
+ int parameter; // tracks whether the data is temperature or pressure
+
+ bool dataPresent; // should know of data is available in file of not
+ int currentPage; // the current page that is displayed -1,0,1,2 or 3
+ bool changePage; // false means go stay on page, true means go to new Page
+
+
+ void showPageOne(); // shows date/time/duration info of data
+ void showPageTwo(); // shows max/min/average info of data
+ void showPageThree(); // shows plot of data
+ void clear(); // clears the LCD screen but status bar remains
+ float calculateAverage(float array[], int size); // returns average
+ float calculateMaximum(float array[], int size); // returns maximum
+ float calculateMinimum(float array[], int size); // return minimum
+ void plot(float array[], int size); // plots the data on screen
+ void initArray(); // intialises the data Array
+ void invertPixels(); // highlights the string in the sixth bank
+
+protected:
+ /**
+ Creates a data controller instance
+
+ @param file - file location of logged data
+ @param pr - parameter of logged data. 1 for temperature, 2 for pressure
+
+ */
+ DataController(char *file, int pr);
+
+ /**
+ Starts the execution of the data controller
+
+ */
+ void begin();
+
+ /**
+ Navigates to the next page
+
+ */
+ void nextPage();
+
+ /**
+ Navigates to the previous page
+
+ */
+ void previousPage();
+
+
+};
+
+
+
+
+
+
+
+
+DataController::DataController( char *file , int pr)
+{
+ // Initialise private data attributes
+ dataPresent = false;
+ currentPage = 0;
+ changePage = false;
+ dataAmount = 0;
+ parameter = pr;
+
+ if (pr) { // if the parameter is temperature
+ char *uts = " Cel"; // units are in celsius
+ strcpy(units,uts);
+ } else { // if parameter is pressure
+ char *uts = "mb"; // units are in millibars
+ strcpy(units,uts);
+ }
+
+
+ // Create Keys along with their respective Value Buffers
+ // Value data for each key is stored in Value Buffer
+
+ // Time Key
+ char *theTimeKey = "timeKey";
+ char theTimeValue[BUFSIZ];
+
+ // Date Key
+ char *theDateKey = "dateKey";
+ char theDateValue[BUFSIZ];
+
+ // Duration Key
+ char *theDurationKey = "durationKey";
+ char theDurationValue[BUFSIZ];
+
+ // Counter Key
+ char *theCounterKey = "counterKey";
+ char theCounterValue[BUFSIZ];
+
+ // Value buffer is to store data points of retreived data
+ char theValue[BUFSIZ];
+
+ // initialise array where data points of retreived data
+ // will be stored
+ void initArray();
+
+ if (cfg.read(file)) { // if the CFG file exists, read it
+
+ // initialise
+ dataPresent = true;
+ int count = 0;
+
+ //retrieve the date
+ if (cfg.getValue(theDateKey, &theDateValue[0], sizeof(theDateValue))) {
+
+ strcpy(date,theDateValue);
+
+ }
+
+ // retrieve the time
+ if (cfg.getValue(theTimeKey, &theTimeValue[0], sizeof(theTimeValue))) {
+
+ strcpy(time,theTimeValue);
+
+ }
+
+ // retrieve the duration
+ if (cfg.getValue(theDurationKey, &theDurationValue[0], sizeof(theDurationValue))) {
+
+ strcpy(duration,theDurationValue);
+
+ }
+
+
+ // retrieve the number of elements stored
+ if (cfg.getValue(theCounterKey, &theCounterValue[0], sizeof(theCounterValue))) {
+
+ count = atoi(theCounterValue); // convert to integer
+
+ }
+
+ // retrieve/parse the available data points depending of the number of elements
+ for ( int i = 0; i < (count+1); i++) {
+
+ // Create a new key
+ char theKey[20] = "key";
+
+ char countString[20]; // create empty string
+
+ sprintf(countString,"%d",i); // convert int to string
+
+ strcat(theKey,countString); //concatentate the strings
+
+ // retreive tha data point and store it in array
+ if (cfg.getValue(theKey, &theValue[0], sizeof(theValue))) {
+
+ dataArray[i] = atof(theValue); // convert to string to float and store in array
+
+ }
+
+ }
+ // update variable with the number of retrieved elements/datapoints
+ dataAmount = count+1;
+
+ // calculate maximum value of retrieved data points
+ float max = calculateMaximum(dataArray,dataAmount);
+ // calculate average value of retreived data points
+ float avg = calculateAverage(dataArray, dataAmount);
+ // calculate maximum value of retieved data points
+ float min = calculateMinimum(dataArray, dataAmount);
+
+ sprintf(maximum,"%0.2f%s",max,units); // converting float to string
+ sprintf(average,"%0.2f%s",avg,units); // converting float to string
+ sprintf(minimum,"%0.2f%s",min,units); // converting float to string
+
+ } else { // there is no file available
+ currentPage = -1;
+ }
+
+}
+
+void DataController::begin()
+{
+
+ while (currentPage != -1) { // the user does not exit
+
+ if ( currentPage == 0) { // show the first page
+
+ showPageOne();
+
+ while(!changePage) { // user does not change the page
+
+ // mbed goes to sleep to save power
+ Sleep();
+ }
+ changePage = false; // reset
+ clear(); // clear the screen
+ }
+
+ if (currentPage == 1) { // show the second page
+
+ showPageTwo();
+ while(!changePage) { // user does not change page
+
+ // mbed goes to sleep to save power
+ Sleep();
+
+ }
+ changePage = false; //reset
+ clear(); // clear the screen
+ }
+
+ if (currentPage == 2) { // show the third page
+
+ showPageThree();
+ while(!changePage) { // user does not change page
+
+ // mbed goes to sleep to save power
+ Sleep();
+
+ }
+
+ changePage = false; //reset
+ clear(); // clear the screen
+
+ }
+
+
+ }
+
+}
+
+void DataController::nextPage()
+{
+ // add the current page
+ currentPage++;
+ changePage = true; // user wants to change page
+
+ // prevents from going to a page that doesnt exist
+ if (currentPage > 2) {
+
+ currentPage = 2; // set to the third page
+ }
+}
+
+void DataController::previousPage()
+{
+ // subtract the current page
+ currentPage--;
+ changePage = true; // user wants to change page
+
+ // prevents from navigating to a page that doesn't exist
+ if (currentPage < -1) {
+
+ currentPage = -1; // leave the data controller
+ }
+
+}
+
+void DataController::clear()
+{
+ // clears the section of the LCD being used
+ for ( int x = 0; x < 84; x++) {
+
+ for ( int y = 8; y < 48; y++) {
+
+ lcd.clearPixel(x,y);
+
+ }
+
+ }
+
+ lcd.refresh();
+
+
+}
+
+void DataController::showPageOne()
+{
+ // data on the first page
+
+ lcd.printString("Date: ",0,2); // Date
+ lcd.printString("Time: ",0,3); // Time
+ lcd.printString("Durtn: ",0,4); // Duration
+ lcd.printString("View Data", 0,5); // View Data
+ lcd.printString(date,35,2); // Date Value
+ lcd.printString(time,35,3); // Time Value
+ lcd.printString(duration,40,4); // Duration Value
+ invertPixels(); // invert Pixels in the 6th bank
+}
+
+void DataController::showPageTwo()
+{
+ // data on the second page
+
+ lcd.printString("Max: ",0,2); // Maximum
+ lcd.printString("Avg: ",0,3); // Average
+ lcd.printString("Min: ",0,4); // Minimum
+ lcd.printString("View Plot", 0,5); // View Plot
+ lcd.printString(maximum,30,2); // Maximum Value
+ lcd.printString(average,30,3); // Average Value
+ lcd.printString(minimum,30,4); // Minimum Value
+ invertPixels(); // invert Pixels in the 6th bank
+}
+
+void DataController::showPageThree()
+{
+ // plot data on the LCD screen
+ plot(dataArray,dataAmount);
+
+}
+
+float DataController::calculateMaximum(float array[], int size)
+{
+ // Scan though Array and determine maximum
+ float max = array[0];
+
+ for (int i = 1; i < size; i++) {
+
+ if ( array[i] > max ) {
+
+ max = array[i];
+
+ }
+ }
+
+ return max;
+
+}
+
+float DataController::calculateAverage(float array[], int size)
+{
+
+ float total = 0;
+ float avg = 0;
+
+ // caculate the total of data points
+ for ( int i = 0; i < size; i++) {
+
+ total = total + array[i];
+
+ }
+
+ // divide total by number of data points to get average
+ avg = total/size;
+
+ return avg;
+
+}
+
+float DataController::calculateMinimum(float array[], int size)
+{
+ float min = array[0];
+
+ // scan through array and determing minimum
+ for (int i = 1; i < size; i++) {
+
+ if ( array[i] < min ) {
+
+ min = array[i];
+
+ }
+ }
+
+ return min;
+
+}
+
+void DataController::plot(float array[], int size)
+{
+ for (int i = 0; i < size; i++) {
+
+ float value = array[i];
+
+ if (parameter) { // parameter is temperature
+ lcd.drawLine(i,(31*((50-value)/50)+16),i,47,1);
+ } else { // parameter is pressure
+ lcd.drawLine(i,(31*((1200-value)/1200)+16),i,47,1);
+ }
+
+ }
+
+}
+
+void DataController::initArray()
+{
+ // initialise dataArray elements to zero
+ for ( int i = 0; i < 84; i++) {
+ dataArray[i] = 0;
+ }
+}
+
+void DataController::invertPixels()
+{
+ int onset = 39; // x coordinate where inversion starts
+ int termination = onset + 9; // bank's length height is 9 pixels
+
+ for ( int m = onset; m < termination; m++) {
+
+ for ( int n = 0; n < 84; n++) {
+
+ if((lcd.getPixel(n,m)) == 0) { // if the pixel is clear
+ lcd.setPixel(n,m); // set the pixel
+ } else {
+ lcd.clearPixel(n,m); // else clear the pixel
+ }
+
+ }
+ }
+
+ lcd.refresh(); // refresh the lcd screen
+
+
+}
+
+
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/DurationScreen.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,157 @@
+/**
+@file DurationScreen.h
+
+*/
+
+#ifndef DURATIONSCREEN_H
+#define DURATIONSCREEN_H
+
+#include "ListController.h"
+#include "Inputs.h"
+
+/**
+@brief Allows the user to select different time lengths over which they want to log data\n
+@brief Consists of a List controller with 4 selectable options:\n
+@brief 5 minutes, 10 minutes, 30 minutes, 1 hour\n
+@author Augustine K Kizito\n
+@date April 2015
+*/
+
+
+class DurationScreen : public ListController // inherit the list Controller properties
+{
+private:
+ bool changeScreen; // tracks if the user pressed a button that changes the screen
+ int nextScreen; // tracks whether the user wants to go to
+ //the previous screen or next screen
+
+ void onScrollUp(); // user pressed the scroll up button
+ void onScrollDown(); // user pressed the scroll down button
+ void onEnter(); // user pressed the enter button
+ void onBack(); // user pressed the back button
+
+public:
+ /**
+ This function creates an instance of the Duration Screen
+
+ */
+ DurationScreen()
+ :ListController( "Duration", // Title
+ "5 minutes", // Option 1
+ "10 minutes", // Option 2
+ "30 minutes", // Option 3
+ "1 hour", // Option 4
+ 4) // Number of Options
+ {};
+ /**
+ Manages the execution of the Duration Screen
+
+ @returns
+
+ -1 - Navigate to previous screen\n
+ 0 - User selected option 1\n
+ 1 - User selected option 2\n
+ 2 - User selected option 3\n
+ 3 - User selected option 4
+
+ */
+ int start();
+
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+int DurationScreen::start()
+{
+
+ // Activate PullDown Resistors
+ enterButton.mode(PullDown);
+ upButton.mode(PullDown);
+ downButton.mode(PullDown);
+ backButton.mode(PullDown);
+
+ upButton.rise(this,&DurationScreen::onScrollUp); // call onScrollUp when the up button is pressed
+ downButton.rise(this,&DurationScreen::onScrollDown); // call onScrollDown when the down button is pressed
+ enterButton.rise(this,&DurationScreen::onEnter); // call onEnter when the enter button is pressed
+ backButton.rise(this,&DurationScreen::onBack); // call onBack when the back button is pressed
+
+ // Launch the List Controller
+ ListController::showInfo();
+ changeScreen = false;
+
+ debounce.start(); // start the debounce timer
+
+ while(!changeScreen) {
+
+ // mbed goes to sleep to save power
+ Sleep();
+ }
+
+ // detach all interrupts
+ upButton.rise(NULL);
+ downButton.rise(NULL);
+ enterButton.rise(NULL);
+ backButton.rise(NULL);
+
+ return nextScreen;
+}
+
+void DurationScreen::onScrollUp()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+
+ ListController::scrollUp(); // scroll up
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void DurationScreen::onScrollDown()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+
+ ListController::scrollDown(); // scroll down
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void DurationScreen::onEnter()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+ // sound the buzzer
+ playSound();
+ nextScreen = ListController::getCurrentOption(); // get the option that user selected
+ changeScreen = true; // user wants to go to a different screen
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void DurationScreen::onBack()
+{
+ if(debounceSuccess()) { // debouncing was successful
+ // sound the buzzer
+ playSound();
+ nextScreen = -1; // go to previous screen
+ changeScreen = true; // user wants to go to a different screen
+ debounce.reset();
+ }
+
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Inputs.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,58 @@
+/**
+@file Inputs.h
+@brief All the necessary inputs for the weather application are stored in this file\n
+@brief Inputs in this case are buttons.\n
+@brief A timer was also implemented that would compensate for multiple interrupts when buttons are pressed\n
+@author Augustine K Kizito\n
+@date April 2015
+*/
+#ifndef INPUTS_H
+#define INPUTS_H
+
+#include "ConfigFile.h"
+
+
+//Button Objects
+InterruptIn upButton(p17); // up Button
+InterruptIn downButton(p18); // down Button
+InterruptIn enterButton(p16); // enter Button
+InterruptIn backButton(p15); // back Button
+
+LocalFileSystem local("local"); // create local file system object
+ConfigFile cfg; // create ConfigFile object
+
+// timer that is used to observe and prevent multiple interrupts
+Timer debounce;
+
+void debounceReset() // resets the debounce timer
+{
+ debounce.reset(); // reset the timer
+
+}
+
+// ticker that resets the debounce every 20 minutes to prevent
+// program from freezing
+Ticker rdb;
+void debounceInit()
+{
+ rdb.attach(&debounceReset,1200.0); // call debounce reset after 20 minutes
+}
+//void debounceReset(); // resets the debounce timer
+//rdb.attach(&debounceReset,1200.0); // call debounce reset after 20 minutes
+
+bool debounceSuccess()// checks if debouncing was successful
+{
+
+ if (debounce.read_ms() > 200) { // check if the debounce timer is more than 200ms
+ return true;
+ }
+
+ else {
+ return false;
+ }
+}
+
+
+
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/IntervalScreen.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,153 @@
+/**
+@file IntervalScreen.h
+
+*/
+
+#ifndef INTERVALSCREEN_H
+#define INTERVALSCREEN_H
+
+#include "ListController.h"
+#include "Inputs.h"
+
+/**
+@brief Allows the user to select different time intervals overwhich they would like to plot\n
+@brief either temperature or pressure against time\n
+@brief Consists of a List controller with 4 selectable options:\n
+@brief 100ms, 500ms, 1 second, 5 seconds
+@author Augustine K Kizito
+@date April 2015
+*/
+
+
+class IntervalScreen : public ListController // inherit the list Controller properties
+{
+private:
+ bool changeScreen; // tracks if the user pressed a button that changes the screen
+ int nextScreen; // tracks whether the user wants to go to
+ //the previous screen or next screen
+
+ void onScrollUp(); // user pressed the scroll up button
+ void onScrollDown(); // user pressed the scroll down button
+ void onEnter(); // user pressed the enter button
+ void onBack(); // user pressed the back button
+
+public:
+ /**
+ Creates an instance of Interval Screen
+
+ */
+ IntervalScreen()
+ :ListController( "Interval", // Title
+ "100ms", // Option 1
+ "500ms", // Option 2
+ "1 second", // Option 3
+ "5 seconds", // Option 4
+ 4) // Number of Options
+ {};
+
+ /**
+ Manages the execution of the Interval Screen
+
+ @returns
+
+ -1 - Navigate to previous screen\n
+ 0 - User selected option 1\n
+ 1 - User selected option 2\n
+ 2 - User selected option 3\n
+ 3 - User selected option 4\n
+
+ */
+ int start();
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+int IntervalScreen::start()
+{
+
+ // Activate PullDown Resistors
+ enterButton.mode(PullDown);
+ upButton.mode(PullDown);
+ downButton.mode(PullDown);
+ backButton.mode(PullDown);
+
+ upButton.rise(this,&IntervalScreen::onScrollUp); // call onScrollUp when the up button is pressed
+ downButton.rise(this,&IntervalScreen::onScrollDown); // call onScrollDown when the down button is pressed
+ enterButton.rise(this,&IntervalScreen::onEnter); // call onEnter when the enter button is pressed
+ backButton.rise(this,&IntervalScreen::onBack); // call onBack when the back button is pressed
+
+ ListController::showInfo(); // launch the List Controller
+ changeScreen = false;
+
+ debounce.start(); // start the debounce timer
+
+ while(!changeScreen) {
+
+ // mbed goes to sleep to save power
+ Sleep();
+ }
+
+ // detach all interrupts
+ upButton.rise(NULL);
+ downButton.rise(NULL);
+ enterButton.rise(NULL);
+ backButton.rise(NULL);
+
+ return nextScreen;
+}
+
+void IntervalScreen::onScrollUp()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+
+ ListController::scrollUp(); // scroll up
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void IntervalScreen::onScrollDown()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+
+ ListController::scrollDown(); // scroll down
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void IntervalScreen::onEnter()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+ // sound the buzzer
+ playSound();
+ nextScreen = ListController::getCurrentOption(); // get the option that user selected
+ changeScreen = true; // user wants to go to a different screen
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void IntervalScreen::onBack()
+{
+ if(debounceSuccess()) {
+ // sound the buzzer
+ playSound();
+ nextScreen = -1; // go to previous screen
+ changeScreen = true; // user wants to go to a different screen
+ debounce.reset(); // reset the debounce timer
+ }
+
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ListController.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,180 @@
+/**
+@file ListController.h
+
+*/
+
+#ifndef LISTCONTROLLER_H
+#define LISTCONTROLLER_H
+
+#include "mbed.h"
+#include "Outputs.h"
+
+/**
+@brief Manages the display of upto 4 possible options on LCD that the user can select.\n
+@brief also has a scrolling feature that allows user to browse the options\n
+@author Augustine Kizito K
+@date April 2015
+*/
+class ListController
+{
+private:
+ char title[32]; // title of the list
+ char option1[32]; // option 1 on the list
+ char option2[32]; // option 2 on the list
+ char option3[32]; // option 3 on the list
+ char option4[32]; // option 4 on the list
+ int numberOfOptions; // available number of options
+ int currentOption; // tracks position of current cell
+
+ void invertPixels(int option); // inverts pixels in a given bank i.e highlighting an option
+
+protected:
+ /**
+ Creates a List Controller instance
+
+ @param t - string title of list
+ @param op1 - option 1 on the list
+ @param op2 - option 2 on the list
+ @param op3 - option 3 on the list
+ @param op4 - option 4 on the list
+ @param nOO 0 - available number of options
+
+ */
+ ListController( char t[], char op1[], char op2[], char op3[], char op4[], int nOO);
+
+ /**
+ Populates the LCD screen with the a list of browse-able and selectable options
+
+ */
+ void showInfo(); // populate the screen with controller data
+
+ /**
+ Scrolls to the previous option
+
+ */
+ void scrollUp();
+
+ /**
+ Scrolls to the next option
+
+ */
+ void scrollDown();
+
+ /**
+ Gets the current/highlighted option and returns is to the calling function
+
+ @returns the currentt option 0 - 3
+ */
+ int getCurrentOption(); // returns the highlighted Option 0-3
+
+};
+
+
+
+
+
+
+
+ListController::ListController( char t[], char op1[], char op2[], char op3[], char op4[],int nOO)
+{
+ // initialisations
+ strcpy(title,t);
+ strcpy(option1,op1);
+ strcpy(option2,op2);
+ strcpy(option3,op3);
+ strcpy(option4,op4);
+ numberOfOptions = nOO;
+ currentOption = 0;
+
+}
+
+void ListController::showInfo()
+{
+ lcd.printString(title,15,1); // print title
+ lcd.printString(option1,0,2); // print option1
+ lcd.printString(option2,0,3); // print option2
+ lcd.printString(option3,0,4); // print option3
+ lcd.printString(option4,0,5); // print option4
+
+ invertPixels(currentOption); // highlight the current option
+}
+
+void ListController::scrollUp()
+{
+ playSound(); // buzzer makes sound
+ invertPixels(currentOption); // UN invert/highlight current option
+ currentOption--; // current position is less by 1
+
+ if (currentOption < 0) { // prevents from inverting a non existent option
+
+ currentOption = 0;
+ invertPixels(currentOption); // invert all pixels in current bank
+
+ } else {
+ invertPixels(currentOption); // invert all pixels in current bank
+ }
+
+
+}
+
+void ListController::scrollDown()
+{
+ playSound(); // buzzer makes sound
+ invertPixels(currentOption); // UN-invert/highlight the current option
+ currentOption++; // current option is more by 1
+
+ if (currentOption > numberOfOptions-1) { // prevents from inverting a non existant option
+
+ currentOption = numberOfOptions-1;
+ invertPixels(currentOption); // invert all pixels in current option
+ } else {
+ invertPixels(currentOption); // invert all pixels in current option
+ }
+}
+
+
+int ListController::getCurrentOption()
+{
+ return currentOption;
+
+}
+
+void ListController::invertPixels(int option)
+{
+
+
+ int onset; // x coordinate where inversion starts
+
+ // first bank consists of status bar showing time and battery icon
+ // second bank consists of the title
+
+ if (option == 0) { // invert third bank
+ onset = 15;
+ } else if ( option == 1) { // invert fourth bank
+ onset = 23;
+ } else if ( option == 2) { // invert fifth bank
+ onset = 31;
+ } else {
+ onset = 39; // invert sixth bank
+ }
+
+ int termination = onset + 9; // bank's length height is 9 pixels
+
+ for ( int m = onset; m < termination; m++) {
+
+ for ( int n = 0; n < 84; n++) {
+
+ if((lcd.getPixel(n,m)) == 0) { // if the pixel is clear
+ lcd.setPixel(n,m); // set the pixel
+ } else {
+ lcd.clearPixel(n,m); // else clear the pixel
+ }
+
+ }
+ }
+
+ lcd.refresh(); // refresh the lcd screen
+
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/LogOptionScreen.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,140 @@
+/**
+@file LogOptionScreen.h
+*/
+#ifndef LOGOPTIONSCREEN_H
+#define LOGOPTIONSCREEN_H
+
+#include "ListController.h"
+#include "Inputs.h"
+
+/**
+@brief Allos the user to select which parameter they would\n
+@brief like to log or view a previous log i.e either temperature or pressure\n
+@brief it consists of a list controller with two options
+@author Augustine K Kizito
+@date April 2015
+*/
+
+
+class LogOptionScreen : public ListController // inherit the list Controller properties
+{
+private:
+ bool changeScreen; // tracks if the user pressed a button that changes the screen
+ int nextScreen; // tracks whether the user wants to go to
+ //the previous screen or next screen
+
+ void onScrollUp(); // user pressed the scroll up button
+ void onScrollDown(); // user pressed the scroll down button
+ void onEnter(); // user pressed the enter button
+ void onBack(); // user pressed the back button
+
+public:
+ /**
+ Creates an instance of the log options screen
+
+ */
+ LogOptionScreen()
+ :ListController( "Parameter", // Title
+ "Temperature", // Option 1
+ "Pressure", // Option 2
+ "", // Option 3
+ "", // Option 4
+ 2) // Number of Options
+ {};
+ /**
+ Manages the execution of the Log Options Screen
+
+ @returns
+
+ -1 - Navigate to previous screen\n
+ 0 - User selected option 1\n
+ 1 - User selected option 2
+
+ */
+ int start();
+
+
+};
+
+
+
+
+
+
+int LogOptionScreen::start()
+{
+
+ // Activate PullDown Resistors
+ enterButton.mode(PullDown);
+ upButton.mode(PullDown);
+ downButton.mode(PullDown);
+ backButton.mode(PullDown);
+
+ upButton.rise(this,&LogOptionScreen::onScrollUp); // call onScrollUp when the up button is pressed
+ downButton.rise(this,&LogOptionScreen::onScrollDown); // call onScrollDown when the down button is pressed
+ enterButton.rise(this,&LogOptionScreen::onEnter); // call onEnter when the enter button is pressed
+ backButton.rise(this,&LogOptionScreen::onBack); // call onBack when the back button is pressed
+
+ // Launch the List Controller
+ ListController::showInfo();
+ changeScreen = false;
+
+ debounce.start(); // start the debounce timer
+
+ while(!changeScreen) {
+
+ // mbed goes to sleep to save power
+ Sleep();
+ }
+
+ // detach all interrupts
+ upButton.rise(NULL);
+ downButton.rise(NULL);
+ enterButton.rise(NULL);
+ backButton.rise(NULL);
+
+ return nextScreen;
+}
+
+void LogOptionScreen::onScrollUp()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+
+ ListController::scrollUp(); // scroll up
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void LogOptionScreen::onScrollDown()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+
+ ListController::scrollDown(); // scroll down
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void LogOptionScreen::onEnter()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+ // Sound the buzzer
+ playSound();
+ nextScreen = ListController::getCurrentOption(); // get the option that user selected
+ changeScreen = true; // user wants to go to a different screen
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void LogOptionScreen::onBack()
+{
+ if(debounceSuccess()) { // debouncing succeeded
+ // sound the buzzer
+ playSound();
+ nextScreen = -1; // go to previous screen
+ changeScreen = true; // user wants to go to a different screen
+ debounce.reset();
+ }
+
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/LogScreen.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,144 @@
+/**
+@file LogScreen.h
+
+
+*/
+
+#ifndef LOGSCREEN_H
+#define LOGSCREEN_H
+
+#include "ListController.h"
+#include "Inputs.h"
+
+/**
+@brief Displays the options related to persistent data on the LCD screen \n
+@brief It is a list with two selectable options :\n
+@brief new log and view log\n
+@brief new log option allows the user to log temperature or pressure or a preset amount of time\n
+@brief and store the recorded data on the mbed flash drive\n
+@brief view log option allows the user to view data that has been previously logged, either temperature or pressure.\n
+@brief user will be able to know, the date, time and duration of the log. the user will view a summary of the logged data\n
+@brief i.e maximum, minimum and average values of the recorded data. A plot agains time of the data will also be available
+@author Augustine Kizito K
+@date April 2015
+*/
+
+
+
+class LogScreen : public ListController // inherit the list Controller properties
+{
+private:
+ bool changeScreen; // tracks if the user pressed a button that changes the screen
+ int nextScreen; // tracks whether the user wants to go to
+ //the previous screen or next screen
+
+ void onScrollUp(); // user pressed the scroll up button
+ void onScrollDown(); // user pressed the scroll down button
+ void onEnter(); // user pressed the enter button
+ void onBack(); // user pressed the back button
+
+public:
+ /**
+ Creates an instance of the Log Screen
+
+ */
+ LogScreen()
+ :ListController( "Log", // Title
+ "New Log", // Option 1
+ "View Log", // Option 2
+ "", // Option 3
+ "", // Option 4
+ 2) // Number of Options
+ {};
+ /**
+ Manages the execution of the Log Screen
+
+ @returns
+
+ -1 - Navigate to previous screen\n
+ 0 - User selected option 1\n
+ 1 - User selected option 2
+
+ */
+ int start(); // Manages the execution of the Temperature Screen
+
+
+};
+
+int LogScreen::start()
+{
+
+ // Activate PullDown Resistors
+ enterButton.mode(PullDown);
+ upButton.mode(PullDown);
+ downButton.mode(PullDown);
+ backButton.mode(PullDown);
+
+ upButton.rise(this,&LogScreen::onScrollUp); // call onScrollUp when the up button is pressed
+ downButton.rise(this,&LogScreen::onScrollDown); // call onScrollDown when the down button is pressed
+ enterButton.rise(this,&LogScreen::onEnter); // call onEnter when the enter button is pressed
+ backButton.rise(this,&LogScreen::onBack); // call onBack when the back button is pressed
+
+ // Launch the List Controller
+ ListController::showInfo();
+ changeScreen = false;
+
+ debounce.start(); // start the debounce timer
+
+ while(!changeScreen) {
+
+ // mbed goes to sleep to save power
+ Sleep();
+ }
+
+ // detach all interrupts
+ upButton.rise(NULL);
+ downButton.rise(NULL);
+ enterButton.rise(NULL);
+ backButton.rise(NULL);
+
+ return nextScreen;
+}
+
+void LogScreen::onScrollUp()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+
+ ListController::scrollUp(); // scroll up
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void LogScreen::onScrollDown()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+
+ ListController::scrollDown(); // scroll down
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void LogScreen::onEnter()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+ // sound the buzzer
+ playSound();
+ nextScreen = ListController::getCurrentOption(); // get the option that user selected
+ changeScreen = true; // user wants to go to a different screen
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void LogScreen::onBack()
+{
+ if(debounceSuccess()) { // debugging was successful
+ // sound the buzzer
+ playSound();
+ nextScreen = -1; // go to previous screen
+ changeScreen = true; // user wants to go to a different screen
+ debounce.reset(); // reset the debounce timer
+ }
+
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MainMenuScreen.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,122 @@
+/**
+@file MainMenuScreen.h
+
+*/
+#ifndef MAINMENUSCREEN_H
+#define MAINMENUSCREEN_H
+
+#include "ListController.h"
+#include "Inputs.h"
+
+/**
+@brief Displays the main menu on the LCD screen\n
+@brief It is a list with four selectable options :\n
+@brief temperature, pressue , log and settings
+@author Augustine Kizito K
+@date April 2015
+*/
+
+
+
+class MainMenuScreen : public ListController
+{
+private:
+ bool changeScreen; // tracks if the user pressed a button that changes the screen
+ int nextScreen; // tracks whether the user wants to go to
+ //the previous screen or next screen
+
+ void onScrollUp(); // user pressed the scroll up button
+ void onScrollDown(); // user pressed the scroll down button
+ void onEnter(); // user pressed the enter button
+
+public:
+ /**
+ Creates an instance of the main menu screen
+
+ */
+ MainMenuScreen()
+ :ListController( "MainMenu", // Title
+ "Temperature", // Option 1
+ "Pressure", // Option 2
+ "Log", // Option 3
+ "Settings", // Option 4
+ 4) // Number of Options
+ {};
+ /*
+ Manages the execution of the main menu screen
+
+ @returns
+ 0 - User selected option 1\n
+ 1 - User selected option 2\n
+ 2 - User selected option 3\n
+ 3 - User selected option 4\n
+
+ */
+ int start();
+
+
+};
+int MainMenuScreen::start()
+{
+
+
+ enterButton.mode(PullDown); // activate pull down resistor
+ upButton.mode(PullDown); // activate pull down resistor
+ downButton.mode(PullDown); // acivate pull down resistor
+
+ upButton.rise(this,&MainMenuScreen::onScrollUp); // call onScrollUp when the up button is pressed
+ downButton.rise(this,&MainMenuScreen::onScrollDown); // call onScrollDown when the down button is pressed
+ enterButton.rise(this,&MainMenuScreen::onEnter); // call onEnter when the enter button is pressed
+
+ // Launch the List Controller
+ ListController::showInfo();
+ changeScreen = false;
+
+ debounce.start(); // start the debouncing timer
+
+ while(!changeScreen) {
+
+ // mbed goes to sleep to save power
+ Sleep();
+ }
+
+ // detach all interrupts
+ upButton.rise(NULL);
+ downButton.rise(NULL);
+ enterButton.rise(NULL);
+ backButton.rise(NULL);
+
+ return nextScreen;
+}
+
+void MainMenuScreen::onScrollUp()
+{
+ if (debounceSuccess()) { // debouncing successful
+
+ ListController::scrollUp(); // scroll up
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void MainMenuScreen::onScrollDown()
+{
+ if (debounceSuccess()) { // debouncing successful
+
+ ListController::scrollDown(); // scroll down
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void MainMenuScreen::onEnter()
+{
+ if (debounceSuccess()){ // debouncing successful
+ // sound the buzzer
+ playSound();
+ nextScreen = ListController::getCurrentOption(); // get the option that user selected
+ changeScreen = true; // user wants to go to a different screen
+ // reset the debounce timer
+ debounce.reset();
+ }
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/N5110.lib Mon May 11 15:25:52 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/eencae/code/N5110/#780a542d5f8b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Outputs.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,119 @@
+/**
+@file Outputs.h
+@brief Contains all the outputs required for the weather station application\n
+@brief the outputs are N5110 LCD screen, piezo buzzer, red LED and blue LED
+@author Augustine K Kizito
+@date April 2015
+*/
+
+#ifndef OUTPUTS_H
+#define OUTPUTS_H
+
+#include "N5110.h"
+#include "beep.h"
+#include "PowerControl/PowerControl.h"
+
+N5110 lcd(p7,p8,p9,p10,p11,p13,p26); // pwm for led backlight
+Beep buzzer(p21); // pwm for buzzer
+
+DigitalOut logLed(p24); //led that turns on when logging
+DigitalOut batStatLed(p23); // led that turns on when battery voltage is low
+
+Ticker batStatTimer;
+bool batStatLedState = false; // tracks if the batStatLed is in use
+
+void turnOnBatStatLed() // turns on the battery status led
+{
+ if(!batStatLedState) { // battery status led is not already on
+ // turn it on
+ batStatLed = 1;
+ // call this function every 2 seconds
+ batStatTimer.attach(&turnOnBatStatLed,2);
+ // battery status led is now in use
+ batStatLedState = true;
+ } else { // battery status led is already on
+
+ // toggle the battery status led
+ batStatLed = !batStatLed;
+ }
+
+}
+
+void turnOffBatStatLed() // turns off the battery status led
+{
+ // battery status led is still on
+ if (batStatLedState) {
+ // disable the interrupt that toggles the led
+ batStatTimer.detach();
+ // the battery status led is off
+ batStatLedState = false;
+ // turn off the battery status led
+ batStatLed = 0;
+
+ }
+
+}
+
+Ticker logLedTimer;
+bool logLedState = false; // tracks if the log Led is in use
+
+void turnOnLogLed() // turns on the log led
+{
+ if(!logLedState) { // log led is not already on
+ // turn it on
+ logLed = 1;
+ // call this function every 2 seconds
+ logLedTimer.attach(&turnOnLogLed,2);
+ // log led is now in use
+ logLedState = true;
+ } else { // log led is already on
+
+ // toggle the log led
+ logLed = !logLed;
+ }
+
+}
+
+void turnOffLogLed() // turns off the log led
+{
+ // log led is still on
+ if (logLedState) {
+ // disable the interrupt that toggles the led
+ logLedTimer.detach();
+ // the log led is off
+ logLedState = false;
+ // turn off the log led
+ logLed = 0;
+
+ }
+
+}
+
+bool soundFx = true; // variable that tracks the sound effects
+int currentBrightness; // variable that tracks the LCD brightness
+
+void playSound()
+{
+ if (soundFx) { // the sound effects are activated
+
+ // if brightenss is at 50 or 20 % , reduce buzzer frequency.
+ // this is implemented because the above modes seem to affect the
+ // PWM signal to the LCD brightness. Reducing the buzzer frequency
+ // somewhat alleviates this problem
+
+ if (currentBrightness == 50 || currentBrightness == 25 ) {
+ buzzer.beep(80,0.05); // sound 80kHz tone
+
+ } else { // sound the normal 2kHz Tone
+ buzzer.beep(2000.0,0.1);
+ }
+
+
+
+ }
+
+
+}
+
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ParameterController.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,134 @@
+/**
+@file ParameterController.h
+
+*/
+
+#ifndef PARAMETERCONTROLLER_H
+#define PARAMETERCONTROLLER_H
+
+#include "mbed.h"
+#include "Outputs.h"
+
+/**
+@brief Manages the display of parameter data on the LCD.
+@brief paramters used in the project like temperature, pressure and baterry voltage
+@author Augustine Kizito K
+@date April 2015
+*/
+
+class ParameterController
+{
+private:
+ char value[32]; // value of the parameter
+ char parameter[32]; // name of the parameter
+ char unit[32]; // unit of the parameter
+ char sentiment[32]; // sentiment of the parameter
+
+protected:
+ /**
+ Creates a parameter controller intstance
+
+ @param p - string name of parameter
+ @param u - string units of parameter
+
+ */
+ ParameterController(char p[], char u[] );
+
+ /**
+ Set the sentiment of the parameter
+
+ @param s - string sentiment of parameter
+
+ */
+ void setSentiment(char s[]);
+
+ /**
+ Set the value of the parameter
+
+ @param v - float v value of parameter
+
+ */
+ void setValue( float v);
+
+ /**
+ Set the units of the parameter
+
+ @param u - string unit of parameter
+
+ */
+ void setUnit(char u[]);
+
+ /**
+ Populate the LCD screen with the appropriate parameter data
+
+ */
+ void showInfo();
+
+ /**
+ Update the LCD screen with new data
+
+ */
+ void updateInfo();
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+ParameterController::ParameterController( char p[], char u[]) // constructor
+{
+
+ strcpy(parameter,p);
+ strcpy(unit,u);
+
+}
+
+void ParameterController::setValue( float v) // set the current value of the parameter
+{
+
+ sprintf(value,"%0.2f",v); // converting float to string
+}
+
+void ParameterController::setSentiment( char s[]) // set the current current sentiment of the value
+{
+ strcpy(sentiment,s);
+}
+
+void ParameterController::showInfo() // populate the screen with Controller data
+{
+ lcd.printString(parameter,15,1); // print parameter
+ lcd.printString(value,0,2); // print value
+ lcd.printString(unit,0,3); // print unit
+ lcd.printString("Sentiment:",0,4);
+ lcd.printString(sentiment,0,5); // print sentiment
+
+ lcd.refresh(); // refresh the lcd screen
+
+}
+
+void ParameterController::updateInfo() // update the screen with new info
+{
+ lcd.printString(value,0,2); // print value
+ lcd.printString(unit,0,3); // print unit
+ lcd.printString(sentiment,0,5); // print sentiment
+
+ lcd.refresh(); // refresh the lcd screen
+
+}
+
+void ParameterController::setUnit( char u[])
+{
+ strcpy(unit,u);
+
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PowerControl.lib Mon May 11 15:25:52 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/JST2011/code/PowerControl/#d0fa2aeb02a4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/PressureLog.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,252 @@
+/**
+@file pressurelog.h
+*/
+#ifndef PRESSURELOG_H
+#define PRESSURELOG_H
+
+#include "Outputs.h"
+#include "ConfigFile.h"
+#include "Sensors.h"
+
+/**
+@brief logs pressure values over a predetermined length of time\n
+@brief the logged data is then stored on the onboard flash memory\n
+@brief the lCD screen is turned off after 5 seconds to save energy
+@author Augustine K Kizito
+@date April 2015
+*/
+
+
+class PressureLog
+{
+private:
+ bool logFinished; // tracks if logging was successfuly finished
+ int logCounter; //tracks how many times data has been logged
+ bool changeScreen; // tracks if the user pressed a button that changes the screen
+ int nextScreen; // tracks whether the user wants to go to
+ //the previous screen or next screen
+ Timeout stop; // timeout that will turn off the screen after a given time
+ Ticker logTimer; // ticker that will log data at intervals
+ Ticker batLedTimer; // ticker that will check battery status at intervals
+ ConfigFile pcfgW; // pressure CFG object
+
+ void onBack(); // user pressed the back button
+ void turnOffScreen(); // powers down the lcd screen
+ void logData(); // logs data by storing it in ConfigFile object
+ void saveData(); // saves data to the mbed flash drive
+ void initCfg(int duration); // initialises the cfg object with vital data
+ void checkBatVoltage(); // checks if batteryVoltage is low
+
+public:
+ /**
+ Manages the execution of the Pressure Log Screen
+
+ @param - integer duration, the length of time to pressure
+ @returns
+ -1 - navigate to previous screen
+
+ */
+ int start(int duration);
+
+
+};
+
+int PressureLog::start(int duration)
+{
+ // initialisations
+ logFinished = false;
+ logCounter = 0;
+ lcd.printString("Logging...",20,2);
+
+ backButton.mode(PullDown); // activate pullDown Resistor
+ backButton.rise(this,&PressureLog::onBack); // call onBack when the back button is pressed
+
+ stop.attach(this,&PressureLog::turnOffScreen, 5); // turn off LCD screen after 5 seconds
+ batLedTimer.attach(this, &PressureLog::checkBatVoltage, 10); // check battery voltage every 5 seconds
+
+ // check the Battery Voltage
+ checkBatVoltage();
+ // Turn on the Log Led
+ turnOnLogLed();
+ // Initialise CFG object
+ initCfg(duration);
+ // start the debounce timer
+ debounce.start();
+
+ // 84 data points should be recorded for every log
+
+ logData(); // log the data
+
+ if ( duration == 0) {
+ // this intervals makes 84 logs in 5 minutes
+ logTimer.attach(this, &PressureLog::logData,3.614);
+ } else if ( duration == 1) {
+ // this intervals makes 84 logs in 10 minutes
+ logTimer.attach(this, &PressureLog::logData,7.229);
+ } else if ( duration == 2) {
+ // this intervals makes 84 logs in 30 minutes
+ logTimer.attach(this, &PressureLog::logData,21.687);
+ } else {
+ // this intervals makes 84 logs in 1 hour
+ logTimer.attach(this, &PressureLog::logData,42.373);
+ }
+
+ while (!logFinished) {
+
+ // mbed goes to sleep to save power
+ Sleep();
+
+ }
+
+ // remove interrupts
+ logTimer.detach();
+ backButton.rise(NULL);
+
+ turnOffLogLed();
+
+ return -1;
+}
+
+void PressureLog::initCfg( int duration )
+{
+
+ // Create the Duration Key and Value Pair
+ char *theDurationKey = "durationKey";
+ char theDurationValue[32];
+
+ // Set the Duration Value appropriately
+ if ( duration == 0 ) {
+
+ char theDurationString[32] = "5 min";
+ strcpy(theDurationValue,theDurationString);
+
+ } else if ( duration == 1) {
+
+ char theDurationString[32] = "10 min";
+ strcpy(theDurationValue,theDurationString);
+
+ } else if ( duration == 2) {
+
+ char theDurationString[32] = "30 min";
+ strcpy(theDurationValue,theDurationString);
+
+ } else {
+
+ char theDurationString[32] = "1 hour";
+ strcpy(theDurationValue,theDurationString);
+ }
+
+ // Create the Time and Value Pair
+ char *theTimeKey = "timeKey";
+ char theTimeValue[32];
+
+ // Create the Date Key and Value Pair
+ char *theDateKey = "dateKey";
+ char theDateValue[32];
+
+ ////GET THE CURRENT TIME///////////
+ time_t seconds = time(NULL);
+ strftime(theDateValue, 32, "%d/%m/%y", localtime(&seconds)); // format the date in day/month/year
+ strftime(theTimeValue, 32, "%R", localtime(&seconds)); // format the time in HH:MM 24 Hr clock
+ ////////////////////////////////////////////
+
+ // set the created Key and Value Pairs to the cfg object
+ pcfgW.setValue(theDateKey,theDateValue);
+ pcfgW.setValue(theTimeKey,theTimeValue);
+ pcfgW.setValue(theDurationKey,theDurationValue);
+
+
+}
+
+void PressureLog::logData()
+{
+
+ if ( logCounter < 84 ) { // data is still logging
+
+ // get the current pressure
+ float pressure = getPressure();
+
+ // create a new Counter Key and Value Pair
+ char *theCounterKey = "counterKey";
+ char theCounterValue[32] = "";
+
+ // assign the logCounter as the CounterValue
+ sprintf(theCounterValue,"%d",logCounter);
+
+ // Create a new Key and Value Pair
+ char theKey[32] = "key";
+ char theValue[32] = "";
+
+ // concatentate the Key Value and Counter Value strings
+ strcat(theKey,theCounterValue);
+
+ sprintf(theValue,"%0.2f",pressure); // converting float to string
+
+ // set the created key and value pairs to the cfg object
+ pcfgW.setValue(theCounterKey,theCounterValue);
+ pcfgW.setValue(theKey,theValue);
+
+
+ } else {
+
+ saveData(); // save the data
+ logFinished = true; // logging has finished successfully
+ }
+
+ // increment the log counter
+ logCounter++;
+
+}
+
+void PressureLog::saveData()
+{
+ // save the data to onboard flash memory as a cfg file
+ pcfgW.write("/local/prs.cfg");
+
+}
+
+void PressureLog::onBack()
+{
+ if (debounceSuccess()) { // debouncing successful
+
+ playSound();
+ // if user presses the back button, save data and terminate logging
+
+ saveData(); // save the data
+ logFinished = true; // logging has finished successfully
+ debounce.reset(); // reset the debounce timer
+
+ }
+
+}
+
+void PressureLog::turnOffScreen()
+{
+ // turn off the LCD screen to save power
+ lcd.turnOff();
+
+}
+
+void PressureLog::checkBatVoltage()
+{
+ // read the battery voltage
+ float batteryVoltage = getVoltage();
+
+ if (batteryVoltage < 6.5) { // check if battery is low
+
+ if(!batStatLedState) { // if the battery low led is not already on
+
+ turnOnBatStatLed(); // turn on the battery low led
+ }
+
+
+ } else {
+
+ turnOffBatStatLed(); // ensure that the battery low led is turned off
+
+ }
+
+
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/PressurePlot.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,182 @@
+/**
+@file pressureplot.h
+*/
+#ifndef PRESSUREPLOT_H
+#define PRESSUREPLOT_H
+
+#include "Sensors.h"
+/**
+@brief displays the pressure against time at various intervals\n
+@brief pressure is in mbars
+@author Augustine K Kizito
+@data April 2015
+*/
+
+class PressurePlot
+{
+private:
+ bool changeScreen; // tracks if the user pressed a button that changes the screen
+ int nextScreen; // tracks whether the user wants to go to
+ //the previous screen or next screen
+ int xCord; // tracks the x coordinate
+ char prsString[32]; // temperature value as string
+ bool pause; // tracks if the plotting has been paused
+ int pInterval; // determines the intervals at which data is plotted
+ Ticker timer; // plots data at particular intervals
+
+ void onBack(); // user pressed the back button
+ void onEnter(); // user pressed the on enter button
+ void plotData(); // plot temperature data
+ void clearPlot(); // clear the plotted data
+ void pausePlot(); // it pauses plotting of data so that the user can view it
+
+public:
+ /**
+ Manages the execution of the Pressure Plot Screen
+
+ @param - integer interval, the intervals after which pressure is plotted against time on the LCD screen
+ @returns
+ -1 - navigate to previous screen
+
+ */
+ int start(int interval);
+
+};
+
+int PressurePlot::start(int interval)
+{
+ // initialisations
+ pInterval = interval;
+ xCord = 0; // set the x cordinate to 0
+ pause = false;
+
+ backButton.mode(PullDown); // activate pullDown Resistor
+ enterButton.mode(PullDown); // activate pullDown Resistor
+
+ backButton.rise(this,&PressurePlot::onBack); // call onBack when the back button is pressed
+ enterButton.rise(this,&PressurePlot::onEnter); // call onBack when the back button is pressed
+
+ plotData(); // plot data onto screen
+ lcd.printString("mbars", 40,1);
+
+ // plot data on LCD screen depending on the interval previously selected by the user
+ if ( interval == 0) {
+ timer.attach(this, &PressurePlot::plotData,0.1); // call ISR every 1.0 second
+ } else if ( interval == 1) {
+ timer.attach(this, &PressurePlot::plotData,0.5); // call ISR every 5 seconds
+ } else if ( interval == 2) {
+ timer.attach(this, &PressurePlot::plotData,1); // call ISR every 10 seconds
+ } else {
+ timer.attach(this, &PressurePlot::plotData,5); // call ISR every 30 seconds
+ }
+
+ changeScreen = false;
+ debounce.start(); // start the debounce timer
+
+ while (!changeScreen) {
+
+ // mbed goes to sleep to save power
+ Sleep();
+
+ }
+
+ // remove all interrupts
+ backButton.rise(NULL);
+ enterButton.rise(NULL);
+ timer.detach();
+ return nextScreen;
+}
+
+void PressurePlot::plotData()
+{
+ if (xCord > 83 ) {
+
+ xCord = 0; // reset the xCord back to zero
+
+ clearPlot(); // clear the plot region
+
+ }
+
+ float pressure = getPressure(); // retreive pressure from the sensor
+
+ lcd.drawLine(xCord,(31*((1200-pressure)/1200)+16),xCord,47,1);
+
+ // show pressure on the screen
+ sprintf(prsString,"%0.2f",pressure);
+ lcd.printString(prsString,0,1);
+
+ //increment the coordinate
+ xCord++;
+
+
+}
+
+void PressurePlot::onBack()
+{
+ if(debounceSuccess()) { // debouncing successful
+ // sound the buzzer
+ playSound();
+ nextScreen = -1;
+ changeScreen = true; // user wants to go to a different screen
+ // reset the debounce timer
+ debounce.reset();
+ }
+
+}
+
+void PressurePlot::clearPlot()
+{
+ // clears the plot area
+ for ( int x = 0; x < 84; x++) {
+
+ for ( int y = 16; y < 48; y++) {
+
+ lcd.clearPixel(x,y);
+
+ }
+
+ }
+
+ lcd.refresh();
+
+}
+
+void PressurePlot::onEnter()
+{
+ if (debounceSuccess()) { // debouncing successful
+
+ playSound(); // play sound
+ pausePlot(); // pause any plotting
+ debounce.reset(); // reset debounce timer
+ }
+
+}
+
+void PressurePlot::pausePlot()
+{
+ pause = !pause;
+
+ if (pause) {
+ timer.detach(); // detach timer and stop plotting data
+ } else {
+
+ clearPlot(); // clear the plot area
+ xCord = 0; // start plotting from extreme left
+ plotData();
+
+ // start plotting data again
+ if ( pInterval == 0) {
+ timer.attach(this, &PressurePlot::plotData,0.1); // call ISR every 0.1 second
+ } else if ( pInterval == 1) {
+ timer.attach(this, &PressurePlot::plotData,0.5); // call ISR every 0.5 seconds
+ } else if ( pInterval == 2) {
+ timer.attach(this, &PressurePlot::plotData,1); // call ISR every 1 seconds
+ } else {
+ timer.attach(this, &PressurePlot::plotData,5); // call ISR every 5 seconds
+ }
+
+
+ }
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/PressureScreen.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,142 @@
+/**
+@file PressureScreen.h
+
+*/
+
+#ifndef PRESSURESCREEN_H
+#define PRESSURESCREEN_H
+
+#include "ListController.h"
+#include "Inputs.h"
+#include "Outputs.h"
+
+/**
+
+@brief Displays the pressure options on the LCD screen \n
+@brief It is a list with two selectable options :\n
+@brief view prs and plot prs\n
+@brief view prs shows the current pressure along with the sentiment\n
+@brief prs plot plots the pressure against time on the LCD screen at various intervals\n
+@author Augustine Kizito K
+@date April 2015
+
+*/
+
+
+
+class PressureScreen : public ListController // inherit the list Controller properties
+{
+private:
+ bool changeScreen; // tracks if the user pressed a button that changes the screen
+ int nextScreen; // tracks whether the user wants to go to
+ //the previous screen or next screen
+
+ void onScrollUp(); // user pressed the scroll up button
+ void onScrollDown(); // user pressed the scroll down button
+ void onEnter(); // user pressed the enter button
+ void onBack(); // user pressed the back button
+
+public:
+ /**
+ Creates an instance of the pressure screen
+
+ */
+ PressureScreen()
+ :ListController( "Pressure", // Title
+ "View Prs", // Option 1
+ "Prs Plot", // Option 2
+ "", // Option 3
+ "", // Option 4
+ 2) // Number of Options
+ {};
+ /**
+ Manages the execution of the pressure screen
+
+ @returns
+
+ -1 - Navigate to previous screen\n
+ 0 - User selected option 1\n
+ 1 - User selected option 2
+ */
+ int start();
+
+
+};
+
+int PressureScreen::start()
+{
+
+ // Activate PullDown Resistors
+ enterButton.mode(PullDown);
+ upButton.mode(PullDown);
+ downButton.mode(PullDown);
+ backButton.mode(PullDown);
+
+ upButton.rise(this,&PressureScreen::onScrollUp); // call onScrollUp when the up button is pressed
+ downButton.rise(this,&PressureScreen::onScrollDown); // call onScrollDown when the down button is pressed
+ enterButton.rise(this,&PressureScreen::onEnter); // call onEnter when the enter button is pressed
+ backButton.rise(this,&PressureScreen::onBack); // call onBack when the back button is pressed
+
+ // Launch the List Controller
+ ListController::showInfo();
+ changeScreen = false;
+
+ debounce.start(); // start the debounce timer
+
+ while(!changeScreen) {
+
+ // mbed goes to sleep to save power
+ Sleep();
+ }
+
+ // detach all interrupts
+ upButton.rise(NULL);
+ downButton.rise(NULL);
+ enterButton.rise(NULL);
+ backButton.rise(NULL);
+
+ return nextScreen;
+}
+
+void PressureScreen::onScrollUp()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+
+ ListController::scrollUp(); // scroll up
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void PressureScreen::onScrollDown()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+
+ ListController::scrollDown(); // scroll down
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void PressureScreen::onEnter()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+ // sound the buzzer
+ playSound();
+ nextScreen = ListController::getCurrentOption(); // get the option that user selected
+ changeScreen = true; // user wants to go to a different screen
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void PressureScreen::onBack()
+{
+ if(debounceSuccess()) {
+ // sound the buzzer
+ playSound();
+ nextScreen = -1; // go to previous screen
+ changeScreen = true; // user wants to go to a different screen
+ debounce.reset();
+ }
+
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/PrsViewLogScreen.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,96 @@
+/**
+@file PressureViewLogScreen.h
+
+*/
+
+#ifndef PRSVIEWLOGSCREEN_H
+#define PRSVIEWLOGSCREEN_H
+
+#include "DataController.h"
+#include "Inputs.h"
+
+/**
+@brief shows previously logged pressure data on the LCD screen\n
+@brief the pressure data is displayed in a convenient way by use of
+@brief a data controller
+@author Augustine K Kizito
+@date April 2015
+*/
+
+class PrsViewLogScreen : public DataController
+{
+private:
+
+ void onEnter(); // user pressed the enter button
+ void onBack(); // user pressed the back button
+
+public:
+ /**
+ Creates an instance of the Pressure View Log Screen
+
+ */
+ PrsViewLogScreen()
+ :DataController( "/local/prs.cfg", // File location
+ 0) // parameter, 1 for temperatue, 0 for pressure
+ {};
+ /**
+ Manages the execution of the Pressure View Log Screen
+
+ @returns
+
+ -1 - Navigate to previous screen
+ */
+ int start();
+
+
+};
+
+
+
+
+
+
+
+
+
+
+int PrsViewLogScreen::start()
+{
+ enterButton.mode(PullDown);
+ backButton.mode(PullDown);
+
+ enterButton.rise(this,&PrsViewLogScreen::onEnter); // call onEnter when the enter button is pressed
+ backButton.rise(this,&PrsViewLogScreen::onBack); // call onBack when the back button is pressed
+
+ debounce.start();
+
+ // launch the data controller
+ DataController::begin();
+
+ enterButton.rise(NULL);
+ backButton.rise(NULL);
+ return -1;
+}
+
+void PrsViewLogScreen::onEnter()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+ // sound the buzzer
+ playSound();
+ DataController::nextPage();
+ debounce.reset(); // reset the debounce timer
+ }
+
+}
+
+void PrsViewLogScreen::onBack()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+ // sound the buzzer
+ playSound();
+ DataController::previousPage();
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Sensors.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,80 @@
+/**
+@file sensors.h
+@brief this file contians functions that allow the user to access the sensors used in for the project\n
+@brief the sensors are barameter, thermometer and a simple voltage divider that measures voltage\n
+@author Augustine K Kizito
+@date April 2015
+*/
+#ifndef SENSORS_H
+#define SENSORS_H
+
+#include "BMP180.h"
+
+BMP180 bmp180(p28,p27); // SDA, SCL
+AnalogIn ain(p20); // connected to PP3 battery, used to measure voltage
+
+/**
+Reads the current temperature from the BMP180 sensor and returns the value
+
+@returns float temperature in degrees celsius
+
+*/
+float getTemperature();
+/**
+Reads the current pressure from the BMP180 sensor and returns the value
+
+@returns float pressure in mbars
+
+*/
+float getPressure();
+/**
+Reads the voltage reading across the potential divider connecte to the PP3 Battery
+
+@returns float battery voltage in Volts
+*/
+float getVoltage();
+
+
+
+
+float getTemperature()
+{
+ float temperature; // stores temperature in deg Cel
+
+ if (bmp180.ReadData(&temperature,NULL)) {
+ // tempeature value is returned successfully
+
+ } else {
+ // sensor failed
+ temperature = -100;
+ }
+
+ return temperature;
+}
+
+float getPressure()
+{
+ float pressure; // stores pressure in hPa
+
+ if (bmp180.ReadData(NULL, &pressure)) {
+ // pressure value is returned successfully
+
+ } else {
+ // sensor failed
+ pressure = -10;
+ }
+
+ return pressure;
+
+}
+
+float getVoltage()
+{
+ // calculate voltage
+ float voltage = ain*9.9+1.8;
+
+ return voltage;
+
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SettingController.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,287 @@
+/**
+@file SettingController.h
+
+*/
+
+#ifndef SETTINGCONTROLLER_H
+#define SETTINGCONTROLLER_H
+
+#include "Outputs.h"
+
+/**
+@brief Has the same features as the List Controller.\n
+@brief Displays the current state of a given setting on the screen\n
+@author Augustine Kizito K\n
+@date April 2015
+*/
+
+class SettingController
+{
+private:
+ int currentSetting; // the previously set setting
+ char title[32]; // title of the setting
+ char option1[32]; // the 1st option
+ char option2[32]; // the 2nd option
+ char option3[32]; // the 3rd option
+ char option4[32]; // the 4th option
+ int currentOption; // the current cell position
+ int numberOfOptions; // the number of available of options
+ void setSetting(int option); // make this option a new setting
+ void invertPixels(int option); // highlights pixels in a bank
+ void removeSetting(int option); // remove this option as a setting
+
+
+protected:
+ /**
+ Creates a Setting Controller instance
+
+ @param t - string title of list
+ @param op1 - option 1 on the list
+ @param op2 - option 2 on the list
+ @param op3 - option 3 on the list
+ @param op4 - option 4 on the list
+ @param nOO 0 - available number of options
+
+ */
+ SettingController( char t[], char opt1[],char opt2[], char opt3[], char opt4[],int nOO);
+
+ /**
+ Populates the LCD screen with the a list of browse-able and selectable options
+
+ */
+ void showInfo();
+
+ /**
+ Scrolls to the next option
+
+ */
+ void scrollDown();
+
+ /**
+ Scrolls to the previous option
+
+ */
+
+ void scrollUp();
+
+ /**
+ Gets the current/highlighted option and returns is to the calling function
+
+ @returns the currentt option 0 - 3
+ */
+
+ int getCurrentOption();
+
+ /**
+ Updates the LCD screen with new data
+
+ */
+ void updateData();
+
+ /**
+ Makes an option the current setting
+
+ @param cS - integer location of the setting to be made the current setting
+
+ */
+ void setCurrentSetting(int cS);
+
+ /**
+ Gets the location of the current setting and returns it
+
+ @returns - interger location of current setting 0 - 3
+
+ */
+
+ int getCurrentSetting();
+
+ /**
+ Changes the current setting to the new setting
+
+ */
+ void changeSetting();
+
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+SettingController::SettingController( char t[], char op1[], char op2[], char op3[], char op4[], int nOO )
+{
+ // initilaisations
+ strcpy(title,t);
+ strcpy(option1,op1);
+ strcpy(option2,op2);
+ strcpy(option3,op3);
+ strcpy(option4,op4);
+ numberOfOptions = nOO;
+ currentOption = 0;
+
+}
+
+void SettingController::showInfo()
+{
+ lcd.printString(title,0,1); // print title
+ lcd.printString(option1,0,2); // print option1
+ lcd.printString(option2,0,3); // print option2
+ lcd.printString(option3,0,4); // print option3
+ lcd.printString(option4,0,5); // print option4
+
+
+ setSetting(currentSetting);
+ invertPixels(currentOption); // highlight the current option
+
+
+}
+
+void SettingController::scrollUp()
+{
+ playSound(); // sound the buzzer
+ invertPixels(currentOption); // UN invert/highlight current option
+ currentOption--; // current position is less by 1
+
+ if (currentOption < 0) { // prevents from inverting a non existent option
+
+ currentOption = 0;
+ invertPixels(currentOption); // invert all pixels in current bank
+
+ } else {
+ invertPixels(currentOption); // invert all pixels in current bank
+ }
+}
+
+void SettingController::scrollDown()
+{
+ playSound(); // sound the buzzer
+ invertPixels(currentOption); // UN-invert/highlight the current option
+ currentOption++; // current option is more by 1
+
+ if (currentOption > numberOfOptions-1) { // prevents from inverting a non existant option
+
+ currentOption = numberOfOptions-1;
+ invertPixels(currentOption); // invert all pixels in current option
+ } else {
+ invertPixels(currentOption); // invert all pixels in current option
+ }
+}
+
+int SettingController::getCurrentOption()
+{
+
+ return currentOption;
+}
+
+int SettingController::getCurrentSetting()
+{
+
+ return currentSetting;
+}
+void SettingController::setCurrentSetting( int cs)
+{
+ currentSetting = cs;
+}
+
+void SettingController::invertPixels(int option)
+{
+ int onset; // x coordinate where inversion starts
+
+ // first bank consists of status bar showing time and battery icon
+ // second bank consists of the title
+
+ if (option == 0) { // invert third bank
+ onset = 15;
+ } else if ( option == 1) { // invert fourth bank
+ onset = 23;
+ } else if ( option == 2) { // invert fifth bank
+ onset = 31;
+ } else {
+ onset = 39; // invert sixth bank
+ }
+
+ int termination = onset + 9; // bank's length height is 9 pixels
+
+ for ( int m = onset; m < termination; m++) {
+
+ for ( int n = 0; n < 84; n++) {
+
+ if((lcd.getPixel(n,m)) == 0) { // if the pixel is clear
+ lcd.setPixel(n,m); // set the pixel
+ } else {
+ lcd.clearPixel(n,m); // else clear the pixel
+ }
+
+ }
+ }
+
+ lcd.refresh(); // refresh the lcd screen
+
+}
+
+void SettingController::changeSetting()
+{
+ //saveSetting();
+ //first un-invert the current option
+ invertPixels(currentOption);
+ //then remove the setting from option it was
+ removeSetting(currentSetting);
+ // make the new option as the new setting
+ setSetting(currentOption);
+ //update the current setting
+ currentSetting = currentOption;
+ // ivert the current option
+ invertPixels(currentOption);
+}
+
+void SettingController::removeSetting(int option)
+{
+ // remove the setting marker from the option by removing the letter o
+
+ if ( option == 0 ) {
+ lcd.printString(" ",78,2); //option1
+ } else if ( option == 1 ) {
+ lcd.printString(" ",78,3); //option2
+ } else if ( option == 2 ) {
+ lcd.printString(" ",78,4); //option3
+ } else {
+ lcd.printString(" ",78,5); //option4
+ }
+
+}
+
+void SettingController::setSetting(int option)
+{
+ // make the current position as the new setting by adding letter 0
+ // at the end of the option
+
+ if ( option == 0 ) {
+ lcd.printString("o",78,2); //option1
+ } else if ( option == 1 ) {
+ lcd.printString("o",78,3); //option2
+ } else if ( option == 2 ) {
+ lcd.printString("o",78,4); //option3
+ } else {
+ lcd.printString("o",78,5); //option4
+ }
+ lcd.refresh();
+
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SettingsScreen.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,156 @@
+/**
+@file SettingsScreen.h
+
+*/
+
+#ifndef SETTINGSSCREEN_H
+#define SETTINGSSCREEN_H
+
+#include "ListController.h"
+#include "Inputs.h"
+
+/**
+@brief Displays the settings on the LCD screen \n
+@brief It is a list with three selectable options :\n
+@brief brightness, sound fx and battery status\n
+@brief brightness allows the user to set the LCD backlight brightness to \n
+@brief 100%, 50%, 25% and Off\n
+@brief sound fx allows the user to turn on or off the sound, i.e the buzzer\n
+@brief both brightness and sound settings are persistent, i.e the preseved when the mbed is turned off\n
+@brief battery status is only shows the current battery voltage and along with the sentiment\n
+@author Augustine Kizito K
+@date April 2015
+*/
+
+
+
+class SettingsScreen : public ListController // inherit the list Controller properties
+{
+private:
+ bool changeScreen; // tracks if the user pressed a button that changes the screen
+ int nextScreen; // tracks whether the user wants to go to
+ //the previous screen or next screen
+
+ void onScrollUp(); // user pressed the scroll up button
+ void onScrollDown(); // user pressed the scroll down button
+ void onEnter(); // user pressed the enter button
+ void onBack(); // user pressed the back button
+
+public:
+ /**
+ Creates an instance of a Setttings Screen
+
+ */
+ SettingsScreen()
+ :ListController( "Settings", // Title
+ "Brightness", // Option 1
+ "Sound FX", // Option 2
+ "Battery Status", // Option 3
+ "", // Option 4
+ 3) // Number of Options
+ {};
+ /**
+ Manages the execution of the Settings Screen
+
+ @returns
+
+ -1 - Navigate to previous screen\n
+ 0 - User selected option 1\n
+ 1 - User selected option 2\n
+ 2 - User selected option 3
+
+ */
+ int start();
+
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+int SettingsScreen::start()
+{
+
+ // Activate PullDown Resistors
+ enterButton.mode(PullDown);
+ upButton.mode(PullDown);
+ downButton.mode(PullDown);
+ backButton.mode(PullDown);
+
+ upButton.rise(this,&SettingsScreen::onScrollUp); // call onScrollUp when the up button is pressed
+ downButton.rise(this,&SettingsScreen::onScrollDown); // call onScrollDown when the down button is pressed
+ enterButton.rise(this,&SettingsScreen::onEnter); // call onEnter when the enter button is pressed
+ backButton.rise(this,&SettingsScreen::onBack); // call onBack when the back button is pressed
+
+ ListController::showInfo();
+ changeScreen = false;
+
+ debounce.start(); // start the debounce timer
+
+ while(!changeScreen) {
+
+ // mbed goes to sleep to save power
+ Sleep();
+ }
+
+ // detach all interrupts
+ upButton.rise(NULL);
+ downButton.rise(NULL);
+ enterButton.rise(NULL);
+
+ return nextScreen;
+}
+
+void SettingsScreen::onScrollUp()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+
+ ListController::scrollUp(); // scroll up
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void SettingsScreen::onScrollDown()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+
+ ListController::scrollDown(); // scroll down
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void SettingsScreen::onEnter()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+ // sound the buzzer
+ playSound();
+ nextScreen = ListController::getCurrentOption(); // get the option that user selected
+ changeScreen = true; // user wants to go to a different screen
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void SettingsScreen::onBack()
+{
+ if(debounceSuccess()) {
+ // sound the buzzer
+ playSound();
+ nextScreen = -1; // go to previous screen
+ changeScreen = true; // user wants to go to a different screen
+ // reset the debounce timer
+ debounce.reset();
+ }
+
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SoundScreen.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,217 @@
+/**
+@file SoundScreen.h
+
+*/
+
+#ifndef SOUNDSCREEN_H
+#define SOUNDSCREEN_H
+
+#include "SettingController.h"
+#include "Inputs.h"
+#include "Outputs.h"
+#include "ConfigFile.h"
+
+/**
+@brief Shows the current sound setting of the buzzer\n
+@brief Consists of a Setting Controller\n
+@brief Sound can be set On or Off\n
+@brief the setting is persistent i.e saved onto onboard flash memory\n
+@author Augustine K Kizito
+@date April 2015
+*/
+
+
+
+class SoundScreen: public SettingController // inherit SettingController class
+{
+private:
+ bool changeScreen; // tracks if the user pressed a button that changes the screen
+ char *soundKey; // key to be used for the cfg file
+ char soundValue[BUFSIZ]; // buffer to store the brightness value retrieved from cfg file
+ int sound; // the brightness stored as an int
+
+ void onScrollUp(); // user pressed the scroll up button
+ void onScrollDown(); // user pressed the scroll down button
+ void onEnter(); // user pressed the enter button
+ void onBack(); // user pressed the back button
+ void saveSetting(); // save a selected option as a setting
+ void adjustSound(); //adjust brightness according to the stored setting
+
+public:
+ /**
+ Creates an instance of the Sound Screen
+
+ */
+ SoundScreen()
+ :SettingController( "Sound Fx", // Title
+ "On", // Option 1
+ "Off", // Option 2
+ "",
+ "",
+ 2) // Number of Options
+ {};
+ /**
+ Manages the execution of the Sound Screen
+
+ @returns
+
+ -1 - Navigate to previous screen
+
+ */
+ int start();
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+int SoundScreen::start()
+{
+
+ enterButton.mode(PullDown); // activate pull down resistor
+ upButton.mode(PullDown); // activate pull down resistor
+ downButton.mode(PullDown); // acivate pull down resistor
+ backButton.mode(PullDown); // activate pull down resistor
+
+ upButton.rise(this,&SoundScreen::onScrollUp); // call onScrollUp when the up button is pressed
+ downButton.rise(this,&SoundScreen::onScrollDown); // call onScrollDown when the down button is pressed
+ enterButton.rise(this,&SoundScreen::onEnter); // call onEnter when the enter button is pressed
+ backButton.rise(this, &SoundScreen::onBack);
+
+ debounce.start(); // start the debounce timer
+
+ soundKey = "sound ";
+ cfg.read("/local/sound.cfg"); // prepare the cfg file to be read
+
+ // if key aand value exist, retrieve and store
+ if (cfg.getValue(soundKey, &soundValue[0], sizeof(soundValue))) { // if key aand value exist, retrieve and store
+
+ sound = atoi(soundValue); // convert string to integer
+
+ // set the ListController setting appropriateley
+ if (sound == 1) {
+ SettingController::setCurrentSetting(0);
+ } else {
+ SettingController::setCurrentSetting(1);
+ }
+ }
+
+ adjustSound(); // adjust brightness apprpriately
+ SettingController::showInfo(); //populate the settingController
+ changeScreen = false; // stay on this screen until further notice
+
+ while(!changeScreen) {
+ // mbed goes to sleep to save power
+ Sleep();
+ }
+
+ // detach all interrupts
+ enterButton.rise(NULL);
+ backButton.rise(NULL);
+
+ return -1; // go to the previous screen
+
+}
+
+void SoundScreen::onEnter()
+{
+ if (debounceSuccess()) { // debouncing successful
+
+ // save the setting
+ saveSetting();
+
+ //change the setting marker on the screen accordingly
+ SettingController::changeSetting();
+
+ //adjust the sound accordingly
+ adjustSound();
+
+ playSound();
+ // reset the debounce timer
+ debounce.reset();
+ }
+
+}
+
+void SoundScreen::onBack()
+{
+ if(debounceSuccess()) { // debounce successful
+ // play the sound
+ playSound();
+ changeScreen = true; // user wants to change screen
+ // reset the debounce timer
+ debounce.reset();
+
+ }
+
+
+}
+
+void SoundScreen::onScrollDown()
+{
+ if (debounceSuccess()) { // debouncing successful
+ SettingController::scrollDown(); //scroll Up
+ debounce.reset(); // reset the debounce timer
+ }
+
+}
+
+void SoundScreen::onScrollUp()
+{
+ if (debounceSuccess()) { // debouncing was successful
+ SettingController::scrollUp(); //scroll Down
+ debounce.reset(); // reset the debounce timer
+ }
+
+}
+
+void SoundScreen::saveSetting()
+{
+ // retrieve the current option
+ int currentOption = SettingController::getCurrentOption();
+
+ if ( currentOption == 0) {
+ cfg.setValue(soundKey,"1"); //On
+ } else if ( currentOption == 1) {
+ cfg.setValue(soundKey,"0"); //Off
+ } else {
+ // do nothing
+ }
+
+ // write to the cfg file
+ cfg.write("/local/sound.cfg");
+}
+
+void SoundScreen::adjustSound()
+{
+
+ // retireve currentSetting
+ int currentSetting = SettingController::getCurrentSetting();
+
+ if ( currentSetting == 0) { // On
+ soundFx = true;
+ } else if ( currentSetting == 1) { // Off
+ soundFx = false;
+ } else {
+ // do nothing
+ }
+
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TempViewLogScreen.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,93 @@
+/**
+@file TemperatureViewLogScreen.h
+
+*/
+#ifndef TEMPVIEWLOGSCREEN_H
+#define TEMPVIEWLOGSCREEN_H
+
+#include "DataController.h"
+#include "Inputs.h"
+
+/**
+@brief Displays the Temperature options
+@brief It is a list with two selectable options :\n
+@brief view temp and temp plot\n
+@brief view temp shows the current temperature along with the sentiment\n
+@brief temp plot plots the temperature against time on the LCD screen at various intervals\n
+@author Augustine Kizito K
+@date April 2015
+*/
+
+class TempViewLogScreen : public DataController
+{
+private:
+
+ void onEnter(); // user pressed the enter button
+ void onBack(); // user pressed the back button
+
+public:
+ /**
+ Creates a Temperature View Log Screen instance
+
+ */
+ TempViewLogScreen()
+ :DataController( "/local/temp.cfg", // File location
+ 1) // parameter, 1 for temperatue, 0 for pressure
+ {};
+ /**
+ Manages the execution of the Temperature View Log Screen
+
+ @returns
+
+ -1 - Navigate to previous screen
+
+ */
+ int start(); // Manages the execution of the Temperature Screen
+
+
+};
+
+
+
+
+
+
+int TempViewLogScreen::start()
+{
+ enterButton.mode(PullDown);
+ backButton.mode(PullDown);
+
+ enterButton.rise(this,&TempViewLogScreen::onEnter); // call onEnter when the enter button is pressed
+ backButton.rise(this,&TempViewLogScreen::onBack); // call onBack when the back button is pressed
+
+ debounce.start();
+
+ DataController::begin();
+
+ enterButton.rise(NULL);
+ backButton.rise(NULL);
+ return -1;
+}
+
+void TempViewLogScreen::onEnter()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+ // sound the buzzer
+ playSound();
+ DataController::nextPage();
+ debounce.reset(); // reset the debounce timer
+ }
+
+}
+
+void TempViewLogScreen::onBack()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+ //sound the buzzer
+ playSound();
+ DataController::previousPage();
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TemperatureLog.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,251 @@
+/**
+@file temperaturelog.h
+*/
+
+#ifndef TEMPERATURELOG_H
+#define TEMPERATURELOG_H
+
+#include "Outputs.h"
+#include "ConfigFile.h"
+#include "Sensors.h"
+
+/**
+@brief logs temperature values over a predetermined length of time\n
+@brief the logged data is then stored on the onboard flash memory\n
+@brief the LCD screen is turned off after 5 seconds to save energy
+@date April 2015
+*/
+
+
+
+class TemperatureLog
+{
+private:
+ bool logFinished; // tracks if logging was successfuly finished
+ int logCounter; //tracks how many times data has been logged
+ bool changeScreen; // tracks if the user pressed a button that changes the screen
+ int nextScreen; // tracks whether the user wants to go to
+ //the previous screen or next screen
+ Timeout stop; // timeout that will turn off the screen after a given time
+ Ticker logTimer; // ticker that will log data at intervals
+ Ticker batLedTimer; // ticker that will check battery status at intervals
+ ConfigFile tcfgW; // temperature CFG Write
+
+
+ void onBack(); // user pressed the back button
+ void turnOffScreen(); // powers down the lcd screen
+ void logData(); // logs data by storing it in ConfigFile object
+ void saveData(); // saves data to the mbed flash drive
+ void initCfg(int duration); // initialises the cfg object with vital data
+ void checkBatVoltage(); // checks if batteryVoltage is low
+
+public:
+ /**
+ Manages the execution of the Temperature Log Screen
+
+ @param - integer duration, the length of time to log temperature
+ @returns
+ -1 - navigate to previous screen
+
+ */
+ int start(int duration);
+
+
+};
+
+int TemperatureLog::start(int duration)
+{
+ // initialisations
+ logFinished = false;
+ logCounter = 0;
+ lcd.printString("Logging...",20,2);
+
+ backButton.mode(PullDown); // activate pullDown Resistor
+ backButton.rise(this,&TemperatureLog::onBack); // call onBack when the back button is pressed
+
+ stop.attach(this,&TemperatureLog::turnOffScreen, 5); // turn off LCD screen after 5 seconds
+ batLedTimer.attach(this, &TemperatureLog::checkBatVoltage, 10); // check battery voltage every 5 seconds
+
+ // check battery voltage
+ checkBatVoltage();
+ // turn on the log led
+ turnOnLogLed();
+ // initialise the cfg object
+ initCfg(duration);
+ // start the debounce timer
+
+ debounce.start();
+
+ // 84 data points should be recorded for every log
+
+ logData(); // log the data
+
+ if ( duration == 0) {
+ // this intervals results makes 84 logs in 5 minutes
+ logTimer.attach(this, &TemperatureLog::logData,3.614);
+ } else if ( duration == 1) {
+ // this intervals results makes 84 logs in 10 minutes
+ logTimer.attach(this, &TemperatureLog::logData,7.229);
+ } else if ( duration == 2) {
+ // this intervals results makes 84 logs in 30 minutes
+ logTimer.attach(this, &TemperatureLog::logData,21.687);
+ } else {
+ // this intervals results makes 84 logs in 1 hour
+ logTimer.attach(this, &TemperatureLog::logData,42.373);
+ }
+
+ while (!logFinished) {
+
+ // mbed goes to sleep to save power
+ Sleep();
+
+ }
+
+ // remove interrupts
+ logTimer.detach();
+ backButton.rise(NULL);
+
+ turnOffLogLed();
+
+ return -1;
+}
+
+void TemperatureLog::initCfg( int duration )
+{
+
+ // Create the Duration Key and Value Pair
+ char *theDurationKey = "durationKey";
+ char theDurationValue[32];
+
+ if ( duration == 0 ) {
+
+ char theDurationString[32] = "5 min";
+ strcpy(theDurationValue,theDurationString);
+
+ } else if ( duration == 1) {
+
+ char theDurationString[32] = "10 min";
+ strcpy(theDurationValue,theDurationString);
+
+ } else if ( duration == 2) {
+
+ char theDurationString[32] = "30 min";
+ strcpy(theDurationValue,theDurationString);
+
+ } else {
+
+ char theDurationString[32] = "1 hour";
+ strcpy(theDurationValue,theDurationString);
+ }
+
+ // Create the Time and Value Pair
+ char *theTimeKey = "timeKey";
+ char theTimeValue[32];
+
+ // Create the Date Key and Value Pair
+ char *theDateKey = "dateKey";
+ char theDateValue[32];
+
+ ////GET THE CURRENT TIME///////////
+ time_t seconds = time(NULL);
+ strftime(theDateValue, 32, "%d/%m/%y", localtime(&seconds)); // format the date in day/month/year
+ strftime(theTimeValue, 32, "%R", localtime(&seconds)); // format the time in HH:MM 24 Hr clock
+ ////////////////////////////////////////////
+
+ // set the created Key and Value Pairs to the cfg object
+ tcfgW.setValue(theDateKey,theDateValue);
+ tcfgW.setValue(theTimeKey,theTimeValue);
+ tcfgW.setValue(theDurationKey,theDurationValue);
+
+
+}
+
+void TemperatureLog::logData()
+{
+
+ if ( logCounter < 84 ) { // // data is still logging
+
+ // get the current temperature
+ float temperature = getTemperature();
+
+ // create a new Counter Key and Value Pair
+ char *theCounterKey = "counterKey";
+ char theCounterValue[32] = "";
+
+ // assign the logCounter as the CounterValue
+ sprintf(theCounterValue,"%d",logCounter);
+
+ // Create a new Key and Value Pair
+ char theKey[32] = "key";
+ char theValue[32] = "";
+
+ // concatentate the Key Value and Counter Value strings
+ strcat(theKey,theCounterValue);
+
+ sprintf(theValue,"%0.2f",temperature); // converting float to string
+
+ // set the created key and value pairs to the cfg object
+ tcfgW.setValue(theCounterKey,theCounterValue);
+ tcfgW.setValue(theKey,theValue);
+
+
+ } else {
+
+ saveData(); // save the data
+ logFinished = true; // logging has finished successfully
+ }
+ // increment the log counter
+ logCounter++;
+
+}
+
+void TemperatureLog::saveData()
+{
+ // save the data to onboard flash memory as a cfg file
+ tcfgW.write("/local/temp.cfg");
+
+}
+
+void TemperatureLog::onBack()
+{
+ if (debounceSuccess()) { // debouncing successful
+ playSound();
+ // if user presses the back button, save data and terminate logging
+
+ saveData(); // save the data
+ logFinished = true; // logging has finished successfully
+ debounce.reset(); // reset the debounce timer
+ }
+
+
+}
+
+void TemperatureLog::turnOffScreen()
+{
+ // turn off the LCD screen to save power
+ lcd.turnOff();
+
+}
+
+void TemperatureLog::checkBatVoltage()
+{
+ // read the battery voltage
+ float batteryVoltage = getVoltage();
+
+ if (batteryVoltage < 6.5) { // check if battery is low
+
+ if(!batStatLedState) { // if the battery low led is not already on
+
+ turnOnBatStatLed(); // turn on the battery low led
+ }
+
+ } else {
+
+ turnOffBatStatLed(); // ensure that the battery low led is turned off
+
+ }
+
+
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TemperaturePlot.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,185 @@
+/**
+@file temperatureplot.h
+*/
+#ifndef TEMPERATUREPLOT_H
+#define TEMPERATUREPLOT_H
+
+/**
+@brief displays the temperature against time at various intervals
+@brief temperature is in degrees celsius
+@author Augustine K Kizito
+@data April 2015
+*/
+
+
+
+
+class TemperaturePlot
+{
+private:
+ bool changeScreen; // tracks if the user pressed a button that changes the screen
+ int nextScreen; // tracks whether the user wants to go to
+ //the previous screen or next screen
+ int xCord; // tracks the x coordinate
+ char tempString[32]; // temperature value as string
+ bool pause; // tracks if the plotting has been paused
+ int pInterval; // determines the intervals at which data is plotted
+ Ticker timer; // plots data at particular intervals
+
+ void onBack(); // user pressed the back button
+ void onEnter(); // user pressed the on enter button
+ void plotData(); // plot temperature data
+ void clearPlot(); // clear the plotted data
+ void pausePlot(); // it pauses plotting of data so that the user can see it
+
+public:
+ /**
+ Manages the execution of the Temperature Plot Screen
+
+ @param - integer interval, the intervals after which temperature is plotted against time on the LCD screen
+ @returns
+ -1 - navigate to previous screen
+
+ */
+ int start(int interval);
+
+};
+
+int TemperaturePlot::start(int interval)
+{
+ // Initialisations
+ pInterval = interval;
+ xCord = 0; // set the x cordinate to 0
+ pause = false;
+
+ backButton.mode(PullDown); // activate pullDown Resistor
+ enterButton.mode(PullDown); // activate pullDown Resistor
+
+ backButton.rise(this,&TemperaturePlot::onBack); // call onBack when the back button is pressed
+ enterButton.rise(this,&TemperaturePlot::onEnter); // call onBack when the back button is pressed
+
+ plotData(); //plot data onto the screen
+ lcd.printString("Deg Cel", 40,1);
+
+ // plot data on LCD screen depending on the interval previously selected by the user
+ if ( interval == 0) {
+ timer.attach(this, &TemperaturePlot::plotData,0.1); // call ISR every 1.0 second
+ } else if ( interval == 1) {
+ timer.attach(this, &TemperaturePlot::plotData,0.5); // call ISR every 5 seconds
+ } else if ( interval == 2) {
+ timer.attach(this, &TemperaturePlot::plotData,1); // call ISR every 10 seconds
+ } else {
+ timer.attach(this, &TemperaturePlot::plotData,5); // call ISR every 30 seconds
+ }
+
+ changeScreen = false;
+ debounce.start(); // start the debounce timer
+
+ while (!changeScreen) {
+
+ // mbed goes to sleep to save power
+ Sleep();
+
+ }
+
+ // remove all interrupts
+ backButton.rise(NULL);
+ enterButton.rise(NULL);
+ timer.detach();
+ return nextScreen;
+}
+
+void TemperaturePlot::plotData()
+{
+ if (xCord > 83 ) {
+
+ xCord = 0; // reset the xCord back to zero
+
+ clearPlot(); // clear the plot region
+
+ }
+
+ float temperature = getTemperature(); // retreive temperature from the sensor
+
+ lcd.drawLine(xCord,(31*((50-temperature)/50)+16),xCord,47,1);
+
+ // print temperature onto the screen
+ sprintf(tempString,"%0.2f",temperature);
+ lcd.printString(tempString,0,1);
+
+ // increment the coordinate
+ xCord++;
+
+
+}
+
+void TemperaturePlot::onBack()
+{
+ if(debounceSuccess()) { // debouncing successful
+ // soundt the buzze
+ playSound();
+ nextScreen = -1;
+ changeScreen = true; // user wants to go to a different screen
+ // reset debounce timer
+ debounce.reset();
+ }
+
+}
+
+void TemperaturePlot::clearPlot()
+{
+ // clears the plot area
+
+ for ( int x = 0; x < 84; x++) {
+
+ for ( int y = 16; y < 48; y++) {
+
+ lcd.clearPixel(x,y);
+
+ }
+
+ }
+
+ lcd.refresh();
+
+}
+
+void TemperaturePlot::onEnter()
+{
+ if (debounceSuccess()) { // debouncing successful
+
+ playSound(); // play sound
+ pausePlot(); // pause any plotting
+ debounce.reset(); // reset debounce timer
+ }
+
+}
+
+void TemperaturePlot::pausePlot()
+{
+ pause = !pause;
+
+ if (pause) {
+ timer.detach(); // detach timer and stop plotting data
+ } else {
+
+ clearPlot(); // clear the plot area
+ xCord = 0; // start plotting from extreme left
+ plotData();
+
+ // start plotting data again
+ if ( pInterval == 0) {
+ timer.attach(this, &TemperaturePlot::plotData,0.1); // call ISR every 0.1 second
+ } else if ( pInterval == 1) {
+ timer.attach(this, &TemperaturePlot::plotData,0.5); // call ISR every 0.5 seconds
+ } else if ( pInterval == 2) {
+ timer.attach(this, &TemperaturePlot::plotData,1); // call ISR every 1 seconds
+ } else {
+ timer.attach(this, &TemperaturePlot::plotData,5); // call ISR every 5 seconds
+ }
+
+
+ }
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TemperatureScreen.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,147 @@
+/**
+@file TemperatureScreen.h
+
+*/
+
+#ifndef TEMPERATURESCREEN_H
+#define TEMPERATURESCREEN_H
+
+#include "ListController.h"
+#include "Inputs.h"
+
+/**
+@brief Displays the Temperature options\n
+@brief It is a list with two selectable options :\n
+@brief view temp and temp plot\n
+@brief view temp shows the current temperature along with the sentiment\n
+@brief temp plot plots the temperature against time on the LCD screen at various intervals\n
+@author Augustine Kizito K
+@date April 2015
+*/
+
+
+
+class TemperatureScreen : public ListController // inherit the list Controller properties
+{
+private:
+ bool changeScreen; // tracks if the user pressed a button that changes the screen
+ int nextScreen; // tracks whether the user wants to go to
+ //the previous screen or next screen
+
+ void onScrollUp(); // user pressed the scroll up button
+ void onScrollDown(); // user pressed the scroll down button
+ void onEnter(); // user pressed the enter button
+ void onBack(); // user pressed the back button
+
+public:
+ /**
+ Creates an instance of the Temperature Screen
+
+ */
+ TemperatureScreen()
+ :ListController( "Temperature", // Title
+ "View Temp", // Option 1
+ "Temp Plot", // Option 2
+ "", // Option 3
+ "", // Option 4
+ 2) // Number of Options
+ {};
+ /**
+ Manages the execution of the Temperature Screen
+ @returns
+
+ -1 - Navigate to previous screen\n
+ 0 - User selected option 1\n
+ 1 - User selected option 2
+ */
+ int start();
+
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+int TemperatureScreen::start()
+{
+
+ // Activate PullDown Resistors
+ enterButton.mode(PullDown);
+ upButton.mode(PullDown);
+ downButton.mode(PullDown);
+ backButton.mode(PullDown);
+
+ upButton.rise(this,&TemperatureScreen::onScrollUp); // call onScrollUp when the up button is pressed
+ downButton.rise(this,&TemperatureScreen::onScrollDown); // call onScrollDown when the down button is pressed
+ enterButton.rise(this,&TemperatureScreen::onEnter); // call onEnter when the enter button is pressed
+ backButton.rise(this,&TemperatureScreen::onBack); // call onBack when the back button is pressed
+
+ // Launch the List Controller
+ ListController::showInfo();
+ changeScreen = false;
+
+ debounce.start(); // start the debounce timer
+
+ while(!changeScreen) {
+
+ // mbed goes to sleep to save power
+ Sleep();
+ }
+
+ // detach all interrupts
+ upButton.rise(NULL);
+ downButton.rise(NULL);
+ enterButton.rise(NULL);
+ backButton.rise(NULL);
+
+ return nextScreen;
+}
+
+void TemperatureScreen::onScrollUp()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+
+ ListController::scrollUp(); // scroll up
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void TemperatureScreen::onScrollDown()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+
+ ListController::scrollDown(); // scroll down
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void TemperatureScreen::onEnter()
+{
+ if (debounceSuccess()) { // check if debouncing succeeded
+ playSound();
+ nextScreen = ListController::getCurrentOption(); // get the option that user selected
+ changeScreen = true; // user wants to go to a different screen
+ debounce.reset(); // reset the debounce timer
+ }
+}
+
+void TemperatureScreen::onBack()
+{
+ if(debounceSuccess()) { // if debouncing succeeded
+ playSound();
+ nextScreen = -1; // go to previous screen
+ changeScreen = true; // user wants to go to a different screen
+ debounce.reset(); // reset the debounce timer
+ }
+
+}
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WeatherApp.h Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,912 @@
+/**
+
+@file WeatherApp.h
+
+*/
+
+
+#include "CurrentTemperatureScreen.h"
+#include "TemperatureScreen.h"
+#include "BrightnessScreen.h"
+#include "MainMenuScreen.h"
+#include "SettingsScreen.h"
+#include "TemperaturePlot.h"
+#include "LogScreen.h"
+#include "DurationScreen.h"
+#include "IntervalScreen.h"
+#include "LogOptionScreen.h"
+#include "TempViewLogScreen.h"
+#include "TemperatureLog.h"
+#include "SoundScreen.h"
+#include "Sensors.h"
+#include "PressureScreen.h"
+#include "PressurePlot.h"
+#include "CurrentPressureScreen.h"
+#include "PrsViewLogScreen.h"
+#include "PressureLog.h"
+#include "BatteryStatusScreen.h"
+#include "EthernetPowerControl.h"
+
+/**
+@brief This controls the entire weather application. It is the Navigation Controller
+@brief It determines which screen should be displayed when a button is selected
+@brief It also manages the status bar
+@author Augustine K Kizito
+@date April 2015
+*/
+
+
+class WeatherApp
+{
+private:
+ void appInitialise(); // initalises the weather app
+ void updateStatusBar(); // updates time and battery icon
+ void clearScreen(); // clears everything on the screen apart from the status bar
+ void initSound(); // initialises sound
+ void initBrightness(); // initialises lcd brightness
+
+ Ticker status; // updates the status bar at regular intervals
+public:
+ /**
+ Runs the Weather Application on the mbed
+
+ */
+ void run();
+
+};
+
+void WeatherApp::run()
+{
+ appInitialise();
+
+ // Objects for screens
+ MainMenuScreen menu;
+ TemperatureScreen temp;
+ PressureScreen prs;
+ CurrentTemperatureScreen currTemp;
+ CurrentPressureScreen currPrs;
+ BrightnessScreen bright;
+ SettingsScreen settings;
+ IntervalScreen tempInt;
+ IntervalScreen prsInt;
+ DurationScreen tempDur;
+ DurationScreen prsDur;
+ TemperaturePlot templot;
+ PressurePlot prsplot;
+ LogScreen logg;
+ LogOptionScreen optOne;
+ LogOptionScreen optTwo;
+ TemperatureLog tempLog;
+ PressureLog prsLog;
+ SoundScreen sound;
+ BatteryStatusScreen currBatt;
+
+ // these booleans allow the user to smoothly navigate between layers
+ // the main menu is the first layer, when the user selects an option they go into the second layer and so on.
+ bool backFirstLayer;
+ bool backSecondLayer;
+ bool backThirdLayer;
+ bool backFourthLayer;
+
+ while(1) {
+
+ switch(menu.start()) {
+
+ // Temperature
+ case 0:
+ backFirstLayer = false;
+ clearScreen();
+
+ while(!backFirstLayer) {
+
+ switch(temp.start()) {
+
+ // View Temp
+ case 0:
+ backSecondLayer = false;
+ clearScreen();
+
+ while(!backSecondLayer) {
+
+ switch(currTemp.start()) {
+
+ case -1:
+ clearScreen();
+ backSecondLayer = true;
+ break;
+ }
+ }
+ break;
+
+ //Realtime Plot
+ case 1:
+ backSecondLayer = false;
+ clearScreen();
+
+ while(!backSecondLayer) {
+
+ // Intervals
+
+ switch(tempInt.start()) {
+
+ // 1 second
+ case 0:
+ backThirdLayer = false;
+ clearScreen();
+
+ while(!backThirdLayer) {
+
+ switch(templot.start(0)) {
+
+ // Previous Screen
+ case -1:
+ backThirdLayer = true;
+ clearScreen();
+ break;
+
+ }
+
+ }
+ break;
+
+ // 5 seconds
+ case 1:
+ backThirdLayer = false;
+ clearScreen();
+
+ while(!backThirdLayer) {
+
+ switch(templot.start(1)) {
+
+ // Previous Screen
+ case -1:
+ backThirdLayer = true;
+ clearScreen();
+ break;
+
+ }
+
+ }
+ break;
+
+ // 10 seconds
+ case 2:
+ backThirdLayer = false;
+ clearScreen();
+
+ while(!backThirdLayer) {
+
+ switch(templot.start(2)) {
+
+ // Previous Screen
+ case -1:
+ backThirdLayer = true;
+ clearScreen();
+ break;
+
+ }
+
+ }
+ break;
+
+ // 30 seconds
+ case 3:
+ backThirdLayer = false;
+ clearScreen();
+
+ while(!backThirdLayer) {
+
+ switch(templot.start(3)) {
+
+ case -1:
+ backThirdLayer = true;
+ clearScreen();
+ break;
+
+ }
+
+ }
+ break;
+
+ //Previous Screen
+ case -1:
+ clearScreen();
+ backSecondLayer = true;
+ break;
+ }
+ }
+ break;
+
+ //Previous Screen
+ case -1:
+ backSecondLayer = false;
+ clearScreen();
+ backFirstLayer = true;
+ break;
+
+ }
+ }
+ break;
+
+ // Pressure
+ case 1:
+ backFirstLayer = false;
+ clearScreen();
+
+ while(!backFirstLayer) {
+
+ switch(prs.start()) {
+
+ // View Prs
+ case 0:
+ backSecondLayer = false;
+ clearScreen();
+
+ while(!backSecondLayer) {
+
+ switch(currPrs.start()) {
+
+ // Previous Screen
+ case -1:
+ backSecondLayer = true;
+ clearScreen();
+ break;
+
+ }
+
+ }
+ break;
+
+ // Plot Prs
+ case 1:
+ backSecondLayer = false;
+ clearScreen();
+
+ while(!backSecondLayer) {
+
+ switch(prsInt.start()) {
+
+ // 250 ms
+ case 0:
+ backThirdLayer = false;
+ clearScreen();
+
+ while(!backThirdLayer) {
+ switch(prsplot.start(0)) {
+
+ // Previous Screen
+ case -1:
+ backThirdLayer = true;
+ clearScreen();
+ break;
+
+ }
+
+
+ }
+ break;
+
+ // 500 ms
+ case 1:
+ backThirdLayer = false;
+ clearScreen();
+
+ while(!backThirdLayer) {
+ switch(prsplot.start(1)) {
+
+ // Previous Screen
+ case -1:
+ backThirdLayer = true;
+ clearScreen();
+ break;
+ }
+
+
+ }
+ break;
+
+ // 1 second
+ case 2:
+ backThirdLayer = false;
+ clearScreen();
+
+ while(!backThirdLayer) {
+ switch(prsplot.start(2)) {
+
+ // Previous Screen
+ case -1:
+ backThirdLayer = true;
+ clearScreen();
+ break;
+ }
+
+
+ }
+ break;
+
+ // 5 seconds
+ case 3:
+ backThirdLayer = false;
+ clearScreen();
+
+ while(!backThirdLayer) {
+ switch(prsplot.start(3)) {
+
+ // Previous Screen
+ case -1:
+ backThirdLayer = true;
+ clearScreen();
+ break;
+ }
+
+
+ }
+ break;
+
+ // Previous Screen
+ case -1:
+ backSecondLayer = true;
+ clearScreen();
+ break;
+ }
+ }
+ break;
+
+ // Previous Screen
+ case -1:
+ backFirstLayer = true;
+ clearScreen();
+ break;
+ }
+
+ }
+ break;
+
+ // Log
+ case 2:
+ backFirstLayer = false;
+ clearScreen();
+
+ while(!backFirstLayer) {
+
+ switch(logg.start()) {
+
+ // New Log
+ case 0:
+ backSecondLayer = false;
+ clearScreen();
+
+ while(!backSecondLayer) {
+
+ switch(optOne.start()) {
+
+ //Temperature
+ case 0:
+ backThirdLayer = false;
+ clearScreen();
+
+ while(!backThirdLayer) {
+
+ switch(tempDur.start()) {
+
+ // 5 minutes
+ case 0:
+ backFourthLayer = false;
+ clearScreen();
+ status.detach(); // stop updating status bar
+
+ while (!backFourthLayer) {
+
+ switch(tempLog.start(0)) {
+
+ // Previous Screen
+ case -1:
+ backFourthLayer = true;
+ clearScreen();
+ appInitialise(); // Initialise the app
+
+ }
+
+ }
+ break;
+
+ // 10 minutes
+ case 1:
+ backFourthLayer = false;
+ clearScreen();
+ status.detach(); // stop updating status bar
+
+ while (!backFourthLayer) {
+
+ switch(tempLog.start(1)) {
+
+ // Previous Screen
+ case -1:
+ backFourthLayer = true;
+ clearScreen();
+ appInitialise(); // initialise the app
+
+ }
+
+ }
+ break;
+
+ // 30 minutes
+ case 2:
+ backFourthLayer = false;
+ clearScreen();
+ status.detach(); // stop updating status bar
+
+ while (!backFourthLayer) {
+
+ switch(tempLog.start(2)) {
+
+ // Previous Screen
+ case -1:
+ backFourthLayer = true;
+ clearScreen();
+ appInitialise(); // initialise the app
+
+ }
+
+ }
+ break;
+
+ // 1 Hour
+ case 3:
+ backFourthLayer = false;
+ clearScreen();
+ status.detach(); // stop updating status bar
+
+ while (!backFourthLayer) {
+
+ switch(tempLog.start(3)) {
+
+ // Previous Screen
+ case -1:
+ backFourthLayer = true;
+ clearScreen();
+ appInitialise(); // initialise the app
+
+ }
+
+ }
+ break;
+
+
+ // Previous Screen
+ case -1:
+ backThirdLayer = true;
+ clearScreen();
+
+ }
+ }
+ break;
+
+ //Pressure
+ case 1:
+ backThirdLayer = false;
+ clearScreen();
+
+
+ while(!backThirdLayer) {
+
+ switch(prsDur.start()) {
+
+ // 5 minutes
+ case 0:
+ backFourthLayer = false;
+ clearScreen();
+ status.detach(); // stop updating status bar
+
+ while(!backFourthLayer) {
+
+ switch(prsLog.start(0)) {
+
+ // Previous Screen
+ case -1:
+ backFourthLayer = true;
+ clearScreen();
+ appInitialise(); // initialise the app
+ break;
+
+ }
+
+
+ }
+ break;
+
+ // 10 minutes
+ case 1:
+ backFourthLayer = false;
+ clearScreen();
+ status.detach(); // stop updating status bar
+
+ while(!backFourthLayer) {
+
+ switch(prsLog.start(1)) {
+
+ // Previous Screen
+ case -1:
+ backFourthLayer = true;
+ clearScreen();
+ appInitialise(); // initialise the app
+ break;
+
+ }
+ }
+ break;
+
+ // 30 minutes
+ case 2:
+ backFourthLayer = false;
+ clearScreen();
+ status.detach(); // stop updating status bar
+
+ while(!backFourthLayer) {
+
+ switch(prsLog.start(2)) {
+
+ // Previous Screen
+ case -1:
+ backFourthLayer = true;
+ clearScreen();
+ appInitialise(); // initialise the app
+ break;
+
+ }
+ }
+ break;
+
+ // 1 Hour
+ case 3:
+ backFourthLayer = false;
+ clearScreen();
+ status.detach(); // stop updating status bar
+
+ while(!backFourthLayer) {
+
+ switch(prsLog.start(3)) {
+
+ // Previous Screen
+ case -1:
+ backFourthLayer = true;
+ clearScreen();
+ appInitialise(); // initialise the app
+ break;
+
+ }
+ }
+ break;
+
+ // Previous Screen
+ case -1:
+ backThirdLayer = true;
+ clearScreen();
+ break;
+
+ }
+ }
+ break;
+
+ //Previous Screen
+ case -1:
+ backSecondLayer = true;
+ clearScreen();
+ break;
+
+ }
+
+ }
+ break;
+
+ // View Log
+ case 1:
+ backSecondLayer = false;
+ clearScreen();
+
+ while(!backSecondLayer) {
+
+ switch(optTwo.start()) {
+
+ //Temperature
+ case 0:
+ backThirdLayer = false;
+ clearScreen();
+
+ while(!backThirdLayer) {
+
+ TempViewLogScreen tempView;
+
+ switch(tempView.start()) {
+
+ // Previous Screen
+ case -1:
+ backThirdLayer = true;
+ clearScreen();
+ break;
+ }
+ }
+ break;
+
+ // Pressure
+ case 1:
+ backThirdLayer = false;
+ clearScreen();
+
+ while(!backThirdLayer) {
+
+ PrsViewLogScreen prsView;
+
+ switch(prsView.start()) {
+
+ // Previous Screen
+ case -1:
+ backThirdLayer = true;
+ clearScreen();
+ break;
+ }
+ }
+
+ break;
+
+ // Previous Screen
+ case -1:
+ backSecondLayer = true;
+ clearScreen();
+ break;
+
+ }
+
+
+ }
+ break;
+
+ // Previous Screen
+ case -1:
+ backFirstLayer = true;
+ clearScreen();
+ break;
+ }
+
+
+ }
+ break;
+
+ // Settings
+ case 3:
+ backFirstLayer = false;
+ clearScreen();
+
+ while(!backFirstLayer) {
+
+ switch(settings.start()) {
+
+ // Brightness
+ case 0:
+ backSecondLayer = false;
+ clearScreen();
+
+ while(!backSecondLayer) {
+
+ switch(bright.start()) {
+
+ // Previous Screen
+ case -1:
+ backSecondLayer = true;
+ clearScreen();
+
+ }
+
+ }
+
+ break;
+
+ // Sound FX
+ case 1:
+ backSecondLayer = false;
+ clearScreen();
+
+ while(!backSecondLayer) {
+
+ switch(sound.start()) {
+
+ // Previous Screen
+ case -1:
+ backSecondLayer = true;
+ clearScreen();
+
+ }
+
+ }
+ break;
+
+ // Battery Status
+ case 2:
+ backSecondLayer = false;
+ clearScreen();
+
+ while(!backSecondLayer) {
+
+ switch(currBatt.start()) {
+
+ // Previous Screen
+ case -1:
+ backSecondLayer = true;
+ clearScreen();
+
+ }
+
+ }
+ break;
+
+ // Previous Screen
+ case -1:
+ backFirstLayer = true;
+ clearScreen();
+ break;
+
+
+ }
+ }
+
+ default:
+ // show nothing
+ break;
+
+ }
+
+
+ }
+}
+
+void WeatherApp::updateStatusBar()
+{
+
+ ////GET THE CURRENT TIME///////////
+ time_t seconds = time(NULL);
+
+ char buffer[32];
+ strftime(buffer, 32, "%R", localtime(&seconds)); // format the time in HH:MM 24 Hr clock
+////////////////////////////////////////////
+
+ lcd.printString( buffer, 0,0);// display the time
+
+
+
+ float batteryVoltage = getVoltage();
+
+
+
+
+ // draw the empty battery
+ lcd.setPixel(73,3);
+ lcd.setPixel(72,3);
+ lcd.setPixel(73,4);
+ lcd.setPixel(72,4);
+ lcd.drawRect(74,1,8,5,0);
+ lcd.clearPixel(76,3);
+ lcd.clearPixel(76,4);
+ lcd.clearPixel(78,3);
+ lcd.clearPixel(78,4);
+ lcd.clearPixel(80,3);
+ lcd.clearPixel(80,4);
+
+
+
+ if (batteryVoltage > 7.92) { // battery voltage is greater than 2.6V
+ // battery has three bars
+ lcd.drawLine(76,3,76,4,1);
+ lcd.drawLine(78,3,78,4,1);
+ lcd.drawLine(80,3,80,4,1);
+
+ } else if ( (batteryVoltage < 7.92 )&& (batteryVoltage > 6.5)) { // battery voltage is between 2.64V and 1.65V
+ // battery has two bars
+ lcd.drawLine(78,3,78,4,1);
+ lcd.drawLine(80,3,80,4,1);
+
+ } else if ((batteryVoltage < 6.5) && (batteryVoltage > 6.0)) { // battery voltage is between 1.65V and 0.66V
+ // battery has one bar
+ lcd.drawLine(80,3,80,4,1);
+ } else { // battery voltage is less than 0.66V
+ // empty battery
+ }
+
+ if (batteryVoltage < 6.5) {
+
+ if(!batStatLedState) {
+
+ turnOnBatStatLed();
+ }
+
+
+ } else {
+
+ turnOffBatStatLed();
+
+ }
+
+ lcd.refresh();
+
+}
+
+void WeatherApp::clearScreen()
+{
+ // clear the screen
+ lcd.clear();
+
+ // update the status bar
+ updateStatusBar();
+
+}
+
+void WeatherApp::appInitialise()
+{
+ //*** THIS WAS REMOVED **// it causes program to crash
+ //PHY_PowerDown(); // power down the ethernet port to save power
+
+
+ bmp180.Initialize(); // initialise the temperature/pressure sensor
+ debounceInit(); // initialise the button debouncer
+ lcd.init(); // intialise the lcd
+ //set_time(1431199080); // used to set unix time
+ updateStatusBar(); // update status bar
+ status.attach(this,&WeatherApp::updateStatusBar, 10.0); // update the status bar every 10 seconds
+ initSound(); // initialise sound
+ initBrightness(); // initialsie brightness
+
+
+}
+
+void WeatherApp::initSound() // initialise sound
+{
+ // sound key and value pair
+ char *soundKey = "sound ";
+ char soundValue[BUFSIZ];
+
+ // prepare the cfg file to be read
+ cfg.read("/local/sound.cfg");
+
+ // if key and value exist, retrieve and store
+ if (cfg.getValue(soundKey, &soundValue[0], sizeof(soundValue))) {
+
+ int sound = atoi(soundValue); // convert string to integer
+
+ // set the sound appropriateley
+ if (sound == 1) {
+ soundFx = true; // sound on
+ } else {
+ soundFx = false; // sound off
+ }
+ }
+
+}
+
+void WeatherApp::initBrightness() // initialises brightness
+{
+ // brightness key and value pair
+ char *brightnessKey = "brightness ";
+ char brightnessValue[BUFSIZ];
+
+ // prepare the cfg file to be read
+ cfg.read("/local/bright.cfg");
+
+ // if key aand value exist, retrieve and store
+ if (cfg.getValue(brightnessKey, &brightnessValue[0], sizeof(brightnessValue))) {
+
+ int brightness = atoi(brightnessValue); // convert string to integer
+ currentBrightness = brightness;
+
+ // set the lcd brightness appropriately
+ if (brightness == 100) {
+ lcd.setBrightness(1.0); // 100 %
+ } else if (brightness == 50) {
+ lcd.setBrightness(0.5); // 50 %
+ } else if (brightness == 25) {
+ lcd.setBrightness(0.25); // 25 %
+ } else {
+ lcd.setBrightness(0); // Off
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/beep.lib Mon May 11 15:25:52 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/dreschpe/code/beep/#d8e14429a95f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Mon May 11 15:25:52 2015 +0000
@@ -0,0 +1,7 @@
+#include "WeatherApp.h"
+
+int main(){
+
+ WeatherApp weather; // create weather application object
+ weather.run(); // run the weather application
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon May 11 15:25:52 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/8e73be2a2ac1 \ No newline at end of file