BLE.sendData question


#1

Hi to all,
I have a question about BLE.SendData statement in order to know how is the minimum time interval between 2 call.
In my BLUZ device I receive data from Serial1 every 10ms and I need to send same data to tablet via Bluetooth.
Data length is about 50 o 60 bytes at time.
Is this possible with BLUZ?
Thanks in advance,

Michele.


#2

The answer depends on a few factors, mainly the tablet that you plan to use. BLE throughput is dependent on a few parameters, mainly the connection interval and how many packets can be sent per connection interval. You can read up a bit on connection intervals in our docs here: http://docs.bluz.io/tutorials/low_power/#ble-radio

Each packet is 20 bytes. The lowest possible connection interval is 7.5mSec and then you can send X number of packets per connection interval. X depends on the radio and operating system, but it is usually in the 4-6 packets range. A good case scenario would be 6 20-byte packets every 10 mSec, giving you about 120bytes every 10mSec, or approximately 12kB/sec. That is best case, not many centrals can do that, and in reality you will top out around 8kB/sec with most.

Your requested throughput is 60 bytes per 10mSec, or 6kB/sec. So yes, this is certainly possible, but will require a decent central that can perform close to the best possible throughputs out there.


#3

Hi Eric,
thanks for your explanation!!!
Data interval in my case is 100ms not 10ms (my mistake!!).
This is the code that I use for reading data from Serial1 and send data to BLE:


 #include "application.h"
SYSTEM_MODE(MANUAL);
BLE_ADV_NAME("BLUZDK");

 #define XBEE   Serial1
 #define PROTOCOL SERIAL_8N1

// Constants
const uint32_t baud = 9600;
const size_t READ_BUF_SIZE = 128;
// Global variables
size_t readBufOffset = 0;
uint8_t readBuf[READ_BUF_SIZE];


void setup() {
  XBEE.begin(baud);  
  // set the connection interval to allow values between 20mSec and 40mSec
  //BLE.setConnectionParameters(20,40);

}
void loop() {
  delay(100);
  sendData();
}

void sendData(void)
{
    while (XBEE.available())
    {
        if (readBufOffset < READ_BUF_SIZE)
        {
            char c = XBEE.read();
            if (c != '\n')
            {
                // Add character to buffer
                readBuf[readBufOffset++] = c;
            }
            else
            {
                // End of line character found, process line
                //readBuf[readBufOffset] = 0;
                BLE.sendData((uint8_t*)readBuf, sizeof(readBuf));
                readBufOffset = 0;
                memset(readBuf, 0, sizeof(readBuf));
            }
        }
        else
        {
            readBufOffset = 0;
            memset(readBuf, 0, sizeof(readBuf));
        }
    }
}

In this code data from Serial1 is ok data in BLE is not ok (not all data packets are send to BLE).
What’s wrong in my code?
Thanks in advance,

Michele.


#4

Can you elaborate a bit on the problem? So you said the data in BLE is not OK, that not all packets are sent. How are you measuring that? Are you looking at the data on the tablet? How much is missing?

One thing, you said you want to process data every 100mSec. However, the sendData function will take time. It will take time to read the Serial lines, then the BLE.sendData function takes time to send it over BLE. So for example, let’s say you start at time t=0. if this function took 50mSec to execute, then you would call it, it would take 50mSec, then you would wait another 100mSec. Then the next time you ran, you would start at t+150mSec. The next loop would start at t+300mSec. Etc. So you wouldn’t process every 100mSec, but every 150mSec. It could fall behind that data being sent in.

So you may need to adjust that loop to be smaller to make sure the sendData function isn’t falling behind. Or you could possibly eliminate it all together. Just one thing to look at.


#5

Hi Eric,
thanks for your explanation.
Now I have removed code line with delay:
void loop() {
//delay(100);
sendData();
}

#This is log from Serial1:
#HHMMSS.DD;Latitude etc (omitted)
G;080654.10;45.408291#
G;080654.20;45.408291#
G;080654.30;45.408291#
G;080654.40;45.408291#
G;080654.50;45.408291#
G;080654.60;45.408291#
G;080654.70;45.408291#
G;080654.80;45.408291#
G;080654.90;45.408291#

