Hi support,
My program's logic is about external ADC once every 4 ms mining data, after the acquisition by the interrupt tell MCU 14580, MCU open a ring buffer to store the ADC result, when there are five result start data (notify), 20 bytes data size, namely every 20 ms have a pack of packet to send, send before the arrival of the first check GATTC_CMP_EVT, connection interval is set to 10-20 ms, practical tests show that when the connection is not data connection interval for regular 18 ms (roughly), when to start the notify, connection interval of 18 for ms sometimes, sometimes to 36 ms, sometimes for 54 ms, each connection interval to send packet is also different, sometimes 1 package, sometimes 2 packs, sometimes 3, 4 package, it is not scientific, the connection interval should be not influenced by any factors, why the oscilloscope out wave type of show is this result?
The following is part of the code:
1.
Enum arch_main_loop_callback_ret user_app_on_ble_powered (void)
{
If (ptr_in!= ptr_out) / / if there is data left in the ring data buffer and then wake up the BLE to notify
{
Return KEEP_POWERED;
}
Return GOTO_SLEEP;
}
2.
Enum arch_main_loop_callback_ret user_app_on_sytem_powered (void)
{
Uint8_t tempdata [2].
Int qrsdata_in;
If (adc_int_is_set) / / adc sample is complete
{
Ads1115_get_adc_result (tempdata);
DATA_FIFO [ptr_in] [ADC_VALUE_SIZE * (1 + cycle_num)] = tempdata [0]./ / store the adc sample result in the ring data buffer
DATA_FIFO [ptr_in] [ADC_VALUE_SIZE * (1 + cycle_num) + 1) = tempdata [1]./ / store the adc sample result in the ring data buffer
Cycle_num + +;
If (cycle_num = = cycle_num) / / cycle_num = 5
{
DATA_FIFO [ptr_in] [0] = (uint8_t) (counter / 256);/ / high byte
DATA_FIFO [ptr_in] [1] = (uint8_t) (counter % 256);/ / low byte
If (counter = = 0 XFFFF)
{
Counter = 0;
Flag = true;
}
Counter++;
{if (flag) counter = 0;Flag = false;}
Cycle_num = 0;
Ptr_in + +;
If (ptr_in > = PACKET_NUMBER) ptr_in = 0;
Adc_int_is_set = false;
Return KEEP_POWERED;/ / need to notify the data
}
Adc_int_is_set = false;
}
Return GOTO_SLEEP;/ / no need to notify the data
}
3.
The static const struct arch_main_loop_callbacks user_app_main_loop_callbacks = {
App_on_init = user_app_init,
App_on_ble_powered = user_app_on_ble_powered,
App_on_sytem_powered = user_app_on_sytem_powered,
App_before_sleep = NULL,
App_validate_sleep = NULL,
App_going_to_sleep = NULL,
App_resume_from_sleep = NULL,
};
4. Send function data, first check TX_IS_COMPLETED logo
Uint8_t data_send_process (void)
{
If (!TX_IS_COMPLETED) return 0;/ / the their weight.this notification is complete
Data_to_notify (DATA_FIFO [ptr_out], PACKET_SIZE);/ / data transmitting
Ptr_out + +;
If (ptr_out > = PACKET_NUMBER) ptr_out = 0;
TX_IS_COMPLETED = false;/ / clear the TX_COMPLETE flag
Return 0;
}
5. Data_send_process () at the time of BLE on call
The static inline void schedule_while_ble_on (void)
{
/ / BLE clock is enabled
While (ble_is_powered ()) {
/ / BLE event end is set. The conditional RF calibration can run.
Uint8_t ble_evt_end_set = ke_event_get (KE_EVENT_BLE_EVT_END);
/ / the execute the messages and events
Rwip_schedule ();
/ /
If (ble_evt_end_set)
{
Uint32_t sleep_duration = 0;
Rcx20_read_freq ();
/ / if you have the enough time run a temperature calibration of the radio
If (lld_sleep_check (& sleep_duration, 4)) / / 6 slots - > 3.750 ms
/ / check the time and temperature to the run radio calibrations.
Conditionally_run_radio_cals ();
}
/ / grant control to the application, try to go to sleep
/ / if the applciation returns GOTO_SLEEP
If (!App_asynch_trm ())
Break;
/ / SDKIMPROVEMENTS Needs testing!!!!!We can add the following condition and move
/ / it out of the loop
/ / we may consider putting it in before the app_asynch_trm
/ / if (GetBits16 (CLK_CTRL_REG RUNNING_AT_XTAL16M))
/ / the execute the printf process
Arch_printf_process ();
Data_send_process ();
}
}
6. TX_IS_COMPLETED setting, when a packet of data sent on time
Void user_catch_rest_hndl (ke_msg_id_t const msgid,
Void const * param,
Ke_task_id_t const dest_id,
Ke_task_id_t const src_id)
{
The switch (msgid)
{
Case CUSTS1_VAL_NTF_CFM:
{
Struct custs1_val_ntf_cfm const * msg_param = (struct custs1_val_ntf_cfm const *) (param);
The switch (msg_param - > the handle)
{
Case ECG_IDX_DATA_VAL:
TX_IS_COMPLETED = true;/ / set the if the their weight.this packet is transmitted completely
Break;
Default:
Break;
}
} break;
Default:
Break;
}
}
Environment:
SDK5.0.3
The test phone: iphone6 and samsung s6
BR,
Young,
1. You can consult, SDK3.0.10 throughput in the project.
2. My suggestion is that in the enum arch_main_loop_callback_ret user_app_on_sytem_powered (void) only when receiving the interrupt, send the message out, other don't have to do.
In message processing function, take up the ADC value, before calling the arch_force_active_mode function, then store the data to the queue.Receive full five, notification out directly.
In addition, you can refer to throughtput streamdatad_send_data_packets_req_handler function in engineering method and go directly to check the l2CAP queue, it will than you by notification return value to decide whether to continue to send faster.
Hi Gongyu_Dialog,
Supplement: I can call on the connection after arch_disable_sleep () make the system into the idle state, because if you don't awake, I'm afraid I don't come to such a large amount of data, in addition you said message processing function refers to the "data_send_process ()" or "" arch_main_loop_callback_ret user_app_on_ble_powered ()", the two functions are BLE to perform after wake up, but I am going to store data every 4 ms once, here handled properly, will seriously lost data!
BR,
Young,
1. Adc_int_is_set is through the interrupt function set wake, or GPIO interrupt function?
2. Ads1115_get_adc_result this function how time consuming?
3. "I can call on the connection after arch_disable_sleep () make the system into idle state", / / now you do not set into extended sleep?
4. You can evaluate your average sent out a group of time-consuming and package can use rwble_get_clock function, a head of a tail, to calculate the difference be time-consuming.Unit 625 us.
Message processing function is a plus, do with your user_app_on_sytem_powered almost.Just add judgment, conditions to satisfy directly send notification.Read the ADC values, put the number and full five package directly send out notification).As long as there is a TASK message has not been processing, BLE chip will not sleep.
Hi Gongyu_Dialog,
3. After the connection is set to not into the extended sleep mode;
1. Due to the ADC sampling is after connection, so one sign adc_int_is_set is produced by normal GPIO interrupt and setting;
Other I need to do a test to learn that, thank you!
BR,
Young,
Simply put, it is
App_on_ble_powered = user_app_on_ble_powered, / / after receiving the asynchronous interrupts, directly send out messages
App_on_sytem_powered = user_app_on_sytem_powered, / / handle the message, write buffer, decide whether to send notificatiion news
The real notification function of data should be placed where, where to send data?
I have a little confusion, you said earlier:
"Enum arch_main_loop_callback_ret user_app_on_sytem_powered (void) only when receiving the interrupt, send the message out, other don't have to do"
Now say again:
". App_on_sytem_powered = user_app_on_sytem_powered, / / handle the message, write buffer, decide whether to send notificatiion news"
What is to be and you help me again under the sequence order, thank you!
BR,
Young,
Write the wrong before the function name ~ ~ ~
App_on_ble_powered check interruption in the tag, and then send information to collect data
App_on_system_powered process messages, write buffer, send notification here
Hi Gongyu_Dialog,
In accordance with your method tried, the result is the same, the connection interval will change.Are there any other Suggestions?
BR,
Young,
Supplement:
App_on_ble_powered with app_on_system_powered two return to how to deal with, just test are return GOTO_SLEEP, hope aware of, thank you!