Hi All,
I send larger amount of data through BLE (I know that it wasn't desinged for this purpose, but know I have to do this). Currently the connection parameters are:
- min. connection interval: 6 (7.25 msec)
- max connection itnerval: 6 (7.25 msec)
- slave latency: 0
Therefore the effective connection interval is 7.25 msec. I transfer data by using SimpleProfile_SetParameter, and the appropriate characteristic value is 16 bytes long. These suggest me that the transfer rate should be ~2 kB/s. However, I measured 70 B/s. There is some overhead caused by another operations, but it wouldn't cause this. My questions are:
- Are indications and notifications sent in the same connection event in which the actual data is transferred?
- Are confirmations sent back in the same connection event.
- The most important: what other bottlenecks can be there?
Thanks,
Gergo
I've implemented an adaptation of this code, as part of the SimpleBLEPeripheral project, but find that there is no RF traffic apparent in PacketSniffer when the GATT_Notification method is invoked. Running with the default connection parameters for this project, I'm triggering the notifications by writing a value to a particular attribute in the SimpleGATTProfile service - the simpleProfile_WriteAttrCB method has a case added to the switch for this new attribute UUID. When that case is executed the connection handle is saved and osal_start_timerEx is invoked with an event code that I've defined. That event is seen in simpleBLEPeripheral_ProcessEvent, which reacts to that event code by invoking the timer again and calling a method that is very much like Nick's sendData and invokes GATT_Notification, using that connection handle saved earlier. Here's what the code looks like in simpleBLEPeripheral_ProcessEvent:
// Process the burst event if ( events & SBP_BURST_EVT ) { // Restart the timer osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_BURST_EVT, SBP_BURST_EVT_PERIOD ); uint8 uiStartingAddress = 0; SimpleProfile_NextNotification(uiStartingAddress); SimpleProfile_NextNotification(uiStartingAddress += 20); SimpleProfile_NextNotification(uiStartingAddress += 40); SimpleProfile_NextNotification(uiStartingAddress += 60); return (events ^ SBP_BURST_EVT); }
And here's what the code looks like in SimpleProfile_NextNotification:
bStatus_t SimpleProfile_NextNotification(uint8 uiStartAddress) { bStatus_t status = SUCCESS; uint8 burstData[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // Plug in the starting address burstData[0] = ((uiStartAddress & 0xFF00)>>8); burstData[1] = (uiStartAddress & 0xFF); attHandleValueNoti_t nData; nData.len = 20; nData.handle = 20; osal_memcpy(&nData.value[0], &burstData[0], 20); // Send the notification bStatus_t bStatus = GATT_Notification(simpleProfile_connHandle, &nData, FALSE); if (bStatus == SUCCESS) loopCounter += 20; // When the counter gets to the number of bytes I want to have sent turn off the timer if (loopCounter >= TEST_DATA_TRANSFER_SIZE) { osal_stop_timerEx(main_TaskID, SBP_BURST_EVT); loopCounter = 0; } return status;}
Now it seems to be working. Replaced the battery in the CC2540-MINI key fob. The old one measured 2.6 V, new one is 3.2. Now transmitting notifications.
Thanks Nick for your prompt response !
Senthil
Hi Nick ,
I have two questions
Question 1:
I have used the GATT_Notification to send data (in multiples of 20 bytes ) from the server to the client .I have sent 1020 bytes of data using GATT_Notification .In the Btool I can able to see the data am sending from the server .
But I am planning to update the name of the GATT_server from the client, for that am planning to send the data ( name )through GATT_notification from the client and on the server side i want to know how to read the data sent by GATT_notification ??
Question 2:
Am awaiting reply for this post from an BLE expert like you , I hope you will spend your precious time on the following post too ?
http://e2e.ti.com/support/low_power_rf/f/538/p/188188/677491.aspx#677491
thanks in advance ,
Senthil kumar
Hi Senthil,
Senthil kumar103423 I have used the GATT_Notification to send data (in multiples of 20 bytes ) from the server to the client .I have sent 1020 bytes of data using GATT_Notification .In the Btool I can able to see the data am sending from the server . But I am planning to update the name of the GATT_server from the client, for that am planning to send the data ( name )through GATT_notification from the client and on the server side i want to know how to read the data sent by GATT_notification ??
To send data from Client to Server you should use GATT_WriteNoRsp (Corresponds to GATT_Notification, with no ACK back)
Br
Thanks for your reply.
But my question is how to read the data sent by GATT_notification or GATT_writeNoRsp??
Regards ,
NiceDay,
senthil kumar69729 Hi Nick , Thanks for your reply. But my question is how to read the data sent by GATT_notification or GATT_writeNoRsp?? Regards , Senthil kumar
Notifications will cause a GATT message event which will cause BLECentralProcessGATTMsg() to be called. The received data is handled there after checking pMsg -> method == ATT_HANDLE_VALUE_NOTI.
A GATT write will cause simpleProfileChangeCB() to be called. Recieved data is handled there
Hello everybody!
I am doing my bachelor thesis with BLE CC2540 performance & Power consumption measurements versus CC2510 simpliciTi & CC2430 TI-MAC
I use successfully the GATT_WriteNoRsp from my CENTRAL/MASTER NODE as the fastest way to maximize datarate by using multiple GATT write packets in one connection event with the above:
req.cmd = 1;//ATT_WRITE_REQ;
uint8 m = multiple_packets; //var from 1 to 4
do{
gattRW_status = GATT_WriteNoRsp( simpleBLEConnHandle, &req); if(gattRW_status == SUCCESS) --m; }while(m != 0);
My question are:
1)Is it possible to use multiple packets with GATT_WriteCharValue() function? I tried GATT_WriteCharValue with req.cmd = 1; but it didn't work to me.
I need this because there is a limitation of the GATT_WriteNoRsp() as it can't write data to a peripheral UUID characteristic table bigger than (23 - 15) = 8bytes max and this making it not the most efficient way to achieve the highest possible data-rate.
That means GATT_WriteNoRsp() can multiply the data-rate by 4 but with a maximum 8bytes peripheral UUID characteristic table and without ACK feature.
2)Is any other way to achieve maximum datarate from CENTRAL > PERIPHERAL?
2.1)For instance why not to have the GATT server functions on the central device, so we can use GATT_Notification with multiple packets per connection event because we can't use ?
3)From the tests that i did until now the maximum peripheral characteristic table size it worked to me and i could use it to R & W from the Central Node was 19bytes but some of you use 20bytes maximum packet size. How is that possible on GATT layer because i think its 19bytes the maximum GATT packet size?
3.1) Bug? i have noticed (1.2.0 stack version) when i make a GATT char value REQ from the CENTRAL to read my Peripheral 19bytes characteristic UUID table the last 3 bytes were not successfully predefined, like this for example:
uint8 simpleProfileChar5[SIMPLEPROFILE_CHAR5_LEN] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0 , 1 , 2};
With the packet sniffer i was reading this data after a Central's GATT_WriteCharValue() request: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0 , 0, 0
4) Is it possible not to use the GATT layer and go 1 layer lower and use ATT for data communication both ways more efficient with less overhead?
I will be very happy to see any replies/answers of these CRITICAL questions for my thesis.
Thank you in advance!
The code below looks problematic:
If the write fails due to lack of buffer (i.e. gattRW_status is not SUCCESS), then the code may loop infinitely as the stack will not be processing / sending the data while inside the while loop. You need to modify it to exit the loop as soon as the write fails.
AFAIK this is the fastest way to send data.
To send data from the peripheral to the central you need to use notifications, this can send data at the same rate as WriteNoRsp.
Nick,
What were the power consumption figures when you tested with 5.9 K Bytes per second data rate?
-Nagaraj
Hi Nagaraj,
I did not do any power consumption measurement during any of my throughput tests, although it might be interesting to see. Combine the throughput demo and Application Note AN092 for the answer. I would not expect a low number though, since the TX is gonna be on a lot. Note that CC2541 will be a much more suitable for these kind of applications as the TX power is optimized to a much lower figure (~18mA compared to CC2540's ~24mA). Adding a DCDC would optimize even further (Down to ~14mA in TX)
Keep us updated on the results, if you're digging into this.
Best Regards
I send data packets received via UART from a microcontroller via notifications from a peripheral to a central device.The data packets (18 Bytes) are transmitted in 10ms intervalls from the mircocontroller to a CC2541.
Attached you can find an image from the packet sniffer I took during over-the-air transmission.Could someone please tell me what every second packet is about. I mean P.nbr 103, 105, 107,... which are always sent after notifications.
Hi rider,
Those are packets from the master device. As you know, connection events consist of interleaved RX/TX parts from the master and the slave.
To separate the packets, you can look at the time difference - a high difference is likely a new connection event which always starts from the master, a low delay is switching between master and slave TX.
Best regards,Aslak
Hi Aslak,
Thanks for your answer. I always thought that notifications do not have any kind of acknowledgment.If I understood it correctly from your answer this is SN and NESN acknowledgment.
The longer interval occours in my case always after three notifications. Does that mean that I just send three notifications per connection event? All the other max throughput tests state 4 notifications, so I should find out why I don't send more.
Hi Rider,
riderI always thought that notifications do not have any kind of acknowledgment.
That is partly correct, Notifications are not acknowledged to the Application. At Link Layer level, you will always have acknowledgement.