Can't get BluetoothLE extension to work w/ GATT Service 0x1802 (Immediate Alert)

635 views
Skip to first unread message
Assigned to ewpa...@gmail.com by ghica.va...@gmail.com

Guansheng

unread,
Aug 11, 2017, 6:27:58 AM8/11/17
to MIT App Inventor Forum
We're making a BLE app using AI2 to communicate with an application running of the nRF52 development board. I downloaded the BLE extension from the link in the MIT_App_Inventor_Basic_Connection.pdf file and imported it into my AI2 project. Having played with it for 2 weeks, I'm unable to write a byte to and read from the GATT 0x1802 service (Immediate Alert). According to the Bluetooth Specifications the device and the app should be able to write a unsigned byte to each other, signalling the alert level. I've tried to use the WriteBytes method to send the byte from my app to the device, and use the ReadBytes to read the byte from device on the app, but got nothing. We confirmed the device could properly send & receive this byte word with Nordic's nRF Connect app. Please find my aia file attached, and may someone tell me what is missing in my codes or what I've been doing wrong the whole time?

So far my app is able to scan, discover, connect to, and disconnect from our nRF52 device; check the supported Services and Characteristics of the device; run a 1000ms loop to monitor the values read from the  Battery Service (0x180f) and Tx Power (0x1804). When I have the read180fand1804 procedure (and the corresponding blocks) enabled in my codes, I'm able to see the device battery level (98%) and transmit power (-8 dBm) at the "BLE Message" field refer to attached image (180f&1804.png). On our PC, we monitor the nRF52 board with a terminal and the attached image  BLE123_Log.png is the screenshot. When my app was successfully connected with the nRF52 board, it displays a log message "Connection secured. Role: 1. conn_handle: 0, Peer ID: 1, Procedure: 1", I believe that means bonding was successful. I took the phone away from the nRF52 board, connection was lost, then I walked back toward the board, and connection was re-established, and I could disconnect from the app, as the screenshot shows.

I tried to send a byte to service 1802 by pressing the Ring button. Then I got the Runtime Error "Failed resolution of: Lcom/google/common/collect/Lists;" as shown in the attached image "RuntimeError.png".

But when I disabled the read180fand1804 procedure and enabled the read1802 procedure (refer to screenshot BLE123_Log2.png) , not that I didn't receive any Immediate Alert byte, my connection also didn't show the "Connection secured. Role: 1. conn_handle: 0, Peer ID: 1, Procedure: 1" message. It seems that the bonding was incomplete.

My questions are:

1. How can I read from and write to the GATT Service 0x1802?
2. What does the runtime error "Failed resolution of: Lcom/google/common/collect/Lists;" mean? 
3. When ListPicker displays a list of BLE devices, sometimes the RSSI number appears as 127. When they are some negative numbers like -78, -82, etc., I would assume that means dBm. But what does 127 mean? Is it indicating something special?

Sorry to write such a long post. This is my first thing asking for help on this forum. I try to present my problem as thoroughly as possible. Thank you very much!

Best regards,
Guansheng 
Test_BLE_GATT.aia
180f&1804.png
RuntimeError.png
BLE123_Log.png
BLE123_Log2.png
RuntimeError.png

Ghica

unread,
Aug 11, 2017, 5:29:03 PM8/11/17
to MIT App Inventor Forum
Why do you also have the old BT component loaded? What is the function of it?
I am not sure it interferes with what you are trying to do, but it could help to remove it.
Cheers, Ghica.

Guansheng

unread,
Aug 12, 2017, 12:43:56 AM8/12/17
to mitappinv...@googlegroups.com
Are you referring to the BluetoothClient1.Enabled property? I use it to check whether the phone has Bluetooth enabled, as suggested in this hackster.io tutorial and this pura vida code snippet. If I don't use the BluetoothClient1.Enabled property, how else can I check whether Bluetooth is enabled, since there is no equivalent property available in the BluetoothLE extension?  

Ghica

unread,
Aug 12, 2017, 5:11:32 AM8/12/17
to MIT App Inventor Forum
I see that you removed your rather rude remark. Good.
I do not know the answer to your question and I am not sure about the support for nRF52, therefore I hope that Evan can shed more light on this.
Cheers, Ghica.

gerrikoio

unread,
Aug 12, 2017, 5:51:13 PM8/12/17
to mitappinv...@googlegroups.com
Unlike Battery and TX Power, which are read (+ optional notify) and read only, respectively, the Immediate Alert is defined as WriteWithoutResponse.


So your app won't work as you are trying to read an 1802 service in order to trigger an alarm. There is nothing available within MIT App Inventor where you can define this primary service either.

Then not sure of second question. Maybe related to the primary service.

Your last question re 127 and no negatives being displayed... this sounds like Signed char (8-bit) Two's complement error. Someone would have to look at that.

