Android Question BLE2 SetNotify

mdehrnsb

Member
Licensed User
Longtime User
I am trying to use the BLE2 SetNotify to trigger a DataAvailable event on a characteristic that has notify capability. After setting the SetNotify for the desired characteristic, I do not get any DataAvailable event updates. I have completed an initial ReadData prior to using the SetNotify and get the initial response from the DataAvailable event. Any assistance would be appreciated, especially a code snippet. The BLE2 library apparently has no documentation available for it. Thanks.
 

mdehrnsb

Member
Licensed User
Longtime User
Erel,

I have tried your latest version of BLE2 for SetNotify without success. When the function is called, I get "Setting descriptor. Success = true" but the DataAvailable event never gets raised when the characteristic changes. I am using a custom BLE embedded platform that I designed based on the TI CC2640 SoC processor. This design is based on the TI SensorTag evaluation platform. The embedded design uses an accelerometer to update orientation information and changes a pitch characteristic at 100 ms intervals. I have tested the design with the Andriod TI BLE evaluation app and several BLE scanner apps. When I enable notifications on this characteristic, I get streaming data on all of the apps that I have tried.

This is an outline of the code that I am executing on the B4A program:

  1. I have a button that causes a scan(Null) to execute.
  2. In the DeviceFound event, I test for a particular Device name. If found, I call Connect() with the device ID
  3. In the Connected event, I call ReadData() with a specific service name string
  4. In the DataAvailable event, I use Characteristics.Get(CharacteristicUUID string) to get the byte data. I display the byte data in a Log entry
  5. I have a second button that calls SetNotify() with the same service and characteristic IDs as used in the initial DataAvailable. I get the Set descriptor message but that is it. No further DataAvailable events occur even though I know that the characteristic is being changed.
  6. I have also added a third button on the UI to call ReadData2() with the same serviceID and the Characteristic UUID and the DataAvailable event is called as expected.
If you have any demo code that I can try, or any other words of wisdom, I would greatly appreciate it. It is quite possible that I may be doing something wrong but so far, I cannot determine a problem.

Thanks,

Mark
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Make sure to test it with v1.12. In previous versions non-readable characteristics were not listed at all in the DataAvailable event. In this version they should be listed.

You cannot read non-readable chars with ReadData2. They will only work with SetNotify (as you did in step 5).

Is there any Java code available in the evaluation kit?
 
Upvote 0

mdehrnsb

Member
Licensed User
Longtime User
Erel,

I tried the latest version of BLE2 tonight with the SetNotify function enabled and it raised the DataAvailable event as it should whenever the characteristic was updated. I appreciate your effort in fixing this problem. This will allow me to continue my development and not worry about trying to find a work-around for this issue.

Mark
 
Upvote 0

mdehrnsb

Member
Licensed User
Longtime User
Erel,

I found another problem with the BLE2 SetNotify(). When I set more than one characteristic to have notifications, only the first coded (called) SetNotify() function is active. Any additional SetNotify() calls on other characteristics are not active. I call both SetNotify() functions from the same button click event. I have tested that the DataAvailable event is working properly by coding another button click to call readData2() for both characteristics. When this occurs, both characteristics are updated as expected. I will need to have multiple notifications active at any one time.

Your assistance is appreciated.

Mark.
 
Upvote 0

mdehrnsb

Member
Licensed User
Longtime User
Erel,

I tried your suggestion to use CallSubPlus to delay the SetNotify BLE functions. I tried different delays down to 50 ms but that delay did not work. I settled on 100ms per call. That seemed to work fine. Thanks for your help.
 
Upvote 0

mdehrnsb

Member
Licensed User
Longtime User
Angelo,

I cannot share my complete source code because it is for a new product that is about to be released, but I will be glad to assist you. I am not using the TI SensorTag but I have designed a custom board that uses the TI CC2640 chip. This is similar to the TI CC 2650 used on the SensorTag.

Basically, there are several steps to connect and get data from the BLE device. A summary follows:

