This program consists of the software developed for the ELEC5870M Individual Project. It runs on the mbed LPC1768. It uses the mbed RTOS to perform the following tasks: - Implements intuitive GUI with buttons, LCD TFT Display and LEDs. - Serial Communication with the RPi - I2C communication with INA219 voltage current sensors - Power control at the USB ports

Dependencies:   Adafruit_GFX Adafruit_ST7735 INA219 MODSERIAL MbedJSONValue mbed-rtos mbed

Files at this revision

API Documentation at this revision

Comitter:
OHstin
Date:
Sun Apr 30 17:19:22 2017 +0000
Parent:
5:366f17f1ea9b
Commit message:
Final Code for mbed operation

Changed in this revision

INA219.lib Show annotated file Show diff for this revision Revisions of this file
Inputs.h Show annotated file Show diff for this revision Revisions of this file
Logs/LogManager.h Show annotated file Show diff for this revision Revisions of this file
MbedJSONValue.lib Show annotated file Show diff for this revision Revisions of this file
Outputs.h Show annotated file Show diff for this revision Revisions of this file
RaspiSerial.h Show annotated file Show diff for this revision Revisions of this file
Screens/BatteriesScreen.h Show annotated file Show diff for this revision Revisions of this file
Screens/BatteryScreen.h Show annotated file Show diff for this revision Revisions of this file
Screens/LogScreen.h Show annotated file Show diff for this revision Revisions of this file
Screens/LogSelectScreen.h Show annotated file Show diff for this revision Revisions of this file
Screens/OutputScreen.h Show annotated file Show diff for this revision Revisions of this file
Screens/RaspberryPiScreen.h Show annotated file Show diff for this revision Revisions of this file
Screens/Screens.h Show annotated file Show diff for this revision Revisions of this file
Screens/SettingsScreen.h Show annotated file Show diff for this revision Revisions of this file
Screens/UtilityScreen.h Show annotated file Show diff for this revision Revisions of this file
Screens/ViewLogScreen.h Show annotated file Show diff for this revision Revisions of this file
SensorModel.h Show annotated file Show diff for this revision Revisions of this file
SensorSuite.h Show annotated file Show diff for this revision Revisions of this file
Settings/SettingsTest.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r 366f17f1ea9b -r 196a63a3378d INA219.lib
--- a/INA219.lib	Thu Mar 23 10:59:50 2017 +0000
+++ b/INA219.lib	Sun Apr 30 17:19:22 2017 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/kenjiArai/code/INA219/#4d7fa8c64fae
+https://developer.mbed.org/users/OHstin/code/INA219/#4d7fa8c64fae
diff -r 366f17f1ea9b -r 196a63a3378d Inputs.h
--- a/Inputs.h	Thu Mar 23 10:59:50 2017 +0000
+++ b/Inputs.h	Sun Apr 30 17:19:22 2017 +0000
@@ -14,19 +14,54 @@
 Timer debounce;
 Ticker timerRefresh;
 
-//AnalogIn ain(p20);
-float ain = 0.5;
-float ain1 = 0.5;
-float ain2 = 0.5;
-//AnalogIn ain1(p19);
-//AnalogIn ain2(p18);
+AnalogIn ain(p20);
+//float ain = 0.5;
+//float ain1 = 0.5;
+//float ain2 = 0.5;
+AnalogIn ain1(p19);
+AnalogIn ain2(p18);
 
 int getBatteryPercentage()
 {
 
-    // read from the potentiometer
-    int percentage = ain2*100;
+    // Define SensorSuite class to access the data
+    SensorSuite suite;
+    // create sensor model to get battery data
+    BatteryModel model;
+    model = suite.getBatteryData();
+    
+    float percentage1 = ((model.batteryOneVoltage-3.0)/1.2)*100;
+    
+    float percentage2 = ((model.batteryTwoVoltage-3.0)/1.2)*100;
+    
+    // because battery one has 6600mAH and battery two has 4400mAH
+    int percentage = percentage1*0.6+percentage2*0.4;
+
+    return percentage;
+}
 
+int getBatteryOnePercentage()
+{
+    // Define SensorSuite class to access the data
+    SensorSuite suite;
+    // create sensor model to get battery data
+    BatteryModel model;
+    model = suite.getBatteryData();
+    
+    int percentage = ((model.batteryOneVoltage-3.0)/1.2)*100;
+    return percentage;
+}
+
+int getBatteryTwoPercentage()
+{
+    // Define SensorSuite class to access the data
+    SensorSuite suite;
+    // create sensor model to get battery data
+    BatteryModel model;
+    model = suite.getBatteryData();
+    
+    int percentage = ((model.batteryTwoVoltage-3.0)/1.2)*100;
+    
     return percentage;
 }
 
