Year Two Project ELEC 2645: Embedded Systems Project Portable Weather Station

Dependencies:   BMP180 ConfigFile N5110 PowerControl beep mbed

WeatherApp.h

Committer:
OHstin
Date:
2015-05-11
Revision:
0:da2b8c7a1ec1

File content as of revision 0:da2b8c7a1ec1:

/**

@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
        }
    }

}