Pair function with BLE_Paired_Client. If missing BLE_Paired_Server side, Client side of BZ will ON for notice.
Dependencies: BLE_API mbed nRF51822 nRF51_LowPwr nRF51_Vdd
Fork of BLE_GATT_Example by
Diff: main.cpp
- Revision:
- 23:f826de46d652
- Parent:
- 22:406127954d1f
- Child:
- 24:391e76b51b21
--- a/main.cpp Mon Nov 09 17:08:47 2015 +0000 +++ b/main.cpp Wed Jun 01 12:37:52 2016 +0000 @@ -1,104 +1,229 @@ +/* + * /////// Tested on Switch Science mbed TY51822r3 /////// + * Modified by Kenji Arai + * http://www.page.sannet.ne.jp/kenjia/index.html + * http://mbed.org/users/kenjiArai/ + * + * Started: April 5th, 2016 + * Revised: June 1st, 2016 + * + * Original program: + * BLE_GATT_Example + * https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_GATT_Example/ + * Tested Device: + * BLE_Paired_Client + * + */ + +// Include --------------------------------------------------------------------------------------- #include "mbed.h" -#include "ble/BLE.h" +#include "BLE.h" +#include "nRF51_Vdd.h" +#include "nRF51_lowpwr.h" -DigitalOut led(LED1, 1); -uint16_t customServiceUUID = 0xA000; -uint16_t readCharUUID = 0xA001; -uint16_t writeCharUUID = 0xA002; +// Definition ------------------------------------------------------------------------------------ +// Before using this function, please specify your program are used following functions or not. +#define USE_DEVICE_STDIO_MESSAGES 0 // printf +#define USE_DEVICE_SERIAL 0 // Serial or DEBUG & etc. +#define USE_DEVICE_I2C 1 // Sensors with I2C, LCD, EEPROM, Driver chips & etc. +#define USE_DEVICE_SPI 0 // Sensors with SOI, LCD, EEPROM, Driver chips & etc. +#define USE_DEVICE_SPISLAVE 0 // Communication with master vis SPI +#define USE_DEVICE_PWMOUT 0 // PWM duty output, Serve & etc. +#define USE_DEVICE_ANALOGIN 0 // Analog adc + +#define SHOW_MY_MAC 0 + +#if USE_DEVICE_STDIO_MESSAGES +#define DEBUG(...) { printf(__VA_ARGS__); } +#else +#define DEBUG(...) +#endif + +// Object ---------------------------------------------------------------------------------------- +Ticker ticker; +InterruptIn sw(P0_0); +nRF51_Vdd vdd(3.6f, 1.8f, ONLY4VDD); -const static char DEVICE_NAME[] = "ChangeMe!!"; // change this -static const uint16_t uuid16_list[] = {0xFFFF}; //Custom UUID, FFFF is reserved for development +// ROM / Constant data --------------------------------------------------------------------------- +const static char DEVICE_NAME[] = "JH1PJL"; +static const uint16_t uuid16_list[] = {0xFFFF};//Custom UUID, FFFF is reserved for development +const uint16_t customServiceUUID = 0xA000; +const uint16_t readCharUUID = 0xA001; +const uint16_t writeCharUUID = 0xA002; +const int8_t tx_power_level[8] = + { + RADIO_TXPOWER_TXPOWER_Pos4dBm, // 0 + RADIO_TXPOWER_TXPOWER_0dBm, // 1 + RADIO_TXPOWER_TXPOWER_Neg4dBm, // 2 + RADIO_TXPOWER_TXPOWER_Neg8dBm, // 3 + RADIO_TXPOWER_TXPOWER_Neg12dBm, // 4 + RADIO_TXPOWER_TXPOWER_Neg16dBm, // 5 + RADIO_TXPOWER_TXPOWER_Neg20dBm, // 6 + RADIO_TXPOWER_TXPOWER_Neg30dBm // 7 + }; -/* Set Up custom Characteristics */ -static uint8_t readValue[10] = {0}; -ReadOnlyArrayGattCharacteristic<uint8_t, sizeof(readValue)> readChar(readCharUUID, readValue); +const nRF51_LOWPWR_TypeDef lowpwr_table = + { + #if USE_DEVICE_STDIO_MESSAGES + true, + #else + false, + #endif + #if USE_DEVICE_SERIAL + true, + #else + false, + #endif + #if USE_DEVICE_I2C + true, + #else + false, + #endif + #if USE_DEVICE_SPI + true, + #else + false, + #endif + #if USE_DEVICE_SPISLAVE + true, + #else + false, + #endif + #if USE_DEVICE_PWMOUT + true, + #else + false, + #endif + #if USE_DEVICE_ANALOGIN + true + #else + false + #endif + }; -static uint8_t writeValue[10] = {0}; +// RAM ------------------------------------------------------------------------------------------- +volatile bool triggerSensorPolling = false; +static uint8_t readValue[10] = {0}; +static uint8_t writeValue[10] = {0}; +ReadOnlyArrayGattCharacteristic<uint8_t, sizeof(readValue)> readChar(readCharUUID, readValue); WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(writeValue)> writeChar(writeCharUUID, writeValue); - /* Set up custom service */ GattCharacteristic *characteristics[] = {&readChar, &writeChar}; -GattService customService(customServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *)); +GattService customService( + customServiceUUID, + characteristics, + sizeof(characteristics) / sizeof(GattCharacteristic *) + ); +// Function prototypes --------------------------------------------------------------------------- +void bleInitComplete(BLE::InitializationCompleteCallbackContext *); +void periodicCallback(void); +void buttonPressedCallback(void); +void buttonReleasedCallback(void); +void connectionCallback(const Gap::ConnectionCallbackParams_t *params); +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params); + +//------------------------------------------------------------------------------------------------- +// Control Program +//------------------------------------------------------------------------------------------------- +void reset_cpu(){ + NVIC_SystemReset(); // System RESET!! +} -/* - * Restart advertising when phone app disconnects -*/ -void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) -{ +int main(void){ + uint8_t n = 0; + uint8_t bf_send_to_client[10]; + uint16_t len_send; + + LowPwr set_lowpwr(&lowpwr_table); + sw.fall(&reset_cpu); + ticker.attach(periodicCallback, 5); + BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); + ble.init(bleInitComplete); + while (ble.hasInitialized() == false){ ;} + while (true){ + if (triggerSensorPolling){ // Send Chip Vdd value + triggerSensorPolling = false; + if (++n >= 100){ n = 0;} + sprintf((char *)bf_send_to_client,"%02u %3.2f[V]", n, vdd.read_real_value()); + len_send = strlen((const char *)bf_send_to_client); + ble.gattServer().write(readChar.getValueHandle(), bf_send_to_client, len_send); + } + ble.waitForEvent(); // Save power + } +} + +void periodicCallback(void){ + triggerSensorPolling = true; +} + +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *){ BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising(); } -/* - * Handle writes to writeCharacteristic -*/ -void writeCharCallback(const GattWriteCallbackParams *params) -{ - /* Check to see what characteristic was written, by handle */ - if(params->handle == writeChar.getValueHandle()) { - /* toggle LED if only 1 byte is written */ - if(params->len == 1) { - led = params->data[0]; - (params->data[0] == 0x00) ? printf("led on\n\r") : printf("led off\n\r"); // print led toggle - } - /* Print the data if more than 1 byte is written */ - else { - printf("Data received: length = %d, data = 0x",params->len); - for(int x=0; x < params->len; x++) { - printf("%x", params->data[x]); - } - printf("\n\r"); - } - /* Update the readChar with the value of writeChar */ - BLE::Instance(BLE::DEFAULT_INSTANCE).gattServer().write(readChar.getValueHandle(), params->data, params->len); - } -} -/* - * Initialization callback - */ -void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) -{ +void bleInitComplete(BLE::InitializationCompleteCallbackContext *params){ BLE &ble = params->ble; ble_error_t error = params->error; - if (error != BLE_ERROR_NONE) { - return; - } - + if (error != BLE_ERROR_NONE) { return;} +#if SHOW_MY_MAC + Gap::AddressType_t my_mac_type; + Gap::Address_t my_mac; + ble.gap().getAddress(&my_mac_type, my_mac); + DEBUG( + " my_MAC %02x:%02x:%02x:%02x:%02x:%02x (%s)\r\n", + my_mac[5], my_mac[4], my_mac[3], my_mac[2], my_mac[1], my_mac[0], + (my_mac_type == Gap::ADDR_TYPE_PUBLIC) ? "public" : "random" + ); + DEBUG( + " mac_board_? = {0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x};\r\n", + my_mac[0], my_mac[1], my_mac[2], my_mac[3], my_mac[4], my_mac[5] + ); +#endif + ble.gap().onConnection(connectionCallback); ble.gap().onDisconnection(disconnectionCallback); - ble.gattServer().onDataWritten(writeCharCallback); - - /* Setup advertising */ - ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); // BLE only, no classic BT - ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); // advertising type - ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); // add name - ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); // UUID's broadcast in advertising packet - ble.gap().setAdvertisingInterval(100); // 100ms. - - /* Add our custom service */ + ble.gap().accumulateAdvertisingPayload( + GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE + ); // BLE only, no classic BT + ble.gap().setAdvertisingType( + GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED + ); // advertising type + ble.gap().accumulateAdvertisingPayload( + GapAdvertisingData::COMPLETE_LOCAL_NAME, + (uint8_t *)DEVICE_NAME, + sizeof(DEVICE_NAME) + ); // add name + ble.gap().accumulateAdvertisingPayload( + GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, + (uint8_t *)uuid16_list, + sizeof(uuid16_list) + ); // UUID's broadcast in advertising packet + ble.gap().setTxPower(tx_power_level[2]); + ble.gap().setAdvertisingInterval(1000); // 1000ms. ble.addService(customService); - - /* Start advertising */ ble.gap().startAdvertising(); } -/* - * Main loop -*/ -int main(void) -{ - /* initialize stuff */ - printf("\n\r********* Starting Main Loop *********\n\r"); - - BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); - ble.init(bleInitComplete); - - /* SpinWait for initialization to complete. This is necessary because the - * BLE object is used in the main loop below. */ - while (ble.hasInitialized() == false) { /* spin loop */ } - - /* Infinite loop waiting for BLE interrupt events */ - while (true) { - ble.waitForEvent(); /* Save power */ +void connectionCallback(const Gap::ConnectionCallbackParams_t *params){ + DEBUG("connected as device (handle = %d)\r\n\r", params->handle); + DEBUG( + "Conn. params => min=%d, max=%d, slave=%d, supervision=%d\r\n", + params->connectionParams->minConnectionInterval, + params->connectionParams->maxConnectionInterval, + params->connectionParams->slaveLatency, + params->connectionParams->connectionSupervisionTimeout + ); +#if 0 + Gap::ConnectionParams_t connectionParams; + connectionParams.minConnectionInterval = 200; + connectionParams.maxConnectionInterval = 500; + connectionParams.slaveLatency = 0; + connectionParams.connectionSupervisionTimeout = 1500; + if (BLE::Instance( + BLE::DEFAULT_INSTANCE).gap().updateConnectionParams(params->handle, + &connectionParams) != BLE_ERROR_NONE + ){ + DEBUG("failed to update connection parameter\r\n"); } -} \ No newline at end of file +#endif +}