This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Problem when using "pc-ble-driver-js", sending a large file to peripheral

Hi,

I'm using the  "pc-ble-driver-js" to implement a central on PC, trying to send a file through a Write w/o Response characteristic to a device. It's OK for a small file (eg. 4KB), but when I try to send a  large file, it will break randomly, eg. after several tenth KB.

The error message is: Failed to write to attribute with handle: 23: Timed out when waiting for BLE_EVT_TX_COMPLETE. 

After occurs, the connection keep but any other message (no matter short or long) will not be send to device, unless I disconnect and reconnect it.

I'm using the NodeJS 8.15.1, PCA10031 dongle with v2 SD_API_VERSION.

This is what I send the data out, anything I did it wrong? Thanks

async function sendBurst(data)
{
    let offset = 0;
    let seq = 0;
    let txBuf;
    let i;

    while (true)
    {
        i = data.length - offset;       // no. of byte need to send in this round

        // Prepare the txBuf[]
        if (offset === 0)
        {
            // First packet
            if (i > 20)
                i = 20;

            txBuf = data.slice(0, offset + i);
            txBuf[0] = (data[0] & 0x0f) | (seq << 4);       // insert "seq" into [CMD1]
        }
        else
        {
            // Remaining Packet
            if (i > 19)
                i = 19;

            txBuf = data.slice(offset, offset + i);
            txBuf.unshift(seq << 4);        // insert "seq" into txBuf[0]
        }

        seq ++;
        if (seq >= 7)
            seq = 1;

        offset += i;
        if (offset >= data.length)
        {
            txBuf[0] |= 0x80;
            seq = 0xff;
        }

        // Send it now
        await new Promise((resolve, reject) => {
            adapter.writeCharacteristicValue(charID_burstTx, txBuf, false, (err) => {
                if (err)
                {
                    reject(err);
                    return;
                }
                resolve();
            });
        });

        if (seq == 0xff)
            break;          // abort if all send
    }
}
  • Hi,

    It may be that you are trying to send data too quickly, so that over time for some reason you reach a point where writeCharacteristicValue() times out. You could try to implement a number of retries of the writeCharacteristicValue() call on timeout, with an added delay of a few ms between each try.

    The above would not explain why you have to disconnect and connect again to get things going again. Perhaps a sniffer trace, or logs from the peer device, could shed some light on what happens?

    Regards,
    Terje

  • Thanks tsec,

    Seems you're right, I send the data too quickly, I don't know why but if I add 10ms delay between each writeCharacteristicValue(), the problem gone. But I meet another throughput problem, seems the implementation of the writeCharacteristicValue() is not alright for my application.

  • Hi,

    What I meant was that when you get that error, you wait a few ms, then try again. You do not need to wait between each writeCharacteristicValue(), you only have to wait (and then retry) when you get the waiting for BLE_EVT_TX_COMPLETE error.

    Regards,
    Terje

Related