This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

High Sample Rate with ADC and SoftDevice

I am trying to sample the ADC every 2ms. I notice lots of slowness with BLE advertising and typically can't connect to device over BLE when sampling. I am using PPI, configuring, and starting before the softdevice is enabled.

  1. Should nRF51822 be capable of reading ADC every 1ms to 2ms reliably?

  2. Should I move all the PPI configuration to after the softdevice is enabled and be using the sd_ppi functions?

Thanks!

Edit: Headline, format, added tags.

Parents
  • Hi Chris

    I have attached an adc example which samples voltage on an input pin while the S110 softdevice is enabled. You should be aware of that you need to set the priority of the ADC interrupt explicitly to LOW. Also, PPI channels 8-15 are blocked by the softdevice, as stated in table 6 in the S110 Softdevice Specification v1.1, so using them for the application will cause conflicts with the softdevice. Use only PPI channels 0-7 for the application.

    You should also be aware of that during BLE transmission, the CPU will be blocked, therefore limiting the sampling frequency of the ADC. The ADC itself will be able to process up to 50k samples per second but the CPU will be blocked for ca 0.8 - 6.0 ms when the softdevice is enabled, depending on the amount of data you are sending over the BLE link.

    Table 12 in the S110_Softdevice_Specification_v1.1 states that throughput is up to 120kpbs for sending data from a client. However, when you send 32-40 kbps you would have to select 7.5ms connection interval and send 2 packets per connection interval. The CPU will be blocked for the whole transmission time of the 2 packets and that will block the CPU for about 1.6 ms. Sampling with 1kHz will not work because the ADC only buffers one sample and overwrites it when sampling again. The CPU is simply not available to process the ADC data every 1 millisecond.

    Table 10 in the S110_Softdevice_Specification v1.1 indicates how long the CPU is blocked in respect to what you are sending many packets in each connection interval. The thing is that the length of the blocking period also depends on several factors:

    The CPU blocking time in table 10 is therefore not very accurate because you really need to know the value of the above parameters, so the table is more of an estimate. However, when you want to obtain the shortest CPU blocking period of the softdevice you should set connection interval to 7.5ms, slave latency to zero and transfer as few packets as possible in each connection interval.

    When connection interval is 7.5ms the master and slave 32kHz clock accuracy has very little effect on the lenght of the CPU blocking period. However, it has great effect when connection interval is e.g. 4000 ms and/or when slave latency is high.

    So, to be brief, if you send or receive only one packet per connection interval, you should be able to process ADC samples with 1kHz frequency, given that you choose connection interval of 7,5ms and no slave latency. However, if you send or receive 2 packets per connection interval, you will most likely need to decrease you sampling frequency to 500 Hz.

    You can configure your PPI channels directly before initializing the softdevice or use the sd_ppi functions if you choose to initialize the PPI channels after you initialize the softdevice. Again, only use PPI channels 0-7 for the application.

    ble_app_hrs_with_adc_sample_ain.zip

  • Also, why do you start and stop the hfclk?

    static void adc_sampling_timeout_handler(void * p_context) { uint32_t p_is_running = 0;

    sd_clock_hfclk_request();
    while(! p_is_running) {  							//wait for the hfclk to be available
    	sd_clock_hfclk_is_running((&p_is_running));
    }               
    nrf_gpio_pin_toggle(NRF6310_LED_2);		//Toggle LED2 to indicate start of sampling
    NRF_ADC->TASKS_START = 1;							//Start ADC sampling
    

    }

    void ADC_IRQHandler(void) { /* Clear dataready event */ NRF_ADC->EVENTS_END = 0;

    /* Write ADC result to port 2 */ nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT2, NRF_ADC->RESULT); nrf_gpio_pin_toggle(NRF6310_LED_3);

    //Use the STOP task to save current. Workaround for PAN_028 rev1.5 anomaly 1.
    

    NRF_ADC->TASKS_STOP = 1;

    //Release the external crystal
    sd_clock_hfclk_release();
    

    }

Reply
  • Also, why do you start and stop the hfclk?

    static void adc_sampling_timeout_handler(void * p_context) { uint32_t p_is_running = 0;

    sd_clock_hfclk_request();
    while(! p_is_running) {  							//wait for the hfclk to be available
    	sd_clock_hfclk_is_running((&p_is_running));
    }               
    nrf_gpio_pin_toggle(NRF6310_LED_2);		//Toggle LED2 to indicate start of sampling
    NRF_ADC->TASKS_START = 1;							//Start ADC sampling
    

    }

    void ADC_IRQHandler(void) { /* Clear dataready event */ NRF_ADC->EVENTS_END = 0;

    /* Write ADC result to port 2 */ nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT2, NRF_ADC->RESULT); nrf_gpio_pin_toggle(NRF6310_LED_3);

    //Use the STOP task to save current. Workaround for PAN_028 rev1.5 anomaly 1.
    

    NRF_ADC->TASKS_STOP = 1;

    //Release the external crystal
    sd_clock_hfclk_release();
    

    }

Children
No Data
Related