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!!!

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??
 {