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的数据在几小时内没有太大。我在这里缺少一些东西..
嗨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
我正在使用应用程序侧的读取请求来读取数据。
这是该代码
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
嗨mahmed106,
感谢您的答复。让我检查一下,我会回复你/
Thanks, PM_Dialog
嗨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,因为将修改设备配置,这将导致清除当前属性数据库(如果存在)。
一些纯粹的表现可能以下意义的几件事:
Thanks, PM_Dialog
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
So it means of i reduce my connection interval to 7ms ,, my throughput will increase?
嗨mahmed106,
是的,请尝试使用比750ms更小的连接间隔并通过通知发送数据。根据BLE规范,连接间隔应为7.5ms(CONN_INTERVAL_MIN)到5SEC(CONN_INTERVAL_MAX)。
Thanks, PM_Dialog