• Hi,

    I've read the various tutorials and examples about how this should work, but I just don't seem to be able to get it right.

    If I use the nrF Connect app on my iPad, connect to the Puck it shows the expected UART service with TX/RX.

    If I connect via TinyB, BLE command line I see two services listed:
    1) The expected one for UART: 6e400001-b5a3-f393-e0a9-e50e24dcca9e
    2) Another one: 00001801-0000-1000-8000-00805f9b34fb (what is this one?)

    If I try to add my own service and specify UART:false on the options then the iPad won't connect to the puck at all and the code version still either sees 1 or both of the previously mentioned service uuids.

    I'm trying to use the sample code like this:

    RF.setServices({
      "0000bcde-0000-0000-0000-000000000000" : {
        "0000abcd-0000-0000-0000-000000000000" : {
          value : "Hello", // optional
          maxLen : 5, // optional (otherwise is length of initial value)
          broadcast : false, // optional, default is false
          readable : true,   // optional, default is false
          writable : true,   // optional, default is false
          notify : true,   // optional, default is false
          indicate : true,   // optional, default is false
          description: "My Characteristic",  // optional, default is null
          onWrite : function(evt) { // optional
            console.log("Got ", evt.data);
          }
        }
        // more characteristics allowed
      }
      // more services allowed
    },{advertise:['0000bcde-0000-0000-0000-0­00000000000'], uart:false});
    

    I would expect to only see the one service listed and connection from iPad should work too.
    Also are then any more details about what the various attributes mean ie:

      broadcast : false, // optional, default is false
      notify : true,   // optional, default is false
      indicate : true,   // optional, default is false
      description: "My Characteristic",  // optional, default is null
    

    I also don't see any way to retrieve the description detail via TinyB,
    http://iotdk.intel.com/docs/master/tinyb­/classtinyb_1_1BluetoothGattCharacterist­ic.html

    Quite often I also find that the Puck vanishes or won't connect and I constantly need to either reset it AND or run /etc/init.d/bluetooth restart to keep things running. I've ensured all the libraries are up to date.

    Another note is that in the console of the WebIDE I get the message:

    BLE Connected, queueing BLE restart for later
    

    If I try to put the setService in a timer then that message is written out every time it fires.

  • As an example of the output I get from the tinyB / C++ code.. It also seems as if the Puck appears as 2 devices with an almost identical UUID:

    Bluetooth manager started...
    
    Device discovery..
    
    Discovered devices: 
    Class = BluetoothDevice Path = /org/bluez/hci0/dev_F1_F9_F8_7F_B3_CF Name = DfuTarg Connected = 0 
    
    Class = BluetoothDevice Path = /org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE Name = Puck.js b3ce Connected = 0 
    
    Connecting to device..0xcf0b70
    
    Fetch services..
    
    Class = BluetoothGattService Path = /org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE/se­rvice000b UUID = 6e400001-b5a3-f393-e0a9-e50e24dcca9e Device = /org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE 
    
    Class = BluetoothGattService Path = /org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE/se­rvice000a UUID = 00001801-0000-1000-8000-00805f9b34fb Device = /org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE 
    
    
  • DfuTarg Will be use daily for flashing new firmware.

    Name = Puck.js Is the one you want to use.

  • Thanks, that makes sense. I will just include a filter then on devices like Puck.js*
    Now to sort out the service issue. The end objective here is that I need the Raspberry PI to be talking to at least 3 or 4 Puck.JS tags (approximately simultaneously), I say approximately in that they could be probed sequentially as long as there isn't a significant delay. For example 4xPuck.JS with sensors which need to be aggregated at 20-30hz OR when the sensor values changes if it can be a push rather than polling.

  • Is the issue just that you're still connected to the Puck with one device? It can only accept one connection at a time so won't even advertise while it's connected. If you want to debug things you can always wire up a serial connection (details on the Puck.js page).

    I think 00001801-0000-1000-8000-00805f9b34fb (which is actually just a 16 bit UUID 1801) is a standard Bluetooth way of flagging up when the services advertised by a device have changed.

    Other things that might help:

    • I'm not sure, but using 00000... as the UUID could be causing problems - it's extremely likely it's reserved (it's not a 16 bit UUID if that's what you had intended). I'd either use a normal 16 bit UUID, or use a totally random 128 bit UUID as a base and just vary the 16 bits in the middle like you do currently.
    • The Nordic devices can't change the services that they advertise on the fly, so Espruino has to actually restart the whole Bluetooth stack if items (like UART) are to be removed - hence the message. Obviously if it does that it'll disconnect any connected devices, so it waits until you disconnect. If you just want to update the content data in services then just use NRF.updateServices
  • Hi,
    After making the changes and going back to the 16bit UUIDs and restarting nRF Connect app I can now connect to the Puck and see the single new service with characteristic 0xabcd so that is moving in the right direction!
    However from the tinyB C++ code on the PI I still only see the original two services listed:
    6e400001-b5a3-f393-e0a9-e50e24dcca9e
    00001801-0000-1000-8000-00805f9b34fb
    and not the new one. My guess here is that it looks like bluez must be caching details about the BLE device, given that tinyB is just a wrapper on top of hci/bluez stack. I'm trying to see how to clear the device cache from bluez to see if that helps.

  • I tried deleting /var/lib/bluetooth contents and restarting bluetooth with sudo hciconfig hci0 reset
    Now the C++ code shows only the service: 00001801-0000-1000-8000-00805f9b34fb

  • Do you have to do something like initiate a scan for services? Usually when you connect on BLE you don't know what any of the services are - you have to enumerate them separately.

    BluetoothDevice::get_services_resolved looks like a good start: http://iotdk.intel.com/docs/master/tinyb­/classtinyb_1_1BluetoothDevice.html#a8f1­3d552098d6549a44cbea62d82796c

  • Hi,

    I initiate a scan for a list of services like this:

    controller->connect();
    		std::cout << "Fetch services.." << std::endl;
    		std::vector<std::unique_ptr<BluetoothGat­tService> > service_list;
    		while(!controller->get_services_resolved­()) {
    			service_list = controller->get_services();
    			std::this_thread::sleep_for(std::chrono:­:seconds(1));
    		}
    

    controller is valid and pointing at the puck.js device, but still just the original 2 listed services as opposed to the new one

  • Just to verify this isn't a tinyB issue, I tried the same using bluetoothctl, and here is it's output

    [Puck.js b3ce]# list-attributes
    Primary Service
    	/org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE/se­rvice000b
    	6e400001-b5a3-f393-e0a9-e50e24dcca9e
    	Nordic UART Service
    Characteristic
    	/org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE/se­rvice000b/char000f
    	6e400002-b5a3-f393-e0a9-e50e24dcca9e
    	Nordic UART TX
    Characteristic
    	/org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE/se­rvice000b/char000c
    	6e400003-b5a3-f393-e0a9-e50e24dcca9e
    	Nordic UART RX
    Descriptor
    	/org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE/se­rvice000b/char000c/desc000e
    	00002902-0000-1000-8000-00805f9b34fb
    	Client Characteristic Configuration
    Primary Service
    	/org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE/se­rvice000a
    	00001801-0000-1000-8000-00805f9b34fb
    	Generic Attribute Profile
    [Puck.js b3ce]# 
    
    
  • Ok, so after a few changes, bluetoothctl is showing:

    [bluetooth]# list-attributes F1:F9:F8:7F:B3:CE
    Primary Service
    	/org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE/se­rvice000b
    	0000bcde-0000-1000-8000-00805f9b34fb
    	Unknown
    Characteristic
    	/org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE/se­rvice000b/char000c
    	0000abcd-0000-1000-8000-00805f9b34fb
    	Unknown
    Descriptor
    	/org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE/se­rvice000b/char000c/desc0010
    	00002903-0000-1000-8000-00805f9b34fb
    	Server Characteristic Configuration
    Descriptor
    	/org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE/se­rvice000b/char000c/desc000f
    	00002901-0000-1000-8000-00805f9b34fb
    	Characteristic User Description
    Descriptor
    	/org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE/se­rvice000b/char000c/desc000e
    	00002902-0000-1000-8000-00805f9b34fb
    	Client Characteristic Configuration
    Primary Service
    	/org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE/se­rvice000a
    	00001801-0000-1000-8000-00805f9b34fb
    	Generic Attribute Profile
    [bluetooth]# 
    

    The puck.js code is

    function SetupServices() {
      NRF.setServices({
        0xbcde : {
          0xabcd : {
            value : "Hello", // optional
            maxLen : 5, // optional (otherwise is length of initial value)
            broadcast : true, // optional, default is false
            readable : true,   // optional, default is false
            writable : true,   // optional, default is false
            notify : true,   // optional, default is false
            indicate : true,   // optional, default is false
            description: "My Characteristic",  // optional, default is null
            onWrite : function(evt) { // optional
              console.log("Got ", evt.data);
            }
          }
          // more characteristics allowed
        }
        // more services allowed
      },{advertise:['bcde'], uart:false});
    }
    
    //setInterval(SetupServices,1000);
    SetupServices();
    
    

    but the bluez/tinyB is showing me:

    Bluetooth manager started...
    Device discovery..
    Discovered devices: 
    Class = BluetoothDevice Path = /org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE Name = Puck.js b3ce Connected = 0 
    Connecting to device..0x1aaeff8
    Fetch services..
    Class = BluetoothGattService Path = /org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE/se­rvice000a UUID = 00001801-0000-1000-8000-00805f9b34fb Device = /org/bluez/hci0/dev_F1_F9_F8_7F_B3_CE 
    
    

    So confused now :)

  • As another test, using this code on the puck

    function SetupServices() {
      NRF.setServices({
        0xBCDE: {
          0xABCD : {
            value : "Hello", // optional
            maxLen : 25, // optional (otherwise is length of initial value)
            broadcast : true, // optional, default is false
            readable : true,   // optional, default is false
            writable : true,   // optional, default is false
            notify : true,   // optional, default is false
            indicate : true,   // optional, default is false
            description: "My Characteristic",  // optional, default is null
            onWrite : function(evt) { // optional
              console.log("Got ", evt.data);
            }
          }
          // more characteristics allowed
        }
        // more services allowed
      });
    }
    
    SetupServices();
    
    var cnt = 0;
    setWatch(function() {
      if(cnt++ % 2 === 0)
        LED1.set();
      else
        LED1.reset();
      NRF.updateServices({
        0xBCDE : {
          0xABCD : {
            value : [cnt],
            notify: true
          }
        }
      });
    }, BTN, { repeat:true, edge:"rising", debounce: 50 });
    

    Connecting via nRF Connect iPad app, I can see the service and Characteristic ABCD..
    It's default value however shows as 0x0D and pressing the puck button (which does toggle the led) is not updating that value

  • Are you sure you're subscribing to notifications in the nRF Connect app? It doesn't do it automatically when you look at the service, you have to click the icon by the side of it.

    Just a thought, but maybe try not including the description - i think that'll be responsible for the 0x2901 descriptor at the very least.

  • Ok, I've removed the description, still get a 0x2901 descriptor. Definitely have the app subscribed to notifications. What I have noticed is perhaps it's the way the value is being interpreted, if I specify it as an integer in the updateServices with value : cnt
    it seems to be coming through as a string representation of the value of cnt.

  • Looks like I've gotten it working now, it's all been a bit flaky, but I'll keep trying to make sure it's 100% then I'll share the code here for both the Puck and the C++ tinyB, it's a good base to start from.
    Thanks for the help!

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

How to create custom service and characteristics

Posted by Avatar for JohnH @JohnH

Actions