#DATA TO IOS APP LOGGER
[INFO] : didUpdateValueForCharacteristic= G;080653T;154.56410
[INFO] : didUpdateValueForCharacteristic= G;080653T;154.56410
[INFO] : didUpdateValueForCharacteristic= 2;182.688644;PZ;5.70
[INFO] : didUpdateValueForCharacteristic= 2;182.688644;PZ;5.70
[INFO] : didUpdateValueForCharacteristic= 0000;10162309;1;03;#
[INFO] : didUpdateValueForCharacteristic= 0000;10162309;1;03;#
[INFO] : didUpdateValueForCharacteristic= G;080654.10;45.4082
[INFO] : didUpdateValueForCharacteristic= G;080654.10;45.4082
[INFO] : didUpdateValueForCharacteristic= 91;11.86G;080654.60;
[INFO] : didUpdateValueForCharacteristic= 91;11.86G;080654.60;
[INFO] : didUpdateValueForCharacteristic= 45.408291;11.862310;
[INFO] : didUpdateValueForCharacteristic= 45.408291;11.862310;
[INFO] : didUpdateValueForCharacteristic= 1;03;#
[INFO] : didUpdateValueForCharacteristic= 1;03;#
[INFO] : didUpdateValueForCharacteristic= G;080655.10;45.4082
[INFO] : didUpdateValueForCharacteristic= G;080655.10;45.4082
[INFO] : didUpdateValueForCharacteristic= 91;11.862315;1;03;#
[INFO] : didUpdateValueForCharacteristic= 91;11.862315;1;03;#

#The same with Particle Photon and HM10 BLE:
#This is log from Serial1:
#HHMMSS.DD;Latitude etc (omitted)
G;071139.00;45.408218
G;071139.10;45.408218
G;071139.20;45.408218
G;071139.30;45.408218
G;071139.40;45.408218
G;071139.50;45.408218
G;071139.60;45.408218
G;071139.70;45.408218
G;071139.80;45.408218
G;071139.90;45.408218
G;071140.00;45.408218
G;071140.10;45.408211
G;071140.20;45.408211
G;071140.30;45.408211
G;071140.40;45.408211
G;071140.50;45.408211
G;071140.60;45.408211
G;071140.70;45.408218
G;071140.80;45.408218
G;071140.90;45.408211

#DATA TO IOS APP LOGGER:
[INFO] : = G;071139.00;45.40821
[INFO] : = G;071139.10;45.40821
[INFO] : = G;071139.20;45.40821
[INFO] : = G;071139.30;45.40821
[INFO] : = G;071139.40;45.40821
[INFO] : = G;071139.50;45.40821
[INFO] : = G;071139.60;45.40821
[INFO] : = G;071139.70;45.40821
[INFO] : = G;071139.80;45.40821
[INFO] : = G;071139.90;45.40821
[INFO] : = G;071140.00;45.40821
[INFO] : = G;071140.10;45.40821
[INFO] : = G;071140.20;45.40821
[INFO] : = G;071140.30;45.40821
[INFO] : = G;071140.40;45.40821
[INFO] : = G;071140.50;45.40821
[INFO] : = G;071140.60;45.40821
[INFO] : = G;071140.70;45.40821
[INFO] : = G;071140.80;45.40821
[INFO] : = G;071140.90;45.40821

What’s wrong?!
Thanks in advance,

Michele.


#6

The data you send to the app will come through using our protocol, meaning we use headers and other special characters to denote the kind of data. Have you looked at the code for the bluz iOS app? This would be the relevant section: https://github.com/bluzDK/iOS-app/blob/master/bluz-iOS-app/Libraries/BLEManager.swift#L263

That shows how to parse the data. Even the BLE.sendData function follows the same protocol, so you will need to parse it the same way app side. Just reading from the characteristic for the raw data isn’t sufficient since it has overhead.


#7

Hi Eric,
unfortunately I can not compile the code you sent me because the version I have of xcode is 9.2 and it is not possible to update the code to swift 3.
Do you have any other suggestions?
Thank you,

 Michele.

#8

Yes, that is on my list of things to update :smile:

You can still gather the logic from there about how the data is being handled. I do need to write this up in a doc somewhere as I have to go back and remember it every so often. But the protocol is pretty simple and you should be able to derive it from that code.

I will try and prioritize the doc portion as well as I need to do that anyway