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

Apptimer stop working

Hello.

I am doing a small project where nrf52 reads data from a BME280 temperature sensor via SPI and sends it using ESB.

I have no experience with radio, so I use a ready-made module HOLYIOT-17029 with nRF52832 and PA 2401C.

The device is running on battery power, so it is in sleep mode, upon an event from the Apptimer, it wakes up, turns on clocking HFCLK for SPI, takes data from the BME280 and sends it.

In the ESB handler, I turn off clocking and turn off PA. After exiting the handler, in the main loop, the device falls asleep.

There is also a solar panel. To control the battery and solar panel, I use two chanel of SAADC in polling mode.

The problem is that after a while, the events from the apptimer stop happening.

For debugging I use J-Link and Segger Ozone. I can successfully "attach to running program" without resetting and stop it. It stop in the main loop. I can put a breakpoint in the event handler of the Apptimer event, and I see that it does not happen.

The strangest thing is that if I reset from the debugger and load the firmware again, the events from the apptimer still do not occur. But if I turn off the power and turn it back on, everything starts working again for some time.

Apptimer events occur every 10 seconds. The time until the disappearance of apptimer events is different each time - from 40 minutes to several hours.

The whole project is on github https://github.com/Sergey1560/nrf52_bme280

Here are, in my opinion, the most important parts of the code:

Main loop:

int main(void){
   
   APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
   NRF_LOG_DEFAULT_BACKENDS_INIT();

   NRF_LOG_INFO("Start");
   
   //Start HFCLK for SPI
   clocks_start();

   lfclk_request();
   configure_ram_retention();

   saadc_init();
   spi_init();
   esb_init();

   //Init BME280 
   user_bme280_init();

   //Init App timer 
   init_timer();
     
    while (1) {
            // Enter System ON sleep mode
            __WFE();
            __SEV();
            __WFE();
    }
}

Apptimer init and handler:

void init_timer(void){
    ret_code_t err_code;

    err_code=app_timer_init();
    APP_ERROR_CHECK(err_code);
    
    // Create timers
    err_code = app_timer_create(&timer_id, APP_TIMER_MODE_REPEATED, timer_handler);
    APP_ERROR_CHECK(err_code);

    err_code = app_timer_start(timer_id, APP_TIMER_TICKS(TIMER_MS), NULL);
    APP_ERROR_CHECK(err_code);

}


void timer_handler(void * p_context){
    NRF_LOG_INFO("Timer");
    struct bme280_data bme_data;
    struct tx_data bme_tx_data;
    static uint32_t count=0;

    int16_t adc_value;
    int16_t solar_value;
    double d,p;

    //Start HFCLK for SPI
    clocks_start();
    
    adc_value = saadc_measure(0);
    solar_value = saadc_measure(1);
    
    if(adc_value < 0) adc_value = 0;
    if(solar_value < 0) solar_value = 0;
    
    d = (3.3 * adc_value) / 1024.0;
    d = d * 1.55 * 100.0;

    p = (3.3 * solar_value) / 1024.0;
    p = p * 2 * 1.1 * 100.0;

    bme_data = user_bme280_poll();

    bme_tx_data.count = count;
    bme_tx_data.temperature = bme_data.temperature;
    bme_tx_data.humidity = bme_data.humidity;
    bme_tx_data.pressure = bme_data.pressure;
    bme_tx_data.vbat = (uint32_t)d;
    bme_tx_data.solar_bat = (uint32_t)p;
   
    NRF_LOG_INFO("Cnt: %d Bat %d Solar %d Temp: %d",count++,d,p,bme_tx_data.temperature);

    send_esb_packet(&bme_tx_data);
    
}

ESB send function and event handler:

void send_esb_packet(struct tx_data *data){
    
    set_pa_mode(PA_TX_MODE);

    memcpy(tx_payload.data, (uint32_t *)data, sizeof(struct tx_data));
    NRF_LOG_INFO("Transmitting packet");
    
    if (nrf_esb_write_payload(&tx_payload) != NRF_SUCCESS){
        NRF_LOG_WARNING("write packet failed");
    }
}

void nrf_esb_event_handler(nrf_esb_evt_t const * p_event){
    switch (p_event->evt_id) {
        case NRF_ESB_EVENT_TX_SUCCESS:
            NRF_LOG_DEBUG("TX SUCCESS EVENT");
            break;
        case NRF_ESB_EVENT_TX_FAILED:
            NRF_LOG_DEBUG("TX FAILED EVENT");
            (void) nrf_esb_flush_tx();
            break;
        default:
            NRF_LOG_DEBUG("RX RECEIVED EVENT");
            (void) nrf_esb_flush_tx();
            break;
    }
    //Disable PA
    set_pa_mode(PA_OFF_MODE);
    //Stop Clock
    clocks_stop();
}

Related