BLE local device name automated in Sketch

I have a phone app to control a host of arduino nano 33 BLE boards which are running in peripheral mode. I'm happy to post both AI2 code and arduino sketch code, but I think I have a better chance of getting help if I zoom in on the relevant bits. My AI2 code scans for and displays in a listView all the arduino boards that are advertising the right service and characteristic UUIDS. I ignore the physical address and rssi info and put it in the listView using this section of code:

Everything works fine if, on the arduino side, my sketch contains something like this:

(String) nameVal = (String) "myName";
BLE.setLocalName(nameVal.cstr());

In other words, if the arduino sketch is as above then the listView on my phone will contain a row showing "myName" as an available device.

If, on the other hand, my arduino code creates the variable nameVal programmatically then the phone will show either nothing at all or some gibberish wingding character. For example, this seemingly reasonable code on the arduino will lead the phone to show nothing at all in the listView (even though the empty-seeming row remains clickable and allows me to connect to the arduino).

(String) nameVal = (String) "myName";
String myName() {
return (String)nameVal;
}
BLE.setLocalName(myName().cstr());

This is just the simplest example I could concoct demonstrating a point I dont' understand. But what I'd actually like to do is create the device name that the arduino broadcasts programmatically, using string concatenation so that the name includes state information that allows me to decide whether I want to connect. But I'm obviously missing something basic.

Can anyone help? I'm not sure if the question is better posed at an Arduino discussion site or here, but I thought I'd try here first. If anyone cares, I'm attaching both arduino sketch (as a .sketch_for_ai2_help.txt (1.6 KB) txt file) and AI2 code. The AI2 code started off with Martyn Currey's wonderful tutorial here but any and all bug-generating changes are mine :<
scratch_for_ai2_help_copy.aia (194.1 KB)

Hello ahd

I changed the title of your topic such that should anyone else be searching the forum for clues on this subject, they stand a better chance of finding it.

I find your simple example to be a bit of a puzzle - if you want to build device names programmatically (sprintf()) then why not do that? You can test a snippet of code in the Arduino IDE. (Or with an online C++ compiler if the snippet is not dependant on an Arduino lib).

Note, I know your Sketch is unfinished but in the Characteristics, you should normally only need BLERead or BLENotify, not both.

Hi Chris. Thanks for making the change. I agree that the new title is a better, more descriptive one.

Vis a vis BLERead and BLENotify, fair point - I will try it. To be honest, once I got it to work I didn't revisit the String type characteristic...

With regard to using sprintf(), I haven't tried it yet. I've been flailing around using String myVar = Str1 + Str2 or String myVar = Str1; myVar += Str2 or String myVar = Str1.concat(Str2). No approach has worked for me yet. I suspect it may have to do with different default string types on in sketch and the AI2 platform. But that's just making stuff up. I'm still at sea.

Hi again

It would certainly be best to experiment with the actual device names (with state information). So I think you should first decide the exact format you want the device names to have and then go about programming it. It's certainly possible that this nut has been cracked already by someone else - have you tried a Google search?

Not really, you can use the Arduino String Lib for "real" strings or you can use the C type strings that are really an array of characters. Just don't try to mix them :skull:

Thanks, Chris. I will post again once I've made progress.

I'm getting there... I can now take a device called "devName" that has two binary characteristics and advertise local names like devName_OFF_ON when the first characteristic is off and the second characteristic is on. The phone app is still ugly because when I scan with two available devices then this block:

gives me a display like this on the phone:

Note the ugly display of the device names of the form "physicalAddress devName rssi" rather than just devName.
A similar looking code snippet

gives a much cleaner display when I connect to the periperal:

Any ideas as to why the first code block doesn't parse the elements of ListBLE correctly and display only the devName piece on each row?

Because you coded it wrong. Try this:

1 Like

You also have to watch out for the data packet size, which will fail when oversize. See my Site:
https://www.professorcad.co.uk/appinventortips#TipsBluetooth
Notes about MTU.

You might find this basic example file of some use:
BLE_RECEIVE_STRINGS.aia (194.7 KB)

