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

the sampling rate of measurements using nrf 51822

I am using nrf51822 chips and UART to communicate with my cellphone. I want to know if there are any ways to improve the sampling rate (reading and transmission) of measurement. I am doing the EEG stuff, so more date transitted is favorable. Thanks!

Parents Reply
  • The question is whether it is the sample rate of the ADC that is the limitation, or if it is the BLE throughput. You will not be able to send 2k packets each second, you will have to buffer up multiple samples and send these at a lower interval. Remember that the minimum connection interval in BLE is 7.5 ms, and the phone may limit this even further. With bandwidth configuration of the connection set to HIGH (6 packets per connection interval), you could send up to 800 packets each second (given that the other side of the link support this).

Children
  • Hi Jorgen,

    Thanks for the good point. I guess you mean 1000/7.5*6=800. Could you provide some suggestions on how to modify the code? Appreciate it!

  • If you can post the project, I can try to help you. There are also many threads on DevZone related to the same question.

  • Hi Jorgen, I attached my code here. I use two channels: one for temperature and the other for ECG.  Please help to take a look!

    void adc_1()
    {
        // interrupt ADC
        NRF_ADC->INTENSET = (ADC_INTENSET_END_Disabled <<
        ADC_INTENSET_END_Pos);                        /*!< Interrupt enabled. */
    
           // config ADC
           NRF_ADC->CONFIG = (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos) /* Bits 17..16 :
           ADC external reference pin selection. */
                                               | (ADC_CONFIG_PSEL_AnalogInput2 <<
                                               ADC_CONFIG_PSEL_Pos)                 /*!< Use analog
                                               input 0 as analog input. */
                                               | (ADC_CONFIG_REFSEL_VBG <<
                                               ADC_CONFIG_REFSEL_Pos)                          /*!<
                                               Use internal 1.2V bandgap voltage as reference for
                                               conversion. */
                                               | (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling <<
                                               ADC_CONFIG_INPSEL_Pos) /*!< Analog input specified by
                                               PSEL with no prescaling used as input for the
                                               conversion. */
                                               | (ADC_CONFIG_RES_10bit <<
                                               ADC_CONFIG_RES_Pos);
                                               /*!< 10bit ADC resolution. */
    
           // enable ADC
           NRF_ADC->ENABLE =
           ADC_ENABLE_ENABLE_Enabled;
                   /* Bit 0 : ADC enable. */
    
           // start ADC conversion
           NRF_ADC->TASKS_START = 1;
    
           // wait for conversion to end
           while (!NRF_ADC->EVENTS_END)
           {}
           NRF_ADC->EVENTS_END = 0;
    
         //Save your ADC result
         adc_result = NRF_ADC->RESULT;
         tempvalue=-1481.96+sqrt(2196200+(1.8639-adc_result*3.3/1023)/0.00000388);
         //Use the STOP task to save current. Workaround for PAN_028 rev1.1 anomaly 1.
       NRF_ADC->TASKS_STOP = 1;
    }
    void adc_2()
    {
        // interrupt ADC
           NRF_ADC->INTENSET = (ADC_INTENSET_END_Disabled <<
           ADC_INTENSET_END_Pos);                        /*!< Interrupt enabled. */
    
           // config ADC
           NRF_ADC->CONFIG = (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos) /* Bits 17..16 :
           ADC external reference pin selection. */
                                               | (ADC_CONFIG_PSEL_AnalogInput4 <<
                                               ADC_CONFIG_PSEL_Pos)                 /*!< Use analog
                                               input 0 as analog input. */
                                               | (ADC_CONFIG_REFSEL_VBG <<
                                               ADC_CONFIG_REFSEL_Pos)                          /*!<
                                               Use internal 1.2V bandgap voltage as reference for
                                               conversion. */
                                               | (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling <<
                                               ADC_CONFIG_INPSEL_Pos) /*!< Analog input specified by
                                               PSEL with no prescaling used as input for the
                                               conversion. */
                                               | (ADC_CONFIG_RES_10bit <<
                                               ADC_CONFIG_RES_Pos);
                                               /*!< 10bit ADC resolution. */
    
           // enable ADC
           NRF_ADC->ENABLE =
           ADC_ENABLE_ENABLE_Enabled;
                   /* Bit 0 : ADC enable. */
    
           // start ADC conversion
           NRF_ADC->TASKS_START = 1;
    
           // wait for conversion to end
           while (!NRF_ADC->EVENTS_END)
           {}
           NRF_ADC->EVENTS_END = 0;
    
         //Save your ADC result
         adc_output = NRF_ADC->RESULT;
         //Use the STOP task to save current. Workaround for PAN_028 rev1.1 anomaly 1.
       NRF_ADC->TASKS_STOP = 1;
    }
    /**@brief Application main function.
      */
    
    int main(void)
    {
        uint32_t err_code;
        bool erase_bonds;
        uint8_t start_string[] = START_STRING;
    
           // Initialize.
           APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
           uart_init();
           buttons_leds_init(&erase_bonds);
           ble_stack_init();
           gap_params_init();
           services_init();
           advertising_init();
    
           conn_params_init();
           printf("%s",start_string);
               printf("\n\rADC HAL simple example\r\n");
           printf("Current sample value:\r\n");
           err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
           APP_ERROR_CHECK(err_code);
                  // Enter main loop.
               while(true)
           {
                           adc_1();
                           adc_2();
                        // trigger next ADC conversion
                        //nrf_adc_start();
                  // enter into sleep mode
                  __SEV();
                  __WFE();
                  __WFE();
                           uint8_t str[4];
                           sprintf((char*)str, "ADC:%d TEMP: %.2f", (int)adc_result,(float)tempvalue);//
                           out ADC result
                           ble_nus_string_send(&m_nus, str, strlen((char*)str));
                        nrf_delay_ms(2000);
                           sprintf((char*)str, "ECG-ADC: %d", (int)adc_output);
                           ble_nus_string_send(&m_nus, str, strlen((char*)str));
                        nrf_delay_ms(2000);
                           power_manage();
           }
    
    
    }
    
    
    /**
     * @}
     */

  • This is not enough to help you with throughput. The throughput depends on the BLE configuration, which you have not included in above code. To be able to help you, I would need the entire project (including main/sdk_config.h/IDE project files).

Related