Guansheng

unread,
Aug 12, 2017, 11:30:23 PM8/12/17
to MIT App Inventor Forum
Ghica, it was my first thing posting on Google forum. I misunderstood the button as a statement. Sorry about that.

gerrikoio, I'll try to find another way to send an alert from the BLE device to the smartphone app, but in AI2 current implementation, can I write a byte from the smartphone app to the BLE device? Is the WriteBytes method same as WriteWithoutResponse?

Regarding the RSSI signed two's complement error, when I first turn on the BLE device, initially the RSSI is a negative number for about 2 seconds or so, then it becomes 127 for a few seconds, then it becomes a negative number again. I wonder is it telling us that the BLE device is going through some internal wake-up / not-ready / you-should-wait-for-a-sec kind of state or procedures.

gerrikoio

unread,
Aug 13, 2017, 6:27:52 AM8/13/17
to mitappinv...@googlegroups.com
To send an alert from BLE device to the smartphone app, simply define a custom service in your BLE device firmware, using a 128bit UUID and a custom characteristic. Worth searching online for best practice. You should then define the characteristic using a read and notify. Then within your smartphone app, you use a RegisterForBytes method which will trigger automatically (no need to poll) and a "when BytesReceived" to get the content.

Yes, the terminology can get you in a twist. The WriteBytes method mentioned relates to the smartphone app and WriteWithoutResponse relates to the device. So yes (you're correct they mean the same thing), you would use the WriteBytes method (in smartphone app code) to send a 0,1, or 2 (to a 1802 service, for example) to the characteristic defined as WriteWithoutResponse. If you tried to use a WriteBytesWithResponse method from your app, in this case, you would never receive a response from the device as that is not defined in the characteristic.

Your observation on RSSI sounds plausible and probably means there is no error here.

Evan Patton

unread,
Aug 14, 2017, 2:56:33 PM8/14/17
to MIT App Inventor Forum
1. How can I read from and write to the GATT Service 0x1802?

As gerrikoio cited, the 0x1802 service and corresponding 0x2A06 characteristic are flagged as WriteWithoutResponse only. You should be able to write this service/characteristic pair by using the WriteBytesWithoutResponse block and passing a value of 0, 1, or 2.
 
2. What does the runtime error "Failed resolution of: Lcom/google/common/collect/Lists;" mean? 

I think this is a bug and I'll put it on the issue list. Are you only seeing this in the companion app, a compiled app, or both?
 
3. When ListPicker displays a list of BLE devices, sometimes the RSSI number appears as 127. When they are some negative numbers like -78, -82, etc., I would assume that means dBm. But what does 127 mean? Is it indicating something special?
 
The Bluetooth low energy extension passes through the RSSI unfiltered. According to the docs valid values are [-127,126], so my guess is that Android is using value 127 to report an error/unavailable value. However, the documentation doesn't state either way that this is the case. In practice I would simply ignore those values.

Evan

Guansheng

unread,
Aug 15, 2017, 5:31:48 AM8/15/17
to mitappinv...@googlegroups.com
gerrikoio & Evan,



Thanks for your help. I'm testing in both the companion app and the compiled app, and seeing the same results. I will try to define my own custom service. 

I guess the Runtime Error  "Failed resolution of: Lcom/google/common/collect/Lists;"  has something to do with how the 0, 1, and 2 is entered in the WriteBytes block. For the parameter "values", what should I really put there if I want to write 8-bit numbers 0x00, 0x01, 0x02? According to the BluetoothLE extension documentation, the "values" parameter is a list type. I tried to convert the number "1" into binary and hex but ended up getting some error messages on the phone saying I'm trying to pass a String as a Number. The only way I wouldn't get any error messages is to use a"mark a list" block with a number as the only element in the list, as shown in below images, but then I got no response on the device.


I think I'm coming very close to having a solution. May you guys give shed some light on me about how to deal with this list-type "values" parameter?

Best regards,
Guansheng

Evan Patton

unread,
Aug 15, 2017, 2:37:40 PM8/15/17
to MIT App Inventor Forum
Hi Guansheng,

The error related to com/google/common/collect/Lists is definitely an error with the BLE extension. For the time being, if you give a list of numbers rather than a single number you should be fine. I'll add the Lists problem to our issues list. One goal was to allow for the extension to be somewhat flexible in its representation. Sometimes one wants to send a single byte and other times one wants to send a list. To simplify having to construct a list for the purpose of sending a byte we attempt to convert the byte into a list by wrapping it, but a dependency isn't being linked correctly resulting in this error. Your workaround is technically correct and should work going forward.

Cheers,
Evan

Abraham Getzler

unread,
Aug 15, 2017, 3:07:59 PM8/15/17
to MIT App Inventor Forum
You can add sockets to the Make A List block using the square blue button on the block.

ABG

Neylton Nascimento

unread,
Aug 15, 2017, 5:42:47 PM8/15/17
to MIT App Inventor Forum
Hi Guansheng,

Thanks for your detailed post. It helped me a lot, firstly because I was struggling using the old BLE extension, which is not updated in the APP inventor documents, however you pdf file gave me the clue then I downloaded correct BLE aix. Secondly, your workaround to use make list to write byte helped me as well (gelistofOne). I was struggling also trying to write a 0x01 to wake up sensor for my CC1350 TI sensortag and finally it worked, then I was able to read the sensor value correctly and wake up and read any sensor properly. 

I saw your post and I undestood you are failing to write a byte. You can try workaround debugging writing a byte using your make list (getlistoof_One, then immediately use read byte blocks on same uuid and same charactersitics to read and see if it is really writing byte value you want, the if wrongly wrong you can ty to undestand why that value is written, make soething related to convert string to binary etc.

Regarding the 127 number, I believe it is writting a signed byte which means bit 8 is usied for signal only ( 1 positive, 0 negative or vice- versa I do nto remeber exactly), the other 7 bits is for  value which can be maximum 127, e.g. 01111111 is -127 and 11111111 is +127 in binary. Hope it helps.

Guansheng

unread,
Aug 16, 2017, 10:32:35 AM8/16/17
to MIT App Inventor Forum
Hi Neylton,

I'm glad my problem brings you some useful thought. I didn't think of reading the byte immediately after I've sent it. I really believe I'm close to a solution that I just have to resolve the String-to-Number problem. Thanks for the suggestion. I'll give it a try.

We were able to define a custom service, very similar to the 180f battery level service, to let the app to read a byte from the device.

As Evan points out in the Android documentation, RSSI should range from -127 to 126, and it is in dBm. Since we are dealing with mobile phone not satellite ground station, our RSSI got to be a negative dBm number. I still don't know why my RSSI is negative first, then becomes 127, then negative again. If I try to connect to my device when it's RSSI first appears negative, then I would be connecting to it during that very brief period when it's RSSI becomes 127, and the connection would fail. I must wait for many seconds for my device to clear this stage before making a connection. I mean this 127 value has to mean something. I hope some day we will get to the bottom of this glitch.

Best regards,
Guansheng 

Evan Patton

unread,
Aug 16, 2017, 3:55:52 PM8/16/17
to MIT App Inventor Forum
As I mentioned, we don't do any processing of the RSSI values, so if your phone is reporting 127 then that is coming from the Android drivers, not from our code. For now, I would recommend ignoring any values outside the range declared by the Android documentation and proceed from there.

Evan

Guansheng

unread,
Aug 18, 2017, 5:25:48 AM8/18/17
to MIT App Inventor Forum
 I disable all the ReadBytes, RegisterForBytes, BytesReceived blocks in my program. Then I run the program in the AI2 Companion, and guess what folks, my BLE device responds to both high (0x01) and off (0x00) alerts! From the moment I press the button on the app till the device rings on (and off), there is no noticeable delay (by me). I re-enable all the blocks for services 180f (Battery) and 1804 (Tx Power), run the program again, but the BLE device doesn't respond to the alerts at all. So at this point I suspect the ReadBytes method is interfering with the WriteBytes method.

Since I read the services 180f and 1804 to check the battery level and  transmit power, why don't I make use of the BLE extension included BluetoothLE1.BatteryValue and BluetoothLE1.TxPower properties instead? So I put them into my program, run the Companion app again, and this time the BLE device responds to the alert by about a split of a second after I press the button on my app. The delay is noticeable by human (me), it is not as immediate as if BluetoothLE1.BatteryValue and BluetoothLE1.TxPower aren't included, but the delay is definitely less than a second.

For a moment I really thought I've come to the end of my misery. BUT... the BluetoothLE1.BatteryValue property returns a "Cannot Read Battery Level" statement and the BluetoothLE1.TxPower returns a negative 1 value. But if I read the 180f service I get a numeric value, and a negative 4 value if I read the 1804 service, ON THE SAME DEVICE! So clearly there are some issues with the BluetoothLE1.BatteryValue and BluetoothLE1.TxPower properties. May someone look into that?

I build the program into an apk file and install it on my Android phone. When I press the button to send the alert, I get the good out "Failed resolution of: Lcom/google/common/collect/Lists;" runtime error again.


Evan Patton

unread,
Aug 18, 2017, 9:20:57 AM8/18/17
to MIT App Inventor Forum
Hi Guangsheng,

Thank you for the detailed info. I'm working on BLE bugfixes this morning so I'll add your findings to my list.

Evan

Reply all
Reply to author
Forward
0 new messages