BLE communication with nrf52832 UART demo wedges

575 views
Skip to first unread message

Nyles Nettleton

unread,
Sep 20, 2019, 8:34:14 PM9/20/19
to mitappinv...@googlegroups.com
Hi All,

I've been scouring for days to find anyone with this problem, to no avail...

My setup uses the attached AI2 blocks to talk to an nrf52832 module
running the demo BLE UART code.  Tera Term is connected to the
serial port on the nrf52.

Using the Nordic UART app works fine talking back and forth from my
cell phone to the nrf52.

Using the attached AI2 blocks on my cell works from the cell to the nrf52,
but as soon as I send anything from the nrf52 to the cell, any further text
from the cell doesn't show up.  Further messages from the nrf52 still
show up.

Looks like I can't post the .aia file - I'll post it in a further post if needed.

Any clues here?  TIA  :)

                                  Cheers,
                                      Nyles
BLE01.aia
BLE01blocks00.png

Ghica

unread,
Sep 21, 2019, 4:26:58 PM9/21/19
to MIT App Inventor Forum
You can post the .aia file if you do it by *editing an existing post*, or by sharing it via a Google drive.
Cheers, Ghica.

Nyles Nettleton

unread,
Sep 21, 2019, 4:35:41 PM9/21/19
to MIT App Inventor Forum
Thanks, done.  :)

BodyMindPower

unread,
Sep 22, 2019, 4:50:20 AM9/22/19
to MIT App Inventor Forum
I'm not familiar with this BLE device, but try the following:




Are you testing with Companion or with the APK?

Ghica

unread,
Sep 22, 2019, 11:13:28 AM9/22/19
to MIT App Inventor Forum
Could you please tell us where you found the information about the UUID's and the API protocols to use?
I saw hat this chip uses BLE 5? As far as I know, the BLE extension is not very good at BLE 5 yet.
Also, this block is strange:

blocks (40).png

You have a stringsReceived event, and then you are going to read strings again?? You already have them! That is asking for trouble.
Basically, you should sort out what the protocol to use is first.

But anyway, did you receive anything at all?
Cheers, Ghica.

Nyles Nettleton

unread,
Sep 22, 2019, 2:05:58 PM9/22/19
to MIT App Inventor Forum
I tried switching to bytes, bytes with response and strings with response.  Same problem.  :)
Testing with cell phone and the MBN52832DK development board from Murata.

Odd thing is that with the Nordic UART app, it all just works.

                        Thanks,
                            Nyles

Nyles Nettleton

unread,
Sep 22, 2019, 2:09:00 PM9/22/19
to mitappinv...@googlegroups.com
I got the numbers from several sources - the most compelling was the nRF Connect app,
which shows the service and characteristic UUIDs for the connected device.

And yes, until I receive any text from the nRF52, I can send as many messages as I
like from the AI2 app.  After that, it only works from the nRF52 to the app.

The strange bit may be where I'm joining the old data from the text box with the new
data - if there's a better way of making a scrolling display please let me know.  :)
I did try it with just one message displayed at a time - no difference in behavior.

                                Nyles

BodyMindPower

unread,
Sep 22, 2019, 3:01:21 PM9/22/19
to mitappinv...@googlegroups.com
From my last post: "Are you testing with Companion or with the APK?"
Does it work with Companion?

Nyles Nettleton

unread,
Sep 22, 2019, 3:17:12 PM9/22/19
to mitappinv...@googlegroups.com
Do you mean the MIT AI2 Companion app?  If so, that's how I download the app.

Just tried Connect->AI Companion for the first time - the app came up on the cell
screen, and:

Network Error
  Companion Connection Error state = failed

comes up.  Don't know what that means exactly. 
Actually, the app doesn't always show up.

Gerard Bucas

unread,
Sep 22, 2019, 5:43:30 PM9/22/19
to mitappinv...@googlegroups.com
Hi Nyles,

I have a similar nrf BLE board & I tested your app on it.
In my opinion your "problem" is that you have a "ReadStrings" block (see below) in your "StringsReceived" block.So I have removed it & it definitely works on MY board now (see my comment below on adding "\n" though). The "ReadStrings" block is NEVER required when one uses a "RegisterForStrings" (or Register for anything else). The whole ides of "RegisterForStrings" is that the BLE Extension will automatically call the "StringReceived" block (event) each time that data arrives from the BLE device/peripheral to which you are Connected & Have "RegisteredFor..". So basically once you have "RegisteredForStrings", you simply "sit back & wait" for data to arrive in the "StringsReceived" block, 

