256KB data transfer over BLE , DA14681

了解更多FAQsTutorials

8个帖子/ 0新
Last post
mahmed106
Offline
Last seen:1个月3天前
加入:2019-05-03所
256KB data transfer over BLE , DA14681

Hi Dialog

We are working on a custom board based on DA14681. In our application the normal scnerio is that device records temperature and stores it in eeprom. After several days when user connects the device with BLE app. All offline data gets transferred to the mobile.

我们的EEPROM大小为256KB,数据包大小为10字节,因此我们需要发送25600个数据包,现在我们通过BLE服务传输数据。

这是流程:

1 - 移动应用程序与设备连接。

2 - Mobile app request a read characteristics of the particular service.

3 - DA14681 returns the data bytes that were requested.

So mobile app constantly make a read request and firmware sends the value.

In this method the speed of data transfer is very slow. Aproximately 2 packets per seconds which means it will take 3.5 Hours to send all packets to the mobile app.

我的问题是,有什么快速的方法来做到吗?因为256 kb的数据在几小时内没有太大。我在这里缺少一些东西..

设备:
PM_Dialog
Offline
Last seen:9小时34分钟前
工作人员
加入:2018-02-08 11:03
嗨mahmed106,

嗨mahmed106,

Could you please share the code snippet you are using in order to transmit data over BLE? I assume that you are using BLE notifications or indications for this.

Thanks, PM_Dialog

mahmed106
Offline
Last seen:1个月3天前
加入:2019-05-03所
我正在使用读取请求

我正在使用应用程序侧的读取请求来读取数据。

这是该代码

