BluetoothLE string management

Hello All,
I have some trouble to send strings to my arduino nano 33 BLE board. The MIT App is OK for Byte transmission and my "13" byte value is well received by my Arduino. Nevertheless, the 3 string of char "BOF" that I try to send are never received on Arduino side (I need to send 3 string of char for my application).
My Arduino code seems to be OK. Indeed, it works well when I write manually the string using a BLE application like "nRFconnect" by selecting the dedicated services and characteristics (i use the TEXT mode proposed by nRFconnect). Notice that the 3 "BOF" strings are simulating 3 "Text-Area.Text" that I try to send from my phone to my Arduino, but I had simplified the MIT code in order to identify why he doesn't want to braodcast my 3 strings on these 3 BLE characteristics.

I also tried WriteStringsWithResponse instead of WriteStrings without better success.
Can someone help me ? I try to use this forum answer to a similar problem using ESP32, but in my case, it seems that it don't work.
Thanks if you have an idea.
Best Regards
Thomas.

Do you want to read a string or read bytes? You discuss strings in your post but your blocks call BluetoothLE1.ReadBytes. You may want to consider the following:

  1. For strings, use Bluetooth1.ReadStrings
  2. Use the registration methods rather than the read methods if the device might respond at arbitrary intervals, either BluetoothLE1.RegisterForStrings or BluetoothLE1.RegisterForBytes

It seems like your screenshot is missing some blocks as well, the ReadBytes method has a corresponding when BluetoothLE1.BytesRead block that handles the results. You may want to show us what that looks like in case there is a logic bug there.