@@ -73,9 +108,14 @@
 {
 
     bool outputStatus;
+    
+    // Define SensorSuite class to access the data
+    SensorSuite suite;
+    // create sensor model to get consumption data
+    ConsumptionModel model = suite.getConsumptionData();
 
-    // read the potentiometer
-    if (ain > 0.5) {
+    // read the current
+    if (model.consumptionCurrent > 20) {
         outputStatus = true;
     } else {
         outputStatus = false;
@@ -121,6 +161,21 @@
     }
 }
 
+float getConsumptionPower()
+{
+    // Define SensorSuite class to access the data
+    SensorSuite suite;
+    // create sensor model to get battery data
+    ConsumptionModel model = suite.getConsumptionData();
+
+    // return the power
+    if (model.consumptionCurrent > 0.5) {
+        return model.consumptionCurrent*model.consumptionVoltage*0.001;
+    } else {
+        return 0.0;
+    }
+}
+
 template < class T >
 class Button
 {
diff -r 366f17f1ea9b -r 196a63a3378d Logs/LogManager.h
--- a/Logs/LogManager.h	Thu Mar 23 10:59:50 2017 +0000
+++ b/Logs/LogManager.h	Sun Apr 30 17:19:22 2017 +0000
@@ -3,8 +3,14 @@
 
 #include "LogRecord.h"
 
+// stores
+struct LogInstructions{
+    int parameter;
+    int duration;    
+} logInstructions;  
+
+
 const static char *LOGDATA_LOC = "/local/log.txt";
-
 const static char *LOGDATA1_LOC = "/local/log6.txt";
 const static char *LOGDATA2_LOC = "/local/log2.txt";
 const static char *LOGDATA3_LOC = "/local/log5.txt";
@@ -51,6 +57,8 @@
 {
     // loops through the data structure to find an available
     // spot in the log structure
+    
+
 
     int id = 0;
     if(!logAvailable(id)) {
@@ -58,7 +66,9 @@
         // for example show display message
         return;
     }
-
+    
+    
+    
     // determine the location of the log
     switch(id) {
         case 1:
@@ -76,6 +86,8 @@
         default:
             break;
     }
+    
+    
 
     // id will have the location of the empty log
     //create Log ID
@@ -95,17 +107,27 @@
 
     // intialises the log structure
     // e.g parameter, duration etc
+    
+
     record = new LogRecord(currLog);
     record->initialiseRecord(temp,parameter,duration);
-
+    
+    
     // write the data to file
     writeData(temp,logLocation);
+    
+
+    
+    //RtosTimer timer()
 
     // set an interrupt to do this depending on the interval
     timer1.attach(callback(this,&LogManager::updateLog),10.0); // call ISR every 10.0 seconds
 
     // starts updating the log
     updateLog();
+    
+    
+    
 }
 
 void LogManager::updateLog()
diff -r 366f17f1ea9b -r 196a63a3378d MbedJSONValue.lib
--- a/MbedJSONValue.lib	Thu Mar 23 10:59:50 2017 +0000
+++ b/MbedJSONValue.lib	Sun Apr 30 17:19:22 2017 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/samux/code/MbedJSONValue/#c6f16dde5c94
+https://developer.mbed.org/users/OHstin/code/MbedJSONValue/#c6f16dde5c94
diff -r 366f17f1ea9b -r 196a63a3378d Outputs.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Outputs.h	Sun Apr 30 17:19:22 2017 +0000
@@ -0,0 +1,13 @@
+#ifndef OUTPUTS_H
+#define OUTPUTS_H
+
+#include "Adafruit_ST7735.h"
+
+Adafruit_ST7735 tft(p11, p12, p13, p16, p14, p15); // MOSI, MISO, SCLK, SSEL, TFT_DC, TFT_RST
+DigitalOut RPiLED(p30);    // LED to show RPi is active
+DigitalOut utilityLED(p29);    // LED to show Utility Port is active
+DigitalOut batteryOneLowLED(p26);  // LED to show Battery One voltage is low
+DigitalOut batteryTwoLowLED(p25);     // LED to show Battery Two voltage is low
+//DigitalOut loggingLED(p24);         // LED to show logging is active
+
+#endif
\ No newline at end of file
diff -r 366f17f1ea9b -r 196a63a3378d RaspiSerial.h
--- a/RaspiSerial.h	Thu Mar 23 10:59:50 2017 +0000
+++ b/RaspiSerial.h	Sun Apr 30 17:19:22 2017 +0000
@@ -1,10 +1,10 @@
 #ifndef RASPISERIAL_H
 #define RASPISERIAL_H
-
 #include "MbedJSONValue.h"
 #include "MODSERIAL.h"
 #include <string>
 MODSERIAL raspi(p28, p27); // tx, rx
+DigitalOut piPin(p7);
 
 // this function determines wherther serial is active or inactive
 
@@ -29,6 +29,8 @@
     float b2Current = 0.0;
     float sVoltage = 0.0;
     float sCurrent = 0.0;
+    float oVoltage = 0.0;
+    float oCurrent = 0.0;
 
     // define string to store rounded off sensor data
     char b1VoltageString[5];
@@ -37,17 +39,21 @@
     char b2CurrentString[5];
     char sVoltageString[5];
     char sCurrentString[5];
+    char oVoltageString[5];
+    char oCurrentString[5];
 
     // get access to the sensor suite
     SensorSuite suite;
  
 
     // power up the raspberry pi
+    piPin = 1;
 
     // give the pi some time to boot
-
+    //Thread::wait(1000*10);
+    
     // wait for character x
-    int counter = 120;  // count down to 2 minutes
+    int counter = 180;  // count down to 3 minutes
     char x = NULL;
     while(counter > 0 && x != 'x') {
         x = raspi.getc();
@@ -106,6 +112,16 @@
         // read solar panel data
         sVoltage = sModel.solarVoltage;
         sCurrent = sModel.solarCurrent;
+        
+        
+        
+        // create model to get consumption data
+        ConsumptionModel oModel = suite.getConsumptionData();
+        // read the consumption data
+        oVoltage = oModel.consumptionVoltage;
+        oCurrent = oModel.consumptionCurrent;
+        
+        
 
         ////////////////////////////////////////////////////////////////////////
 
@@ -123,6 +139,8 @@
         sprintf(b2CurrentString,"%0.2f",b2Current);
         sprintf(sVoltageString,"%0.2f",sVoltage);
         sprintf(sCurrentString,"%0.2f",sCurrent);
+        sprintf(oVoltageString,"%0.2f",oVoltage);
+        sprintf(oCurrentString,"%0.2f",oCurrent);
 
         // construct json data
         holder["b1V"] = b1VoltageString;
@@ -131,6 +149,8 @@
         holder["b2C"] = b2CurrentString;
         holder["sV"]  = sVoltageString;
         holder["sC"]  = sCurrentString;
+        holder["oV"]  = oVoltageString;
+        holder["oC"]  = oCurrentString;
 
         // convert json data to string
         jsonString = holder.serialize();
@@ -226,6 +246,9 @@
     }
     
     if (p == 'x') {
+        Thread::wait(1000*12);// wait 12 seconds
+        piPin = 0;
+        myled = 0;
         piStatus = false;
         // send message that connection was made
         serial_ui_letter *letter2 = serial_ui_mail.alloc();
diff -r 366f17f1ea9b -r 196a63a3378d Screens/BatteriesScreen.h
--- a/Screens/BatteriesScreen.h	Thu Mar 23 10:59:50 2017 +0000
+++ b/Screens/BatteriesScreen.h	Sun Apr 30 17:19:22 2017 +0000
@@ -93,7 +93,8 @@
 {
 
     // percentage
-    int batteryPercentage = getBatteryPercentage();
+    int batteryOnePercentage = getBatteryOnePercentage();
+    int batteryTwoPercentage = getBatteryTwoPercentage();
 
     // batteryStatus
     int batteryStatus = getBatteryStatus();
@@ -109,8 +110,8 @@
         batteryTwoCharging = true;
     }
 
-    batteryOne->setBatteryPercentage(batteryPercentage, batteryOneCharging);
-    batteryTwo->setBatteryPercentage(batteryPercentage, batteryTwoCharging);
+    batteryOne->setBatteryPercentage(batteryOnePercentage, batteryOneCharging);
+    batteryTwo->setBatteryPercentage(batteryTwoPercentage, batteryTwoCharging);
 }
 
 
diff -r 366f17f1ea9b -r 196a63a3378d Screens/BatteryScreen.h
--- a/Screens/BatteryScreen.h	Thu Mar 23 10:59:50 2017 +0000
+++ b/Screens/BatteryScreen.h	Sun Apr 30 17:19:22 2017 +0000
@@ -18,6 +18,7 @@
     char voltage_text[20];
     float current;
     float voltage;
+    float power;
     int changeScreen;
     int battery;
     uint16_t backgroundColor;   // stores the background color
@@ -48,6 +49,7 @@
     // initial values
     current = -1.0;
     voltage = -1.0;
+    power = -1.0;
     
     battery = batt; // determine the battery
     
@@ -107,7 +109,7 @@
 
     // display capacity remaining
     tft.setCursor(0, 80);
-    tft.printf("CAPACITY REMAINING[mAH]");
+    tft.printf("POWER[W]");
 
 }
 
@@ -119,6 +121,7 @@
     
     float newCurrent;
     float newVoltage;
+    float newPower;
     
     switch(battery) {
         case BATTERY_ONE:
@@ -133,6 +136,8 @@
             break;
     }
     
+    newPower = newCurrent*newVoltage*0.001;
+    
     int added = 10;
     tft.setTextWrap(true);
     //tft.setTextColor(textColor);
@@ -170,13 +175,29 @@
         tft.printf("%+6.3f",newCurrent);
     }
     
