Measure battery voltage too high and how to use mutil ADC

Hi,

I'm using nRF52832 with S140 v7.2.0 base on nRF5_SDK_17.1.0. I use PCA10100 development kit and set VDDH/5 as input and use internal reference (0.6 V) to do the battery measure. I found the battery voltage measured is a bit high(3.3v) than the actural voltage(3.0v) . The ADC configuration as bellow:

void saadc_init(void)
{
    ret_code_t err_code;

		nrf_saadc_channel_config_t channel_config_NTC = {
    .resistor_p = NRF_SAADC_RESISTOR_DISABLED,      
    .resistor_n = NRF_SAADC_RESISTOR_DISABLED,      
    .gain       = NRF_SAADC_GAIN1_6,                
    .reference  = NRF_SAADC_REFERENCE_VDD4,     
    .acq_time   = NRF_SAADC_ACQTIME_10US,           
    .mode       = NRF_SAADC_MODE_SINGLE_ENDED,      
    .burst      = NRF_SAADC_BURST_DISABLED,         
    .pin_p      = NRF_SAADC_INPUT_AIN5,       
    .pin_n      = NRF_SAADC_INPUT_DISABLED          
		};
		
		nrfx_saadc_config_t    saadc_NTC_config = {
      .resolution = NRF_SAADC_RESOLUTION_12BIT       ///< Resolution configuration.
		};		
		
    err_code = nrf_drv_saadc_init(&saadc_NTC_config, saadc_NTC_callback);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_channel_init(1, &channel_config_NTC);
    APP_ERROR_CHECK(err_code);

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

I use the ADC result to caculate valtage such as: valtage=(ADC_VALUE*6*1200mv)/1024*5, 6 means NRF_SAADC_GAIN1_6, 1200mv means NRF_SAADC_REFERENCE_VDD4, 1024 means NRF_SAADC_RESOLUTION_10BIT and 5 means VDDH/5 as input.

Is there any problem with my code?

Besides, I want to use 4 ADC in total. But when I use the same way to configure another ADC as follow, it returns 0x11 error.

    nrf_saadc_channel_config_t channel_config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);

    err_code = nrf_drv_saadc_init(NULL, saadc_callback);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_channel_init(0, &channel_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);

Could you help me have a look? Thanks a lot.

Parents
  • Hi there,

    Correct me if I'm wrong but 1200mv for NRF_SAADC_REFERENCE_VDD4 seems a bit high, that means that VDD is 4*NRF_SAADC_REFERENCE_VDD4 = 4.8V which is higher than the allowed range for VDD. Can you share the raw ADC_VALUE value that is returned by nrf_drv_saadc_buffer_convert() when the voltage is 3V0?

    Also, what happens if you decrease the voltage down to 2V5. What does it sample as ADC_VALUE? 

    regards

    Jared 

  • Hi Jared,

    ADC_VALUE value is about 95 returned by nrf_drv_saadc_buffer_convert() when the voltage is 3.0V

    I shorted the solder SB36 on the PCA10100 board and then use external supply voltage with 3.0V,but nRF52833 doesn't work. I don't know why

    Regards,

    Alice

  • Hi Alice,

    If the gain is set to 1/6, the resolution to 10 bits, and the reference is VDD/4 where VDD == 3V0, then the ADC should return about 682. 

    Something is not correct in your setup. Are you now saying that the development board doesn't work at all? Can you measure the VDD voltage manually by measuring directly on the VDD header on the board? What voltage do you measure?

    regards
    Jared 

Reply
  • Hi Alice,

    If the gain is set to 1/6, the resolution to 10 bits, and the reference is VDD/4 where VDD == 3V0, then the ADC should return about 682. 

    Something is not correct in your setup. Are you now saying that the development board doesn't work at all? Can you measure the VDD voltage manually by measuring directly on the VDD header on the board? What voltage do you measure?

    regards
    Jared 

Children
  • Hi Jared,

    I use the NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE and just set NRF_SAADC_INPUT_VDD as input source, ADC returns about 854. I caculate the voltage is  3002mv. I use USB cable connect the development board with PC. Is the setup and result right? 

    Then I try to use external supply and I have shorted the solder SB36. I use external supply with 3.3V~3.6V, but 52832 doesn't work. I measured the VDD header on the board,the volage is the same with external supply voltage. 

    Regards,

    Alice

  • Alice said:

    I use the NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE and just set NRF_SAADC_INPUT_VDD as input source, ADC returns about 854. I caculate the voltage is  3002mv. I use USB cable connect the development board with PC. Is the setup and result right? 

    That sounds much better. 

    Alice said:
    Then I try to use external supply and I have shorted the solder SB36. I use external supply with 3.3V~3.6V, but 52832 doesn't work. I measured the VDD header on the board,the volage is the same with external supply voltage. 

    Is it the same code as when you plugged the DK to the computer? Did you modify anything in the code?

    regards

    Jared 

  • Hi Jared,

    Yes, I did't modify anything in the code and it is the same code as when I plugged the DK to the computer.

    Another question, I want to use 4 channel ADC. Now the ADC for measuring battery voltage is OK.  nrf_drv_saadc_init returns error 0x08 when I Initialized another ADC as follow:

    void saadc_init(void)
    {
        ret_code_t err_code;
    
    
    		nrf_saadc_channel_config_t channel_config_NTC = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN7);	
        err_code = nrf_drv_saadc_init(NULL, saadc_NTC_callback);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_channel_init(1, &channel_config_NTC);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);	
    
    
        nrf_saadc_channel_config_t channel_config_battery = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_VDD);			
    
        err_code = nrf_drv_saadc_init(NULL, saadc_Battery_callback);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_channel_init(0, &channel_config_battery);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);
    		
    }

    Regards,

    Alice

  • Hi Alice

    Jared is currently unavailable, and I will help you out in the mean time. 

    You can't initialize the SAADC driver multiple times, nrf_drv_saadc_init(..) should only be called once. 

    Typically the flow goes something like this:

    1) First run nrf_drv_saadc_init(..) to initialize the peripheral

    2) Run nrf_drv_saadc_channel_init(..) once for each channel that you want to use

    3) Run nrf_drv_saadc_buffer_convert(..) to set up the buffers

    4) Start sampling

    Best regards
    Torbjørn

Related