for demo on Thursday
Diff: bit_board.cpp
- Revision:
- 1:032b96b05e51
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bit_board.cpp Wed Jun 12 15:21:01 2019 +0000 @@ -0,0 +1,316 @@ +/* mbed Microcontroller Library + * Copyright (c) 2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mbed.h" +#include "ble/BLE.h" +#include "KeyboardService.h" +#include "MicroBitPin.h" +#include "examples_common.h" +#include "MicroBit.h" +/** + * This program implements a complete HID-over-Gatt Profile: + * - HID is provided by KeyboardService + * - Battery Service + * - Device Information Service + * + * Complete strings can be sent over BLE using printf. Please note, however, than a 12char string + * will take about 500ms to transmit, principally because of the limited notification rate in BLE. + * KeyboardService uses a circular buffer to store the strings to send, and calls to putc will fail + * once this buffer is full. This will result in partial strings being sent to the client. + */ + + //The micro:bit has a matrixed display, this is a simple way to use some LEDs on it +DigitalOut col9(P0_12, 0); +DigitalOut waiting_led(P0_13); +DigitalOut connected_led(P0_15); + +InterruptIn button1(BUTTON_A); +InterruptIn button2(BUTTON_B); + +//InterruptIn key1(MICROBIT_PIN_P0); +// Try to use external signal, rather than button a&b as keys + +BLE ble; +KeyboardService *kbdServicePtr; + +static const char DEVICE_NAME[] = "bit:board wire loop"; +static const char SHORT_DEVICE_NAME[] = "kbd blue"; + +static void onDisconnect(const Gap::DisconnectionCallbackParams_t *params) +{ + HID_DEBUG("disconnected\r\n"); + connected_led = 0; + + ble.gap().startAdvertising(); // restart advertising +} + +static void onConnect(const Gap::ConnectionCallbackParams_t *params) +{ + HID_DEBUG("connected\r\n"); + waiting_led = false; +} + +static void waiting() { + if (!kbdServicePtr->isConnected()) + waiting_led = !waiting_led; + else + connected_led = !connected_led; +} + +void send_string(const char * c) { + if (!kbdServicePtr) + return; + + if (!kbdServicePtr->isConnected()) { + HID_DEBUG("we haven't connected yet..."); + } else { + int len = strlen(c); + kbdServicePtr->printf(c); + HID_DEBUG("sending %d chars\r\n", len); + } +} + +void send_stuff() {send_string("n");wait(0.1);} + +void send_more_stuff() {send_string("p"); wait(0.1);} + +void send_one(){ + inputReportData[0] = 0; + inputReportData[2] = 0x1e; + kbdServicePtr->send(inputReportData); //key down event? + kbdServicePtr->send(emptyInputReportData); // key up event? + wait(0.1); +} + +void send_zero(){// testing input from pins + inputReportData[0] = 0; + inputReportData[2] = 0x27; + kbdServicePtr->send(inputReportData); //key down event? + kbdServicePtr->send(emptyInputReportData); // key up event? + wait(0.1); +} + +void send_up(){// testing input from pins + inputReportData[0] = 0; + inputReportData[2] = 0x52; + kbdServicePtr->send(inputReportData); //key down event? + kbdServicePtr->send(emptyInputReportData); // key up event? + wait(0.1); +} + +void send_down(){// testing input from pins + // kbdServicePtr->putc(DownArrow); + inputReportData[0] = 0; + inputReportData[2] = 0x51; + kbdServicePtr->send(inputReportData); + kbdServicePtr->send(emptyInputReportData); + wait(0.1); +} + +void send_left(){// testing input from pins + inputReportData[0] = 0; + inputReportData[2] = 0x50; + kbdServicePtr->send(inputReportData); + kbdServicePtr->send(emptyInputReportData); + wait(0.1); +} + +void send_right(){// testing input from pins + inputReportData[0] = 0; + inputReportData[2] = 0x4f; + kbdServicePtr->send(inputReportData); + kbdServicePtr->send(emptyInputReportData); + wait(0.1); +} + +void send_space(){// testing input from pins + inputReportData[0] = 0; + inputReportData[2] = 0x2c; + kbdServicePtr->send(inputReportData); + kbdServicePtr->send(emptyInputReportData); + wait(0.1); +} + +void send_delete(){// testing input from pins + inputReportData[0] = 0; + inputReportData[2] = 0x2a; + kbdServicePtr->send(inputReportData); + kbdServicePtr->send(emptyInputReportData); + wait(0.1); +} +void send_tab(){// testing input from pins + inputReportData[0] = 0; + inputReportData[2] = 0x2b; + kbdServicePtr->send(inputReportData); + kbdServicePtr->send(emptyInputReportData); + wait(0.1); +} + +void send_return(){// testing input from pins + inputReportData[0] = 0; + inputReportData[2] = 0x28; + kbdServicePtr->send(inputReportData); + kbdServicePtr->send(emptyInputReportData); + wait(0.1); +} + +void send_release(){ + kbdServicePtr->send(emptyInputReportData); + wait(0.1); +} + + +DigitalIn touch1(MICROBIT_PIN_P13); // for the normal 4 +DigitalIn touch2(MICROBIT_PIN_P14); +DigitalIn touch3(MICROBIT_PIN_P15); +DigitalIn touch4(MICROBIT_PIN_P16); // disable for wire loop example? +InterruptIn touch0(MICROBIT_PIN_P8);// +//DigitalIn touch0(MICROBIT_PIN_P8); // for wire loop example only +AnalogIn x_axis(MICROBIT_PIN_P1); +AnalogIn y_axis(MICROBIT_PIN_P2); +AnalogIn potentiometer(MICROBIT_PIN_P0); + +void JoystickControl(){ + float x,y; + + x = x_axis.read(); + if (x < 0.05f) send_left(); + if (x > 0.95f) send_right(); + + y = y_axis.read(); + if (y < 0.05f) send_down(); + if (y > 0.95f) send_up(); + + wait(0.05); +} + +void crossy_road_touch(){ + if (touch1 == 1) send_space(); + wait(0.05); +} + +enum mode{empty,arithmetic, alphebet, number}; + +void potentiometer_control(){ + mode current_mode = empty; + float value = potentiometer.read(); + + if (value < (float) 229/1024 ) {current_mode = empty;} + else if (value < (float) 307/1024) { current_mode = arithmetic;} + else if (value < (float) 522/1024) { current_mode = number;} + else {current_mode = alphebet;} + + // need to update mode, depending on value + + switch(current_mode){ + case empty: + if (touch1 == 1) send_space(); + if (touch2 == 1) send_delete(); + if (touch3 == 1) send_tab(); + if (touch4 == 1) send_return(); + wait(0.05); + break; + case arithmetic: + if (touch1 == 1) {send_string("+");wait(0.1);} + if (touch2 == 1) {send_string("-");wait(0.1);} + if (touch3 == 1) {send_string("*");wait(0.1);} + if (touch4 == 1) {send_string("/");wait(0.1);} + wait(0.05); + break; + case alphebet: + if (touch1 == 1) {send_string("A");wait(0.1);} + if (touch2 == 1) {send_string("B");wait(0.1);} + if (touch3 == 1) {send_string("C");wait(0.1);} + if (touch4 == 1) {send_string("D");wait(0.1);} + wait(0.05); + break; + case number: + if (touch1 == 1) {send_string("1");wait(0.1);} + if (touch2 == 1) {send_string("2");wait(0.1);} + if (touch3 == 1) {send_string("3");wait(0.1);} + if (touch4 == 1) {send_string("4");wait(0.1);} + wait(0.05); + break; + } +} + +void wire_loop_control(){ +// if (touch0 == 1) {send_string("w");wait(0.1);} // touch, need to stop timer as well + // ???somehow pin8 is active high, need to pull down???? + if (touch1 == 1) {send_string("x");wait(0.1);} // start timer + if (touch2 == 1) {send_string("y");wait(0.1);} // stop timer + if (touch3 == 1) {send_string("z");wait(0.1);} // reset timer +// if (touch4 == 1) {send_string("w");wait(0.1);} + /// try to use interrup +} + +void touched(){send_string("w");wait(0.1);} + +int main(){ + //create_fiber(JoystickControl); +// create_fiber(BLE_fiber); + Ticker heartbeat; + + touch0.fall(touched); + //button1.rise(send_one); +// button2.rise(send_zero); + button1.rise(send_stuff); + button2.rise(send_more_stuff); + + HID_DEBUG("initialising ticker\r\n"); + + heartbeat.attach(waiting, 1); + + HID_DEBUG("initialising ble\r\n"); + ble.init(); + + ble.gap().onDisconnection(onDisconnect); + ble.gap().onConnection(onConnect); + + initializeSecurity(ble); + + HID_DEBUG("adding hid service\r\n"); + KeyboardService kbdService(ble); + kbdServicePtr = &kbdService; + + HID_DEBUG("adding device info and battery service\r\n"); + initializeHOGP(ble); + + HID_DEBUG("setting up gap\r\n"); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::KEYBOARD); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, + (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, + (uint8_t *)SHORT_DEVICE_NAME, sizeof(SHORT_DEVICE_NAME)); + ble.gap().setDeviceName((const uint8_t *)DEVICE_NAME); + + HID_DEBUG("advertising\r\n"); + ble.gap().startAdvertising(); + + while (true) { + ble.waitForEvent(); + + //JoystickControl(); + + // normally, only realize one example: crossy road, potentiometer, or wire loop +// crossy_road_touch(); +// potentiometer_control(); + wire_loop_control(); + } +// release_fiber(); +} + +