static void handle_read_req(ble_service_t *svc, const ble_evt_gatts_read_req_t *evt){
sftemps_service_t * sftemps =(sftemps_service_t *)svc;

if(evt-> handle == sftemps-> purlature_count_h)
{
uint16_t ccc_val = rand()%100;//get_sf_temp_num_records_device();

//ble_storage_get_u16(evt->conn_idx, bcs->bcs_ccc_h, &ccc_val);

//我们很少 - endian,好的,直接从uint16_t写
ble_gatts_read_cfm(evt->conn_idx, evt->handle, ATT_ERROR_OK,
sizeof(ccc_val), &ccc_val);
}
else if (evt->handle == sftemps->temperature_data_h)
{
// uint32_t ccc_val = rand()%100;//get_sf_temp_records_device();

//ble_storage_get_u16(evt->conn_idx, bcs->bcs_ccc_h, &ccc_val);

//我们很少 - endian,好的,直接从uint16_t写

if(readpacketnumber == 0)//第1包标题//添加重启异常但闪存中的数据
{
// readpacketnumfromflash = read_packetnumbers_from_flash();
// printf(“pn%d”,ReadPacketNumfromFlash);
#if NoFlashDummyCode
r_ptr_packetnumber = 50; // rand()%100;
m24elapsedtime = r_ptr_packetnumber * 3;
Memset(LoggingPacket,0x00,sizeof(logingpacket));
loggingpacket [0] = 0xcd;
loggingpacket [1] = 0x11;
loggingpacket [2] = 0x12;
LoggingPacket[3]=M24ElapsedTime >> 24;
LoggingPacket[4]=M24ElapsedTime >> 16;
loggingpacket [5] = m24 elapsedtime >> 8;
LoggingPacket[6]=M24ElapsedTime & 0xFF;
LoggingPacket[7]=R_PTR_PacketNumber>>8;
LoggingPacket[8]=R_PTR_PacketNumber&0xFF;
LoggingPacket[9]=LoggingPacket[0];
for(int by=1;by<9;by++)
{
LoggingPacket[9]^=LoggingPacket[by];
}
ReadPacketNumber++;// Read next packet in next iteration
R_PTR_ChipNo = 1; // Select Chip one as it is the start
r_ptr_readaddress = 0; // 0xF9C9;//从芯片0开始和地址0
#其他
R_PTR_PacketNumber = read_packetNumbers_from_M24Flash();
M24ElapsedTime = ReadElapsedTimeFromM24Flash();
Memset(LoggingPacket,0x00,sizeof(logingpacket));
loggingpacket [0] = 0xcd;
loggingpacket [1] = 0x11;
loggingpacket [2] = 0x12;
LoggingPacket[3]=M24ElapsedTime >> 24;
LoggingPacket[4]=M24ElapsedTime >> 16;
loggingpacket [5] = m24 elapsedtime >> 8;
LoggingPacket[6]=M24ElapsedTime & 0xFF;
LoggingPacket[7]=R_PTR_PacketNumber>>8;
LoggingPacket[8]=R_PTR_PacketNumber&0xFF;
LoggingPacket[9]=LoggingPacket[0];
for(int by=1;by<9;by++)
{
LoggingPacket[9]^=LoggingPacket[by];
}
ReadPacketNumber++;// Read next packet in next iteration
R_PTR_ChipNo = 1; // Select Chip one as it is the start
r_ptr_readaddress = 0; // 0xF9C9;//从芯片0开始和地址0
#endif
}
#if 1
else if(ReadPacketNumber>0 && (ReadPacketNumber{
#if NoFlashDummyCode
dummy_r_ptr_packetnumber = ReadPacketNumber;
Dummy_M24ElapsedTime=Dummy_R_PTR_PacketNumber*3;
Memset(LoggingPacket,0x00,sizeof(logingpacket));
loggingpacket [0] = 0xcd;
LoggingPacket[1]=0x12;
LoggingPacket[2]=0x13;
MEMSET(M24CurrentPacket,0x00,Sizeof(M24CurrentPacket));
LoggingPacket[3]=0;
LoggingPacket[4]=Dummy_R_PTR_PacketNumber++;
LoggingPacket[5]=Dummy_M24ElapsedTime >> 24;
LoggingPacket[6]=Dummy_M24ElapsedTime >> 16;
LoggingPacket[7]=Dummy_M24ElapsedTime >> 8;
LoggingPacket[8]=Dummy_M24ElapsedTime;
loggingpacket [9] = rand()%60;
loggingpacket [10] = rand()%9;
loggingpacket [11] = loggingpacket [0];
for(int by=1;by<11;by++)
{
LoggingPacket[11]^=LoggingPacket[by];
}
ReadPacketNumber++;// Read next packet in next iteration
#其他
Memset(LoggingPacket,0x00,sizeof(logingpacket));
loggingpacket [0] = 0xcd;
LoggingPacket[1]=0x12;
LoggingPacket[2]=0x13;
MEMSET(M24CurrentPacket,0x00,Sizeof(M24CurrentPacket));
// printf("CN %d - Add %d",R_PTR_ChipNo,R_PTR_ReadAddress);
// fflush(stdout);
SequentialReadM24Flash(((R_PTR_ReadAddress & 0xFF00)>>8),(R_PTR_ReadAddress),8,R_PTR_ChipNo);
r_ptr_readaddress + = 8;
for(Uint8_t tempbufffill = 3; tempbufffille <11; tempbufffille ++)
{
loggingpacket [tempbufffille] = m24currentpacket [tempbufffill-3];
// loggingpacket [tempbufffille] = m24_i2c_ad_read((r_ptr_readaddress&0xff),(r_ptr_readaddress&0xff00),r_ptr_chipno);
// printf("\n%d ",R_PTR_ReadAddress);
// r_ptr_readaddress ++;
}
// ReadPacketNumber=(LoggingPacket[3]*10)+LoggingPacket[4]; // If there is a mismatch between packet number write and its read index
loggingpacket [11] = loggingpacket [0];
for(int by=1;by<11;by++)
{
LoggingPacket[11]^=LoggingPacket[by];
}
ReadPacketNumber++;// Read next packet in next iteration
if(R_PTR_ReadAddress>=0xF9F6 && R_PTR_ChipNo<4) // 0xF9F6 is the address which will be the last 64k/15 = 4266
{
r_ptr_chipno ++;
R_PTR_ReadAddress=0;
}
#endif
}
else if(ReadPacketNumber>R_PTR_PacketNumber)// Footer
{
#if NoFlashDummyCode
Memset(LoggingPacket,0x00,sizeof(logingpacket));
loggingpacket [0] = 0xcd;
loggingpacket [1] = 0x13;
loggingpacket [2] = 0x14;
LoggingPacket[3]=0xDA;
ReadPacketNumber = 0;
LoggingStatus = LoggingStopped;
#其他
Memset(LoggingPacket,0x00,sizeof(logingpacket));
loggingpacket [0] = 0xcd;
loggingpacket [1] = 0x13;
loggingpacket [2] = 0x14;
LoggingPacket[3]=0xDA;
if(PassCodeVerification==1)
{
m24flashpacketnumber = 0;
ResetPacketNumberInM24Flash();// take care as high speed read from app may pre-empt it
loggingstatus = loggingstopped;
FLASH_FULL=0;
resetelaspedtimeinm24flash(); //按照从应用程序读取的高速读取可能会预先删除它
M24ElapsedTime=0;
PauseLapaedTimecounting = et_pause;
Resetchipnoinm24Flash(); //按照从应用程序读取的高速读取可能会预防它
}
ReadPacketNumber = 0;

// FlashPacketNumber=1;
// Elapsed_time = 0;
#endif
}
#endif
ble_gatts_read_cfm(evt->conn_idx, evt->handle, ATT_ERROR_OK,
sizeof(LoggingPacket), &LoggingPacket);
#if ENABLE_UART_PRINTF
printf("FLSH-RD %d-%d\n",ReadPacketNumber,R_PTR_PacketNumber);
#endif
}
else
{

ble_gatts_read_cfm(evt->conn_idx, evt->handle, ATT_ERROR_READ_NOT_PERMITTED, 0,
NULL);
}

应用程序持续读取读取请求和DA14681以响应发送数据。

I also have tried notification method it is better than the above method but that also takes alot of time. I want to know the recommeneded method to send large chunks of data over the ble using DA14681

PM_Dialog
Offline
Last seen:9小时34分钟前
工作人员
加入:2018-02-08 11:03
嗨mahmed106,

嗨mahmed106,

感谢您的答复。让我检查一下,我会回复你/

Thanks, PM_Dialog

PM_Dialog
Offline
Last seen:9小时34分钟前
工作人员
加入:2018-02-08 11:03
嗨mahmed106,

嗨mahmed106,

The amount of data that the device can send during a connection interval is closely dependent on the number of packets that the Central allows a peripheral to send. To do so, could you please check how many packets are exchanged when there is a data transaction? Would it be possible to use a BLE sniffer tool, so that we can understand what is happing over the air during the transaction? Do you have the notifications enable after the first read request?

请记住,根据BLE规范,可以在一个数据包中发送多达251个字节的一个数据包。收到/传输数据包的最大数据长度是多少?所以检查dg_configble_data_length_rx_max和dg_configble_data_length_tx_max宏。BLE_GAP_MTU_SIZE_SET()可用于设置适当的MTU_SIZE。请注意,应在属性数据库创建之前调用特定API,因为将修改设备配置,这将导致清除当前属性数据库(如果存在)。

一些纯粹的表现可能以下意义的几件事:

  • 连接间隔。可以使用的最低允许间隔为7.5ms。应用程序代码中使用的连接间隔是什么?中央可以设置连接间隔或外围设备可以请求具有特定的连接间隔,并且它可以接受或不接受(连接更新参数)。
  • 从延迟。你有什么表明这是什么?可以使用等于零(0)的最低延迟值。
  • 每个连接间隔的数据包数。这可能受到中央的限制并影响性能。什么是中央?它是另一个da14681还是智能手机?

Thanks, PM_Dialog

mahmed106
Offline
Last seen:1个月3天前
加入:2019-05-03所
Thanks for the detailed reply

Thanks for the detailed reply. Now i understand better. As per your questions, below is the answers:

1 - 750ms是连接间隔

2 - Slave latency is 0

3 - Central is a smartphone

mahmed106
Offline
Last seen:1个月3天前
加入:2019-05-03所
So it means of i reduce my

So it means of i reduce my connection interval to 7ms ,, my throughput will increase?

PM_Dialog
Offline
Last seen:9小时34分钟前
工作人员
加入:2018-02-08 11:03
嗨mahmed106,

嗨mahmed106,

是的,请尝试使用比750ms更小的连接间隔并通过通知发送数据。根据BLE规范,连接间隔应为7.5ms(CONN_INTERVAL_MIN)到5SEC(CONN_INTERVAL_MAX)。

Thanks, PM_Dialog