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

problem with SAADC Scan mode on 4 anolog channels

Hello I am currently using the NRF52 DK2 PCA10040 with S132 soft device (nRF52 SDK v0.9.2) . I have setup my code to sample 4 analog pins periodically. I configured double buffering non-blocking mode through the driver and have a callback function sending all 4 results over BLE through the UART BLE service. I am using the nRF UART console android application to view my send data. I have set the ADC resolution to 12 bit.

I am only able to receive data for the first two channels when taking values from p_event->data.done.p_buffer

I assume the results should be stored in order from p_buffer[0] - p_buffer[3]. However i recieve results for:

  • ADC channel 0: on p_buffer[0]
  • ADC channel 1: on p_buffer[2]
  • ADC channel 2: can not be seen
  • ADC channel 3: seen on p_buffer[1] and p_buffer[3] (they both read high values when shorted to VDD but are different each time i receive)

I tested this by shorting all ANALOG pins to VDD individually and viewing the Console output.I am unsure if i am reading the pointer in the wrong order or if there is a bug somewhere else.

link to dl my project folder : www.filedropper.com/bleappuart

#define SAMPLES_IN_BUFFER 4
static nrf_saadc_value_t       m_buffer_pool[2][SAMPLES_IN_BUFFER];

void saadc_sampling_event_init(void)
{
    ret_code_t err_code;
    err_code = nrf_drv_ppi_init();
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_timer_init(&m_timer, NULL, timer_handler);
    APP_ERROR_CHECK(err_code);

    /* setup m_timer for compare event every 100ms */
    uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer, 1000);
    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_task_address_get(NRF_SAADC_TASK_SAMPLE);

    /* 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);
}

// Enable ADC sampling event
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)
{
    // Done Event
    if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
    {
        ret_code_t err_code;
     
        err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);
        
        
        //printf("ADC event number: %d\r\n",(int)m_adc_evt_counter);
        char buffer[256];
        unsigned int message_length;
        message_length = sprintf(buffer, "%d %d %d %d", p_event->data.done.p_buffer[0], p_event->data.done.p_buffer[1], p_event->data.done.p_buffer[2], p_event->data.done.p_buffer[3]);
        ble_nus_string_send(&m_nus,(uint8_t *)&buffer,message_length); 
        m_adc_evt_counter++;
    }
}

void saadc_init(void)
{
    ret_code_t err_code;
    
    // Setup All SAADC Channels
    nrf_saadc_channel_config_t channel_1_config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN4);
    channel_1_config.acq_time = NRF_SAADC_ACQTIME_10US;
    channel_1_config.gain = NRF_SAADC_GAIN1_4;
    channel_1_config.reference = NRF_SAADC_REFERENCE_VDD4;
    
    nrf_saadc_channel_config_t channel_2_config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN5);
    channel_2_config.acq_time = NRF_SAADC_ACQTIME_10US;
    channel_2_config.gain = NRF_SAADC_GAIN1_4;
    channel_2_config.reference = NRF_SAADC_REFERENCE_VDD4;
    
    nrf_saadc_channel_config_t channel_3_config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN6);
    channel_3_config.acq_time = NRF_SAADC_ACQTIME_10US;
    channel_3_config.gain = NRF_SAADC_GAIN1_4;
    channel_3_config.reference = NRF_SAADC_REFERENCE_VDD4;
    
    nrf_saadc_channel_config_t channel_4_config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN7);
    channel_4_config.acq_time = NRF_SAADC_ACQTIME_10US;
    channel_4_config.gain = NRF_SAADC_GAIN1_4;
    channel_4_config.reference = NRF_SAADC_REFERENCE_VDD4;
    
    err_code = nrf_drv_saadc_init(NULL, saadc_callback);
    APP_ERROR_CHECK(err_code);
    
    // Initialize Channels
    err_code = nrf_drv_saadc_channel_init(0, &channel_1_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(1, &channel_2_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(2, &channel_3_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(3, &channel_4_config);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0],SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);
    
    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1],SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);
}
Related