aboutsummaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/HoverBitController.cpp61
-rw-r--r--source/HoverBitController.h68
-rw-r--r--source/Screen.h73
-rw-r--r--source/main.cpp147
4 files changed, 114 insertions, 235 deletions
diff --git a/source/HoverBitController.cpp b/source/HoverBitController.cpp
index 65ebf17..df9893e 100644
--- a/source/HoverBitController.cpp
+++ b/source/HoverBitController.cpp
@@ -22,7 +22,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
-#include <MicroBit.h>
#include "HoverBitController.h"
/**
@@ -31,8 +30,7 @@ DEALINGS IN THE SOFTWARE.
*
* @param _uBit the MicroBit instance
*/
-void HoverBitController::init(MicroBit* _uBit) {
- uBit = _uBit;
+void HoverBitController::init() {
mainController = false;
batteryEmpty = false;
batteryMilliVolt = 3700;
@@ -44,37 +42,43 @@ void HoverBitController::init(MicroBit* _uBit) {
roll = 0;
yaw = 0;
throttle = 0;
- failSafeC = 0;
+ lastReceiveTime = uBit.systemTime();
/* I am not completly sure what this does, but it seems to me like this is
putting the air:bit board in some kind of "bind-mode", on the spec-sheet
there isn't any documentation for what 20 pulses means tho... */
- (*uBit).sleep(100);
+ uBit.sleep(100);
int o;
for (o = 0; o < 20; o++) {
AirBit(-90, 0, 90, 0, 90, 0, 0);
- (*uBit).sleep(20);
+ uBit.sleep(20);
}
}
/**
* This is not implemented yet.
*/
-void HoverBitController::failSafe(void) {
- // throttle = 0;
- // roll = 0;
- // yaw = 0;
- // arm = 0;
- // failSafeC++;
+bool HoverBitController::failSafe(void) {
+ unsigned long deltaReceiveTime = uBit.systemTime() - lastReceiveTime;
+ if (deltaReceiveTime > FSAFE_TLIM_THROTTLE) {
+ Throttle(0);
+ Rudder(0);
+ AirBit(0, arm, 0, throttle, roll, roll + 45, servo_1);
+ }
+ if (deltaReceiveTime > FSAFE_TLIM_ARM) {
+ Arm(0);
+ AirBit(0, arm, 0, throttle, roll, roll + 45, servo_1);
+ }
+ return (deltaReceiveTime > FSAFE_TLIM_THROTTLE) || (deltaReceiveTime > FSAFE_TLIM_ARM);
}
/**
* This returns the current voltage of the battery.
*/
-unsigned int HoverBitController::getBatteryVoltage() {
+unsigned int HoverBitController::GetBatteryVoltage() {
float batteryFactor = 4.42;
int batteryMilliVolt = 3700;
- return ((float)((&(*uBit).io.P0)->getAnalogValue()) * batteryFactor * 0.05) + ((float)batteryMilliVolt * 0.95);
+ return ((float)((&uBit.io.P0)->getAnalogValue()) * batteryFactor * 0.05) + ((float)batteryMilliVolt * 0.95);
}
/**
@@ -137,14 +141,16 @@ void HoverBitController::AirBit(int Pitch,int Arm,int Roll,int Throttle,int Yaw,
buf[13] = aux1S & 255;
buf[14] = (6 << 2) | ((aux2S >> 8) & 3);
buf[15] = aux2S & 255;
- (*uBit).serial.send(buf, 16, SYNC_SPINWAIT);
+ uBit.serial.send(buf, 16, SYNC_SPINWAIT);
}
/**
* Method that sends commands with the current values for all parameters.
*/
void HoverBitController::HoverControl() {
- AirBit(0, arm, 0, throttle, roll, roll + 45, servo_1);
+ if (!failSafe()) {
+ AirBit(0, arm, 0, throttle, roll, roll + 45, servo_1);
+ }
}
int HoverBitController::Throttle() {
@@ -154,28 +160,25 @@ void HoverBitController::Throttle(int _throttle) {
if (_throttle > 99) { throttle = 100; }
else if (_throttle < 0) { throttle = 0; }
else { throttle = _throttle; }
+ lastReceiveTime = uBit.systemTime();
}
-int HoverBitController::Servo1() {
- return servo_1;
-}
-void HoverBitController::Servo1(int _servo1) {
- if (_servo1 > 180) { servo_1 = 180; }
- else if (_servo1 < 0) { servo_1 = 0; }
- else { servo_1 = _servo1; }
-}
-int HoverBitController::Roll() {
+int HoverBitController::Rudder() {
+ // The AirBit uses the roll parameter to control the hoverbit's rudder.
return roll;
}
-void HoverBitController::Roll(int _roll) {
- if (_roll > 90) { roll = 90; }
- else if (_roll < -90) { roll = -90; }
- else { roll = _roll; }
+void HoverBitController::Rudder(int _rudder) {
+ // The AirBit uses the roll parameter to control the hoverbit's rudder.
+ if (_rudder > 90) { roll = 90; }
+ else if (_rudder < -90) { roll = -90; }
+ else { roll = _rudder; }
+ lastReceiveTime = uBit.systemTime();
}
bool HoverBitController::Arm() {
return (arm == 1);
}
void HoverBitController::Arm(bool _arm) {
arm = (int)_arm;
+ lastReceiveTime = uBit.systemTime();
}
bool HoverBitController::BatteryEmpty() {
return batteryEmpty;
diff --git a/source/HoverBitController.h b/source/HoverBitController.h
deleted file mode 100644
index 4963cd1..0000000
--- a/source/HoverBitController.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-The MIT License (MIT)
-
-Copyright (c) 2016 British Broadcasting Corporation.
-This software is provided by Lancaster University by arrangement with the BBC.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-*/
-#ifndef HOVERBITCONTROLLER_H_
-#define HOVERBITCONTROLLER_H_
-
-#include <MicroBit.h>
-
-#define BATTERY_LOW_LIMIT 3500
-
-class HoverBitController {
- private:
- MicroBit* uBit;
-
- int buzzer;
- int servo_1;
- int arm;
- int roll;
- int pitch;
- int yaw;
- int throttle;
- int failSafeC;
-
- bool mainController;
- bool batteryEmpty;
- int batteryMilliVolt;
- float batteryFactor;
-
- public:
- void init(MicroBit* _uBit);
- void failSafe(void);
- unsigned int getBatteryVoltage(void);
- void AirBit(int Pitch,int Arm,int Roll,int Throttle,int Yaw,int Aux1,int Aux2);
- void HoverControl();
-
- int Throttle();
- void Throttle(int _throttle);
- int Servo1();
- void Servo1(int _servo1);
- int Roll();
- void Roll(int _roll);
- bool Arm();
- void Arm(bool _arm);
- bool BatteryEmpty();
-};
-
-#endif // HOVERBITCONTROLLER_H_
diff --git a/source/Screen.h b/source/Screen.h
deleted file mode 100644
index b60ba2b..0000000
--- a/source/Screen.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-The MIT License (MIT)
-
-Copyright (c) 2016 British Broadcasting Corporation.
-This software is provided by Lancaster University by arrangement with the BBC.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-*/
-#ifndef SCREEN_H_
-#define SCREEN_H_
-
-#include <MicroBit.h>
-
-enum DisplayMainScreenMode { GRAPHS, BATTERY, OFF };
-
-const char* const strBattDead = "\
- 000,255,255,255,000\n\
- 255,000,255,000,255\n\
- 255,255,255,255,255\n\
- 000,255,000,255,000\n\
- 000,255,000,255,000\n";
-const char* const strBattLow = "\
- 000,000,255,000,000\n\
- 000,255,255,255,000\n\
- 000,255,000,255,000\n\
- 000,255,000,255,000\n\
- 000,255,255,255,000\n";
-static const char* const strBattLevel[] = {
- "\
- 000,000,255,000,000\n\
- 000,255,000,255,000\n\
- 000,255,000,255,000\n\
- 000,255,000,255,000\n\
- 000,255,255,255,000\n",
- "\
- 000,000,255,000,000\n\
- 000,255,000,255,000\n\
- 000,255,000,255,000\n\
- 000,255,255,255,000\n\
- 000,255,255,255,000\n",
- "\
- 000,000,255,000,000\n\
- 000,255,000,255,000\n\
- 000,255,255,255,000\n\
- 000,255,255,255,000\n\
- 000,255,255,255,000\n",
- "\
- 000,000,255,000,000\n\
- 000,255,255,255,000\n\
- 000,255,255,255,000\n\
- 000,255,255,255,000\n\
- 000,255,255,255,000\n"
-};
-
-void plotYLine(MicroBit *uBit, int y1, int y2, int x);
-
-#endif // SCREEN_H_
diff --git a/source/main.cpp b/source/main.cpp
index caf8ffe..de11801 100644
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -27,6 +27,9 @@ 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;
@@ -44,68 +47,64 @@ DisplayMainScreenMode displayMainScreenMode = GRAPHS;
void onConnected(MicroBitEvent) {
bConnected = 1;
uBit.audio.soundExpressions.play(ManagedString("giggle"));
+}
- // mobile app will send ASCII strings terminated with the colon character
- ManagedString eom(":");
+void onDisconnected(MicroBitEvent) {
+ bConnected = 0;
+ uBit.audio.soundExpressions.play(ManagedString("sad"));
+}
- while (bConnected) {
- ManagedString msg = uart->readUntil(eom);
- int length = msg.length();
- const char* command = msg.toCharArray();
+void onDelim(MicroBitEvent) {
+ ManagedString msg = uart->readUntil(BLE_UART_DELIM);
- ManagedString accString("ACC:");
+ int length = msg.length();
+ const char* command = msg.toCharArray();
- char cCommand = command[0];
- char cChar;
- int startI = 1;
- bool bEOC = false;
- int valLength = 0;
+ ManagedString accString("ACC:");
- for (int i = 1; i < length; i++) {
- cChar = command[i];
+ char cCommand = command[0];
+ char cChar;
+ int startI = 1;
+ bool bEOC = false;
+ int valLength = 0;
- 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;
- }
+ for (int i = 1; i < length; i++) {
+ cChar = command[i];
- 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());
- }
+ 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;
+ }
- cCommand = cChar;
- startI = i+1;
- bEOC = false;
+ 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 {
+ // We ignore it :)
}
+
+ 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;
- uBit.audio.soundExpressions.play(ManagedString("sad"));
+ // @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 iconBatteryDead() {
@@ -195,7 +194,25 @@ void mainScreen() {
bool bDelayElapsed = (uBit.systemTime() - tmpTimer) > 1000;
if (bDelayElapsed) { tmpTimer = uBit.systemTime(); }
- if (bDelayElapsed && bConnected) { uart->send(ManagedString("B:") + ManagedString(batteryMilliVolt)); }
+ 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:
@@ -216,23 +233,19 @@ void mainScreen() {
}
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);
- }
- }
}
void onButtonA_press(MicroBitEvent e) {
+ nextMainScreenDisplayMode();
}
void onButtonB_press(MicroBitEvent e) {
}
+void onButtonAB_press(MicroBitEvent e) {
+ DisplayMainScreenMode tmpDMode = displayMainScreenMode;
+ displayMainScreenMode = OFF;
+ uBit.display.scroll(VERSION);
+ displayMainScreenMode = tmpDMode;
+}
int main() {
uBit.init();
@@ -245,23 +258,27 @@ int main() {
/* Initialize hover:bit controller module
* the init procedure have to be run within 100ms after air:bit power up */
- controller.init(&uBit);
+ 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_BLE_UART, MICROBIT_UART_S_EVT_DELIM_MATCH, onDelim);
+
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_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.soundExpressions.play(ManagedString("hello"));
while (1) {
- batteryMilliVolt = controller.getBatteryVoltage();
+ batteryMilliVolt = controller.GetBatteryVoltage();
if (uBit.logo.isPressed()) {
if (!bCapLogoIsPressed) {