cleaned up and commented after demo day

Dependencies:   microbit

bit_board.cpp

Committer:
xx316
Date:
2019-06-18
Revision:
2:4f3f5d2fec6b
Parent:
1:032b96b05e51

File content as of revision 2:4f3f5d2fec6b:

/* 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);

BLE ble;
KeyboardService *kbdServicePtr;

static const char DEVICE_NAME[] = "bit:board potentiometer"; // this is the name displayed after connection
static const char SHORT_DEVICE_NAME[] = "kbd red"; // this is the name on bluetooth advertise

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(){ // send a char '1'
    inputReportData[0] = 0;
    inputReportData[2] = 0x1e;
    kbdServicePtr->send(inputReportData); //key down event
    kbdServicePtr->send(emptyInputReportData); // key up event
    wait(0.1);
}

void send_zero(){// // send a char '2'
    inputReportData[0] = 0;
    inputReportData[2] = 0x27;
    kbdServicePtr->send(inputReportData); //key down event
    kbdServicePtr->send(emptyInputReportData); // key up event
    wait(0.1);
}

void send_up(){// send the up array key signal - you can't type this key as a character
    inputReportData[0] = 0;
    inputReportData[2] = 0x52;
    kbdServicePtr->send(inputReportData); //key down event
    kbdServicePtr->send(emptyInputReportData); // key up event
    wait(0.1);
}

void send_down(){// send the down array key signal - you can't type this key as a character
    inputReportData[0] = 0;
    inputReportData[2] = 0x51;
    kbdServicePtr->send(inputReportData);
    kbdServicePtr->send(emptyInputReportData);
    wait(0.1);
}

void send_left(){
    inputReportData[0] = 0;
    inputReportData[2] = 0x50;
    kbdServicePtr->send(inputReportData);
    kbdServicePtr->send(emptyInputReportData);
    wait(0.1);
}

void send_right(){
    inputReportData[0] = 0;
    inputReportData[2] = 0x4f;
    kbdServicePtr->send(inputReportData);
    kbdServicePtr->send(emptyInputReportData);
    wait(0.1);
}

void send_space(){
    inputReportData[0] = 0;
    inputReportData[2] = 0x2c;
    kbdServicePtr->send(inputReportData);
    kbdServicePtr->send(emptyInputReportData);
    wait(0.1);
}

void send_delete(){
    inputReportData[0] = 0;
    inputReportData[2] = 0x2a;
    kbdServicePtr->send(inputReportData);
    kbdServicePtr->send(emptyInputReportData);
    wait(0.1);
}
void send_tab(){
    inputReportData[0] = 0;
    inputReportData[2] = 0x2b;
    kbdServicePtr->send(inputReportData);
    kbdServicePtr->send(emptyInputReportData);
    wait(0.1);
}

void send_return(){
    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); 
DigitalIn touch2(MICROBIT_PIN_P14);
DigitalIn touch3(MICROBIT_PIN_P15);
DigitalIn touch4(MICROBIT_PIN_P16); 
InterruptIn touch0(MICROBIT_PIN_P8);
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) 175/1024 ) {current_mode = empty;}
    else if (value < (float) 276/1024) { current_mode = arithmetic;}
    else if (value < (float) 487/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
    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
}

void touched(){send_string("w");wait(0.1);}

int main(){
    Ticker heartbeat;

    touch0.fall(touched);
    button1.rise(send_stuff);  // testing the ability to send string
    button2.rise(send_more_stuff);

    HID_DEBUG("initialising ticker\r\n");

    heartbeat.attach(waiting, 1); // led indicator

    HID_DEBUG("initialising ble\r\n");
    ble.init();

    ble.gap().onDisconnection(onDisconnect); // define behaviour when connection is lost
    ble.gap().onConnection(onConnect);// define behaviour when connection is made

    initializeSecurity(ble);

    HID_DEBUG("adding hid service\r\n");
    KeyboardService kbdService(ble); // declare keyboard service
    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();  
        
        potentiometer_control(); // example 1
        
//        wire_loop_control(); // example 2
    }
}