diff options
Diffstat (limited to 'source/main.cpp')
-rw-r--r-- | source/main.cpp | 296 |
1 files changed, 91 insertions, 205 deletions
diff --git a/source/main.cpp b/source/main.cpp index caf8ffe..16e665a 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -27,261 +27,147 @@ DEALINGS IN THE SOFTWARE. #include "HoverBitController.h" #include "Screen.h" +#define VERSION "0.0.1" +#define BLE_UART_DELIM ":" + 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")); - - // mobile app will send ASCII strings terminated with the colon character - ManagedString eom(":"); - - while (bConnected) { - ManagedString msg = uart->readUntil(eom); - int length = msg.length(); - const char* command = msg.toCharArray(); - - ManagedString accString("ACC:"); - - char cCommand = command[0]; - char cChar; - int startI = 1; - bool bEOC = false; - int valLength = 0; - - for (int i = 1; i < length; i++) { - cChar = command[i]; - - if (i >= length - 1) { - bEOC = true; - valLength = i - startI + 1; - } else if (cChar == 'R' || cChar == 'T' || cChar == 'A' || cChar == 'S') { - bEOC = true; - valLength = i - startI; - } - - if (bEOC) { - /* We will just assume that we end up with a valid integer here */ - int value = atoi(msg.substring(startI, startI + valLength).toCharArray()); - - if (cCommand == 'R') { - controller.Roll(value); - accString = accString + ManagedString("R") + ManagedString(controller.Roll()); - } else if (cCommand == 'T') { - controller.Throttle(value); - accString = accString + ManagedString("T") + ManagedString(controller.Throttle()); - } else if (cCommand == 'A') { - controller.Arm(value == 1); - accString = accString + ManagedString("A") + ManagedString(controller.Arm()); - } else if (cCommand == 'S') { - controller.Servo1(value); - accString = accString + ManagedString("S") + ManagedString(controller.Servo1()); - } - - cCommand = cChar; - startI = i+1; - bEOC = false; - } - } - // @TODO: Move this to the hoverControl module, we would rather like to have that there, or in the main loop. - // it could also be in the same clause as the batttery sending, but we might want to have it more - // dependent on actual received values. - uart->send(accString); - } - } void onDisconnected(MicroBitEvent) { bConnected = 0; + hoverBitDisplay.updateBLEState(false); uBit.audio.soundExpressions.play(ManagedString("sad")); } -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); +void onDelim(MicroBitEvent) { + ManagedString msg = uart->readUntil(BLE_UART_DELIM); + uBit.display.image.setPixelValue(1, 0, 255); + + int length = msg.length(); + const char* command = msg.toCharArray(); + + ManagedString accString("ACC:"); + + char cCommand = command[0]; + char cChar; + int startI = 1; + bool bEOC = false; + int valLength = 0; + + for (int i = 1; i < length; i++) { + cChar = command[i]; + + if (i >= length - 1) { + bEOC = true; + valLength = i - startI + 1; + } else if (cChar == 'R' || // Roll + cChar == 'T' || // Throttle + cChar == 'A' || // Arm + cChar == 'S' || // (Servo1) Keeping this for compatability + cChar == 'D' // DisplayMainScreenMode + ) { + bEOC = true; + valLength = i - startI; } - } - 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 (bDelayElapsed && bConnected) { uart->send(ManagedString("B:") + ManagedString(batteryMilliVolt)); } - - 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); + if (bEOC) { + /* We will just assume that we end up with a valid integer here */ + int value = atoi(msg.substring(startI, startI + valLength).toCharArray()); + + if (cCommand == 'R') { + controller.Rudder(value); + accString = accString + ManagedString("R") + ManagedString(controller.Rudder()); + } else if (cCommand == 'T') { + controller.Throttle(value); + accString = accString + ManagedString("T") + ManagedString(controller.Throttle()); + } else if (cCommand == 'A') { + controller.Arm(value == 1); + accString = accString + ManagedString("A") + ManagedString(controller.Arm()); + } else if (cCommand == 'D') { + switch (value) { + case 0: + hoverBitDisplay.mode(GRAPHS); + break; + case 1: + hoverBitDisplay.mode(BATTERY); + break; + case 2: + hoverBitDisplay.mode(OFF); + break; } + } else { + // We ignore it :) } - break; - } - if (bConnected) { - uBit.display.image.setPixelValue(0, 0, 255); - } else { - if (bDelayElapsed) { bBLEIndicator = !bBLEIndicator; } - if (bBLEIndicator) { - uBit.display.image.setPixelValue(0, 0, 0); - } else { - uBit.display.image.setPixelValue(0, 0, 255); + cCommand = cChar; + startI = i+1; + bEOC = false; } } + // @TODO: Move this to the hoverControl module, we would rather like to have that there, or in the main loop. + // it could also be in the same clause as the batttery sending, but we might want to have it more + // dependent on actual received values. + uart->send(accString); } -void onButtonA_press(MicroBitEvent e) { -} -void onButtonB_press(MicroBitEvent e) { +void onButtonAB_press(MicroBitEvent e) { + hoverBitDisplay.pause(); + uBit.display.scroll(VERSION); + 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); uBit.serial.redirect(uBit.io.P1, uBit.io.P2); - /* Initialize hover:bit controller module - * the init procedure have to be run within 100ms after air:bit power up */ - controller.init(&uBit); + /* Initialize hover:bit controller module, these timeouts are some voodo + magic I don't quite understand. But for the init method to function + as we want, there should be a relatively long delay here. */ + uBit.sleep(3000); + controller.init(); // Setup listeners uBit.messageBus.listen(MICROBIT_ID_BLE, MICROBIT_BLE_EVT_CONNECTED, onConnected); uBit.messageBus.listen(MICROBIT_ID_BLE, MICROBIT_BLE_EVT_DISCONNECTED, onDisconnected); - uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, onButtonA_press); - uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonB_press); + uBit.messageBus.listen(MICROBIT_ID_BLE_UART, MICROBIT_UART_S_EVT_DELIM_MATCH, onDelim); + + uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, onButtonAB_press); // uartService // 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); + uBit.audio.setVolume(20); uBit.audio.soundExpressions.play(ManagedString("hello")); + hoverBitDisplay.mode(GRAPHS); while (1) { - batteryMilliVolt = controller.getBatteryVoltage(); - - if (uBit.logo.isPressed()) { - if (!bCapLogoIsPressed) { - bCapLogoIsPressed = true; - nextMainScreenDisplayMode(); - } - } 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(); + if (uBit.systemTime() % 2000 > 1900) { + uart->send( + ManagedString("B:") + + ManagedString((int)controller.GetBatteryVoltage()) + ); + } uBit.sleep(20); + schedule(); } // If main exits, there may still be other fibers running or registered event handlers etc. |