+    // display the power
+    if (newPower == power){
+        // do nothing    
+    } else {
+        
+        // first delete the previous value
+        tft.setCursor(0, 80+added);
+        tft.setTextColor(backgroundColor);
+        tft.printf("%+6.3f",power);
+        
+        // then write the new current values
+        tft.setCursor(0, 80+added);
+        tft.setTextColor(textColor);
+        tft.printf("%+6.3f",newPower);
+    }
+    
 
     // display capacity remaining
-    tft.setCursor(0, 80+added);
-    tft.printf("1800");
+    //tft.setCursor(0, 80+added);
     
     voltage = newVoltage;
     current = newCurrent;
+    power = newPower;
 }
 
 void BatteryScreen::buttonPressed( int button )
diff -r 366f17f1ea9b -r 196a63a3378d Screens/LogScreen.h
--- a/Screens/LogScreen.h	Thu Mar 23 10:59:50 2017 +0000
+++ b/Screens/LogScreen.h	Sun Apr 30 17:19:22 2017 +0000
@@ -35,7 +35,7 @@
     
     changeScreen = 0;
     scroll = false;
-    enter = true;
+    enter = false;
     
     
     while (changeScreen == 0){
@@ -103,6 +103,7 @@
         case ENTERBUTTON:
             // navigate to the selected option
             enter = true;
+            break;
             
         default:
             // do nothing
diff -r 366f17f1ea9b -r 196a63a3378d Screens/LogSelectScreen.h
--- a/Screens/LogSelectScreen.h	Thu Mar 23 10:59:50 2017 +0000
+++ b/Screens/LogSelectScreen.h	Sun Apr 30 17:19:22 2017 +0000
@@ -105,6 +105,7 @@
         case ENTERBUTTON:
             // navigate to the selected option
             enter = true;
+            break;
             
         default:
             // do nothing
diff -r 366f17f1ea9b -r 196a63a3378d Screens/OutputScreen.h
--- a/Screens/OutputScreen.h	Thu Mar 23 10:59:50 2017 +0000
+++ b/Screens/OutputScreen.h	Sun Apr 30 17:19:22 2017 +0000
@@ -13,8 +13,11 @@
 private:
     void drawOutputScreen();
     void drawTile();
+    void updateTile();
+    void drawWattage(float wattage, uint16_t color);
 
     int changeScreen;
+    float previousWattage;
     ListController *list;   // manages the list
     bool scroll;    // updated when a scroll event occurs
     bool enter;     // updated when an enter event occurs
@@ -30,6 +33,7 @@
 
 int OutputScreen::start()
 {
+    previousWattage = -1;
 
     // draw the screen
     drawOutputScreen();
@@ -43,7 +47,7 @@
 
 
     while (changeScreen == 0) {
-        //updateTile();
+        updateTile();
 
         // scroll event occured
         if (scroll) {
@@ -95,16 +99,103 @@
     //Button<BatteriesScreen>::activateButtons();
 }
 
+
+
 void OutputScreen::drawTile()
-{
-    // draw the tile background
+{   
+    // draw the green background
     tft.fillRect(0,0,tft.width(),63,ST7735_YELLOW);
+    
+    // draw the text
+    tft.setTextSize(1);
+    tft.setCursor(5,5);
+    tft.setTextColor(ST7735_BLUE);
+    tft.printf("Power:");
+    
+    // update the power values
+    updateTile();
+}
 
-    // the design of this tile is pending
-    tft.setCursor(5,5);
-    tft.setTextSize(1);
-    tft.setTextColor(ST7735_RED);
-    tft.printf("To be designed!...");
+void OutputScreen::updateTile()
+{
+    // read the current power
+    float wattage = getConsumptionPower();
+    
+    // temporary storage
+    char wattageString[5];
+    
+    // tracks previously measured power
+    // ensure first value is ridiculous 
+    // to enable print on startup
+    //static float previousWattage = -1;
+    
+    //  convert float to char*
+    //  to round off to 1 decimal place
+    sprintf(wattageString,"%.1f",wattage);    
+    
+    // convert back to float
+    wattage = atof(wattageString);
+    
+    // multiply by 10
+    wattage = wattage*10;
+    
+    // convert float to integer
+    float currentWattage = wattage;
+    
+    if(currentWattage != previousWattage){
+        
+        // first delete the previous wattage
+        drawWattage(previousWattage,ST7735_YELLOW);
+        // then write the new wattage
+        drawWattage(currentWattage,ST7735_RED);
+        
+    
+    }else{
+        // do nothing    
+    }
+    
+    // update the previous wattage
+    previousWattage = currentWattage;
+}
+
+void OutputScreen::drawWattage(float wattage, uint16_t color)
+{
+    // convert float to integer
+    int wattageInt = wattage;
+    
+    // divide by 10
+    int firstInt = wattageInt/10;
+    
+    // print the quotient as the first value
+    int secondInt = wattageInt%10;
+    
+    // the coordinates of the first large digit
+    int startWidth = 40;
+    int startHeight = 15;
+    
+    // The first Large Digit
+    tft.setTextSize(6);
+    tft.setCursor(startWidth, startHeight);
+    tft.setTextColor(color);
+    tft.printf("%d",firstInt);
+    
+    // the decimal point
+    tft.setCursor(startWidth+ 28, startHeight + 21);
+    tft.setTextSize(3);
+    tft.printf(".");
+    
+    // The second Large Digit
+    tft.setCursor(startWidth + 45, startHeight);
+    tft.setTextSize(6);
+    tft.printf("%d", secondInt);
+    
+    // The power units
+    tft.setCursor(startWidth + 80, startHeight + 15);
+    tft.setTextSize(3);
+    tft.printf("W");
+    
+    // reset the text size to smallest  
+    tft.setTextSize(1);  
 }
 
 void OutputScreen::buttonPressed(int button)
diff -r 366f17f1ea9b -r 196a63a3378d Screens/RaspberryPiScreen.h
--- a/Screens/RaspberryPiScreen.h	Thu Mar 23 10:59:50 2017 +0000
+++ b/Screens/RaspberryPiScreen.h	Sun Apr 30 17:19:22 2017 +0000
@@ -92,6 +92,8 @@
                 if (piCxn == 0) {
                     // pi attempts to connect
                     piCxn = 1;
+                    
+                    // turn on pi LED
 
                     // initiate connection here
                     connectPi();
@@ -200,20 +202,24 @@
         // secondly write the new connection words
         switch(piCxn) {
 
-                // delete "DISCONNECTED"
+                // write "DISCONNECTED"
             case 0:
                 tft.printf("DISCONNECTED");
+                // turn off PI LED
+                RPiLED = 0;
                 break;
-                // delete "CONNECTING..."
+                // write "CONNECTING..."
             case 1:
                 tft.printf("CONNECTING...");
+                // turn on PI LED
+                RPiLED = 1;
                 break;
-                // delete "CONNECTED"
+                // write "CONNECTED"
             case 2:
                 tft.printf("CONNECTED");
                 break;
             case 3:
-                // delete "DISCONNECTING..."
+                // write "DISCONNECTING..."
                 tft.printf("DISCONNECTING...");
                 break;
 
diff -r 366f17f1ea9b -r 196a63a3378d Screens/Screens.h
--- a/Screens/Screens.h	Thu Mar 23 10:59:50 2017 +0000
+++ b/Screens/Screens.h	Sun Apr 30 17:19:22 2017 +0000
@@ -16,5 +16,6 @@
 #include "RecordScreen.h"
 #include "SolarValueScreen.h"
 #include "RaspberryPiScreen.h"
+#include "UtilityScreen.h"
 
 #endif
\ No newline at end of file
diff -r 366f17f1ea9b -r 196a63a3378d Screens/SettingsScreen.h
--- a/Screens/SettingsScreen.h	Thu Mar 23 10:59:50 2017 +0000
+++ b/Screens/SettingsScreen.h	Sun Apr 30 17:19:22 2017 +0000
@@ -72,6 +72,8 @@
 {
 
     // construct the list
+    
+    /**
     list = new ListController( 0,
                                0,
                                "Settings",
@@ -81,6 +83,18 @@
                                "",
                                backgroundColor,
                                2);
+                               
+    **/
+    
+    list = new ListController( 0,
+                               0,
+                               "Settings",
+                               "LCD Screen",
+                               "",
+                               "",
+                               "",
+                               backgroundColor,
+                               1);
 
     // draw the list
     list->drawList();
diff -r 366f17f1ea9b -r 196a63a3378d Screens/UtilityScreen.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Screens/UtilityScreen.h	Sun Apr 30 17:19:22 2017 +0000
@@ -0,0 +1,372 @@
+#ifndef UTILITYSCREEN_H
+#define UTILITYSCREEN_H
+
+
+DigitalOut utilityPin(p8);
+int uCxn = 0;      // tracks the connection of the raspberry pi
+int prevuCxn = 0;  // tracks the previous connection of the raspberry pi
+
+class UtilityScreen: public Button <UtilityScreen>
+{
+public:
+    UtilityScreen(uint16_t backgroundColor);
+    int start();
+    void buttonPressed(int button);
+
+private:
+    void drawUtilityScreen();
+    void drawData();
+    void displayStaticData();
+    void displayDynamicData();
+    void updateData();
+    void deAllocateMemory();
+    void turnOnUtilityPort();
+    void turnOffUtilityPort();
+
+    // list
+    ListController *list;
+    // updated when a scroll event occurs
+    bool scroll;
+    // updated when an enter event occurs
+    bool enter;
+    // background color
+    uint16_t bgColor;
+    // text color;
+    uint16_t textColor;
+    
+    float current;
+    float voltage;
+    float power;
+
+    int changeScreen;
+
+};
+
+UtilityScreen::UtilityScreen(uint16_t backgroundColor)
+{
+    bgColor = backgroundColor;
+    // determine the color of text
+    if (bgColor == ST7735_WHITE ) {
+        textColor = ST7735_RED;
+    } else if (bgColor == ST7735_BLACK) {
+        textColor = ST7735_CYAN;
+    }
+}
+
+int UtilityScreen::start()
+{
+    // initial values
+    current = -1.0;
+    voltage = -1.0;
+    power = -1.0;
+    
+    // draw the screen
+    drawUtilityScreen();
+
+    // attach interrupts to buttons
+    Button<UtilityScreen>::activateButtons(this);
+
+    changeScreen = 0;
+    scroll = false;
+    enter = false;
+
+    while(changeScreen==0) {
+
+        // update the raspberyy pi data
+        updateData();
+
+        // scroll event occured
+        if(scroll) {
+            // perform scroll on the list
+            list->scroll();
+            // reset variable
+            scroll = false;
+        }
+
+        // enter event occured
+        if (enter) {
+            // read the current option on the list
+            int option = list->getCurrentOption();
+
+            if (option == 1) {
+                // make connection with pi
+                //myled = 1;
+
+                // first status of utility port
+                //piCxn = 1;
+                
+                // utility port is not yet turned on
+                if (uCxn == 0) {
+                    // turn on utlity port
+                    uCxn = 1;
+
+                    // initiate connection here
+                    turnOnUtilityPort();
+
+                } else {
+                    // do nothing
+                }
+
+
+            } else {
+                // disconnect with pi
+                //piCxn = 3;
+
+                // first check the pi connection
+                if (uCxn == 1) { // utility port is turned on
+                    // turn off the utility port
+                    uCxn = 0;
+                    turnOffUtilityPort();
+
+                } else {
+                    // do nothing
+                }
+                //myled = 0;
+            }
+            enter = false;
+        }
+
+        Thread::wait(200);
+    }
+
+    // detach interrupts to buttons
+    Button<UtilityScreen>::deActivateButtons();
+
+    // free up any memory
+    deAllocateMemory();
+
+    return changeScreen;
+}
+
+void UtilityScreen::updateData()
+{
+
+    displayDynamicData();
+    
+   
+
+}
+
+void UtilityScreen::drawUtilityScreen()
+{
+    // draw static data here
+    tft.setTextColor(textColor);
+    
+
+    displayStaticData();
+
+
+
+    // construct the list
+    list = new ListController( 0,
+                               63,
+                               "Turn Port on",
+                               "Yes",
+                               "No",
+                               "",
+                               "",
+                               bgColor,
+                               2);
+
+    // draw the list
+    list->drawList();
+    
+
+}
+
+void UtilityScreen::displayStaticData()
+{ 
+    
+    // the static data is displayed here e.g headings
+    tft.setTextWrap(true);
+    tft.setTextColor(textColor);
+
+    // display title
+    char title[20];
+    if (uCxn){
+     strcpy(title,"UTILITY PORT ON");   
+    } else {
+     strcpy(title,"UTILITY PORT OFF");  
+    }
+    tft.setCursor((tft.width()/2)-50,4);
+    tft.printf("%s",title);
+
+    // display voltage
+    tft.setCursor(0, 20);
+    tft.printf("VOLTAGE[V]:");
+
+    // display minimum
+    tft.setCursor(0, 35);
+    tft.printf("CURRENT[mA]:");
+
+    // display capacity remaining
+    tft.setCursor(0, 50);
+    tft.printf("POWER[W]:");
+
+}
+
+
+void UtilityScreen::displayDynamicData()
+{
+    // first retrieve data from the sensor suite
+    SensorSuite suite;
+    ConsumptionModel model = suite.getConsumptionData();
+    
+    float newCurrent;
+    float newVoltage;
+    float newPower;
+    
+    newCurrent = model.consumptionCurrent;
+    newVoltage = model.consumptionVoltage;
+    newPower = newCurrent*newVoltage*0.001;
+    
+    
+    
+
+    tft.setTextWrap(true);
+    //tft.setTextColor(textColor);
+    
+    // the dynamic data is displayed here e.g values
+    
+    if (newVoltage == voltage)
+    {
+        // do nothing    
+    }  else {
+        
+        tft.setCursor(tft.width()/2, 20);
+        // first delete the previous value
+        tft.setTextColor(backgroundColor);
+        tft.printf("%+6.3f",voltage);
+        
+        tft.setCursor(tft.width()/2, 20);
+        // then write the new voltage values
+        tft.setTextColor(textColor);
+        tft.printf("%+6.3f",newVoltage);
+    }
+    
+    if (newCurrent == current){
+        // do nothing    
+    } else {
+        
+        // first delete the previous value
+        tft.setCursor(tft.width()/2, 35);
+        tft.setTextColor(backgroundColor);
+        tft.printf("%+6.3f",current);
+        
+        // then write the new current values
+        tft.setCursor(tft.width()/2, 35);
+        tft.setTextColor(textColor);
+        tft.printf("%+6.3f",newCurrent);
+    }
+    
+     if (newPower == power)
+    {
+        // do nothing    
+    }  else {
+        
+        tft.setCursor(tft.width()/2, 50);
+        // first delete the previous value
+        tft.setTextColor(backgroundColor);
+        tft.printf("%+6.3f",power);
+        
+        tft.setCursor(tft.width()/2, 50);
+        // then write the new voltage values
+        tft.setTextColor(textColor);
+        tft.printf("%+6.3f",newPower);
+    }
+    
+
+   
+    
+    voltage = newVoltage;
+    current = newCurrent;
+    power = newPower;
+}
+
+
+void UtilityScreen::deAllocateMemory()
+{
+    // deallocate memory that was created dynamically
+    delete list;
+}
+
+void UtilityScreen::buttonPressed(int button)
+{
+    switch(button) {
+
+        case BACKBUTTON:
+            // navigate to the previous screen
+            changeScreen = -1;
+            break;
+
+        case SCROLLBUTTON:
+            // scroll to the next option
+            scroll = true;
+            break;
+
+        case ENTERBUTTON:
+            // navigate to the selected option
+            enter = true;
+            break;
+
+        default:
+            // do nothing
+            break;
+    }
+}
+
+void UtilityScreen::turnOnUtilityPort()
+{
+    /**
+    ui_serial_letter *letter2 = ui_serial_mail.alloc();
+    letter2->activateSerial = true;
+    ui_serial_mail.put(letter2);
+    
+    // start the thread 
+     // launch serial communication with raspberry pi
+    
+    thread3.start(raspiSerial);
+    
+    **/
+    
+    // turn on utility port
+    utilityPin = 1;
+    utilityLED = 1;
+    
+    // delete text "UTILITY PORT OFF"
+    tft.setTextColor(backgroundColor);
+    tft.setCursor((tft.width()/2)-50,4);
+    tft.printf("UTILITY PORT OFF");
+    
+    
+    // print text "UTILITY PORT ON"
+    tft.setTextColor(textColor);
+    tft.setCursor((tft.width()/2)-50,4);
+    tft.printf("UTILITY PORT ON");
+}
+
+void UtilityScreen::turnOffUtilityPort()
+{
+    /**
+    ui_serial_letter *letter2 = ui_serial_mail.alloc();
+    letter2->activateSerial = false;
+    ui_serial_mail.put(letter2);
+    **/
+    
+    // turn off utility port
+    utilityPin = 0;
+    utilityLED = 0;
+    
+    // delete text "UTILITY PORT ON"
+    tft.setTextColor(backgroundColor);
+    tft.setCursor((tft.width()/2)-50,4);
+    tft.printf("UTILITY PORT ON");
+    
+    
+    // print text "UTILITY PORT OFF"
+    tft.setTextColor(textColor);
+    tft.setCursor((tft.width()/2)-50,4);
+    tft.printf("UTILITY PORT OFF");
+}
+
+#endif
\ No newline at end of file
diff -r 366f17f1ea9b -r 196a63a3378d Screens/ViewLogScreen.h
--- a/Screens/ViewLogScreen.h	Thu Mar 23 10:59:50 2017 +0000
+++ b/Screens/ViewLogScreen.h	Sun Apr 30 17:19:22 2017 +0000
@@ -21,6 +21,7 @@
     int changeScreen;
     uint16_t backgroundColor;   // stores the background color
     bool showDetails;   // knows when it is time to show a record's details
+    bool scroll;
 };
 
 ViewLogScreen::ViewLogScreen(uint16_t bgColor)
@@ -45,7 +46,12 @@
     while (changeScreen == 0) {
         //updateTile();
         //wait_ms(250);
-       Thread::wait(250);   
+       Thread::wait(250);  
+       
+       if (scroll){
+            list->scroll();
+            scroll = false;   
+        } 
 
         if(showDetails && (numberOfRecords>0)) {
             // first deactivate the buttons
@@ -161,13 +167,15 @@
 
         case SCROLLBUTTON:
             // scroll to the next option
-            list->scroll();
+            //list->scroll();
+            scroll = true;
             break;
 
         case ENTERBUTTON:
             // navigate to the selected option
             //changeScreen = ListController::getCurrentOption();
             showDetails = true;
+            break;
 
         default:
             // do nothing
diff -r 366f17f1ea9b -r 196a63a3378d SensorModel.h
--- a/SensorModel.h	Thu Mar 23 10:59:50 2017 +0000
+++ b/SensorModel.h	Sun Apr 30 17:19:22 2017 +0000
@@ -57,12 +57,14 @@
 {
 public:
     ConsumptionModel();
+    ConsumptionModel(float oV, float oC);
     float consumptionVoltage;
     float consumptionCurrent;
 };
 
-ConsumptionModel::ConsumptionModel()
+ConsumptionModel::ConsumptionModel(float oV, float oC)
 {
-    
+    consumptionVoltage = oV;
+    consumptionCurrent = oC;
 }
 #endif
\ No newline at end of file
diff -r 366f17f1ea9b -r 196a63a3378d SensorSuite.h
--- a/SensorSuite.h	Thu Mar 23 10:59:50 2017 +0000
+++ b/SensorSuite.h	Sun Apr 30 17:19:22 2017 +0000
@@ -27,7 +27,7 @@
     // functions used to inteface with suite
     BatteryModel getBatteryData();   // retrieve information about batteries
     SolarModel getSolarData();       // retrieve information about solar panel
-    ConsumptionModel getConsumption();  // retrieve information about consumption
+    ConsumptionModel getConsumptionData();  // retrieve information about consumption
 
 
 private:
@@ -87,9 +87,10 @@
 void SensorSuite::setupSensors()
 {
     // dynamically configure the sensors
-    sensorOne = new INA219(i2c, INA219_ADDR_VG);    // for battery one
-    sensorTwo = new INA219(i2c, INA219_ADDR_GV);    // for battery two
+    sensorOne = new INA219(i2c, INA219_ADDR_GV);    // for battery one
+    sensorTwo = new INA219(i2c, INA219_ADDR_VG);    // for battery two
     sensorThree = new INA219(i2c, INA219_ADDR_GG);  // for solar panel
+    sensorFour = new INA219(i2c, INA219_ADDR_VV);  // for power consumption
 
     // querry the position of the batteries
 }
@@ -125,6 +126,26 @@
             b2Current = sensorOne->read_current();
             b2Current = sensorOne->read_bus_voltage();
         }
+        
+        if (b1Voltage < 3.4)
+        {
+            // turn on LED
+            batteryOneLowLED = 1;
+            
+        } else {
+            // turn off LED
+            batteryOneLowLED = 0;
+        }
+        
+        if (b2Voltage < 3.4)
+        {
+            // turn on LED    
+            batteryTwoLowLED = 1;
+        } else {
+            
+            // turn off LED    
+            batteryTwoLowLED = 0;
+        }
         // release access to battery data
         battery_mutex.unlock();
 
@@ -140,12 +161,14 @@
 
 
         // restrict access to consumption data
-        //consumption_mutex.lock();
+        consumption_mutex.lock();
 
         // read values from the output sensor
-
+        outVoltage = sensorFour->read_bus_voltage();
+        outCurrent = sensorFour->read_current();
+        
         // release access to consumption data
-        //consumption_mutex.unlock();
+        consumption_mutex.unlock();
 
         // unlock the general mutex
         //general_mutex.unlock();
@@ -190,6 +213,20 @@
 
 }
 
+ConsumptionModel SensorSuite::getConsumptionData()
+{
+    // restrict access to consumption data to a single thread
+    consumption_mutex.lock();
+    
+    // collect consumption data
+    ConsumptionModel model(outVoltage, outCurrent);
+    
+    // allow access to consumption data to different threads
+    consumption_mutex.unlock();   
+    
+    return model; 
+}
+
 // ensure that sensor data is initialised
 // voltage-current sensors
 INA219* SensorSuite::sensorOne = NULL;      // sensor 1
diff -r 366f17f1ea9b -r 196a63a3378d Settings/SettingsTest.h
--- a/Settings/SettingsTest.h	Thu Mar 23 10:59:50 2017 +0000
+++ b/Settings/SettingsTest.h	Sun Apr 30 17:19:22 2017 +0000
@@ -36,6 +36,8 @@
     float previousWattage;
     ListController *controller;
     bool writeFlag;
+    bool scroll;
+    bool enter;
 
 };
 
@@ -87,6 +89,18 @@
 
             writeFlag = false;
         }
+        
+        if (scroll) {
+            
+            controller->scroll();
+            scroll = false;
+        }
+        
+        if (enter) {
+            changeScreen = controller->getCurrentOption();
+            changeColor(changeScreen);
+            enter = false;
+        }
         //wait_ms(500);
         Thread::wait(200);   
     }
@@ -167,13 +181,12 @@
 
         case SCROLLBUTTON:
             // scroll to the next option
-            controller->scroll();
+            scroll = true;
             break;
 
         case ENTERBUTTON:
             // navigate to the selected option
-            changeScreen = controller->getCurrentOption();
-            changeColor(changeScreen);
+            enter = true;
 
         default:
             // do nothing
@@ -182,18 +195,5 @@
 }
 
 #endif
-class SettingsTest
-{
-public:
 
-    SettingsTest( char [] = "", char [] = "" );
-    char value[32];
-    char key[32];
-};
 
-SettingsTest::SettingsTest( char k[], char v[] )
-{
-    strcpy(value,v);
-    strcpy(key, k);
-}
-
diff -r 366f17f1ea9b -r 196a63a3378d main.cpp
--- a/main.cpp	Thu Mar 23 10:59:50 2017 +0000
+++ b/main.cpp	Sun Apr 30 17:19:22 2017 +0000
@@ -2,7 +2,7 @@
 #include "rtos.h"
 #include "MbedJSONValue.h"
 #include <string>
-#include "Adafruit_ST7735.h"
+#include "Outputs.h"
 #include "MailBoxes.h"
 #include "SensorSuite.h"
 
@@ -15,6 +15,8 @@
 DigitalOut backlight(p17);
 
 
+
+
 #define OFF 1
 #define ON 0
 
@@ -25,7 +27,7 @@
 LocalFileSystem local("local");
 
 //Adafruit_ST7735 tft(p11, p12, p13, p10, p8, p9); // MOSI, MISO, SCLK, SSEL, TFT_DC, TFT_RST
-Adafruit_ST7735 tft(p11, p12, p13, p16, p14, p15); // MOSI, MISO, SCLK, SSEL, TFT_DC, TFT_RST
+
 #include "Icons.h"
 #include "Inputs.h"
 #include "Settings.h"
@@ -40,6 +42,7 @@
 void changeBackgroundColor();
 bool settingsExist( const char *fname);
 void uiThread();
+void logThread();
 void sensorThread();
 
 uint16_t currentColor;
@@ -71,7 +74,9 @@
 DeleteLogScreen *deleteLog;
 LogManager *log1;
 RaspberryPiScreen *rpiScreen;
+UtilityScreen   *utilityScreen;
 //LogManager *log2;
+Thread loggingThread(osPriorityNormal, (DEFAULT_STACK_SIZE * 2.25), NULL);
 
 int main()
 {
@@ -80,14 +85,14 @@
     thread.start(sensorThread);
 
     // launch the user interface
-    // turn on backlight 
+    // turn on backlight
+    
+
+    
     backlight = 1;
     Thread thread2(osPriorityNormal, (DEFAULT_STACK_SIZE * 2.25), NULL);
     thread2.start(uiThread);
-
-    // launch serial communication with raspberry pi
-    //Thread thread3(osPriorityNormal, (DEFAULT_STACK_SIZE * 2.25), NULL);
-    //thread3.start(raspiSerial);
+    
 
 
     while(true) {
@@ -105,6 +110,14 @@
     suite.begin();
 }
 
+void logThread()
+{
+    
+    LogManager logg;
+    // launch the log thread
+    logg.createNewLog(logInstructions.parameter,logInstructions.duration);
+}
+
 void uiThread()
 {
     // set the current time
@@ -134,26 +147,6 @@
 
 
 
-    /**
-    wait(5);
-    relayOne = OFF;
-    relayTwo = OFF;
-    relayThree = OFF;
-    wait(5);
-    while(1) {
-
-        relayTwo = ON;
-        relayOne = ON;
-        relayThree = ON;
-
-        wait(5);
-        relayOne = OFF;
-        relayTwo = OFF;
-        relayThree = OFF;
-        wait(5);
-    }
-
-    **/
 
 
 
@@ -250,7 +243,35 @@
                                     break;
                             }
                         }
-                    
+
+                        break;
+
+                    case 2:
+                        // clear screen
+                        tft.fillScreen(backgroundColor);
+                        backToSecondLayer = false;
+
+                        while(!backToSecondLayer) {
+                            switch(utilityScreen->start()) {
+                                case -1:
+                                    // clear screen
+                                    tft.fillScreen(backgroundColor);
+                                    backToSecondLayer = true;
+                                    break;
+                                default:
+                                    // do nothing
+                                    break;
+                            }
+                        }
+
+                        break;
+
+                    case -1:
+                        // clear screen
+                        tft.fillScreen(backgroundColor);
+                        backToFirstLayer = true;
+                        break;
+
                     default:
                         // do nothing
                         break;
@@ -426,10 +447,14 @@
 
                                                         case 1:
                                                             // start logging for 30 seconds
-                                                            log1 = new LogManager();
-                                                            log1->createNewLog(POWER_CONSUMPTION,THIRTY_SECONDS);
+                                                            //log1 = new LogManager();
+                                                            //log1->createNewLog(POWER_CONSUMPTION,THIRTY_SECONDS);
+                                                        
+                                                            //logInstructions.parameter = POWER_CONSUMPTION;
+                                                            //logInstructions.duration = THIRTY_SECONDS;
+                                                            //loggingThread.start(logThread);
+                                                            
                                                             tft.fillScreen(backgroundColor);
-
                                                             // navigate all the way back to log screen
                                                             backToFourthLayer = true;
                                                             backToThirdLayer = true;
@@ -449,6 +474,7 @@
                                                             // clear the screen
                                                             tft.fillScreen(backgroundColor);
                                                             backToFourthLayer = true;
+                                                            break;
                                                     }
                                                 }
                                                 break;
@@ -475,6 +501,7 @@
                                                 // clear the screen
                                                 tft.fillScreen(backgroundColor);
                                                 backToThirdLayer = true;
+                                                break;
                                         }
                                     }
                                     break;
@@ -505,6 +532,8 @@
 }
 
 
+
+
 void changeBackgroundColor()
 {
     Settings settings;
@@ -528,6 +557,7 @@
         delete battScreen;
         delete solarValueScreen;
         delete rpiScreen;
+        delete utilityScreen;
 
         // create new screens
         createScreens();
@@ -553,5 +583,6 @@
     battScreen = new BatteryScreen(backgroundColor);
     solarValueScreen = new SolarValueScreen(backgroundColor);
     rpiScreen = new RaspberryPiScreen(backgroundColor);
+    utilityScreen = new UtilityScreen(backgroundColor);
 }