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

BLE + ADC + Timer

Hey everyone. I'm trying to read ADC value from sensor and send it via ble.

I use timer to get the value from sensor every 5 seconds, however ADC interruption correlates with BLE interruption and I get an error via serial port

APP_ERROR:ERROR:Fatal
:INFO:Health Themometer Sensor Start!
:INFO:Fast advertising
:INFO:ADC event counter: 1
:INFO:Temperature: 24°C
:INFO:ADC event counter: 2
:INFO:Temperature: 24°C
APP_ERROR:ERROR:Fatal
:INFO:Health Themometer Sensor Start!
:INFO:Fast advertising 

I looked at hts example where it uses timer for simulation battery level and it works, but my not.

I have 3 main functions:

static void lmt70_event_handler(nrf_drv_adc_evt_t const * p_event) // this is adc conversion interruption, if I remove everything below, I don't have errors, but even though I remove everything instead of first NRF_LOG I get this error again
{
    if (p_event->type == NRF_DRV_ADC_EVT_DONE)
    {
        adc_counter++;
        NRF_LOG_INFO("ADC event counter: %d\r\n", adc_counter);

        float LMT70_reading = ADC_RESULT_IN_MILLI_VOLTS(p_event->data.done.p_buffer[0]);
        float A_val = LMT70_AMul * (LMT70_reading * LMT70_reading * LMT70_reading);
        float B_val = LMT70_BMul * (LMT70_reading * LMT70_reading);
        float C_val = LMT70_CMul * LMT70_reading;

        float degC = A_val + B_val + C_val + LMT70_DMul;
        if (isConnected)
            temperature_measurement_send(degC);
        NRF_LOG_INFO("Temperature: %d°C\r\n", degC);
       
    }
}

static void lmt70_timeout_handler(void * p_context) // this is timer interruption
{
    UNUSED_PARAMETER(p_context);
    APP_ERROR_CHECK(nrf_drv_adc_buffer_convert(adc_buffer, ADC_BUFFER_SIZE));
    for (uint32_t i = 0; i < ADC_BUFFER_SIZE; i++)
    {
        nrf_drv_adc_sample();
        __SEV();
        __WFE();
        __WFE();
        NRF_LOG_FLUSH();
    }
}

I use 2.0.1 softdevice

  • What SDK are you using? If you define DEBUG and put a breakpoint in app_error_handler(), what is the line number, file name and error code? You should turn of optimizations.

  • I use 12.2.0

    what I got via gdb

    (gdb) bt
    #0  0x0001bd6a in app_error_save_and_stop (id=1, pc=63332, info=0)
        at /Users/im/Dropbox/nRF51822/Unzipped/SDK/12.2.0/components/libraries/util/app_error.c:113
    #1  0x0001bdaa in app_error_fault_handler (id=1, pc=63332, info=0)
        at /Users/im/Dropbox/nRF51822/Unzipped/SDK/12.2.0/components/libraries/util/app_error_weak.c:32
    #2  0x000299c8 in softdevice_fault_handler (id=1, pc=63332, info=0)
        at /Users/im/Dropbox/nRF51822/Unzipped/SDK/12.2.0/components/softdevice/common/softdevice_handler/softdevice_handler.c:90
    #3  <signal handler called>
    #4  0x0000f766 in ?? ()
    #5  0x0000f71c in ?? ()
    Backtrace stopped: previous frame identical to this frame (corrupt stack?)
    
  • Not app_error_save_and_stop(), but app_error_handler():

    void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
    {
        error_info_t error_info =
        {
            .line_num    = line_num,
            .p_file_name = p_file_name,
            .err_code    = error_code,
        };
        app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info));
    
        UNUSED_VARIABLE(error_info);
    }
    
  • I found the problem with this block

    static void lmt70_timeout_handler(void * p_context)
    {
        UNUSED_PARAMETER(p_context);
        NRF_LOG_INFO("lmt70_timeout_handler\r\n");
        /*APP_ERROR_CHECK(nrf_drv_adc_buffer_convert(adc_buffer, ADC_BUFFER_SIZE));
        for (uint32_t i = 0; i < ADC_BUFFER_SIZE; i++)
        {
            // manually trigger ADC conversion
            nrf_drv_adc_sample();
            // enter into sleep mode
            __SEV();
            __WFE();
            __WFE();
            nrf_delay_ms(100);
            NRF_LOG_FLUSH();
        }*/
    }
    

    If I leave this code commented, ble and timer work fine, if I remove comments I get this problem which described above.

    my ADC is:

    ret_code_t ret_code;
        nrf_drv_adc_config_t config = NRF_DRV_ADC_DEFAULT_CONFIG;
        config.interrupt_priority = 0;
    
        ret_code = nrf_drv_adc_init(&config, lmt70_event_handler);
        APP_ERROR_CHECK(ret_code);
    
        channel1.config.config.input = NRF_ADC_CONFIG_SCALING_INPUT_FULL_SCALE;
        channel1.config.config.resolution = NRF_ADC_CONFIG_RES_10BIT;
        channel1.config.config.reference = NRF_ADC_CONFIG_REF_VBG;
    
        nrf_drv_adc_channel_enable(&channel1);
        timer_init();
    
  • What does nrf_drv_adc_buffer_convert() return? NRF_SUCCESS (0x00000000)? Or an error? (PS. When using the SoftDevice you can use sd_app_evt_wait() instead of

        __SEV();
        __WFE();
        __WFE();
    
Related