ReadStrings_blocks.png



I also took the liberty of adding a few other things to your .aia.
1. Removed the parenthesis around all Strings Received that the AI2 BLE Extension inserts. Personally I find them irritating (as they are NOT sent by the BLE sending device (as you know!). So the log now looks much "cleaner".

2. I added a a few "safety" checks in your code (eg: don't send if NOT connected, don't try & connect if no device has been selected, don't stop scanning if not scanning, etc). As I am sure you noticed those things all give BLE errors. So now you should be able to press any buttons, in any condition, without errors. Of course a better (additional) way to do this (from a UI point of view) is to enable/disble buttons as the "Status" changes (eg: ONLY "enable" the Disconnect Button once Connected, ONLY enable the "Stop Scan" button when Scanning. etc).

3. I also added a VerticalScrollArrangement around your log so that it now scrolls a lot better. I suggest you also add a "Clear Log" button (makes life a lot easier when you are using this in real life!) :).

4. One other thing I noticed is that you always add a "\n" (linefeed) at the end of every string you send. On my BLE board this does not work correctly & my own firmware does NOT handle that \n character very well (in fact it ignores the whole string!). So in my case it actually "looks like" nothing was sent. This COULD maybe also be a problem in your case (depends on your firmware in BLE device). To make it easy for you (& me!) to test this, I added a "LongClick" option on the "Send" button, which will NOT add the "\n". So in my setup it ONLY works if I use this option (Send all data with a LongClick instead of a "Normal" Click). You may want to try that as well in case this was actually one of your problems as well. If in fact that is one of your problems, you can reverse the functionality of the Click & LongClick. Easy to do!

Anyway, modified .aia attached - hope this helps! Try it & let me know if it works now!?

Good luck & Regards

Gerard
BLE01_v2.aia

Nyles Nettleton

unread,
Sep 22, 2019, 7:13:45 PM9/22/19
to MIT App Inventor Forum
Gerard,

Amazing how much one can learn in an instant.  You are awesome!  Works
perfectly now - I can get on to the meat of the project now.  :D

                          Cheers!
                              Nyles

Gerard Bucas

unread,
Sep 23, 2019, 12:04:50 AM9/23/19
to mitappinv...@googlegroups.com
Hi again Nyles,

Thanks! Glad to hear that it works now. :)

Couple of additional "tips" for you:

1. You don't really need the "Connect" button. You can replace its blocks with the "AfterPicking" block, so that you will automatically connect when the user "Selects" the BLE device from the Scan List. So simply replace your "ButtonConnect.click" block with this block (same code just a different activation mechanism):

AfterPickingBlock.png


2. There is actually a "ScanForServices" function available in a new "Beta" Release of the BLE extension fro AI2. I have found this to be a major additional feature! This allows you to Scan ONLY for Devices that offer the Services that you need (in your case the "Nordic UART Service"). To get your hands on this, you will need to ask "nicely" ( :) ) on this forum and I am sure Evan (who is THE man here!) will let you have a copy of that. This is especially useful if (for example!) you are demo'ing/using your app in a location where there are many BLE devices (eg: Starbucks!), as the list of "DevicesFound" can go down from >30 to 1 (or very few). Makes the whole experience much more "pleasant" (you have to try it to fully appreciate it!). I have been using that Beta for 6 months now with various BLE devices and I have never had a problem with it!

