How to split a string into small chunks of fixed length in C to send from Arduino BLE?

arduino, bluetooth-lowenergy, c

Solution

Not knowing the first thing about Arduino and BLE, I can only offer assistance with the actual math you're doing, which is wrong.

First some minor points:

char data[] = "lat:29.459612,lon:44.011856,speed:0.75,sats:9";
char sendBuffer[20];

int len = sizeof(data); // HERE
int buflen= sizeof(sendBuffer); // HERE

Both of those should be `size_t` type. Apart from that, unless you're planning on sending the terminating nullchar character of your string, the actual data size of your send should be one-less than what you have now, which you can get via simple subtraction or via `strlen`.

Beyond that, this is completely wrong:

for( i=buflen; i<len+buflen; i=i+buflen){
    memcpy(sendBuffer,data,i);
    *data= *data+i;
    ble.print("AT+BLEUARTTX=");
    ble.println(sendBuffer);
    delay(10000);
}

The string you're sending is 45 characters. This loop starts at 20. Therefore, the first iteration of your `memcpy` will do this:

memcpy(sendBuffer, data, 20);

However, the second iteration will do this:

memcpy(sendBuffer, data, 40);

The third:

memcpy(sendBuffer, data, 60);

but by that time you're long since invoked undefined behavior.

Further, your attempt to increment your source buffer starting location using pointer math is wrong, and looks like you tried to "fix" the problem of modifying a non-lvalue. i.e. It looks like you first tried this:

data = data + i;

and when that didn't work, you shoved `*` in front of each `data`, it compiled, so you ran with it. Believe me. C is not a language you want throw at a wall to see if something sticks.

Finally, I highly suspect your `println` member requires a nulchar terminated string, which you're not providing.

The following code addresses all of the above. It just dumps to a console. You'll have to tailor it for your needs regarding sending it... wherever.

Example

#include <stdio.h>
#include <string.h>

int main()
{
    char data[] = "lat:29.459612,lon:44.011856,speed:0.75,sats:9";
    char buffer[21] = {0}; // note space for terminator

    size_t len = strlen(data);      // doesn't count terminator
    size_t blen = sizeof(buffer)-1; // doesn't count terminator
    size_t i = 0;

    // put up a header row so you can see the output in columns
    for (i=0; i<blen; ++i)
        printf("%zu", i%10);
    fputc('\n', stdout);

    // the actual loop that enumerates your buffer
    for (i=0; i<len/blen; ++i)
    {
        memcpy(buffer, data + (i*blen), blen);
        puts(buffer);
    }

    // if there is anything left over
    if (len % blen)
        puts(data + (len - len % blen));

    return 0;
}

Output

01234567890123456789
lat:29.459612,lon:44
.011856,speed:0.75,s
ats:9

Note we never overwrite the 21'st char in that send-buffer, which was initialized to 0's, so it is always terminated. Also we pick up the short frame (if there is one) directly from the source string as the last operation.

I leave integrating the actual send logic to you.

Problem

I am trying to send a long String data from my Arduino BLE program to my android app. How I can split my long string into chunks of 20 bytes to send to the app. ``` char data[] = "lat:29.459612,lon:44.011856,speed:0.75,sats:9"; char sendBuffer[20]; int len = sizeof(data); int buflen= sizeof(sendBuffer); int i = 0; for (i=buflen; i<len+buflen; i=i+buflen) { memcpy(sendBuffer,data,i); *data= *data+i; ble.print("AT+BLEUARTTX="); ble.println(sendBuffer); delay(10000); } ``` But I am not getting the expected result. Thank you for any help!

Original source