This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Softdevice timer

Hey guys,

I'm working with SES, nRF52832 and SDK14.2.0.

I have a timing problem and would like to describe the problem from the beginning.

I have a 1-wire temperature sensor that is read by the slave and then the slave sends the sensor data to the master via BLE every second. (That is my goal.)

1) First I measured the "temperature conversion time" of the sensor with the project: peripheral / uart, which I modified with a timer for the interval transmission (of 1 second) and with a timer for measuring the time.

Timer for sending in intervals:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
/**< Driver instance for timer 1 */
const nrf_drv_timer_t TIMER_SEND_DATA = NRF_DRV_TIMER_INSTANCE(1);
/**
* @brief Handler for timer events.
*/
void timer_event_handler(nrf_timer_event_t event_type, void* p_context)
{
switch (event_type)
{
case NRF_TIMER_EVENT_COMPARE1:
send_telegram(); //with temperature data
break;
default:
//Do nothing.
break;
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Timer for measuring:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
///////Function to measure time
/**< Temperature request and read */
int OneWire_Read_Temperature(void)
{
uint32_t captured_value = 0;
.....
/**< Start of the time measurement */
NRF_TIMER2->TASKS_CLEAR = 1;
NRF_TIMER2->TASKS_START = 1;
/**< DS18B20 store thermal data in the scratchpad (2-byte temp register) */
while (! OneWire_Read_Byte()); /**< Sensor respond by transmitting a 0 while temperatur conversion is in progress and a 1 when conversion is done
* after storing the Sensor returns to its low power idle state */
/**< End of the time measurement */
NRF_TIMER2->TASKS_CAPTURE[1] = 1;
captured_value = NRF_TIMER2->CC[1];
NRF_TIMER2->TASKS_STOP = 1;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

And I get the measured time around 702 milliseconds (with small deviations in the microsecond range). And this value is ok.

When I measure all the code that is triggered by the timer (case NRF_TIMER_EVENT_COMPARE1), I get a measured value of approx. 720 milliseconds.

Everything fits up to here.

2) Now I would like to send the sensor data via BLE and have selected the following programs for the slave and the master:

Slave: ble_peripheral/ble_app_uart

Master: ble_central/ble_app_uart_c

I set the timer for sending after every second exactly as in the "peripheral / uart" project. I have installed the timer for measuring in "case NRF_NRF_TIMER_EVENT_COMPARE1":

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* @brief Handler for timer events.
*/
void timer_event_handler(nrf_timer_event_t event_type, void* p_context)
{
int RetVal;
uint32_t captured_value = 0;
switch (event_type)
{
case NRF_TIMER_EVENT_COMPARE1:
/**< Start of the runtime measurement */
NRF_TIMER2->TASKS_CLEAR = 1;
NRF_TIMER2->TASKS_START = 1;
RetVal = send_temperature(); /**< Function call to send the temperature value to the master */
if (RetVal != READ_TEMP_SUCCESSFUL) /**< When an error occurs: report it */
{
printf("ERROR: %x \r\n", RetVal);
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

But here I get totally random values ​​like: 140.000 ticks, 69.000 ticks or 12.000 ticks, although the temperature conversion alone takes about 702.000 ticks (702 milliseconds). Is that because of the softdevice (ble)? If so, what can I change? I'm a bit baffled here...

For this reason, I configured the measurement timer in the master-program in "ble_nus_c_evt_handler":

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**@brief Callback handling NUS Client events.
*
* @details This function is called to notify the application of NUS client events.
*
* @param[in] p_ble_nus_c NUS Client Handle. This identifies the NUS client
* @param[in] p_ble_nus_evt Pointer to the NUS Client event.
*/
/**@snippet [Handling events from the ble_nus_c module] */
static void ble_nus_c_evt_handler(ble_nus_c_t * p_ble_nus_c, ble_nus_c_evt_t const * p_ble_nus_evt)
{
ret_code_t err_code;
uint32_t captured_value = 0;
switch (p_ble_nus_evt->evt_type)
{
....
case BLE_NUS_C_EVT_NUS_TX_EVT:
/**< End of the runtime measurement */
NRF_TIMER2->TASKS_CAPTURE[1] = 1;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Here I get values ​​in 1 second intervals, but the values ​​fluctuate very strongly (up to 200 ms) ... That means the master gets values ​​in an interval between 0.8 and 1.2 seconds, but I need an accurate interval of 1 second... Does anyone know what I can do? I would be very happy about any help ..

Best regards,

Christoph