3. Be careful of the StringsReceived "content". This is NOT related to AI2 but the way BLE works (so the same happens in the Nordic & Adafruit BLE test apps). When your device is sending a string with a "println('String')" function (eg: in Arduino based firmware), the string will contain BOTH a <CR> and a <LF> (or \e and \n) at the end of it. Those two characters can cause some issues if you are not expecting them (especially as they are NON printable - so they don't show up in your log unless you convert them to something printable - which is possible & easy). So you may want to filter those out (depends on your application). 

4. If your BLE device sends strings longer than 3 characters (which is actually at least five character with <CR><LF> added!), they may not "arrive" as a single string! This gave me endless problems when I started out with this stuff. So, for example, when your device issues a println("ABC123") command, the string may arrive in your app as:
"ABC1" followed by a separate sting of "23\e\n" (and sometimes even in 3 or more pieces depending on length of string). This is also visible in the Nordic & Adafruit BLE test apps (so NOT related to AI2 - it is the way BLE works - or the fact that many of the sending BLE devices only have a 4 or 6 character send buffer!). This behavior is also effected by the rate at which your BLE device sends out data (so you may not experience it). Anyway, if you want to be guaranteed to receive the string "intact/complete" (the way it was sent), you need to "gather" the pieces (in "BLE1.StringsReceived") until you find a "\n" in your string. Relatively easy to do but sort of a pain!

Anyway, that's it!  

Welcome to AI2 - greatest tool on earth (for creating Android apps!).

Regards

Gerard


 

Nyles Nettleton

unread,
Sep 23, 2019, 1:37:48 PM9/23/19
to MIT App Inventor Forum
Excellent advice!  Thanks again so much!

If you're ever in the Phoenix area, I owe you a drink.  :D

                         Cheers,
                             Nyles
Message has been deleted

ABG

unread,
Sep 23, 2019, 1:55:38 PM9/23/19
to mitappinv...@googlegroups.com
Regarding the message fragmentation problem mentioned by @Gerard,
please see the attached code fragment to handle message reassembly
and delimiter (\r\n) handling for strings arriving via the BLE
Strings  Received event.

I use a for each loop on the StringsReceived list items instead of
implicit list to text conversion to avoid the extra spaces that would
be inserted between text fragments in the (item item item) default list-to-text conversion
in the sample earlier in this thread.

The reassemble procedure handles reassembly of small text fragments
within an IncomingDataLabel.Text field for visibility and
because i didn't want to have to remember whether or not AI2
procedures parameters work by value or by reference.

When a delimiter is encountered, the reassembler procedure checks if the preceding
message has been completely handled (is the MessageLabel Text empty?),
and then it would clip off the incoming message from the IncomingDataLabel.Text
buffer, frop the new message text into the MessageLabel.Text buffer, then call
a procedure to handle the new message.

(editted to fix bug in label.text handling - ABG)
(re-editted  for another label.text blooper - ABG)

ABG



Designer.PNG
when BLE1 Strings Received.png
reassemble.png
reassemble.png
BLE_message_reassembler.aia
blocks.png

Nyles Nettleton

unread,
Sep 23, 2019, 2:02:02 PM9/23/19
to MIT App Inventor Forum
Hi ABG,

Marvelous, thank you!  So much useful information in one place.  :)

                                              Cheers,
                                                  Nyles

ABG

unread,
Sep 23, 2019, 2:04:46 PM9/23/19
to MIT App Inventor Forum
Hold on, I found another bug where I used a
component instead of its .Text value.

Will re-upload new ...

ABG

ABG

unread,
Sep 23, 2019, 3:02:27 PM9/23/19
to MIT App Inventor Forum
I proof read my code, and it should be good now.

Sorry for the ready-fire-aim sequence.

ABG

Nyles Nettleton

unread,
Sep 23, 2019, 3:28:16 PM9/23/19
to MIT App Inventor Forum
Hah!  Thanks again.  :D

Gerard Bucas

unread,
Sep 24, 2019, 6:48:45 PM9/24/19
to mitappinv...@googlegroups.com
Hi ABG

Interesting approach! I actually developed a little test app to test my own code for re-assembly of BLE strings received a couple of months ago (when I started with AI2 & BLE).
As there are always many ways to skin a cat in Software, I thought I would post my version here as well (together with the "test Harnas" app that also generates test data to emulate the string fragments typically received from BLE devices (I was amazed how many different ways some strings were received in my BLE App, so I wanted to make sure I could test all cases in my code). So here it is in all its glory! Let me know what you think..!? :)

The actual "string re-assembly" block looks like this (pretty simple actually):

re-AssembleBLEstrings.png



The test/demo .aia is also attached.

Enjoy,

Gerard
reAssembleBLEstrings.aia
Message has been deleted

ABG

unread,
Sep 24, 2019, 11:02:39 PM9/24/19
to mitappinv...@googlegroups.com
I tightened up your while/if/then/break loop by
applying DeMorgan's Law and a local variable for 
the length of the global input buffer in the loop.

