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

Dependencies:   BMP180 ConfigFile N5110 PowerControl beep mbed

DataController.h

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

File content as of revision 0:da2b8c7a1ec1:

/**
@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