Saadc stuck in calibration + Mesh 5.0.0

hi.

I have a firmware using standard GATT, now im implementing the mesh layer.

Im using SDK 17.0.2 + MESH 5.0.0. (im not using the new sdk connect because it is very difficult to me)

in my node i have implemented the SAADC using only the library 17.0.2, the rutine GET_temperature, WORKS fine

BUT, when i integrate this rutine in the MESH, the program stuck in the while (nrfx_saadc_is_busy())

could you help me, what is the wrong?

I did some thing but not works.

1.- eliminate the all wait for event and interface. not worked

2.- Increase the saadc priority, but not work.

I 

uint16_t GetTemperature(void){
  
  ret_code_t err_code;
  uint16_t med_temp=0;
  int16_t temp_avg_1=0;
  int16_t temp_max=0;
  int16_t temp_min=0;

  while (med_temp<100)
  {
    if (!nrf_drv_saadc_is_busy())
    {
      med_temp++;
      adc_buf_NPT=0;

     err_code = nrfx_saadc_calibrate_offset();

********** from HERE **********
     while (nrfx_saadc_is_busy()) // Wait for calibration to complete
     {
        __WFE(); //
        __SEV(); //
        __WFE(); // This sequence puts the system to sleep (SystemON) while waiting
      }
********** To HERE **********
    APP_ERROR_CHECK(err_code);
      
      err_code =nrfx_saadc_sample_convert(0, &adc_buf_NPT);
      if (temp_max==0) temp_max=adc_buf_NPT;
      if (temp_min==0) temp_min=adc_buf_NPT;
      if (adc_buf_NPT<=temp_min) temp_min=adc_buf_NPT;
      if (adc_buf_NPT>=temp_max) temp_max=adc_buf_NPT;         
      if (adc_buf_NPT<0) {adc_buf_NPT=0;}    
      temp_avg_1= (temp_avg_1*(med_temp-1) +adc_buf_NPT)/(med_temp);  
      APP_ERROR_CHECK(err_code); 
    } 
  }

thanks.

Ricardo

Parents
  • Hi Ricardo!

    Do you want to put the device to sleep (system on) while waiting?

    the program stuck in the while (nrfx_saadc_is_busy())

    Can you see any error codes or logs?

    Br,
    Joakim

  • Hi Joakim

    thanks for your answew

    Do you want to put the device to sleep (system on) while waiting?

    -No,  I dont  want to put the sleep (system on)

    Can you see any error codes or logs?

    the device does not send any error. only it is stucking in the while cycle, waiting the saadc finish.

    the objective of the firmware is the device belong a mesh, and send the temperature, the temeprature is measure by ADC fuction. this fuction WORKS in a standad firmware using GATT Bluetooth LE broadcasting.

    But now, when the device using MESH topology, when I want to calibrate the ADC, the cycle stuck when waiting to nrfx_saadc_is_busy()

    are there some restriction using MESH and reading/calibrating SAADC at the same time?

    thanks

    Ricardo.

  • Hi.

    Saw you created another ticket for this, where you got a suggestion from one of my colleagues;
    "It looks to me like you always calibrate before measurement. In that case I would likely have enabled saadcs interrupt on CALIBRATEDONE event, then configured an app_timer to trigger an nrfx_saadc_calibrate_offset() on given intervals, and then on each CALIBRATEDONE event in the saadc interrupt you can execute an adc sample conversion. The actual sample value(s) can be stored in some global buffer that is fetched by calling GetTemperature()."

     Br,
    Joakim

  • Hi Joakim

    Thanks for you follow up.

    The principal problem is when we use MESH, the radio has a first priority of the interruptions.

    in my case the problem was to use the WHILE to check  nrfx_saadc_is_busy(), to wait if the calibration is ready, this while, generate a anormal behaviour.

    The solution was secuenciate the steps of the SAADC (init, calibration, waiting calibration, measure, un init) this secuencial step I include in the main loop.

    I share part of the code.

    important take a look to this

    thanks

    Ricardo

    int main(void) {
      bsp_board_init(BSP_INIT_LEDS);
      Temp_adc[0]=NRF_SAADC_INPUT_AIN2;
      Temp_adc[1]=NRF_SAADC_INPUT_AIN4;
      ret_code_t err_code;
      
      __LOG_INIT(LOG_SRC_APP, LOG_LEVEL_DBG1, LOG_CALLBACK_DEFAULT);
      __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- BLE Mesh App Demo PARA NODO -----\n");
    
      ERROR_CHECK(app_timer_init());
      mesh_helper_init();
      mesh_helper_start();
    
      
      ERROR_CHECK(app_timer_create(&timer, APP_TIMER_MODE_REPEATED, periodic_Measure));
      ERROR_CHECK(app_timer_start(timer, APP_TIMER_TICKS(5000), NULL));
    
      ERROR_CHECK(app_timer_create(&timer2, APP_TIMER_MODE_REPEATED, periodic_send));
      ERROR_CHECK(app_timer_start(timer2, APP_TIMER_TICKS(500), NULL));
    
      while (1) {
          sd_app_evt_wait();
        
          if (Step_Process==Temp_init)
          {
          bsp_board_led_on(1);
          Temperature_voltage_init(Temp_adc[Adc_temp]);
          Step_Process = Temp_calibration;
          }
          if (Step_Process == Temp_calibration) {
            err_code = nrfx_saadc_calibrate_offset();
            APP_ERROR_CHECK(err_code);
            Step_Process = Temp_cal_wait;
          }
    
          if (Step_Process == Temp_cal_wait) {
            if (!nrfx_saadc_is_busy()) {
              Step_Process = Temp_measure;
            }
          }
          if (Step_Process == Temp_measure) {
            adc_buf_NPT_result[Adc_temp] = GetTemperature();
            nrf_drv_saadc_channel_uninit(0);
            nrf_drv_saadc_uninit();
            if (Adc_temp < 1) {
              Adc_temp++;
              Step_Process = Temp_init;
            } else {
              
              Adc_temp=0;
              Sonda_temp1 = Temp_NTC(adc_buf_NPT_result[0]);
              Sonda_temp2 = Temp_NTC(adc_buf_NPT_result[1]);
              temp = Sonda_temp1;
              Measuring_ok = true;
              Step_Process = Temp_Finish;
    
            }
          }
      }
    }

Reply
  • Hi Joakim

    Thanks for you follow up.

    The principal problem is when we use MESH, the radio has a first priority of the interruptions.

    in my case the problem was to use the WHILE to check  nrfx_saadc_is_busy(), to wait if the calibration is ready, this while, generate a anormal behaviour.

    The solution was secuenciate the steps of the SAADC (init, calibration, waiting calibration, measure, un init) this secuencial step I include in the main loop.

    I share part of the code.

    important take a look to this

    thanks

    Ricardo

    int main(void) {
      bsp_board_init(BSP_INIT_LEDS);
      Temp_adc[0]=NRF_SAADC_INPUT_AIN2;
      Temp_adc[1]=NRF_SAADC_INPUT_AIN4;
      ret_code_t err_code;
      
      __LOG_INIT(LOG_SRC_APP, LOG_LEVEL_DBG1, LOG_CALLBACK_DEFAULT);
      __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- BLE Mesh App Demo PARA NODO -----\n");
    
      ERROR_CHECK(app_timer_init());
      mesh_helper_init();
      mesh_helper_start();
    
      
      ERROR_CHECK(app_timer_create(&timer, APP_TIMER_MODE_REPEATED, periodic_Measure));
      ERROR_CHECK(app_timer_start(timer, APP_TIMER_TICKS(5000), NULL));
    
      ERROR_CHECK(app_timer_create(&timer2, APP_TIMER_MODE_REPEATED, periodic_send));
      ERROR_CHECK(app_timer_start(timer2, APP_TIMER_TICKS(500), NULL));
    
      while (1) {
          sd_app_evt_wait();
        
          if (Step_Process==Temp_init)
          {
          bsp_board_led_on(1);
          Temperature_voltage_init(Temp_adc[Adc_temp]);
          Step_Process = Temp_calibration;
          }
          if (Step_Process == Temp_calibration) {
            err_code = nrfx_saadc_calibrate_offset();
            APP_ERROR_CHECK(err_code);
            Step_Process = Temp_cal_wait;
          }
    
          if (Step_Process == Temp_cal_wait) {
            if (!nrfx_saadc_is_busy()) {
              Step_Process = Temp_measure;
            }
          }
          if (Step_Process == Temp_measure) {
            adc_buf_NPT_result[Adc_temp] = GetTemperature();
            nrf_drv_saadc_channel_uninit(0);
            nrf_drv_saadc_uninit();
            if (Adc_temp < 1) {
              Adc_temp++;
              Step_Process = Temp_init;
            } else {
              
              Adc_temp=0;
              Sonda_temp1 = Temp_NTC(adc_buf_NPT_result[0]);
              Sonda_temp2 = Temp_NTC(adc_buf_NPT_result[1]);
              temp = Sonda_temp1;
              Measuring_ok = true;
              Step_Process = Temp_Finish;
    
            }
          }
      }
    }

Children
No Data
Related