Hello. First of all, thank you for this fantastic application designer. It makes app design accessible to people like me, knowing few about SW. That is probably why I have some difficulties, and also because of my poor knowledge of BLE.
I try to write string, not byte. Byte is OK (I don't realy know why... It was not working using Bluetooth1.WriteBytes, but since I use Bluetooth1.WriteByteswithResponse together with a Bluetooth1.ReadBytes, it seems to do what I want :slight_smile:).
It is OK when I use nRF Connect App (App designed by Nordic Semiconductor in order to play with bluetooth) :



As you can see, I can use this app to write a text, "john" in this screenshot, and my Arduino nano board perfectly received it.
So that is why I don't understand what I'm doing wrong with the Bluetooth1.WriteStrings command.

I notice there is a "when BluetoothLE1.StringsWritten" block, and i tried this :
Capture2

The result in my AI compagnon is (see the last line reporting my status) :

I don't understand why there is some brackets [ ] and some quotation marks " " around the BOF word. Coud it be the reason why my Ardunio don't receive the string ?

Thanks for your help
Regards. Thomas.

Your question has two parts:

  • What's with the ["..."] wrapper?

  • Why doesn't the Arduino receive the string(s)?

  • The [" ... "] wrapper has two layers to it. The outer layer is ai2's way of telling you it is displaying the automatic text conversion of a list of values (albeit just 1 value). Did you notice the trailing "s" in the variable name stringValues ? That's the extension designer's way of reminding you that you will be receiving a list of values. The inner "..." markup is AI2's way of demarcating the list elements, in this case a single string or 3 characters.

Your second question can't be answered without seeing the Arduino code and the AI2 transmission code.


Please export your project and post it here.

1 Like

Thank you for the answer about [" "]
Here is my aia

testamilight.aia (471.4 KB)

and my ino (board is nano 33BLE) :

#include <ArduinoBLE.h>
BLEService BadgeService("19B10000-E8F2-537E-4F6C-A104768A1214"); // BLE Badge Service
BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-A104768A1214", BLERead | BLEWrite);
BLEStringCharacteristic nomCharacteristic("19B10002-E8F2-537E-4F6C-A104768A1214", BLEWrite,20);
BLEStringCharacteristic prenomCharacteristic("19B10003-E8F2-537E-4F6C-A104768A1214", BLEWrite,20);
BLEStringCharacteristic fonctionCharacteristic("19B10004-E8F2-537E-4F6C-A104768A1214", BLEWrite,20);

String MonNOM = String(20);
String MonPRENOM = String(20);
String MaFONCTION = String(20);

void setup()
{
Serial.begin(9600);
Serial.println();
Serial.println("setup");
if (!BLE.begin())
{
Serial.println("starting BLE failed!");
while (1);
}
BLE.setLocalName("color my name");
//BLE.setAdvertisedServiceUuid(BadgeService.uuid());
BLE.setAdvertisedService(BadgeService);
BadgeService.addCharacteristic(switchCharacteristic);
BadgeService.addCharacteristic(nomCharacteristic);
BadgeService.addCharacteristic(prenomCharacteristic);
BadgeService.addCharacteristic(fonctionCharacteristic);
BLE.addService(BadgeService);
switchCharacteristic.writeValue(0);
nomCharacteristic.writeValue("");
prenomCharacteristic.writeValue("");
fonctionCharacteristic.writeValue("");
BLE.advertise();

delay(100);
}

void loop()
{
// listen for BLE peripherals to connect:
BLEDevice central = BLE.central();

// if a central is connected to peripheral:
if (central)
{
// while the central is still connected to peripheral:
while (central.connected())
{
// if the remote device wrote to the characteristic,
// use the value to control the LED:
if (switchCharacteristic.written())
{
switch(switchCharacteristic.value())
{
case 1: Serial.println("magenta"); break;
case 2: Serial.println("blue"); break;
case 3: Serial.println("yellow"); break;
case 4: Serial.println("cyan"); break;
case 5: Serial.println("orange"); break;
case 6: Serial.println("white"); break;
case 7: Serial.println("grey"); break;
case 8: Serial.println("red"); break;
case 9: Serial.println("dark grey"); break;
case 10: Serial.println("black"); break;
case 11: Serial.println("green"); break;
case 13: updateBio();break;
}
}
}
}
}

void updateBio()
{
Serial.println("bio");
Serial.println(nomCharacteristic.value());
Serial.println(prenomCharacteristic.value());
Serial.println(fonctionCharacteristic.value());
}

I have not developped the code for the physical interface that i want to do with a led aray panel. So the Arduino code is still simple.

Thank you.

I have a couple of questions about your BLE characteristics:

I regret I don't have more experience with BLE to give you a better analysis.
I am posting your blocks for the benefit of our BLE experts ...

Also see FAQ Section: BlueTooth
for the latest version of the Ble extension.

Yes, the BLE extension (as of 2018, IIRC) is case insensitive to UUIDs.

This is not a requirement for BLE. Characteristics can be write-only.

Or shall I generate a single BLE characteristics for a single BLE service ?
My fear is that I'm doing something wrong with your App designer, because, from Arduino side, the code is OK when I write the characteristics manualy with nRFConnect app. Any Idea what it could be ?
Thanks
Thomas.

Good news, now it's OK !
I don't really know why, but I had to declare the characteristics as "BLERead | BLEWrite" and to use a sequence : WriteStringsWithResponse + ReadStrings instead of WriteStrings.
Here is my new block sequence :


Notice another error that I fund : The WriteByteWithResponse of "13" value +ReadBytes sequences shall be done at the end, after having broadcasted the Strings (if not, the "updateBio()" subprogram is launched before update of strings).
Hope it will helps other people having some trouble with strings.
Regards
Thomas

2 Likes

Thank you Thomas,
I faced the same issue and after some days of trials I was going to test "WriteStringWithResponse", your post just boosted that.

@ABG , thanks for your clarification regarding text messagges on MIT...

Now strings comunication is running so far but I get annoying "square" after the string on Arduino serial monitor.
Can someone of you help to understand the reason?

Screenshot 2024-09-28 182824

Upload everything.

The square is probably an unreadable character like a null.

here is the simple *.aia

BLE_string_connection.aia (202.5 KB)

and the *.ino
ArduinoBLE_string_hall_3.ino (3.5 KB)
the "null" doesn't appear when I use nRF Connect

I'm just familiarizing with BLE and MIT App inventor, with the target to send to the app data collected on several sensors. I think strings are the most simple way to send data and comands trought the BLE.

Look at your characteristic names compared to their permitted functions:


unsigned int cont = 0;

// set the size of the incoming and outgoing strings. Max 512:
const int characteristicSize = 128;

// create service and characteristics:
BLEService stringService("7def8317-7300-4ee6-8849-46face74ca2a");
BLEStringCharacteristic txChar1("7def8317-7301-4ee6-8849-46face74ca2a",
    BLERead | BLENotify, characteristicSize);
BLEStringCharacteristic txChar2("7def8317-7302-4ee6-8849-46face74ca2a",
    BLERead | BLENotify, characteristicSize);
BLEStringCharacteristic rxChar1("7def8317-7303-4ee6-8849-46face74ca2a",
    BLEWrite, characteristicSize);

tx = transmit,
rx = receive?

Does that match


void loop() {
  // Listen for events:
  BLE.poll();

  //if a serial string comes in, set it in the txCharacteristic:

   flow = flow + 1;
   sending1 = String(cont);
   sending2 = String(flow);
   txChar1.setValue(sending1);
   txChar2.setValue(sending2);
   rxChar1.setValue(receiving1);
   Serial.print("testo1:   ");
   Serial.println(sending1);
   Serial.print("testo2:   ");
   Serial.println(sending2);
   Serial.print("testo3:   ");
   Serial.println(receiving1);     
delay(150);
}

?

Note the attributes of your BLE component:
image
See that NullTerminateStrings option you have checked?
Could that be the cause of that termination character?

1 Like

Thanks a lot @ABG , it was definitively the flag in the "NullTerminationStrings" :face_with_hand_over_mouth:, I didn't know that setting.

It's working great!

Regarding the permitted functions in arduino, I see that they are exactly the opposite of the real needs! ... nevermind until the things are running :slight_smile: . I try to swicht them and I let you know

Thanks for telling us what worked!