example firmware for nRF51-Dongle to use with Opentrigger
Dependencies: BLE_API mbed nRF51822
Fork of BLE_Button by
Diff: main.cpp
- Revision:
- 16:7a9fde930f8a
- Parent:
- 15:9f9f5d82743d
- Child:
- 17:33d38b30e640
--- a/main.cpp Tue Jun 14 14:02:15 2016 +0000 +++ b/main.cpp Tue Jun 14 17:30:26 2016 +0000 @@ -21,9 +21,9 @@ #include "mbed.h" #include "ble/BLE.h" -DigitalOut led1(LED1); -DigitalOut led2(LED2); -DigitalOut led3(LED3); +DigitalOut led1(LED1); /* RED : Indicating a pressed button */ +DigitalOut led2(LED2); /* GREEN : Blinking to indicate that the device is running */ +DigitalOut led3(LED3); /* BLUE : Only on when advertising */ InterruptIn button0(P0_15); InterruptIn button1(P0_16); @@ -33,8 +33,7 @@ InterruptIn button5(P0_20); const uint16_t MIN_ADVERT_INTERVAL = 50; /* msec */ -const uint16_t MAX_ADVERT_INTERVAL = 5000; /* msec */ -static uint8_t gpio_states[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static uint8_t gpio_states[] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; /* initial state is up */ enum { RELEASED = 0, @@ -52,7 +51,7 @@ /* Note that the buttonPressedCallback() executes in interrupt context, so it is safer to access * BLE device API from the main thread. */ buttonState = PRESSED; - gpio_states[0]=0x01; + gpio_states[0]=0x00; } void button0ReleasedCallback(void) @@ -60,20 +59,23 @@ /* Note that the buttonReleasedCallback() executes in interrupt context, so it is safer to access * BLE device API from the main thread. */ buttonState = RELEASED; - gpio_states[0]=0x00; + gpio_states[0]=0x01; } -void button1PressedCallback(void) { buttonState = PRESSED; gpio_states[1]=0x01; } -void button1ReleasedCallback(void){ buttonState = RELEASED; gpio_states[1]=0x00; } -void button2PressedCallback(void) { buttonState = PRESSED; gpio_states[2]=0x01; } -void button2ReleasedCallback(void){ buttonState = RELEASED; gpio_states[2]=0x00; } -void button3PressedCallback(void) { buttonState = PRESSED; gpio_states[3]=0x01; } -void button3ReleasedCallback(void){ buttonState = RELEASED; gpio_states[3]=0x00; } -void button4PressedCallback(void) { buttonState = PRESSED; gpio_states[4]=0x01; } -void button4ReleasedCallback(void){ buttonState = RELEASED; gpio_states[4]=0x00; } -void button5PressedCallback(void) { buttonState = PRESSED; gpio_states[5]=0x01; } -void button5ReleasedCallback(void){ buttonState = RELEASED; gpio_states[5]=0x00; } +// Callbacks for the other 5 Buttons +void button1PressedCallback(void) { buttonState = PRESSED; gpio_states[1]=0x00; } +void button1ReleasedCallback(void){ buttonState = RELEASED; gpio_states[1]=0x01; } +void button2PressedCallback(void) { buttonState = PRESSED; gpio_states[2]=0x00; } +void button2ReleasedCallback(void){ buttonState = RELEASED; gpio_states[2]=0x01; } +void button3PressedCallback(void) { buttonState = PRESSED; gpio_states[3]=0x00; } +void button3ReleasedCallback(void){ buttonState = RELEASED; gpio_states[3]=0x01; } +void button4PressedCallback(void) { buttonState = PRESSED; gpio_states[4]=0x00; } +void button4ReleasedCallback(void){ buttonState = RELEASED; gpio_states[4]=0x01; } +void button5PressedCallback(void) { buttonState = PRESSED; gpio_states[5]=0x00; } +void button5ReleasedCallback(void){ buttonState = RELEASED; gpio_states[5]=0x01; } + +// Just in case void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) { BLE::Instance().gap().startAdvertising(); @@ -95,17 +97,35 @@ error("Panic!"); } -void setPir(uint8_t pir){ +bool gpioSet(void){ + return + gpio_states[0] == 0x00 || + gpio_states[1] == 0x00 || + gpio_states[2] == 0x00 || + gpio_states[3] == 0x00 || + gpio_states[4] == 0x00 || + gpio_states[5] == 0x00 + ; +} + +void updateManufacturerData(void){ + + // disable interrupts while building the package to avoid a race condition + __disable_irq(); + // http://tokencube.com/bluetooth-sensor.html uint8_t data[] = { 0xee, 0xff, // Tokencube Manufacturer ID 0x04, // Token Module Version 0x01, // Firmware Version 0x11, // Page 1 of 1 - 0x07, pir, // pir value + 0x07, gpioSet() ? 0x01 : 0x00, // pir value (0x00 = off, 0x01 = on) // custom data - state of all 6 gpio's + // 0x00 = down, 0x01 = up 0x0F, gpio_states[0], gpio_states[1], gpio_states[2], gpio_states[3], gpio_states[4], gpio_states[5] }; + + __enable_irq(); BLE::Instance().gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, data, sizeof(data)); } @@ -143,7 +163,7 @@ ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); ble.gap().setAdvertisingInterval(MIN_ADVERT_INTERVAL); - setPir(0x00); + updateManufacturerData(); error = ble.gap().startAdvertising(); if (error != BLE_ERROR_NONE) onBleInitError(ble, error); @@ -158,9 +178,18 @@ { Ticker ticker; + // Turn off all LED's led1 = !0; led2 = !0; led3 = !0; - ticker.attach(periodicCallback, 1); + // Put all GPIO's in PullUp mode, so we do not need pullup resistors. + button0.mode(PullUp); + button1.mode(PullUp); + button2.mode(PullUp); + button3.mode(PullUp); + button4.mode(PullUp); + button5.mode(PullUp); + + // Setup handler for all buttons button0.fall(button0PressedCallback); button0.rise(button0ReleasedCallback); button1.fall(button1PressedCallback); @@ -173,6 +202,9 @@ button4.rise(button4ReleasedCallback); button5.fall(button5PressedCallback); button5.rise(button5ReleasedCallback); + + // This will make our green led blink + ticker.attach(periodicCallback, 1); BLE &ble = BLE::Instance(); ble.init(bleInitComplete); @@ -182,29 +214,27 @@ uint8_t cnt = 0; while (true) { + + // we only care about situations where a button was pressed if (buttonState != IDLE) { - if(buttonState == PRESSED) { - led1=!1; - setPir(0x01); - } - if(buttonState == RELEASED) { - led1=!0; - setPir(0x00); - } + if(buttonState == PRESSED) led1=!1; + if(buttonState == RELEASED) led1=!0; + + updateManufacturerData(); cnt = 0; buttonState = IDLE; } - + // stop advertising after 3 cycles if(cnt < 1){ ble.gap().startAdvertising(); led3 = !1; } - if(cnt > 5){ + if(cnt > 3){ ble.gap().stopAdvertising(); led3 = !0; }else{ - cnt++; + if(!gpioSet()) cnt++; } ble.waitForEvent();