Experimental BLE project showing how IO can be made with an App over BLE. Pointer to matching App will be added when ready, initially this works with: - Android App [nRF-Master Control Panel], supports Write,Read,Notify - Android Project [BluetoothLeGatt]
Dependencies: BLE_API mbed nRF51822
This is an experimental project for BLE (Bluetooth LE == Bluetooth Low Energy == Bluetooth Smart).
- It supports general IO over BLE with Read/Notify/Write support.
- It is compatible with FOTA using Android App "nRF Master Control Panel" (20150126)
- IO supported by:
- Custom Android App is in the WIKI under: Android-App, developed from Android Sample "BluetoothLeGatt"
- Android App: nRF-MCP (Master Control Panel)
- iOS App LightBlue.
- General HRM, HTM, Battery and similar apps should be able to access the matching services.
- It includes combinations of code from other projects, alternative code included can be tried by moving comments (, //)
- 20150126 bleIO r25: It compiles for both "Nordic nRF51822" and "Nordic nRF51822 FOTA" platforms
- 20150126 The matching bleIO App (in wiki) doesn't support FOTA yet, use Android App "nRF Master Control Panel"
Feedback and ideas greatly appreciated!!!
Diff: main.cpp
- Revision:
- 15:b2c8bdef2d20
- Parent:
- 14:b968df367145
- Child:
- 16:3e83f2babdfb
--- a/main.cpp Mon Dec 22 15:05:32 2014 +0000 +++ b/main.cpp Wed Dec 24 20:35:21 2014 +0000 @@ -106,9 +106,9 @@ const static char pcDeviceName[] = "bleIOv04"; //Advertised device name (Max length depends on available space with other Advertising data) BLEDevice ble; //Pointers to services for accesses outside main() - HealthThermometerService *pServiceHTM; //tempChar.getValueAttribute().getHandle() - BatteryService *pServiceBattery; //battLevel.getValueAttribute().getHandle() HeartRateService *pServiceHRM; + HealthThermometerService *pServiceHTM; + BatteryService *pServiceBattery; DeviceInformationService *pServiceDeviceInfo; LinkLossService *pServiceLinkLoss; //x DFUService *pServiceDFU; @@ -284,6 +284,15 @@ DEBUG(" sIOn4: Handle:%d Len:%d [%02X %02X %02X %02X]\n", IOn4.getValueHandle(), sizeof(sIOn4), sIOn4.pu[0], sIOn4.pu[1], sIOn4.pu[2], sIOn4.pu[3]); uLen=sizeof(puBuf8); ble.readCharacteristicValue(IOn4.getValueHandle(), puBuf8, &uLen); // Real Characteristic's Actual Value DEBUG(" cIOn4: Handle:%d Len:%d [%02X %02X %02X %02X]\n", IOn4.getValueHandle(), uLen, puBuf8[0], puBuf8[1], puBuf8[2], puBuf8[3] ); + + //DEBUG("\n Handles for Standard Services' Characteristics:\n"); + //DEBUG(" HRM: Rate:%d Location:%d Control:%d", pServiceHRM->getCharacteristic(0)->getValueHandle(),pServiceHRM->getCharacteristic(1)->getValueHandle(),pServiceHRM->getCharacteristic(2)->getValueHandle()); + //DEBUG(" HTM: Temp:%d Type:%d", pServiceHTM->getCharacteristic(0)->getValueHandle(),pServiceHTM->getCharacteristic(1)->getValueHandle()); + //DEBUG(" Batt: Level:%d", pServiceBattery->getCharacteristic(0)->getHandle()); + //DEBUG(" DeviceInfo: %d~%d", pServiceDeviceInfo->getCharacteristic(0)->getHandle(), pServiceDeviceInfo->getCharacteristic(5)->getHandle()); + //DEBUG(" LinkLoss: AlertLevel:%d", pServiceLinkLoss->getCharacteristic(0)->getHandle()); + //DEBUG(" DFU:%d", pServiceDFU.getValueAttribute().getHandle()); + //DEBUG(" UART:%d\n", pServiceUART.getValueAttribute().getHandle()); } //==== Soft Updates to Characteristics for initial tests: (Most replaced by real buttons/sensors/timers ) @@ -475,17 +484,30 @@ //vShowIO(); //Show IO Characteristic Status } -void Callback_BLE_onUpdatesEnabled(Gap::Handle_t tHandle) +void Callback_BLE_onUpdatesEnabled(Gap::Handle_t tHandle) // Notifications +{ //Triggered when click the UpdateContinuousIcon in nRF-MCP(ThreeDownArrows) + if (tHandle == IOn4.getValueHandle()) { DEBUG("\nBLEi: onUpdates(Handle:%d) Enabled? - IOn4\n", tHandle); //This Occurs when selected by App nRF-MCP as has Notify property set + } else if (tHandle == IOr4.getValueHandle()) { DEBUG("\nBLEi: onUpdates(Handle:%d) Enabled? - IOr4\n", tHandle); // Notify not enabled on this Characteristic + } else if (tHandle == IOw8.getValueHandle()) { DEBUG("\nBLEi: onUpdates(Handle:%d) Enabled? - IOw8\n", tHandle); // Notify not enabled on this Characteristic + } else { DEBUG("\nBLEi: onUpdates(Handle:%d) Enabled? - Characteristic?\n", tHandle); + } + //TODO: process Enable/Disable for Each Notify Charaxcteriistic of each Service +} + +void Callback_BLE_onUpdatesDisabled(Gap::Handle_t tHandle) // Notifications { //Triggered when click the UpdateContinuousIcon in nRF-MCP(ThreeDownArrows) - if (tHandle == IOn4.getValueHandle()) { DEBUG("\nBLEi: onUpdates(Handle:%d) Enabled - IOn4\n", tHandle); //This Occurs when selected by App nRF-MCP as has Notify property set - //} else if (tHandle == IOr4.getValueHandle()) { DEBUG(" onUpdates(Handle:%d) Enabled - IOr4\n", tHandle); // Notify not enabled on this Characteristic - //} else if (tHandle == IOw8.getValueHandle()) { DEBUG(" onUpdates(Handle:%d) Enabled - IOw8\n", tHandle); // Notify not enabled on this Characteristic - } else { DEBUG("\nBLEi: onUpdates(Handle:%d) Enabled - Characteristic?\n", tHandle); + if (tHandle == IOn4.getValueHandle()) { DEBUG("\nBLEi: onUpdates(Handle:%d) Disabled? - IOn4\n", tHandle); //This Occurs when selected by App nRF-MCP as has Notify property set + } else if (tHandle == IOr4.getValueHandle()) { DEBUG("\nBLEi: onUpdates(Handle:%d) Disabled? - IOr4\n", tHandle); // Notify not enabled on this Characteristic + } else if (tHandle == IOw8.getValueHandle()) { DEBUG("\nBLEi: onUpdates(Handle:%d) Disabled? - IOw8\n", tHandle); // Notify not enabled on this Characteristic + } else { DEBUG("\nBLEi: onUpdates(Handle:%d) Disabled? - Characteristic?\n", tHandle); } - - - + //TODO: process Enable/Disable for Each Notify Charaxcteriistic of each Service } +void Callback_BLE_onConfirmRx(Gap::Handle_t tHandle) // Confirmations?? +{ + DEBUG("\nBLEi: ConfirmationRx(Handle:%d)\n", tHandle); +} + // Adopted 20141213 from http://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_LinkLoss/file/440ee5e8595f/main.cpp void Callback_BLE_onLinkLoss(LinkLossService::AlertLevel_t level) @@ -576,7 +598,7 @@ DEBUG("\n __MODULE__[" __MODULE__ "] __FILE__[" __FILE__ "] __BASE_FILE__[" __BASE_FILE__ "]\n"); DEBUG(" __FUNCTION__[%s] __PRETTY_FUNCTION__[%s]\n", __FUNCTION__, __PRETTY_FUNCTION__) - vShowIO(); + //vShowIO(); Show Raw initialized values before any BLE Ticker ticker1; //PR: Timer Object(Structure) ticker1.attach(CallbackTicker1, 5.0); //PR: Timer Handler, Float=PeriodSeconds (Note BLE default wakes about 50Hz/20msec) @@ -595,6 +617,8 @@ ble.onDataWritten(Callback_BLE_onDataWritten); //PR: Occurs when an update to a Characteristic has been received over BLE ble.onTimeout(Callback_BLE_onTimeout); //PR: ??? Hasn't occured, TODO: Monitor and find out what causes this ble.onUpdatesEnabled(Callback_BLE_onUpdatesEnabled);//PR: Occurs when host enables notify on a Characteristic that has Notify property set + ble.onUpdatesDisabled(Callback_BLE_onUpdatesDisabled); //TODO: + ble.onConfirmationReceived(Callback_BLE_onConfirmRx); //TODO: //ble.onDataRead(Callback_BLE_onDataRead) //TODO: Need a callback for when reading data so can ensure characteristic is fully up to data before it is passed back (For now update periodically) //BLE2: Setup Services (with their initial values and options) @@ -615,7 +639,7 @@ DEBUG("BLE: Setup Custom IO Service\n"); ble.addService(ServiceIO); //Pointer: pServiceIO - //vShowIO(); + vShowIO(); // Show Initialized values with bleIO initialized (includes tHandle) //TODO: Ensure outputs in correct Initial state //BLE3: Setup advertising