Bluetooth message is cut off at 20 characters

Hello. I'm using a Nano to send a data string through a BT-05 Bluetooth module to the BLExAR application on an iPad. A data string is formatted like this:

84,85,84,85,84,85, 0,45,45,45,45,45

On the Arduino console, I see this exact example string so I know what I'm sending. However, on the BLExAR console I see the string broken up into two parts, the first being 20 characters in length:

84,85,84,85,84,85, 0
,45,45,45,45,45

BLExAR support insists this is not caused by their application. I've tried both SoftwareSerial and NeoSWSerial. The setup code is:

NeoSWSerial BTserial(6,5); //pins I'm using, TX is through a resistor divider.
BTserial.begin(9600);

What can I do to send the full string? FYI, BLExAR graphs each value, and the comma changes the color of the graph for each data.

Thank you.

The problem might be in the software or hardware that you provided almost no details about. Did you read the forum introductory thread about how to post?

However, I can guess, BLE is packet based. It can not support continuous character streams, it has to break them up in order to packetize them. It sounds like your code doesn't compensate for that.

How do you delineate your messages? Timing, or start/end markers?

The default data size of a BLE packet is 20 characters, maximum. Curious, no?

1 Like

Hello,

I tested this version of code, which replicates the problem. The hardware is simply a Nano and a BT-05 Bluetooth module connected to pins 6 and 5 of the Nano.

//This version stripped down to show only Bluetooth comms

#include <NeoSWSerial.h>
NeoSWSerial BTserial(6,5); //pin 6 is Arduino RX, pin 5 is TX through resistor divider 

char wholestring[50] = "85,85,85,85,85,85, 0,45,45,45,45,45"; //Creates example string to send

void setup() 
{
Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect (cleans up initial output).
  }

BTserial.begin(9600);
}

void loop() {

Serial.print("Wholestring "); Serial.println(wholestring); //send to Arduino Serial Monitor
BTserial.write(wholestring); delay(100); //send to BT-05 module [BLExAR]
 
delay(2000);
}

Good. What do you want to do now?

For symmetrical testing, you should probably also use the write() method on Serial, you use println() instead. Or, use the println() method with BTSerial.

Look and see if there are any RX time out settings in BLExAR.

Thank you aarg and jremington for responding.

I commented out the Serial.print to the Serial Monitor as it is only to prove my string is properly formatted. I tried changing BTserial.write to BTserial.println. This does not change the result on the BLExAR console:

84,85,84,85,84,85, 0
,45,45,45,45,45

Josh from Maker Portal (company that makes BLExAR) states that, "This is actually not an app issue, it’s a serial issue. You will likely have to look into serial handling in Arduino for the BLE chip. You may need to increase the baud rate and match it in software."

There is no software specification for BLExAR. There are only example projects. None I found are relevant.

jremington - The BLE specification states there is a packet size of 23 bytes and it isn't a stretch to think there are 3 bytes going to overhead of some kind. The spec also states this can be changed to up to 512 bytes.

Question is, how do I get around this 20 character limitation?

Thanks, Jeff

You will need to look at the specs for the BT-05 module that you have and see if there is any way to set/change the MTU from the default 20 bytes.

Packetize the data yourself, observing the 20 byte limit. The .write() function is intended for arbitrary binary data, and has no way of guessing your desired packet size or format.

The spec also states this can be changed to up to 512 bytes.

Yes, both sender and receiver have to be enabled for this option. I have not seen any reports of successfully executing this option, on this forum.

Take a look at the SerialTransfer library, written by a forum member. It can transfer large chunks of data and may make the "packetizing task" pretty easy.

I had a look around the BLexAR examples. If there is any documentation or source code page I could not find it. That would send me running before purchasing it.

There are at least two plotting examples presented. I think the app must use a time out to delimit values. Here is one of them:

#include "DHT.h"
#include <SoftwareSerial.h>

#define DHTPIN 2     // what digital pin we're connected to

//#define DHTTYPE DHT11   // DHT 11
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

DHT dht(DHTPIN, DHTTYPE);
SoftwareSerial ble_device(0,1); // HM-10 TX/RX pins

void setup() { 
  dht.begin(); // prepare DHT sensor
  ble_device.begin(9600); // prepare BLE module
}

void loop() {
  delay(2000); // delay in-between readings
  //float f = dht.readHumidity(); // uncomment to send humidity
  float f = dht.readTemperature(true); // send temperature data
  char f_str[6]; // prepare character array to send
  dtostrf(f,2,1,f_str); // format data into char array
  ble_device.write(f_str); // send to BLExAR
}

