diff options
author | Jakob Stendahl <jakob.stendahl@outlook.com> | 2021-02-28 11:50:15 +0100 |
---|---|---|
committer | Jakob Stendahl <jakob.stendahl@outlook.com> | 2021-02-28 11:50:15 +0100 |
commit | 4cceee770b44a7a9606543087bb89901574c7540 (patch) | |
tree | ea7540d3530bf9e2e1eb127895b7eb021c1534b2 | |
parent | 418b418be9d36db42eb729df4a875439673001b7 (diff) | |
download | hoverbit-ble-4cceee770b44a7a9606543087bb89901574c7540.tar.gz hoverbit-ble-4cceee770b44a7a9606543087bb89901574c7540.zip |
:art: Move display related code to Screen.cpp
-rw-r--r-- | inc/Screen.h | 35 | ||||
-rw-r--r-- | source/Screen.cpp | 234 | ||||
-rw-r--r-- | source/main.cpp | 165 |
3 files changed, 277 insertions, 157 deletions
diff --git a/inc/Screen.h b/inc/Screen.h index e141a86..abac919 100644 --- a/inc/Screen.h +++ b/inc/Screen.h @@ -26,6 +26,10 @@ DEALINGS IN THE SOFTWARE. #define SCREEN_H_ #include <MicroBit.h> +#include "HoverBitController.h" + +extern MicroBit uBit; +extern HoverBitController controller; enum DisplayMainScreenMode { GRAPHS, BATTERY, OFF }; @@ -74,6 +78,35 @@ const char* const bluetoothSymbol = "\ 255,000,255,000,255\n\ 000,000,255,255,000\n"; -void plotYLine(MicroBit *uBit, int y1, int y2, int x); +class HoverBitDisplay { + private: + DisplayMainScreenMode screenMode; + unsigned int tmpTimer; + bool BLEconnected; + bool bBLEIndicator; + bool flipFrame; + bool isPause; + + void lowBattery(); + void BLENotConnected(); + void mainScreen(); + void showGraphs(); + + public: + void mode(DisplayMainScreenMode mode); + DisplayMainScreenMode mode(); + void nextMode(); + void pause(); + void pause(bool p); + void update(); + void updateBLEState(bool connected); +}; + +void plotYLine(int y1, int y2, int x); +void plotXLine(int x1, int x2, int y); +void iconBatteryDead(); +void iconBatteryLow(); +void iconBatteryCharging(); +void batteryLevelFullScreen(); #endif // SCREEN_H_ diff --git a/source/Screen.cpp b/source/Screen.cpp index c778798..ad52247 100644 --- a/source/Screen.cpp +++ b/source/Screen.cpp @@ -24,18 +24,246 @@ DEALINGS IN THE SOFTWARE. */ #include "Screen.h" +DisplayMainScreenMode displayMainScreenMode = OFF; + /** * Method for plotting a line, gotten from wonder-bit-source. */ -void plotYLine(MicroBit *uBit, int y1, int y2, int x) { +void plotYLine(int y1, int y2, int x) { if (y1 >= y2) { for (int y = y2; y <= y1; y++) { - (*uBit).display.image.setPixelValue(x, y, 255); + uBit.display.image.setPixelValue(x, y, 255); } } else if (y1 < y2) { for (int y = y1; y <= y2; y++) { - (*uBit).display.image.setPixelValue(x, y, 255); + uBit.display.image.setPixelValue(x, y, 255); + } + } +} + +/** + * Draw a line along the X axis + */ +void plotXLine(int x1, int x2, int y) { + + if (x1 >= x2) { + for (int x = x2; x <= x1; x++) { + uBit.display.image.setPixelValue(x, y, 255); + } + } + else if (x1 < x2) { + for (int x = x1; x <= x2; x++) { + uBit.display.image.setPixelValue(x, y, 255); + } + } + } + +/** + * Display the dead battery icon. + */ +void iconBatteryDead() { + MicroBitImage img(strBattDead); + uBit.display.print(img); +} + +/** + * Display the low battery icon. + */ +void iconBatteryLow() { + MicroBitImage img(strBattLow); + uBit.display.print(img); +} + +/** + * Show a battery charging icon. + */ +void iconBatteryCharging() { + int batteryMilliVolt = controller.GetBatteryVoltage(); + int low = 0; + int high = 3; + if (batteryMilliVolt >= 4200) { + low = 3; + } else if (batteryMilliVolt >= 4040) { + low = 2; + } else if (batteryMilliVolt >= 3900) { + low = 1; + } + + for (int i = low; i <= high; i++) { + MicroBitImage img(strBattLevel[i]); + uBit.display.print(img); + uBit.sleep(400); + } +} + +/** + * Display the appropriate battery icon based on battery voltage. + */ +void batteryLevelFullScreen() { + int batteryMilliVolt = controller.GetBatteryVoltage(); + int level = 0; + if (controller.Arm()) { + level = (((batteryMilliVolt - 3400) * 3) / 500); + } else { + level = (((batteryMilliVolt - 3700) * 3) / 500); + } + if (level < 0) { level = 0; } + if (level > 3) { level = 3; } + MicroBitImage img(strBattLevel[level]); + uBit.display.print(img); +} + +/** + * Get DisplayScreenMode. + */ +DisplayMainScreenMode HoverBitDisplay::mode() { + return screenMode; +} + +/** + * Set DisplayScreenMode. + */ +void HoverBitDisplay::mode(DisplayMainScreenMode mode) { + screenMode = mode; +} + +/** + * Go to the next HoverBitDisplay mode. + */ +void HoverBitDisplay::nextMode() { + uBit.display.clear(); + switch (screenMode) { + case GRAPHS: + screenMode = BATTERY; + break; + case BATTERY: + screenMode = OFF; + break; + case OFF: + screenMode = GRAPHS; + break; + } +} + +/** + * Pause the HoverBitDisplay module, this means that you are + * free to print what you want without this module interefering + */ +void HoverBitDisplay::pause() { + pause(true); +} + +/** + * Turn on or off HoverBitDisplay pause. + */ +void HoverBitDisplay::pause(bool p) { + if (p) { + uBit.display.clear(); + } + isPause = p; +} + +/** + * Set BLE connected state, this determines if the bluetooth icon is + * shown on screen or not. + */ +void HoverBitDisplay::updateBLEState(bool connected) { + BLEconnected = connected; +} + +/** + * This updates the matrix display to what should be displayed now. + */ +void HoverBitDisplay::update() { + if (isPause) { return; } + int batteryMilliVolt = controller.GetBatteryVoltage(); + + flipFrame = (uBit.systemTime() - tmpTimer) > 1000; + if (flipFrame) { tmpTimer = uBit.systemTime(); } + + if ((((&uBit.io.P0)->getAnalogValue()) < 600) && (((&uBit.io.P0)->getAnalogValue()) >= 400)) { + iconBatteryCharging(); + } else if (controller.BatteryEmpty() || (batteryMilliVolt < BATTERY_LOW_LIMIT && (&uBit.io.P0)->getAnalogValue() > 300)) { + lowBattery(); + } else if (!BLEconnected) { + BLENotConnected(); + } else { + mainScreen(); + } +} + +/** + * Displays dead or low battery icon. + */ +void HoverBitDisplay::lowBattery() { + if (controller.BatteryEmpty()) { + iconBatteryDead(); + } else if (controller.GetBatteryVoltage() > BATTERY_LOW_LIMIT - 50) { + iconBatteryLow(); + } else { + iconBatteryDead(); + } +} + +/** + * Called by HoverBitDisplay::update when BLEConnected is false. + * Flashes a bluetooth symbol on screen. + */ +void HoverBitDisplay::BLENotConnected() { + if ((((uBit.systemTime() >> (12 - 1) & 1)) == 1)) { + bBLEIndicator = !bBLEIndicator; + uBit.display.clear(); + if (bBLEIndicator) { + MicroBitImage img(bluetoothSymbol); + uBit.display.print(img); + } else { + // Need to actually see this to know if I want to flash only + // blank screen or with battery. + //batteryLevelFullScreen(); + } + } +} + +/** + * Method that does the "default" main screen mode. + * Called when in a connected "normal" operating state. + */ +void HoverBitDisplay::mainScreen() { + switch (displayMainScreenMode) { + case OFF: + break; + case BATTERY: + uBit.display.clear(); + batteryLevelFullScreen(); + break; + case GRAPHS: + default: + showGraphs(); + break; + } +} + +/** + * Show the GRAPH displayMainScreenMode + */ +void HoverBitDisplay::showGraphs() { + uBit.display.clear(); + if (controller.Arm()) { + if (uBit.systemTime() % 500 > 250) { + uBit.display.image.setPixelValue(0, 0, 255); + } + } + uBit.display.image.setPixelValue(0, (100 - controller.Throttle()) / 25, 255); + uBit.display.image.setPixelValue((45 - controller.Rudder()) / 18, 2, 255); + int batteryMilliVolt = controller.GetBatteryVoltage(); + if (batteryMilliVolt > 100) { + if (controller.Arm()) { + plotYLine(0, (((batteryMilliVolt - 3400) * 4) / 500), 4); + } else { + plotYLine(0, (((batteryMilliVolt - 3700) * 4) / 500), 4); } + } else if (uBit.systemTime() % 500 > 250) { + uBit.display.image.setPixelValue(4, 4, 255); } } diff --git a/source/main.cpp b/source/main.cpp index de11801..3c3f626 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -33,24 +33,20 @@ DEALINGS IN THE SOFTWARE. MicroBit uBit; MicroBitUARTService *uart; HoverBitController controller; +HoverBitDisplay hoverBitDisplay; bool bConnected = false; - -bool batteryEmpty = false; bool bCapLogoIsPressed = false; -int batteryMilliVolt = 3700; -unsigned long tmpTimer; -bool bBLEIndicator = false; - -DisplayMainScreenMode displayMainScreenMode = GRAPHS; void onConnected(MicroBitEvent) { bConnected = 1; + hoverBitDisplay.updateBLEState(true); uBit.audio.soundExpressions.play(ManagedString("giggle")); } void onDisconnected(MicroBitEvent) { bConnected = 0; + hoverBitDisplay.updateBLEState(false); uBit.audio.soundExpressions.play(ManagedString("sad")); } @@ -107,150 +103,22 @@ void onDelim(MicroBitEvent) { uart->send(accString); } -void iconBatteryDead() { - MicroBitImage img(strBattDead); - uBit.display.print(img); -} - -void iconBatteryLow() { - MicroBitImage img(strBattLow); - uBit.display.print(img); -} - -void lowBattery() { - if (batteryEmpty) { - iconBatteryDead(); - } else if (batteryMilliVolt > BATTERY_LOW_LIMIT - 50){ - iconBatteryLow(); - } else { - iconBatteryDead(); - } -} - -void iconBatteryCharging() { - int low = 0; - int high = 3; - if (batteryMilliVolt >= 4200) { - low = 3; - } else if (batteryMilliVolt >= 4040) { - low = 2; - } else if (batteryMilliVolt >= 3900) { - low = 1; - } - - for (int i = low; i <= high; i++) { - MicroBitImage img(strBattLevel[i]); - uBit.display.print(img); - uBit.sleep(400); - } -} - -void batteryLevelFullScreen() { - int level = 0; - if (controller.Arm()) { - level = (((batteryMilliVolt - 3400) * 3) / 500); - } else { - level = (((batteryMilliVolt - 3700) * 3) / 500); - } - if (level < 0) { level = 0; } - if (level > 3) { level = 3; } - MicroBitImage img(strBattLevel[level]); - uBit.display.print(img); -} - -void plotYLine(int y1, int y2, int x) { - /** - * Draw a line along the Y axis. y1: first pixel, y2: last pixel - */ - - if (y1 >= y2) { - for (int y = y2; y <= y1; y++) { - uBit.display.image.setPixelValue(x, y, 255); - } - } - else if (y1 < y2) { - for (int y = y1; y <= y2; y++) { - uBit.display.image.setPixelValue(x, y, 255); - } - } -} - -void nextMainScreenDisplayMode() { - uBit.display.clear(); - switch (displayMainScreenMode) { - case GRAPHS: - displayMainScreenMode = BATTERY; - break; - case BATTERY: - displayMainScreenMode = OFF; - break; - case OFF: - displayMainScreenMode = GRAPHS; - break; - } -} - -void mainScreen() { - bool bDelayElapsed = (uBit.systemTime() - tmpTimer) > 1000; - if (bDelayElapsed) { tmpTimer = uBit.systemTime(); } - - if (bConnected) { - if (bDelayElapsed) { - uart->send(ManagedString("B:") + ManagedString(batteryMilliVolt)); - } - } else { - if (bDelayElapsed) { - bBLEIndicator = !bBLEIndicator; - uBit.display.clear(); - if (bBLEIndicator) { - MicroBitImage img(bluetoothSymbol); - uBit.display.print(img); - } else { - // Need to actually see this to know if I want to flash only - // blank screen or with battery. - //batteryLevelFullScreen(); - } - } - return; - } - - switch (displayMainScreenMode) { - case OFF: - break; - case BATTERY: - uBit.display.clear(); - batteryLevelFullScreen(); - break; - case GRAPHS: - default: - uBit.display.clear(); - if (batteryMilliVolt > 100) { - if (controller.Arm()) { - plotYLine(0, (((batteryMilliVolt - 3400) * 4) / 500), 4); - } else { - plotYLine(0, (((batteryMilliVolt - 3700) * 4) / 500), 4); - } - } - break; - } -} - void onButtonA_press(MicroBitEvent e) { - nextMainScreenDisplayMode(); + hoverBitDisplay.nextMode(); } + void onButtonB_press(MicroBitEvent e) { } + void onButtonAB_press(MicroBitEvent e) { - DisplayMainScreenMode tmpDMode = displayMainScreenMode; - displayMainScreenMode = OFF; + hoverBitDisplay.pause(); uBit.display.scroll(VERSION); - displayMainScreenMode = tmpDMode; + hoverBitDisplay.pause(false); } int main() { uBit.init(); uBit.audio.setVolume(255); - tmpTimer = uBit.systemTime(); // Setup serial for Spektsat communication with air:bit board uBit.serial.setBaud(115200); @@ -273,30 +141,21 @@ int main() { // Note GATT table size increased from default in MicroBitConfig.h // #define MICROBIT_SD_GATT_TABLE_SIZE 0x500 uart = new MicroBitUARTService(*uBit.ble, 32, 32); - uart->eventOn(BLE_UART_DELIM); + uart->eventOn(BLE_UART_DELIM); uBit.audio.soundExpressions.play(ManagedString("hello")); while (1) { - batteryMilliVolt = controller.GetBatteryVoltage(); - if (uBit.logo.isPressed()) { if (!bCapLogoIsPressed) { bCapLogoIsPressed = true; - nextMainScreenDisplayMode(); + hoverBitDisplay.nextMode(); } - } else if (bCapLogoIsPressed ){ + } else if (bCapLogoIsPressed) { bCapLogoIsPressed = false; } - if ((((&uBit.io.P0)->getAnalogValue()) < 600) && (((&uBit.io.P0)->getAnalogValue()) >= 400)) { - iconBatteryCharging(); - } else if (controller.BatteryEmpty() || (batteryMilliVolt < BATTERY_LOW_LIMIT && (&uBit.io.P0)->getAnalogValue() > 300)) { - lowBattery(); - } else { - mainScreen(); - } - + hoverBitDisplay.update(); controller.HoverControl(); uBit.sleep(20); } |