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

  • it returns NRF_SUCCESS and I see the value of conversion

    It seems adc interrupt correlates with BLE interrupts, cause when I increased the timer and connected to ble device before my adc handler interrupted I got working device

  • I see that you are using interrupt priority 0, this is reserved for the SoftDevice and shouldn't used. The application can use interrupt priority 1 or 3.

  • I changed adc interrupt priority to 3 (the lowest priority) and It didn't help, if I connect to ble in the same time when adc handler is activated I get error, if I connect earlier or later then adc is activated then everything is ok. I thought softdevice has the highest priority

  • Ok. Have you been able to put a breakpoint in app_error_handler()? What is the line number, file name and error code?

  • yes, I put breakpoint and got error:

    error_code: 13313
    in this code
    
    if (!m_hts_meas_ind_conf_pending)
        {
            hts_sim_measurement(&simulated_meas, value);
            NRF_LOG_INFO("hts_sim_measurement\r\n");
            err_code = ble_hts_measurement_send(&m_hts, &simulated_meas);
    
            switch (err_code)
            {
                case NRF_SUCCESS:
                    // Measurement was successfully sent, wait for confirmation.
                    NRF_LOG_INFO("Measurement was successfully sent, wait for confirmation.\r\n");
                    m_hts_meas_ind_conf_pending = true;
                    break;
    
                case NRF_ERROR_INVALID_STATE:
                    // Ignore error.
                    NRF_LOG_INFO("Measurement has invalid state.\r\n");
                    break;
    
                default:
                    **APP_ERROR_HANDLER(err_code);**
                    break;
            }
        }
    

    highlighted the error with **

    It seems to me I fixed this error.

    I use adc to measure the temperature and I have a variable which has boolean values isConnected. I set true in this case

    case BLE_GAP_EVT_CONNECTED:
    isConnected = true;
    

    And every time when my data from adc is ready I check this variable, if it's true, I send the new value.

    I guess I would send it before my services are initiated, and this error has come. I remove setting the value from line above and set it in this line

    case BLE_HTS_EVT_INDICATION_ENABLED:
    isConnected = true;
    

    And now it works!

Related