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

nrf52 adc spike problem

Hi,

I'm using nrf52 with s132(v17.0.0).

When I connect nrf52 with my phone, there is error like this picture.

And, the code is

#define SAADC_SAMPLES_IN_BUFFER 240

void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{
    if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
    {
        ret_code_t err_code;
        uint16_t bytes_to_send = (uint16_t) SAADC_SAMPLES_IN_BUFFER;
        uint8_t DATA[SAADC_SAMPLES_IN_BUFFER];
        // set buffers
        err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAADC_SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);

        // print samples on hardware UART and parse data for BLE transmission

        for (int i = 0; i < SAADC_SAMPLES_IN_BUFFER; i++)
        {
          DATA[i] = p_event->data.done.p_buffer[i];
        }
       err_code = ble_nus_data_send(&m_nus, DATA, &bytes_to_send, m_conn_handle);
         
        if ((err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_NOT_FOUND))
        {
            APP_ERROR_CHECK(err_code);
        }
        
    }
}

When the buffer is filled, then next buffer is filled by ADC value.

I guess the problem occurs at this time.

Also, when I use printf function to see value in PC, same problem occurs.

How can I solve this?

Thank you.

Parents
  • Hi.

    First of all, I attached screenshot picture which means Xaxis label(1st buffer, 2nd buffer).

    I applied sine graph. 

    In one buffer([0, ~ , 239]), there are linearity. And I can get sine graph so exactly.

    But when the buffer is changed, the problem occurs.

    There are no linearity.

    I guess the reason happens in changing buffer ( [0, ~ ,239] -> [0, ~ 239] ).

    And I'm using PPI to use SAADC function.

    I attached the code.

    Thanks

    void saadc_sampling_event_init(void)
    {
        ret_code_t err_code;
        err_code = nrf_drv_ppi_init();
        APP_ERROR_CHECK(err_code);
        
        nrf_drv_timer_config_t timer_config = NRF_DRV_TIMER_DEFAULT_CONFIG;
        timer_config.frequency = NRF_TIMER_FREQ_31250Hz;
    
        err_code = nrf_drv_timer_init(&m_timer, &timer_config, timer_handler);
        APP_ERROR_CHECK(err_code);
    
        /* setup m_timer for compare event */
        uint32_t ticks = nrf_drv_timer_us_to_ticks(&m_timer,SAADC_SAMPLE_RATE);
        nrf_drv_timer_extended_compare(&m_timer, NRF_TIMER_CC_CHANNEL0, ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);
        nrf_drv_timer_enable(&m_timer);
    
        uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer, NRF_TIMER_CC_CHANNEL0);
        uint32_t saadc_sample_event_addr = nrf_drv_saadc_sample_task_get();
    
        /* setup ppi channel so that timer compare event is triggering sample task in SAADC */
        err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel);
        APP_ERROR_CHECK(err_code);
        
        err_code = nrf_drv_ppi_channel_assign(m_ppi_channel, timer_compare_event_addr, saadc_sample_event_addr);
        APP_ERROR_CHECK(err_code);
    }
    
    
    void saadc_sampling_event_enable(void)
    {
        ret_code_t err_code = nrf_drv_ppi_channel_enable(m_ppi_channel);
        APP_ERROR_CHECK(err_code);
    }
    
    
    void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
    {
        if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
        {
            ret_code_t err_code;
            uint16_t bytes_to_send = (uint16_t) SAADC_SAMPLES_IN_BUFFER;
            uint8_t DATA[SAADC_SAMPLES_IN_BUFFER];
            // set buffers
            err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAADC_SAMPLES_IN_BUFFER);
            APP_ERROR_CHECK(err_code);
    
            // print samples on hardware UART and parse data for BLE transmission
    
            for (int i = 0; i < SAADC_SAMPLES_IN_BUFFER; i++)
            {
              DATA[i] = p_event->data.done.p_buffer[i];
              printf("%d\r\n", DATA[i]);
            }
           err_code = ble_nus_data_send(&m_nus, DATA, &bytes_to_send, m_conn_handle);
             
            if ((err_code != NRF_ERROR_INVALID_STATE) 
            && (err_code != NRF_ERROR_NOT_FOUND)
            && (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING))
            {
                APP_ERROR_CHECK(err_code);
            }
            
        }
    }
    
    
    void saadc_init(void)
    {
        ret_code_t err_code;
    	
        nrf_drv_saadc_config_t saadc_config = NRF_DRV_SAADC_DEFAULT_CONFIG;
        saadc_config.resolution = NRF_SAADC_RESOLUTION_8BIT;
    	
        nrf_saadc_channel_config_t channel_0_config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);
    
        channel_0_config.gain = NRF_SAADC_GAIN1_6;
        channel_0_config.reference = SAADC_CH_CONFIG_REFSEL_Internal;
        channel_0_config.acq_time = NRF_SAADC_ACQTIME_40US;
        
        err_code = nrf_drv_saadc_init(&saadc_config, saadc_callback);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_channel_init(0, &channel_0_config);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0],SAADC_SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);   
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1],SAADC_SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Application main function.
     */
    int main(void)
    {
        bool erase_bonds;
    
        // Initialize.
          uart_init();
        log_init();
        timers_init();
        buttons_leds_init(&erase_bonds);
        power_management_init();
        ble_stack_init();
        gap_params_init();
        gatt_init();
        services_init();
        advertising_init();
        conn_params_init();
        
        saadc_sampling_event_init();
        saadc_init();
        saadc_sampling_event_enable();
    
        // Start execution.
        printf("\r\nUART started.\r\n");
        NRF_LOG_INFO("Debug logging for UART over RTT started.");
        advertising_start();
    
        // Enter main loop.
        for (;;)
        {
            idle_state_handle();
        }
    }   

  • ENENER said:

    I applied sine graph. 

    In one buffer([0, ~ , 239]), there are linearity. And I can get sine graph so exactly.

    But when the buffer is changed, the problem occurs.

    There are no linearity.

    I guess the reason happens in changing buffer ( [0, ~ ,239] -> [0, ~ 239] ).

    And I'm using PPI to use SAADC function.

    Thank you for clarifying.

    Is the graph here from the values that the phone is receiving - i.e the phone is creating this graph to display the values it is getting, or is this a graph generated to illustrate the issue from the outputted SAADC values directly(no phone involved)? If there is a phone involved - could you tell me which BLE connection parameters are you using?
    How is this graph generated, and could you show me the raw output of the SAADC instead?
    I suppose the resolution of your graph is a little low, but it seems that the first value of the second buffer somehow is equal to the second last value of the first buffer.

    Since you are using double buffering the SAADC will immediately continue to sample into the next buffer once the first buffer is filled - so there will be no computational time necessary here before sampling resumes. This way, you will not miss a single sample.

    Best regards,
    Karl

Reply
  • ENENER said:

    I applied sine graph. 

    In one buffer([0, ~ , 239]), there are linearity. And I can get sine graph so exactly.

    But when the buffer is changed, the problem occurs.

    There are no linearity.

    I guess the reason happens in changing buffer ( [0, ~ ,239] -> [0, ~ 239] ).

    And I'm using PPI to use SAADC function.

    Thank you for clarifying.

    Is the graph here from the values that the phone is receiving - i.e the phone is creating this graph to display the values it is getting, or is this a graph generated to illustrate the issue from the outputted SAADC values directly(no phone involved)? If there is a phone involved - could you tell me which BLE connection parameters are you using?
    How is this graph generated, and could you show me the raw output of the SAADC instead?
    I suppose the resolution of your graph is a little low, but it seems that the first value of the second buffer somehow is equal to the second last value of the first buffer.

    Since you are using double buffering the SAADC will immediately continue to sample into the next buffer once the first buffer is filled - so there will be no computational time necessary here before sampling resumes. This way, you will not miss a single sample.

    Best regards,
    Karl

Children
Related