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:
- 16:3e83f2babdfb
- Parent:
- 15:b2c8bdef2d20
- Child:
- 17:93538044f003
--- a/main.cpp Wed Dec 24 20:35:21 2014 +0000 +++ b/main.cpp Sat Dec 27 14:33:12 2014 +0000 @@ -263,26 +263,26 @@ DEBUG(" ShowIO:\n"); // IOw8 Write + uLen=sizeof(puBuf8); ble.readCharacteristicValue(IOw8.getValueHandle(), puBuf8, &uLen); // Real Characteristic's Actual Value DEBUG(" sIOw8: Handle:%d Len:%d L1:%d L2:%d %04X %04X %04X\n", IOw8.getValueHandle(), uLen, sIOw8.s.L1pwm100, sIOw8.s.L2pwm255, sIOw8.s.px[0], sIOw8.s.px[0], sIOw8.s.px[0]); //DEBUG(" pIOw8: Handle:%d Len:%d [%02X %02X %02X %02X %02X %02X %02X %02X]\n", IOw8.getValueHandle(), sizeof(pIOw8), pIOw8[0], pIOw8[1], pIOw8[2], pIOw8[3],pIOw8[4], pIOw8[5], pIOw8[6], pIOw8[7]); DEBUG(" sIOw8: Handle:%d Len:%d [%02X %02X %02X %02X %02X %02X %02X %02X]\n", IOw8.getValueHandle(), sizeof(sIOw8), sIOw8.pu[0],sIOw8.pu[1],sIOw8.pu[2],sIOw8.pu[3],sIOw8.pu[4],sIOw8.pu[5],sIOw8.pu[6],sIOw8.pu[7]); - uLen=sizeof(puBuf8); ble.readCharacteristicValue(IOw8.getValueHandle(), puBuf8, &uLen); // Real Characteristic's Actual Value DEBUG(" cIOw8: Handle:%d Len:%d [%02X %02X %02X %02X %02X %02X %02X %02X]\n", IOw8.getValueHandle(), uLen, puBuf8[0], puBuf8[1], puBuf8[2], puBuf8[3], puBuf8[4], puBuf8[5], puBuf8[6], puBuf8[7] ); // IOr4 Read + uLen=sizeof(puBuf8); ble.readCharacteristicValue(IOr4.getValueHandle(), puBuf8, &uLen); // Real Characteristic's Actual Value DEBUG("\n sIOr4: Handle:%d Len:%d B1:%d B2:%d B1p:%d B1r:%d B2p:%d B2r:%d\n", IOr4.getValueHandle(), uLen, sIOr4.s.bB1p, sIOr4.s.bB2p, sIOr4.s.uB1p, sIOr4.s.uB1r, sIOr4.s.uB2p, sIOr4.s.uB2r); //DEBUG(" pIOr4: Handle:%d Len:%d [%02X %02X %02X %02X]\n", IOr4.getValueHandle(), sizeof(pIOr4), pIOr4[0], pIOr4[1], pIOr4[2], pIOr4[3]); //DEBUG(" sIOr4: Handle:%d Len:%d [%02X %02X %02X %02X][%.4s]\n", IOr4.getValueHandle(), sizeof(sIOr4), sIOr4.pu[0], sIOr4.pu[1], sIOr4.pu[2], sIOr4.pu[3], sIOr4.pc ); DEBUG(" sIOr4: Handle:%d Len:%d [%02X %02X %02X %02X]\n", IOr4.getValueHandle(), sizeof(sIOr4), sIOr4.pu[0], sIOr4.pu[1], sIOr4.pu[2], sIOr4.pu[3]); // Read Actual IOr4 Characteristic's data back from Service (i.e. last written to service): - uLen=sizeof(puBuf8); ble.readCharacteristicValue(IOr4.getValueHandle(), puBuf8, &uLen); // Real Characteristic's Actual Value DEBUG(" cIOr4: Handle:%d Len:%d [%02X %02X %02X %02X]\n", IOr4.getValueHandle(), uLen, puBuf8[0], puBuf8[1], puBuf8[2], puBuf8[3] ); // IOn4 Notify + uLen=sizeof(puBuf8); ble.readCharacteristicValue(IOn4.getValueHandle(), puBuf8, &uLen); // Real Characteristic's Actual Value DEBUG("\n sIOn4: Handle:%d Len:%d B1:%d B2:%d B1p:%d B2r:%d %.2f\n", IOn4.getValueHandle(), uLen, sIOn4.s.bB1p, sIOn4.s.bB2p, sIOn4.s.uB1p, sIOn4.s.uB2r, ((float)sIOn4.s.iTempC100/100.0)); //DEBUG("\n pIOn4: Handle:%d Len:%d [%02X %02X %02X %02X]\n", IOn4.getValueHandle(), sizeof(pIOn4), pIOn4[0], pIOn4[1], pIOn4[2], pIOn4[3]); 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"); @@ -486,22 +486,22 @@ 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); + 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 + //TODO: process Enable for Each Notify Characteriistic 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) 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); + 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 + //TODO: process Disable for Each Notify Characteriistic of each Service } void Callback_BLE_onConfirmRx(Gap::Handle_t tHandle) // Confirmations?? {