I have not thought of a way to automate the device names (how does each board know which board it is....). Apart from the data packets size limit, there will be a device name size limit too, don't know what that is. If it is generous, that makes life easier.

How many boards are there? Is the main point of automating the name to avoid compiling several Sketches? - it's not difficult to produce several Sketch variations, just copy-paste the one line and recompile/upload.

Hi Patryk and Chris. Thank you for your help, and apologies for the two days of radio silence - I was visiting family and 'afk'.

Patryk, I tried your suggestion without success. My Sketch snippet looks like this (my full sketch file is attached):

When I scan, I see

But when I select and connect, I get the following:

So, no joy yet :<

But thank you again for your time and help. If I find a quick fix then I will post it.
scratch_for_ai2_help_copy (1).aia (194.5 KB)

Hi Chris. There may be 20 or 30 boards and, no, the point of automating the name is not just to avoid the work of compiling sketches. Each peripheral board has characteristics that are dynamic, i.e. changing in time in a way that's determined by sensors and the environment. I want to be able to 'know' which boards are in a given state so I can interact with them selectively, e.g. turn a sensor on/off.

I can see a potential issue with the List from BLE - it is a string of values divided by a single char, so the CSV Block only works if that char is a comma. Using a space char can be done as you have found - my preference is a '|' as it is stands out as the delimiter when observing the List unsplit and it is very unlikely that a pipe char would actually be part of the data.

Can you post here two or three examples of what will be automated names?

I'm an idiot. Of course the csv block doesn't parse space-separated blocks.
image

Re. examples of automated names: As per the Arduino code I posted originally, the idea was to have a "baseName" to which I'd append underscore-separated text representing the current state of various characteristics. Whenever the characteristic is changed in the code there's a block to stop advertising, change the local device name, and restart advertising. Very kludgy, but seems to work reliably (so far). Because the total length of the local device name seems to be a constraint (I don't understand why yet), I've opted to keep the baseNames short (FC1, FC2, ...) and represent the characteristic values with OFF or ON. In the same spirit of keeping the local device name short, there's no description of which OFF or ON is associated with which characteristic. It's defined by the order in the name, i.e. FC1_OFF_ON means that characteristic one in in the OFF state and characteristic two is in the ON state. Again, it's a kludge - won't work with continuously valued characteristics, doesn't offer a description, etc.

Actually, what would you recommend re. the csv versus space separation mismatch? The local device name that's advertised by the arduino peripheral is a space-separated string with 3 components, e.g. "some_mac_address local_device_name rssi_value". I don't know if it's possible to change that. Asssuming that's immutable, i.e. that I have to live with that format of the local device name, I'm stuck again because I don't see an alternative to the "list from csv row text" component that can handle space separation. I think it's probably an easy workaround, but I'm too new to Sketch to see it.

Well, I would represent ON with 1 and OFF with 0. Keeps the string short.

I'm not sure it is necessary to do this by prefixing the board's name - your GUI could have a list of devices (Base Names) and along side their status data. You will need to make 33 seperate connections if there are 33 devices all running at once, so that's 33 separate Procedures (Blocks) waiting to receive and process the data. This would be possible because once a board's connection address is known, it can be stored or hard-coded in the App and a direct connection made without scanning.

1 and 0 rather than ON and OFF, sure.

But the other idea doesn't allow the app to be easily 'future-proofed' against the addition of more devices in the future. That's why I want to avoid hardcoding. Which brings up another point of ignorance for me: The arduinos are going to be hard to access and I'd like to be able to change their baseNames programmatically rather than hard coding them. I know that the arduinos can be unplugged and their programming remains in static memory so they resume functioning correctly when powered up again. Is there a way to change a variable in the arduino using an android phone (using AI2, ideally) in such a way that the change is in static rather than dynamic memory, and so will persist through a power cycle? I guess the simple answer is "Don't be so lazy... Just try it!" and I will - but I'm guessing that it won't work at a first attempt...

So connecting to BLE devices is working fine now?

I improved your "when.connected" block:

scratch_for_ai2_help_copyc (1).aia (194.4 KB)