Note: Your code should be placed in the Starter file. This example assumes that the BLE manager is named Manager.

  1. Call Manager.Scan(Null)
  2. The event Manager_DeviceFound() is raised for each device found. This event contains the string name of the device, its serial number, advertising data and RSSI. You can determine if this is your device if the name string matches SensorTag (I believe that it is the default SensorTag string name) or the Id matches the SensorTag's serial number. If you are writing an app that can use multiple SensorTags, you will need to store the Id of each tag in a file on the phone for later comparison. If the event is raised with the Id that you want to connect to, call Manager.Connect2(Id, False). Connect2() allows a faster connection versus Connect()
  3. Once the connection has occurred, the event Manager_Connected() is raised with a list as the services available. Call Manager.ReadData(service) with the service UUID that you want to read.
  4. The event Manager_DataAvailable() is raised with the service Id string and the characteristics as a map. You can loop through each characteristic in the map to read its data. Alternately, I use Characteristics.ContainsKey(CharacteristicUUID) with a series of IF statements to look at only certain characteristics that I am interested in.
  5. Use Characteristics.Get(characteristicUUID) to get the the raw bytes from the characteristic. You will then have to convert the bytes into a format more usable such as an int, float, etc. Use ByteConverter to do this.

That is basically it. There are some other things to consider:

  • Use Manager.Disconnect to disconnect from the target.
  • Use Manager.SetNotify if a characteristic uses notifications. Note that you MAY NOT BE ABLE TO issue multiple SetNotify() calls for multiple characteristics one after another and expect them to be processed by Android. I have found that you need a delay of about 200-300 ms between each call for Android to process them. Use CallSubPlus to do this.
  • Use Manager.WriteData to update a characteristic. Note that the event Manager_WriteComplete gets raised after each write is completed. Again, you may not be able to write multiple characteristics at the same time. If needed, use a queue that gets de-queued for each new characteristic update in Manager_WriteComplete.

Hopefully, this helps. Let me know if I can be of more assistance.

Mark
 
Upvote 0

AngeloDavalli

Member
Licensed User
Longtime User
Thanks Mark,
I read now your answer because I was very busy, I'll try to improuve you suggestions as soon as possible and I'll you inform about the results.
angelo
 
Upvote 0

AngeloDavalli

Member
Licensed User
Longtime User
Angelo,

I cannot share my complete source code because it is for a new product that is about to be released, but I will be glad to assist you. I am not using the TI SensorTag but I have designed a custom board that uses the TI CC2640 chip. This is similar to the TI CC 2650 used on the SensorTag.

Basically, there are several steps to connect and get data from the BLE device. A summary follows:

Note: Your code should be placed in the Starter file. This example assumes that the BLE manager is named Manager.

  1. Call Manager.Scan(Null)
  2. The event Manager_DeviceFound() is raised for each device found. This event contains the string name of the device, its serial number, advertising data and RSSI. You can determine if this is your device if the name string matches SensorTag (I believe that it is the default SensorTag string name) or the Id matches the SensorTag's serial number. If you are writing an app that can use multiple SensorTags, you will need to store the Id of each tag in a file on the phone for later comparison. If the event is raised with the Id that you want to connect to, call Manager.Connect2(Id, False). Connect2() allows a faster connection versus Connect()
  3. Once the connection has occurred, the event Manager_Connected() is raised with a list as the services available. Call Manager.ReadData(service) with the service UUID that you want to read.
  4. The event Manager_DataAvailable() is raised with the service Id string and the characteristics as a map. You can loop through each characteristic in the map to read its data. Alternately, I use Characteristics.ContainsKey(CharacteristicUUID) with a series of IF statements to look at only certain characteristics that I am interested in.
  5. Use Characteristics.Get(characteristicUUID) to get the the raw bytes from the characteristic. You will then have to convert the bytes into a format more usable such as an int, float, etc. Use ByteConverter to do this.

That is basically it. There are some other things to consider:

  • Use Manager.Disconnect to disconnect from the target.
  • Use Manager.SetNotify if a characteristic uses notifications. Note that you MAY NOT BE ABLE TO issue multiple SetNotify() calls for multiple characteristics one after another and expect them to be processed by Android. I have found that you need a delay of about 200-300 ms between each call for Android to process them. Use CallSubPlus to do this.
  • Use Manager.WriteData to update a characteristic. Note that the event Manager_WriteComplete gets raised after each write is completed. Again, you may not be able to write multiple characteristics at the same time. If needed, use a queue that gets de-queued for each new characteristic update in Manager_WriteComplete.

Hopefully, this helps. Let me know if I can be of more assistance.

Mark
 
Upvote 0

AngeloDavalli

Member
Licensed User
Longtime User
I've follow your steps but I'cant still read the data (accelerometer, magnetometer ...) because in the TI Sensor Tag is necessary enable notifications in two steps: I'm able to set notify for the accellerometer using: manager.setnotify("f000aa30-0451-4000-b000-000000000000","f000aa31-0451-4000-b000-000000000000",true) but I can't enable at the notification in the bluetooth GattDescriptor. Have you any suggestions ?
 
Upvote 0
Top