This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Max transfer rate on BLE communication

Other Parts Discussed in Thread: CC2540, CC2541

Hi

We're trying to modify the SimpleBLEPeripheral sample code to achieve the highest possible transfer rate in both master to slave and slave to master blob data transfers.

We're currently using the USB attached CC2540 dongle to communicate between the host PC and the slave and sending ATT_WriteReq commands to the device. Unfortunately we're getting only 3 packets per second transfered using this technique.

Is there a way to queue up transfers using the USB dongle so that we can get 3 packets to be transferred during each connection interval? Do we need to modify the code running on the USB attached CC2540 dongle?

Many thanks

James

  • MASTER send ATT_WriteRep command to the SLAVE, in CC2540USB MASTER modified which part, can only use 3 packets

  • Here's some more information regarding the problems we're seeing:

    We are using the TI BLE Vendor Specific HCI interface over USB to communicate with the CC2540 USB dongle and have been able to transfer data successfully but at an extremely low throughput (around 70 bytes/s). Our Windows code which talks to the USB dongle is based on the BLEHealthDemo project on the TI wiki:

     http://processors.wiki.ti.com/index.php/Category:HealthDemo

    Transfers are currently initiated using the ATT_WriteReq HCI command. We then wait for an ATT_WriteRsp from the device before sending another ATT_WriteReq.

    1. Many of the news group posts refer to the use of the GATT_WriteNoRsp command. Unfortunately this doesn’t appear to be available through the HCI interface (according to the TI BLE Vendor Specific HCI documentation). Is this the case or are we missing something?
    2. In order to achieve the maximum transfer rate, it appears to be necessary to queue up multiple packets to be sent for each connection event. Is this possible over the HCI interface and if so, how is this done?
    3. If it is possible to queue up multiple transfer packets, how do we prevent buffer overflows at the transmitting side?
    4. If high transfer rates (8kbytes/s) are not achievable over the HCI interface, what is the alternative – custom code on the dongle?

    We have currently concentrated on Master to Slave throughput, however we will also need to move data in the other direction. Can you provide any advice on maximising throughput in Save to Master transactions as well please?

    Any help on these issues is greatly appreciated.

    James

  • (Update to the original post made by James Ibberson)
    To recap, we have a design which uses the CC2540 and we’re attempting to achieve the highest-possible data throughput (in either direction) - this must be sustained throughput as we may have up to 100kbytes of data.  There are several posts on this forum which indicate that a throughput of 8-10kbytes/sec is achievable, but with no detail behind those claims.  Our initial testing currently achieves 2.5kbyte/sec from Master - Slave (over a range of a few inches), so is some way below the target.

    Our measured throughput (2.5kbyte/s) was achieved by making a small code change on the BLE dongle supplied with the CC2540 dev kit (our code is based on the HostTestRelease – CC2540USB Master project from the TI installation).   We set the connection interval to 7.5msec (as indicated in this forum) and we expect to see 3 packets sent in each connection interval , each with 20 bytes payload (3 * 20 * 1000/7.5 = 8kbyte/sec).

    We also modified the PC-dongle interface so that the dongle buffers 160 bytes locally.  The dongle application attempts to stream the data out using the un-acknowledged transfer function GATT_WriteNoRsp(). This function will buffer up to 4 x 20 byte packets. Every time a packet goes out we appear to get called back in processEventsGATT() with the ATT_HANDLE_VALUE_NOTI event, and we use this as a trigger to send out another packet.

    Note, for the sake of experiment we further modified the code so that a single send request from the host PC causes the dongle to repeatedly transmit the contents of its local buffer (the packet queue just wraps). This has been done to try to completely isolate any interaction with the PC.  However, we’re still only getting about 2.5kbyte/s across the link.

    Questions: 

    1. Is calling GATT_WriteNoRsp the best way to achieve maximum throughput?
    2. Is waiting for the ATT_HANDLE_VALUE_NOTI event a good way to kick off the next packet?
    3. Is there some hidden latency either in calling GATT_WriteNoRsp or in the processEventsGATT callback?
    4. Is there an event which lets us know a connection interval has passed – we might use this to kick off a further chunk of packets?
    5. Is there something else we need to change (besides the connection interval) that could be ‘pacing’ what the BLE stack is doing?
    6. Is the Master actually waiting for responses from the Slave (the documentation for GATT_WriteNoRsp says it is not)?
    7. Related to question 4: Can we be sure that when we set the connection interval to 7.5msec, it really is 7.5msec?

     

  • I was able to achieve an "error corrected" ~5kB/sec of sustained throughput in either direction. The error I had to correct for was Notification packets received out-of-order under heavy load. When my throughput test used an internally generated data pattern (a well-known pattern so received data could be verified as good and in order) I could set the connection interval as low as 10, which I understand is 10 X 1.5 msec, yes? When the throughput test used is UART-to send over BLE link- to UART, the minimum connection interval setting was 12 (10 worked, but resulted in a lot of "busy" traffic, so 12 would be more efficient for overall power consumption). Setting the connection interval shorter, under heavy throughput load, resulted in so many Notification packets out of order that the RAM space to error correct became prohibitive. I posted to my profile "Files" area a folder containing .hex files that demonstrate all of these throughput tests on standard TI development kit hardware which you are welcome to try out.

  • Hi Graham and James,

    I modified simpleBLEperipheral project to do some high data rate tests.

    simplekeys.c: I changed the key attribute skKeyPressed to be the size of 20 instead (maximum) and in the SK_SetParameter function I changed the length check to 20 instead.

    simpleBLEperipheral.c/h: I added a an OSAL event which is called by a button press that periodically sets the 20 byte key attribute in the simple keys profile for times, as following code snippet;

      if ( events & SBP_BURST_EVT )
    {
    // Restart timer
    if ( SBP_BURST_EVT_PERIOD )
    {
    osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_BURST_EVT, SBP_BURST_EVT_PERIOD );
    }
    SK_SetParameter( SK_KEY_ATTR, 20, &burstData );
    SK_SetParameter( SK_KEY_ATTR, 20, &burstData );
    SK_SetParameter( SK_KEY_ATTR, 20, &burstData );
    SK_SetParameter( SK_KEY_ATTR, 20, &burstData );


    return (events ^ SBP_BURST_EVT);
    }

    I started with a rather high burst period which I lowered together with the connection interval for several tests. I set the connection interval in BTool and established connection, enabled notifications for key press and click the button on keyfob to start the burst. I checked with sniffer since BTool overloads (at 10ms connection interval even the sniffer overloads after a while).

    I tested 50ms, 20ms, 15ms and 10ms connection interval and a could see clearly in the sniffer window (shortly for 10ms though) that everything was sent correct, giving the data rates 1.6kB/s, 4kB/s, 5.3kB/s and 8kB/s.

    This is just some brief and basic tests and note that in this example, GATT_Notification() is used.

    I hope this could help you a bit, I will however continue to test.

    Br

  • Hi,

    As with many others, I require a two way data stream between connected devices with a datarate as high as possible (8kB/s should work well).

    I see that the data is sent from the peripheral to the central device using GATT_Notification messages to send more than one Attribute update per connection interval.

    The question is - how can I achieve this rate in the other direction? Using the GATT_WriteCharValue on the central device to update an Attribute on the peripheral only allows one update per connect interval im guessing due to error checking.

    Thanks Mike

  • You can use the GATT_WriteNoRsp function.

  • Sasha Kalmanovich said:
    GATT_WriteNoRsp

    I have tried the GATT_WriteNoRsp function and receive an INVALIDPARAMETER error. The exact same write request is successfully transmitted using GATT_WriteCharValue()

  • This is my code and it works fine:
    
    
     attWriteReq_t writeReq;
     writeReq.handle = handle;
    writeReq.len = msgSize + 1;
       writeReq.sig=0; 
       writeReq.cmd = 1;//ATT_WRITE_REQ;  
    GATT_WriteNoRsp( 0, &writeReq);
  • Thanks,

    It is working now. I had the cmd field set to 0 for GATT_WriteCharValue. Changing it to 1 fixed the problem. I cant find a description of what this field does in the API - where did you get the value of 1 from?

  • Hi Michael,

    I just had the exact same problem with the GATT_WriteNoRsp function. Did you found the explanation of this "cmd" field and why it works when it is set to 0 for the command GATT_WriteCharValue?

    Regards,

    Jerome

  • Hi Jerome,

    No, this question has not been answered, If you find out i'd like to know too.

    Thanks

  • Hi Eng351 ,

    You said that you have achieived the 8KB/s from Pheripheral to Central using GATT_Notification ,can you please put some light over it ,by providing some example code ? 

    It will be greatly helpful !

    To my understanding ,when i enable the notification (Client characteristic configuration ) ,the Pheripheral will send the notifications when the key is pressed (In Keypress notifications in KeyfobDemo application).

    Below is the log captured using Btool ,when the key is pressed and Released ,

    -Type		: 0x04 (Event)
    -EventCode : 0xFF (HCI_LE_ExtEvent)
    -Data Length : 0x09 (9) bytes(s)
    Event : 0x051B (ATT_HandleValueNotification)
    Status : 0x00 (Success)
    ConnHandle : 0x0000 (0)
    PduLen : 0x03 (3)
    Handle : 0x0046 (70)
    Value : 01
    Dump(Rx):
    04 FF 09 1B 05 00 00 00 03 46 00 01

    ------------------------------------------------------------------------------------------------------------------------
    [2] : <Rx> - 04:43:12.421
    -Type : 0x04 (Event)
    -EventCode : 0xFF (HCI_LE_ExtEvent)
    -Data Length : 0x09 (9) bytes(s)
    Event : 0x051B (ATT_HandleValueNotification)
    Status : 0x00 (Success)
    ConnHandle : 0x0000 (0)
    PduLen : 0x03 (3)
    Handle : 0x0046 (70)
    Value : 00
    Dump(Rx):
    04 FF 09 1B 05 00 00 00 03 46 00 00
    
    
    So when the API GATT_Notification is used ( in the code of Keyfob_demo_slave ) it will send some more notifications to the Central device with some data (8KB /sec ) ??
    I am a new bee in BLE ,any help in this will help me to enlight my knowledge in BLE .

    Thanks in Advance ,

    Senthil 

  • Hi Senthil,

    I am happy to give some pointers but my code has been developed for a commercial application. If you look at some of the other posts on max communication rate you will find some examples provided by TI staff e.g. Nick L.

    I have not achieved 8KB/s, Nick L's max speed test reached around 5-6KB/s.

    My advice is:

    1. Get notifications working.

    2. Increase characteristic size to the max (18-20 bytes) and ensure you can transfer all bytes successfully with each notification.

    3. Create stream code to fragment your data buffer into chunks and send them on each connection interval (it is helpful to use one of the bytes as a data length counter for when the data to send is less than the max). Obviously you will need code at the other end to re-assemble the stream.

    4. Reduce the connection interval as low as possible to increase the data rate.

    5. Try to send more than one notification on each connect interval to increase your data rate (Nick L's example sends up to 4). Note that there is a known issue with notifications arriving out of order when more than one is sent per connect interval. From a recent post TI is investigating this. For now your code will need a sequence number to re-assemble in order (like TCP).

  • Hi Eng351,

    Thanks for your immediate response and your explanation is well understandable .

    I will come back to you if i had queries later .

    One quick question ,Theoritically i have read that transfer rate of BLE is 1 MB/sec .Based on what they have calculated this ? 

  • The raw burst data rate is 1Mb/s (1000kb/s) not 1MB/s. This is the rate at which data is transferred when transmitting.

    BLE works by transmitting data in small bursts which frequency hop each interval (i.e. a low duty cycle) so that it uses very little power (this is the whole idea behind the low energy part of BLE).

    The actual application data rate is much lower than this due to the low duty cycle above, reponse latency & max packet size, and protocol overhead which is fairly high given the small maximum packet size. 

  • Hi guys,

    I'm trying to measure the throughput of CC2540, any ideas on how to go about it?

    Thanks in advance

  • Dear Nick,

    To Test the Maximum data transfer rate,you have used GATT_Notification().

    If I Modify,

    SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR4,SIMPLEPROFILE_CHAR20_LEN, charValue20 )  to transfer 20 bytes.

    Can i achieve data transfer upto 8 KB/s?

    Thanks

    Arul

  • Hi! The CC2541 the same problem with low speed or it can run faster?

  • Hello Igor,

    For the CC2541 operating in BLE Mode, you will have the same speed restrictions.

    The CC2541 can operate in Propritary Mode (Non BLE) at a data rate of up to 2Mbps.  You can actually switch to proprietary mode for high data transfers and then switch back to BLE.  You can find an example on the wiki for using the CC2541 in proprietary mode.

    Thanks