I also redid the preprocessing to accommodate a list input,
based on your procedure parameter name.

ABG

reassembleToGlobal.png

Gerard Bucas

unread,
Sep 25, 2019, 4:31:54 AM9/25/19
to mitappinv...@googlegroups.com
Hi ABG,

As I grew up in the jungles of Africa (& went to school there) I never learnt all that theory! 
All I know is that my code/algorithm has been happily & flawlessly working for many months in real life applications (in the hands of a number of different users with different BLE devices).

So working on the assumption that you are a LOT smarter than I am, I will take your word for it that this is actually an improvement...! :)

Did you test it against my test data!?

Curious...

Gerard

Edit: 
So in deference to what you are saying, I have in fact removed the offending "break" from that While Loop (so it makes the whole block even shorter!).
I edited my earlier post to reflect that (also updated the associated .aia file). 

So I think this is a good compromise - agreed!? :)

ABG

unread,
Sep 25, 2019, 5:40:28 PM9/25/19
to MIT App Inventor Forum
Did I test it?

Actually, not with hardware.
Just by reading the code and looking for gaps.
(I don't have any BLE hardware.)

I see a gap between any code that takes 
the list of strings that arrives from the BLE ReceivedStrings
event and feeds it directly into a text block 
without taking into account the blanks that will be
inserted between arrived strings within the parentheses.

If such code has been working on a set of devices,
is it because the devices never send more than one
string at a time, or is because the messages sent
by the devices will survive having spaces inserted into them?

I'm hoping some one with device experience will answer
that for me.


Regarding my attempts to reduce block count,
it's a game among programmers, like saving pennies.
A poor man needs to save pennies, and
a rich man delights in saving pennies.

ABG

Gerard Bucas

unread,
Oct 1, 2019, 1:18:39 PM10/1/19
to mitappinv...@googlegroups.com
Hi ABG,

Somehow I missed this post from you - my humble apologies.

I guess I am a bad communicator! 

It seems I didn't get the objective of the 'reAssembleBLEstrings.aia' I posted across to you (& therefore probably others as well).

Obviously I am NOT going to post a .aia which is dependent on a BLE device (& by implication on firmware running on such a device!). The whole point of the 'reAssembleBLEstrings.aia' I posted was to have a SIMPLE test app which demonstrates the "re-assembly of BLE strings" by EMULATING the "fragmented" data typically received from a BLE device. As I have analyzed/debugged REAL BLE DATA received from a number of different real-world BLE devices, I created a "BLE test data set" and a "test harness" tool for myself (that is the .aia I posted) to test the re-assembly algorithm/code to make sure all cases are handled correctly and one can observe EXACTLY what happens and how it all works. THAT was my objective.

I guess you never really looked at it as it would have quickly become obvious as to what the purpose was and what it demonstrates/tests. 

So the 'reAssembleBLEstrings.aia' I posted does NOT USE BLE AND THEREFORE DOES NOT REQUIRE A BLE DEVICE! I simply pulled out the "BLE strings re-assembly" procedure in my real BLE apps and put it in a test harness together with a set of BLE test data that should clearly indicate how BLE stings can arrive In a BLE connected app. This allows one to quickly grasp the concept of how strings are fragmented (the fragments are clearly shown in the app) and how the strings are then "re-assembled" and then handed off to whatever procedure one needs to handle the "complete re-assembeld string".

I included the "BLE.StringsReceived" block ONLY to clearly show that it could call the exact same procedure that is used by the test data generator code. So to someonbe looking at it, they can quickly see that all they need to do is to hook those two together (as is shown in the code in demo). So the "B:LE.StringsReceived" block is NEVER USED (& there is NO "BLE connection" logic in the test harness app I posted - it is simply there to demonstrate how one would use that block in a real BLE connected app. So the whole purpose of this test harness was to first show people the typical (& extreme) ways that BLE data actually arrives (from real-world BLE decvices) and then how all those seemingly unusual fragments that arrive are easily re-assembled into the "complete" strings, which were sent by the BLE device.

Anyway, maybe I wasted my time posting it here as it could ONLY be understood by someone who would actually take their time to download and run the (very simple!)  'reAssembleBLEstrings.aia' app. That is certainly what I do when someone posts something like that. But as I said, having grown up in Africa, I guess I react a little different to people from other parts of the world! My bad... :)

As for your comments regarding rich & poor people, I don't really want to enter into a debate on that here (except if we ever meet for a coffee in Florida!).

So I hope this clarifies my intentions/purpose & that I have suffiuciently excited you to actually download that  'reAssembleBLEstrings.aia' and have a quick look at it (NO BLE DEVICE REQUIRED!). Will take a MAX of 5 minutes of your time - not a lot even for a super busy man.

Best Regards

Gerard

ABG

unread,
Oct 2, 2019, 12:09:09 PM10/2/19
to MIT App Inventor Forum
@Gerard, I have found the .aia file I missed,
and gone through it with a fine tooth comb,
giving it the attention it deserves.

For the benefit of the other board users, I have 
attached quick shots of the contents,
to illustrate the project in the board.

You asked for comments on it, so here goes ...

The GUI is clear and well laid out.
(My error on the Help button is not you, it's me)

Workflow is clear.

Components are well named, with a consistent naming standard.

Blocks are well commented
(Blame the .PNG export facility for not showing them)

I don't understand why the block list with the
test data uses <cr> and <lf> instead of
\r and \n, translating them in a procedure.

ABG



Capture.PNG
processReconstructedStrings.png
reAssembleBLEstrings.zip
runtime error on help button.PNG
when BLE1 StringsReceived.png
when btnClearLogs Click.png
when btnHelp Click.png
when btnSendBLEdata Click.png
when btnSendBLEdata LongClick.png
when Screen1 Initialize.png
blocks.png
clearLogs.png
Designer.PNG
extractStrings.png
global charsRcvdSoFar.png
global emulatedBLEtestData.png
global listIndex.png
global maxLogLength.png
insetCRandLFs.png

Gerard Bucas

unread,
Oct 2, 2019, 3:17:56 PM10/2/19
to MIT App Inventor Forum
Hi ABG,

OK - it seems like we are back on the same wavelength!!

You REALLY did look at the detail this time - duly impressed!! :)

Good question re "<cr> and <lf> " on UI & in test data blocks.

My original goal was to show them as \n and \r on the UI label (what I mean is sort of "escaping them" so that they show up as text "\n" or "\r" on the UI and then I substitute those "text values" with the real \r & \n before sending to the re-assembler).

The problem is that if one includes them in the "test data list" (block) then they will not be "seen" (non-printable) by the user - so he/she can't "see" what is REALLY contained "inside" the test string. So I needed to "represent" them with something "printable" and then I replace those printable "placeholders" by the real \n & \r before sending them to the re-assembler.
Besides them not being printable, the \n will of course also "print" an empty line, which further confuses the user trying to understand what is going on in this whole concept.

Most people starting with BLE are confused by this "protocol", everyone assumes (including me when I started!) that "ReceiveStrings" means "Strings" as THEY define a "String" (ie" the way they sent it, in an Arduino "println()" statement). Most beginners don't realize that with an Arduino "println('1234')", it actually sends  "1234\r\n"  and even if they do (as I did!) they assume that the BLE.StringsReceived will "receive" exactly what they send, ie: "1234" in a single BLE.StringsReceived.... Of course the BLE protocol just makes sure that all the bytes/characters are ALL delivered AND in sequence (thank goodness for THAT!) and it doesn't treat a "\n" as anything special.... (eg: end of string). VERY confusing to most..... 

This should be better explained in the documentation of the AI2 BLE Extension in my opinion as it is difficult to find coherent stuff on this subject even in Google! That's why I wrote that little "tool" to help me (& others) better understand the "problem". 

The "beauty" of the way I structured that demo/tool app, is that 100% the SAME "delivery logic" can be used to process "BLE Test Data" or by a real-live "BLE.StringsReceived". LITERALLY no change, so someone should be able to just "drop" in those two procedures (extractStrings & processReconstructedStrings) EXACTLY "as is" directly into their "real BLE" app & feed it the data from BLE.StringsReceived (after removing the enclosing parenthesis as I indicated in my "BLE.StringsReceived" block - that is why I also included that).

Anyway, I am being too long-winded - so please forgive me - will stop boring you with all this!

Will definitely need to meet for a coffee when next I am in Florida!

Best Regards

Gerard  
Reply all
Reply to author
Forward
0 new messages