aboutsummaryrefslogtreecommitdiff
path: root/source/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/main.cpp')
-rw-r--r--source/main.cpp296
1 files changed, 91 insertions, 205 deletions
diff --git a/source/main.cpp b/source/main.cpp
index caf8ffe..d2848c9 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 "1.0.0"
+#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.