0

bleuart.print() method comparison
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

bleuart.print() method comparison

by jps2000 on Thu Mar 07, 2019 1:51 pm

I want to share and discuss two possible methods of sending data via BLE
I use two feather nrf52. The first is peripheral and sending data from an IMU. The second works as central and send received data to a PC directly to Excel (PLX_DAQ for Excel Version 2).

Euler data can be sent by method 1:
bleuart.print(yaw,1);
bleuart.print(",");
bleuart.print(pitch,1);
bleuart.print(",");
bleuart.println(roll,1);

or by method 2:
bleuart.println(String(yaw,1) + "," + String(pitch,1) + "," + String(roll,1) );

In fact both methods are doing the same but when RSSI is low or it disconnects and connects again the second method is favorable to the first.
Reason is I think that BLE data transfer is protected against errors. but this works only within one print command.

So in case of weak signals it may happen that by using method 1 one or more of the print commands are not handled successfully and may be skipped. That means separators or data are missing and the correct assigning to columns or graphs is gone.

By contrast, method 2 sends the complete set of data with one command.
In case of a failure the whole line is skipped. Hence data can not appear in a wrong column caused by data or separator loss.

Considering data transfers via Serial both methods are interchangeable. Method 1 is more clear.

In conclusion I suggest to use only concatenated string data transfer for BLE (method2 ) when it is important to have a set of data correctly transferred.

Any thoughts?

jps2000
 
Posts: 449
Joined: Fri Jun 02, 2017 4:12 pm

Re: bleuart.print() method comparison

by p2w on Thu Mar 07, 2019 3:40 pm

The problem with using the Nordic UART service as if it where a wired serial port is that it is limited in the number of characters you can send in one message. The standard maximum payload is 21 bytes. If you want to send 3 floating point numbers in ASCII format, chances are more than one packet is required. Unless... you send it as binary. Use bleuart.write() instead and send a structure:
Code: Select all | TOGGLE FULL SIZE
typedef struct imu_s
{
    float yaw;
    float pitch;
    float roll;
} imu_t;

void send_imu( float yaw, float pitch, float roll )
{
    static imu_t data;
    data.yaw = yaw;
    data.pitch = pitch;
    data.roll = roll;
    bleuart.write( (uint8_t *)&data, sizeof( data ) );
}

In the receiver callback you can simply print them to Serial or something to write'm to the PC.

p2w
 
Posts: 95
Joined: Fri Dec 15, 2017 5:29 am

Re: bleuart.print() method comparison

by jps2000 on Thu Mar 07, 2019 4:18 pm

Thanks I am aware of this limitation.
I am sending definitely more bytes in one set of data.
Another constraint in used data format is that i also want to plot the data with the BluefruitLE connect app. So I have to send the separators between variables as well as possible min and max values to override the nasty auto-scale function in this app.

Anyhow, calling print probably uses a fifo that takes care of longer strings to be sent. so basically this works

Also the introduction of checksum to check proper data transfer could be a solution.

jps2000
 
Posts: 449
Joined: Fri Jun 02, 2017 4:12 pm

Re: bleuart.print() method comparison

by hathach on Fri Mar 08, 2019 6:46 am

You can send more than 20 bytes per packet if negotiate higher MTU (just added it in recent code). Though only central role can initiate mtu negotiations, normally iOS will do that authentically ~100 bytes. We will add an api for bluefruit central as well.

You can also use sprintf to manipulate string before using print/write as well.

hathach
 
Posts: 1020
Joined: Tue Apr 23, 2013 1:02 am

Re: bleuart.print() method comparison

by jps2000 on Fri Mar 08, 2019 8:07 am

Good ideas
unfortunately I am quite weak with string syntax.

I found that checking with the nrf toolbox and the nrf logger what is going into the air is really instructive.
Edited: But also Debug mode Level 2 shows how many bytes per transmission are sent.

Just now I noticed that println starts a separate transmission just for sending \r\n ( CR, LF). Awesome!

So it is recommended to pack those two in the string and using print instead of println !!!!

Replacing this:
bleuart.println(String(yaw,1) + "," + String(pitch,1) + "," + String(roll,1) );
by that:
bleuart.print(String(yaw,1) + "," + String(pitch,1) + "," + String(roll,1) + "\r\n" );
saves a separate transmission or about 10 ms of time

Hence my conclusion is: Put everything together to a string ( by using any appropriate method) before sending over BLE and use print (write) instead of println

jps2000
 
Posts: 449
Joined: Fri Jun 02, 2017 4:12 pm

Please be positive and constructive with your questions and comments.