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
Revision 6:196a63a3378d, committed 2017-04-30
- 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
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); }