BLE : How do I trigger the notifications and indications ? How do I get the data sent by the notify or indicate request and reply to the server in case of an indicate ?

Hello,

 

I'm a beginner and I'm facing an issue: I'm creating an app to communicate in BLE with a server. It's inspired from the NordicThingy project.

 

I've found a way to Write in the server using the method requestWrite so I can send data to the server with my app.

 

This time I want to receive data sent by my server using "NOTIFY Request" or a "INDICATE Request."

However, I don't know how to trigger the notifications or indications and get the data sent by the server via a "NOTIFY Request" or a "INDICATE Request".

 - Is there a method to get the data sent by the server via a "NOTIFY Request" or a "INDICATE Request"?

- In case I'm using Indicate, How do I reply to the server in case of an indicate

 

Thank you in advance for your precious collaboration.

 

Cordially.

  • I use notify.  One thing is the characteristic must handle notify.  To turn on notify, you write to the descripto.

    For example:

    var cccd = char.getDescriptor(Ble.cccdUuid());
    cccd.requestWrite([0x01,0x00]b);

  • Hello,

    Thank you very much Jim Slight smile

    After turning the characteristic on, which method can I use to retrieve the cata sent by notifications ?

    Thank you in advance.

    Cordially.

  • In the Ble Delegate. onCharacteristicChanged() gets called when new data comes in.

  • Hi Jim,

    I think I undestand : According to the definition of onCharacteristChanged in my app, once it's called, it means I can retrieve the data through a requestRead on the notify characteristic ?

  • When you turn on notify for a characteristic that supports it,onCharactisticChanged is called with the dat.  No need to do a read.  Here's the BLE profiles for the thingy: https://nordicsemiconductor.github.io/Nordic-Thingy52-FW/documentation/firmware_architecture.html

    You'll notic many of the characteristics for the environment service are notify (like temperature).  If you look at the sameple in the SDK, you'll see how that  is handled.

    also, in my blog post, you can look at the piGD example, as it's a bit simpler to follow: forums.garmin.com/.../would-you-like-some-raspberry-pi-with-your-connect-iq

  • Hi Jim, sorry for the delay in my response. 

    I understood how you retrieve the data thanks to onCharactisticChanged(characteristic, value) where "value" is the data that I sent with the servor via the notify request. 

    However, when I try to print the value with the instruction : Sys.println(value), I get the following error : format is too large for array.

    Have you met this type of error before ?

    Cordially.

  • What are you sending from the server?  You can send a max of something like 22 bytes.  What you get is a byte array.

  • Hi jim,

    *I send characters such as "9" (a python string). I convert them in byte which gives me when I print it on my python Server : [dbus.Byte(57), dbus.Byte(10)] (whis is "9" in byte).

    Then I sent it to the app of the watch.

    *In my garmin app, when I print the value (thanks to onCharacteristicChanged(characteristic, value)), it returns :

    [57, 10]. I can thus retrieve the data. 

    I would like now to convert this data into a string (thus to "9") so I tried to reuse the methode of the NordicThingy application: 

    value.decodeNumber( Lang.NUMBER_FORMAT_SINT32, null ) +
    (value.decodeNumber( Lang.NUMBER_FORMAT_UINT8, { :offset => 4 } ) / 100.0);
    Sys.println(value);

    However I get the following error : format is too large for array. I don't know which format I should use to convert the byte array I get into a string.

    Could you please five me some piece of advice ?

    Cordially. 

  • The first byte 57, which is the ascii code for a 9.  The 10 is ascii for a line feed.  All you really need is the first byte, so

    value[0].toChar()

    will give you the character '9'. and toString() will give you the string "9"

    In the thingy, the byte array has things encoded, so a 32 bit value is in 4 bytes.  The reason you're getting the error is your byte array only has 2 bytes.

    What is the range of this ?  is it 0-9, thus one byte ascii, 0-255 which can be a single byte (or it can be a signed value)?

    Let's save the sever wants to send the number 100.

    it can be done so your app sees [100] in value (the actual number) or a string for the number and sees [49,48,48] (the characters for "100".  The first is simpler, while the second, you need to reconstruct the string and then possibly convert it to a Number.

  • Hi Jim,

    Thanks you very much. For now, I'm working with the 0-9 range characters so value[0].ToChar() gives me the appropriate characters.

    I'm going to work now on the indicate request Smile.

    Thank you for your help