Bluetooth client speed and buffering issue

If using the string version, use "|" - but I would try the Bytes version first, using commas, which would be faster as there is no need to split the data at the phone end.

Have not seen all your code, but as you can see from my code snippet, a Clock Timer may not be required if you use the 'Register for Bytes" Block instead.

... note also that I have shown a BLE solution using the MIT BLE extension. Your sending device may not be compatible with BLE. If not, the code can be adapted for Classic BT but you do then need a Clock Timer. The Script also needs to send an "End of Data Packet" character, and the App needs to know beforehand what that character is (usually we use Ascii char 10 = #LF (Line-feed).

If it is possible to use BLE, there should be speed benefits.

Yes, I noted you used BLE. Now, I am starting to learn BLE because I always wanted to learn it! (ESP32 supports BLE)
Meanwhile, I want to keep this existing version that use classical BT. Because some users phones may not have BLE.
So, could you pls write the code for standard BT?
I tried to change your code for standard BT, but i got error.
(the "byte" version is preferred)

Hi,
sorry not having answered before, but I read mails only in the evening (here in Italy is 8:20 PM).
I saw that Chris has already told you a lot of hints.
Anyway If you need pieces of my Arduino code, I will send them tomorrow morning.
Tonite I'm busy with... my family :slight_smile:
Have a great evening.

Kind of. I have nothing to test the code with right now, so no doubt you will need to fix my bugs! Note, if the connection works and data streams but starts to fail, tweak the milliseconds up in both the Script and the App. A faster phone could make a difference.

Script snippet:

ScriptSnippet.txt (732 Bytes)

byte a[4];
int i = 0;

void loop() {

         if (millis() - oldmillis >= 10)
         {
               oldmillis = millis();

                    a[i] = map(analogRead(A0), 0, 4096.0, 0, 255);

                       i = i + 1;

               If(i > 3)
               {
                         i = 0;

                         ESP_BT.write(a[0]);
                         ESP_BT.write(',');
                         ESP_BT.write(a[1]);
                         ESP_BT.write(',');
                         ESP_BT.write(a[2]);
                         ESP_BT.write(',');
                         ESP_BT.write(a[3]);
                         ESP_BT.write('\n');
               }
         }
}

App Code:
I have butchered my BT Basic Template that has been successfully used by many people, but that does not mean the butchered version will work as expected :upside_down_face

Note, Test as an APK, not via the Companion.

Tips:

  1. Do not run from the finished install panel displayed, run via the App Icon.
  2. If an eligible device is within 2-3 metres of your phone/tablet, it probably won't be found (Bluetooth flaw).

BT_4ValsStreamIn.aia (12.8 KB)

(Click on the image to view at full scale)

Edit: Script snippet BT packet array corrected.
Edit2: Script snippet file updated

Dear Chris,
maybe I'm wrong but pay attention to the size of the array: in C they start from element 0 so if the dimension declared is 4 , element 4 does not exist, and the array ends at 3.
You better declare: byte a[5];
It costs nothing...
Cheers.

Hi Uskiara

You are correct - in fact it's better to use element 0 of an array of 4. I'm using too many programming languages at the same time :innocent:

Yep.
i.e. PASCAL starts from 1 (I remember when I was using Turbo Pascal 3 by Borland : the complete IDE < 64 Kilobytes):
...another century.... :scream:
Cheers, Ugo.

Thank you Chris and uskiara,

I will test and report the results.
Thank you again so much for your time.

Sirous

1 Like

Dear Chris and uskiara,

I tested ur code. After some minor debugging, it works. Thank you :wink:

the length of the list must be twice the length of data, because the commas also appear in the received data.I had to omit the commas after receive.
Also, connecting the end of one pack to the start of the next pack took some work.

Is this the fastest way to send several bytes in a single transmition?
I increased the pack of data to 10 to save more time.
Is it possible to make a string of bytes in the arduino, send to the app, and put them in a list so that there are no commas?
Besides, I am worried that executing 20 times " ESP_BT.write(......)" might be lengthy and so I miss some of 10 millisecond intervals.

Dear Sirous please find here below a chunk of Arduino code.
I've tested it on a Uno board.
What it does is:
it initializes the BT line @115200
it acquires a ne value every 10 milliseconds
it converts the byte into the two characters representing the byte
it appends the two characters to a string (initialized to empty every 4 bytes)
when 4 bytes have been acquired it transmits the string once on BT
repeats forever.

I hope the comments wil lhelp you.
This means that you will receive a string on the APP once every 4 bytes. the string has a fixed length of 14 characters: 8 of them are the 4 bytes (two characters each) 4 commas and a CRLF pair.
The two lines commented are for debug purposes only. you can throw them away. I have used them to verify if the algorithm works (it works :slightly_smiling_face:)

On the APP now you receive a unique string of 14 characters terminated with a CRLF pair.
An improvement is: to avoid the commas, since every value is on two characters, so the values that the app receives are always in fixed position in the string : for example char 1 and char 2 are value 1;
char 3 and 4 are value 2 and so on until the CRLF is reached.
In this case you trasmits 4 characters less (the 4 commas). But try first with the commas.

Good luck !
Ugo.


#define baudBT 115200


int i = 0;
String TxBuf;
long oldmillis;
byte ByBuf = 0;
byte CarBy = 0;
char CarHi;
char CarLo;




void setup() {
  // put your setup code here, to run once:
  Serial.begin(baudBT);                                               // initialize baudrate for BT @115200
  
}

void loop() {

         if (millis() - oldmillis >= 10)                              // if 10 milliseconds have elapsed, triggers a new acquisition
         {
               oldmillis = millis();                                  // snapshot to the time for next slot
               ByBuf = map(analogRead(A0), 0, 4096.0, 0, 255);        // acquires from A/D converter and reduces  value to 1 byte
//   ByBuf = ByBuf + 1;                                                 *********** debug  
//   if(ByBuf == 255) ByBuf = 0;                                        *********** debug
               CarBy = (ByBuf & 0xF0) >> 4;                           // keep high nibble and shifts down to right (reduces to 0-0x0F)
               if(CarBy > 9) CarBy += 7;                              // converts to ASCII char (takes into account the gap between number 9 and 0x0A: see ASCII map) 
               CarHi = CarBy +'0';                                    // see above
               CarBy = (ByBuf & 0x0F);                                // repeats for the low nibble (does not need to shift down since it is already on the right) 
               if(CarBy > 9) CarBy += 7;                              // converts to ASCII char
               CarLo = CarBy +'0'; 
               TxBuf = TxBuf + CarHi + CarLo + ",";                   // appends the two characters representing the byte to the string plus a comma 
               i = i + 1;                                             // increases the counter of bytes

               if(i > 3)                                              // four bytes acquired, transmits the buffer on BT
               {

                         Serial.println(TxBuf);                       // transmits the characters to the APP
                         TxBuf = "";                                  // resets the tx buffer to empty  
                         i = 0;                                       // resets the counter
               }
         }
}

Hi

If you are "Receiving commas" and they are being used as the value delimiter, make sure you are using commas as the delimiter in the App. Sounds like you have a mismatch!
The total size of the payload (send string) should not exceed 32 bytes, including the end-of-data character. It is possible to extend this if the sending device allows, by adjusting the MTU, but only when using BLE.

Sorry I forgot to say:
each character pair received by the app represents a single byte: therefore you will receive, for example a string like CF,35,A0,BB, Carriage Return LineFeed.
The pairs shall then be converted in decimal to 207,53,160,187, with an AI2 conversion operation (a math block).
stay tuned :sunglasses:

(I added a ``` line before your inline code, to preserve its indentation. I learned of this markup through word of mouth from ewpatton.)

Wow really awesome! Many thanks for this hint :smiley:
... and with your post I've also leanrt a way of saying ("word of mouth").
Much appreciated.

@Sirous : did you try ? Shall I rewrite it for the NodeMCU ESP board ?
(I should have one, somewhere, lost in a drawer....) :thinking:
Cheers

Not yet!
I am working on a few projects at the same time, plus my regular "job".
I'll test as soon as I can.
Thanks

Sure !!! Take it easy :slight_smile:
Cheers!

Dear friends,

I chose the "comma" approach, with ten bytes in every pack, and I'm happy with the results.
Thank you so much for your help. :heart:

Sirous

2 Likes

Thanks for your feedback Sirous. I'm really happy having been of some help.
in effect an Arduino board is much faster than the CPU we were using to make a spacecraft to fly.... :crazy_face:
Cheers.

1 Like