The data sent to the BLexAR app for plotting, is send without any new line or other delimiter. The only way the app could possibly sort out the values is by the in-between reading delay of 2000 ms.

They made it tiresome to navigate around for plotting examples so I won't post the others I found and lost (it's a very showy site). But of the ones I saw, all used inter-reading delays which obscures any definite answer about how packets are delimited, leaving it only to guesswork. However as the examples (except for one) did not send any delimiting characters at all, it would not be a stretch to believe that the ioS app does use timing for that.

Which means, the Maker Portal rep is probably wrong, it is likely a problem with the app. None of the examples send more than 20 bytes, so there is no possibility of seeing a problem with them. I guess you could see it as a bug, or a limitation. But if it's not acknowledged behaviour, I would call it a bug, because the API should come down on the side of temporal or EOL delimitation, in a definite way. Since the packetization will affect any BT traffic and this is a BT app, it should rely on EOL or some other delimitation. Really, it looks like a serious design flaw.

If the designer wishes to continue using temporal delimitation in the ioS app, they should at least make the implications imposed by BT clear to all to all its users. But it would obviously be better to use EOL instead, it would be much more robust and easier to define and control on the Arduino side.

I did too, and agree. Not even worth $3.99.

To make decent plots, I send data via serial to a PC and run one of many available plotting programs.

One possible avenue, take the example sketch and modify it only to send the required longer data burst, present it to "Josh" and point out, constitutes a valid MRE or at least something they should support since it's their own code. Ask him, "hey this is your own serial code so how come it doesn't work? Or please explain, why my simple addition didn't work?".

e.g.

#include "DHT.h"
#include <SoftwareSerial.h>

#define DHTPIN 2     // what digital pin we're connected to

//#define DHTTYPE DHT11   // DHT 11
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

DHT dht(DHTPIN, DHTTYPE);
SoftwareSerial ble_device(0,1); // HM-10 TX/RX pins

void setup() { 
  dht.begin(); // prepare DHT sensor
  ble_device.begin(9600); // prepare BLE module
}

void loop() {
  delay(2000); // delay in-between readings
  //float f = dht.readHumidity(); // uncomment to send humidity
  float f = dht.readTemperature(true); // send temperature data
  char f_str[6]; // prepare character array to send
  dtostrf(f,2,1,f_str); // format data into char array
  ble_device.write(f_str); // send to BLExAR
  //
  // sketch is unmodified except for the following...
  // now just send the same data but repeat often enough to exceed 20 chars:
  ble_device.write(','); // send to BLExAR
  ble_device.write(f_str); // send to BLExAR
  ble_device.write(','); // send to BLExAR
  ble_device.write(f_str); // send to BLExAR
  ble_device.write(','); // send to BLExAR
  ble_device.write(f_str); // send to BLExAR
  ble_device.write(','); // send to BLExAR
  ble_device.write(f_str); // send to BLExAR
  //... add more if necessary to exceed the 20 chars
}

Aarg and Jremington, I have read your responses. My data collection requirement is mobile, so using a proper PC + serial port isn't practical. Agreed, there isn't a stitch of documentation for BLExAR, only limited examples, and actually there isn't a single example that demonstrates how to change plot colors although there is one picture that shows two colors. The Maker engineer told me that comma delimited data can change colors and this works beautifully. I'm inserting an example trace showing 7 independent graphs.

However, note that this is exactly 20 characters of data, and what it represents is temperature from 6 DHT11 sensors, plus a control output. These sensors also provide humidity data, and that is the reason why 20 characters isn't enough. I need 5 sensors worth of humidity data which brings the string length to 35.

Maker is telling me that only a single string sent as such can achieve a plot like this. They are also saying that the BLE module is breaking up the string at 20 characters, which they have no control over. This seems to make sense because the BLE spec tells us there is a limit at 23 characters (the MTU).

I think then that the goal is to change the MTU. I need to figure out how to do that.

Thank you. Jeff

If you do manage to increase the buffer size, post the results as other people will be interested.

I will try! One detail I missed, the final delay of 2000ms is because a DHT11 sensor has a 2s cycle time, plus I have no need to collect data more quickly.

Why do the temperature and humidity data need to be sent in one group. Why can't you send the temperature and humidity in two different groups? Each will meet the 20 byte requirement.

Given that you have a BT-05 at one end, and the BLExAR at the other, I do not think you will be able to change the MTU. Neither is a fully configurable device.

cattledog, breaking up the data into sub-20 character lines just makes the graphs into a mess. The data sent just looks like this:
84,85,84,85,84,85, 0
45,45,45,45,45
The resulting graphs are a mashup.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.